use crate::{
command,
state::model::{Album, Artist, Episode, EpisodeId, Playlist, Show, Track, TrackId},
ui::single_line_input::LineInput,
};
use ratatui::widgets::ListState;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PlaylistCreateCurrentField {
Name,
Desc,
}
#[derive(Debug)]
pub enum PopupState {
Search {
query: String,
},
UserPlaylistList(PlaylistPopupAction, ListState),
UserFollowedArtistList(ListState),
UserSavedAlbumList(ListState),
DeviceList(ListState),
ArtistList(ArtistPopupAction, Vec<Artist>, ListState),
ThemeList(Vec<crate::config::Theme>, ListState),
ActionList(Box<ActionListItem>, ListState),
PlaylistCreate {
name: LineInput,
desc: LineInput,
current_field: PlaylistCreateCurrentField,
},
}
#[derive(Debug, Clone)]
pub enum ActionListItem {
Track(Track, Vec<command::Action>),
Artist(Artist, Vec<command::Action>),
Album(Album, Vec<command::Action>),
Playlist(Playlist, Vec<command::Action>),
Show(Show, Vec<command::Action>),
Episode(Episode, Vec<command::Action>),
}
#[derive(Debug)]
pub enum PlaylistPopupAction {
Browse {
folder_id: usize,
search_query: String,
},
AddTrack {
folder_id: usize,
track_id: TrackId<'static>,
search_query: String,
},
AddEpisode {
folder_id: usize,
episode_id: EpisodeId<'static>,
search_query: String,
},
}
#[derive(Copy, Clone, Debug)]
pub enum ArtistPopupAction {
Browse,
ShowActions,
}
impl PopupState {
pub fn list_state(&self) -> Option<&ListState> {
match self {
Self::DeviceList(list_state)
| Self::UserPlaylistList(.., list_state)
| Self::UserFollowedArtistList(list_state)
| Self::UserSavedAlbumList(list_state)
| Self::ArtistList(.., list_state)
| Self::ThemeList(.., list_state)
| Self::ActionList(.., list_state) => Some(list_state),
Self::Search { .. } | Self::PlaylistCreate { .. } => None,
}
}
pub fn list_state_mut(&mut self) -> Option<&mut ListState> {
match self {
Self::DeviceList(list_state)
| Self::UserPlaylistList(.., list_state)
| Self::UserFollowedArtistList(list_state)
| Self::UserSavedAlbumList(list_state)
| Self::ArtistList(.., list_state)
| Self::ThemeList(.., list_state)
| Self::ActionList(.., list_state) => Some(list_state),
Self::Search { .. } | Self::PlaylistCreate { .. } => None,
}
}
pub fn list_selected(&self) -> Option<usize> {
match self.list_state() {
None => None,
Some(state) => state.selected(),
}
}
pub fn list_select(&mut self, id: Option<usize>) {
match self.list_state_mut() {
None => {}
Some(state) => state.select(id),
}
}
}
impl ActionListItem {
pub fn n_actions(&self) -> usize {
match self {
ActionListItem::Track(.., actions)
| ActionListItem::Artist(.., actions)
| ActionListItem::Album(.., actions)
| ActionListItem::Playlist(.., actions)
| ActionListItem::Show(.., actions)
| ActionListItem::Episode(.., actions) => actions.len(),
}
}
pub fn name(&self) -> &str {
match self {
ActionListItem::Track(track, ..) => &track.name,
ActionListItem::Artist(artist, ..) => &artist.name,
ActionListItem::Album(album, ..) => &album.name,
ActionListItem::Playlist(playlist, ..) => &playlist.name,
ActionListItem::Show(show, ..) => &show.name,
ActionListItem::Episode(episode, ..) => &episode.name,
}
}
pub fn actions_desc(&self) -> Vec<String> {
match self {
ActionListItem::Track(.., actions)
| ActionListItem::Artist(.., actions)
| ActionListItem::Album(.., actions)
| ActionListItem::Playlist(.., actions)
| ActionListItem::Show(.., actions)
| ActionListItem::Episode(.., actions) => {
actions.iter().map(|a| format!("{a:?}")).collect::<Vec<_>>()
}
}
}
}