src/app/state.rs (4952B)
1 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2 pub enum SyncState {
3 Idle,
4 Scanning,
5 }
6
7 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
8 pub enum PlayState {
9 Playing,
10 Paused,
11 Stopped,
12 }
13
14 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
15 pub enum RepeatMode {
16 Off,
17 All,
18 One,
19 }
20
21 impl RepeatMode {
22 pub fn next(self) -> Self {
23 match self {
24 RepeatMode::Off => RepeatMode::All,
25 RepeatMode::All => RepeatMode::One,
26 RepeatMode::One => RepeatMode::Off,
27 }
28 }
29
30 pub fn as_str(self) -> &'static str {
31 match self {
32 RepeatMode::Off => "Off",
33 RepeatMode::All => "All",
34 RepeatMode::One => "One",
35 }
36 }
37
38 pub fn from_label(s: &str) -> Self {
39 match s {
40 "All" => RepeatMode::All,
41 "One" => RepeatMode::One,
42 _ => RepeatMode::Off,
43 }
44 }
45
46 pub fn symbol(self) -> &'static str {
47 match self {
48 RepeatMode::Off => "\u{F0456}", // nf-md-repeat
49 RepeatMode::All => "\u{F0456}", // nf-md-repeat
50 RepeatMode::One => "\u{F0458}", // nf-md-repeat_once
51 }
52 }
53 }
54
55 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
56 pub enum Tab {
57 Queue,
58 Directories,
59 Artists,
60 Albums,
61 Genre,
62 Format,
63 Playlists,
64 }
65
66 impl Tab {
67 pub const ALL: [Tab; 7] = [
68 Tab::Queue,
69 Tab::Directories,
70 Tab::Artists,
71 Tab::Albums,
72 Tab::Genre,
73 Tab::Format,
74 Tab::Playlists,
75 ];
76
77 pub fn title(self) -> &'static str {
78 match self {
79 Tab::Queue => "Queue",
80 Tab::Directories => "Directories",
81 Tab::Artists => "Artists",
82 Tab::Albums => "Albums",
83 Tab::Genre => "Genre",
84 Tab::Format => "Format",
85 Tab::Playlists => "Playlists",
86 }
87 }
88
89 pub fn index(self) -> usize {
90 Tab::ALL.iter().position(|&t| t == self).unwrap_or(0)
91 }
92
93 pub fn from_index(i: usize) -> Self {
94 Tab::ALL.get(i).copied().unwrap_or(Tab::Queue)
95 }
96 }
97
98 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
99 pub enum FocusedPane {
100 Library,
101 Playlist,
102 Lyrics,
103 }
104
105 impl FocusedPane {
106 pub fn next(self) -> Self {
107 match self {
108 FocusedPane::Library => FocusedPane::Playlist,
109 FocusedPane::Playlist => FocusedPane::Lyrics,
110 FocusedPane::Lyrics => FocusedPane::Library,
111 }
112 }
113
114 pub fn prev(self) -> Self {
115 match self {
116 FocusedPane::Library => FocusedPane::Lyrics,
117 FocusedPane::Playlist => FocusedPane::Library,
118 FocusedPane::Lyrics => FocusedPane::Playlist,
119 }
120 }
121 }
122
123 #[derive(Debug, Clone)]
124 pub struct PlaybackState {
125 pub state: PlayState,
126 pub position_secs: f64,
127 pub duration_secs: f64,
128 pub volume: f32,
129 pub shuffle: bool,
130 pub repeat: RepeatMode,
131 }
132
133 impl Default for PlaybackState {
134 fn default() -> Self {
135 Self {
136 state: PlayState::Stopped,
137 position_secs: 0.0,
138 duration_secs: 0.0,
139 volume: 0.8,
140 shuffle: false,
141 repeat: RepeatMode::Off,
142 }
143 }
144 }
145
146 #[derive(Debug, Clone, Default)]
147 pub struct QueueState {
148 pub tracks: Vec<usize>,
149 pub current_index: Option<usize>,
150 pub selected_index: usize,
151 /// Positions into `tracks`, in shuffled play order — a real permutation, so
152 /// a shuffled pass reaches every track exactly once and can end. Empty while
153 /// shuffle is off.
154 pub shuffle_order: Vec<usize>,
155 /// How far into `shuffle_order` playback has got. Also what makes "previous"
156 /// mean the previous shuffled track rather than the previous queue row.
157 pub shuffle_pos: usize,
158 }
159
160 #[derive(Debug, Clone)]
161 pub struct Playlist {
162 pub name: String,
163 pub tracks: Vec<usize>,
164 /// Paths the library did not contain at the last remap, kept verbatim.
165 /// An unmounted drive or a partial scan must not delete playlist entries,
166 /// so they park here and are restored the moment the files reappear.
167 pub missing: Vec<std::path::PathBuf>,
168 }
169
170 impl Playlist {
171 pub fn new(name: impl Into<String>) -> Self {
172 Self {
173 name: name.into(),
174 tracks: Vec::new(),
175 missing: Vec::new(),
176 }
177 }
178 }
179
180 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
181 pub enum InfoView {
182 Clock,
183 AlbumArt,
184 }
185
186 impl InfoView {
187 pub fn next(self) -> Self {
188 match self {
189 InfoView::Clock => InfoView::AlbumArt,
190 InfoView::AlbumArt => InfoView::Clock,
191 }
192 }
193
194 pub fn as_str(self) -> &'static str {
195 match self {
196 InfoView::Clock => "Clock",
197 InfoView::AlbumArt => "AlbumArt",
198 }
199 }
200
201 pub fn from_label(s: &str) -> Self {
202 match s {
203 "AlbumArt" => InfoView::AlbumArt,
204 _ => InfoView::Clock,
205 }
206 }
207 }
208