ommp.git

ommp

~ Oh My Music Player — a standalone terminal music player built with Rust and ratatui
git clone https://github.com/debuman/ommp.git

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