From 93fcf5d6a6f5461ccb46b09faa58b7bedb49886f Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Mon, 23 Oct 2023 06:49:05 +0200 Subject: [PATCH] AMADEUS: The message of what to show is send at update time, not at view time --- amadeus/src/app.rs | 49 ++++++++--------- amadeus/src/components/mainpanel/mod.rs | 53 ++++++++++++++++--- amadeus/src/components/mainpanel/playlists.rs | 27 ++++++---- 3 files changed, 89 insertions(+), 40 deletions(-) diff --git a/amadeus/src/app.rs b/amadeus/src/app.rs index 86b9c8ec..e1eba7fa 100644 --- a/amadeus/src/app.rs +++ b/amadeus/src/app.rs @@ -60,8 +60,9 @@ pub struct Amadeus { /// The main panel, displays the queue, history, etc. mainpanel: mainpanel::State, - /// What to show in the main panel. - show: MainPanelDisplay, + /// Whever to show the main panel or not, if we don't show the mainpanel, then we show the + /// config panel. + show_main_panel: bool, /// Currently playing kara, for the title. current_kara: Option<Arc<Kara>>, @@ -89,6 +90,7 @@ impl Default for Amadeus { // Manual defaults. last_instant: iced::time::Instant::now(), sidebar_size: Some(300), + show_main_panel: false, // Has default. kara_store: Arc::new(KaraStore::new()), @@ -99,7 +101,6 @@ impl Default for Amadeus { bottombar: Default::default(), topbar: Default::default(), mainpanel: Default::default(), - show: Default::default(), current_kara: Default::default(), playback_state: Default::default(), modal: Default::default(), @@ -663,10 +664,16 @@ impl Application for Amadeus { // Change what the main panel displays + We have informations to pass to it Message::MainPanelMessage(message) => self.mainpanel.update(message).map(Message::from), - Message::MainPanelDisplay(show) => { - self.show = show; + Message::MainPanelDisplay(MainPanelDisplay::Config) => { + self.show_main_panel = false; Command::none() } + Message::MainPanelDisplay(MainPanelDisplay::MainPanel(show)) => { + self.show_main_panel = true; + self.mainpanel + .update(mainpanel::Message::Show(show)) + .map(Message::from) + } // A message for the side panel. Message::SideBarResize(size) => { @@ -732,30 +739,24 @@ impl Application for Amadeus { } // Main panel - let inner_main_panel = container(match self.show { - MainPanelDisplay::MainPanel(ref show) => self.mainpanel.view(show).map(Message::from), - MainPanelDisplay::Config => self.config.view().map(Message::from), + let inner_main_panel = container(match self.show_main_panel { + true => self.mainpanel.view().map(Message::from), + false => self.config.view().map(Message::from), }) .width(Length::Fill) .height(Length::Fill) .padding(20); - let main_panel_title = row![ - text(&self.show).size(SIZE_FONT_TITLE), - horizontal_space(Length::Fill), - ]; - let main_panel_title = match self.show { - MainPanelDisplay::Config => { - main_panel_title.push(Into::<Element<'_, Self::Message>>::into(row![ - tip!(icon!(SIZE_FONT_MEDIUM | Fullscreen -> Message::ToggleFullScreen) => Bottom | "Toggle fullscreen"), - tip!(icon!(SIZE_FONT_MEDIUM | Github -> Message::OpenLinkInBrowser(LEKTORD_HOME_LINK)) => Bottom | "Open lektor homepage"), - tip!(icon!(SIZE_FONT_MEDIUM | Bug -> Message::OpenLinkInBrowser(LEKTORD_ISSUES_LINK)) => Bottom | "Open issues for lektor"), - tip!(icon!(SIZE_FONT_MEDIUM | XOctagon -> Message::ShutdownLektord) => Bottom | "Shutdown lektord and exit amadeus"), - ])) - } - MainPanelDisplay::MainPanel(ref show) => { - main_panel_title.push(self.mainpanel.view_actions(show).map(Message::from)) - } + let main_panel_title = match self.show_main_panel { + true => self.mainpanel.view_title().push(self.mainpanel.view_actions().map(Message::from)), + false => row![ + text("Settings").size(SIZE_FONT_TITLE), + horizontal_space(Length::Fill), + tip!(icon!(SIZE_FONT_MEDIUM | Fullscreen -> Message::ToggleFullScreen) => Bottom | "Toggle fullscreen"), + tip!(icon!(SIZE_FONT_MEDIUM | Github -> Message::OpenLinkInBrowser(LEKTORD_HOME_LINK)) => Bottom | "Open lektor homepage"), + tip!(icon!(SIZE_FONT_MEDIUM | Bug -> Message::OpenLinkInBrowser(LEKTORD_ISSUES_LINK)) => Bottom | "Open issues for lektor"), + tip!(icon!(SIZE_FONT_MEDIUM | XOctagon -> Message::ShutdownLektord) => Bottom | "Shutdown lektord and exit amadeus"), + ], } .padding(0) .height(Length::Shrink) diff --git a/amadeus/src/components/mainpanel/mod.rs b/amadeus/src/components/mainpanel/mod.rs index 545d339d..e894b964 100644 --- a/amadeus/src/components/mainpanel/mod.rs +++ b/amadeus/src/components/mainpanel/mod.rs @@ -5,7 +5,11 @@ pub mod playlists; pub mod queue; pub mod search; -use iced::{Command, Element}; +use crate::style_sheet::sizes::*; +use iced::{ + widget::{horizontal_space, row, text, Row}, + Command, Element, Length, +}; use search::filter; use std::sync::Arc; @@ -16,6 +20,7 @@ pub struct State { search: search::State, history: history::State, playlists: playlists::State, + show: Show, } /// What to show in the main panel. @@ -35,6 +40,7 @@ pub enum Message { Queue(queue::Message), Search(search::Message), Playlists(playlists::Message), + Show(Show), } /// Request more information to display. Those things requires to communicate whith the server. @@ -46,6 +52,17 @@ pub enum Request { Playlists(playlists::Request), } +impl std::fmt::Display for Show { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Show::Queue => f.write_str("Queue"), + Show::History => f.write_str("History"), + Show::Database => f.write_str("Search Database"), + Show::Playlist(plt) => write!(f, "Playlist {plt}"), + } + } +} + impl From<history::Message> for Message { fn from(value: history::Message) -> Self { Self::History(value) @@ -107,27 +124,49 @@ impl State { Message::Search(msg) => self.search.update(msg).map(Request::Search), Message::History(msg) => self.history.update(msg).map(Request::History), Message::Playlists(msg) => self.playlists.update(msg).map(Request::Playlists), + Message::Show(show) => match show { + Show::Playlist(ref name) => { + let name = name.clone(); + self.show = show; + self.playlists + .update(playlists::Message::ShowPlaylist(name)) + .map(Request::from) + } + show => { + self.show = show; + Command::none() + } + }, } } + /// View the name of the main panel. As we don't return anny message, we add a generic type to + /// adapt this function to any message type. + pub fn view_title<'a, T: 'a>(&'a self) -> Row<'a, T> { + row![ + text(&self.show).size(SIZE_FONT_TITLE), + horizontal_space(Length::Fill), + ] + } + /// View some global actions, to be displayed above the main panel, along side the main panel /// name. Function called by the Amadeus application. - pub fn view_actions(&self, show: &Show) -> Element<'_, Request> { - match show { + pub fn view_actions(&self) -> Element<'_, Request> { + match self.show { Show::Queue => self.queue.view_actions().map(Request::from), Show::History => self.history.view_actions().map(Request::from), Show::Database => self.search.view_actions().map(Request::from), - Show::Playlist(plt) => self.playlists.view_actions(plt).map(Request::from), + Show::Playlist(ref plt) => self.playlists.view_actions(plt).map(Request::from), } } /// Render the state of the component. - pub fn view(&self, show: &Show) -> Element<'_, Request> { - match show { + pub fn view(&self) -> Element<'_, Request> { + match self.show { Show::Queue => self.queue.view().map(Request::from), Show::History => self.history.view().map(Request::from), Show::Database => self.search.view().map(Request::from), - Show::Playlist(plt) => self.playlists.view(plt).map(Request::from), + Show::Playlist(ref plt) => self.playlists.view(plt).map(Request::from), } } } diff --git a/amadeus/src/components/mainpanel/playlists.rs b/amadeus/src/components/mainpanel/playlists.rs index 5a5956e9..9b11ea3c 100644 --- a/amadeus/src/components/mainpanel/playlists.rs +++ b/amadeus/src/components/mainpanel/playlists.rs @@ -6,7 +6,10 @@ use lektor_utils::log; use std::sync::Arc; #[derive(Default)] -pub struct State(HashMap<Arc<str>, (PlaylistInfo, karalist::State)>); +pub struct State { + playlists: HashMap<Arc<str>, (PlaylistInfo, karalist::State)>, + to_show: Option<Arc<str>>, +} #[derive(Debug, Clone)] pub enum Message { @@ -22,6 +25,8 @@ pub enum Message { RemoveKaraFromPlaylist(Arc<str>, KId), AddKaraToPlaylist(Arc<str>, Arc<Kara>), + + ShowPlaylist(Arc<str>), } #[derive(Debug, Clone)] @@ -45,27 +50,26 @@ pub enum Request { impl State { pub fn update(&mut self, message: Message) -> Command<Request> { match message { - // Update a playlist Message::KeepPlaylists(plts) => { - self.0.retain(|name, _| plts.contains(name)); + self.playlists.retain(|name, _| plts.contains(name)); Command::none() } Message::Reload(plt, karas) => { - match self.0.get_mut(&plt) { + match self.playlists.get_mut(&plt) { Some((_, plt)) => plt.update(karalist::Message::Reload(karas)), None => log::error!("failed to update playlist {}", plt.as_ref()), } Command::none() } Message::UpdatePlaylistInfos(plt, infos) => { - match self.0.get_mut(&plt) { + match self.playlists.get_mut(&plt) { Some((old, _)) => *old = infos, None => log::error!("failed to update playlist {}", plt.as_ref()), } Command::none() } Message::RemoveKaraFromPlaylist(plt, id) => { - match self.0.get_mut(&plt) { + match self.playlists.get_mut(&plt) { Some((_, plt)) => plt.update(karalist::Message::RemoveId(id)), None => log::error!( "failed to delete kara {id:?} from playlist {}", @@ -75,18 +79,23 @@ impl State { Command::none() } Message::DeletePlaylist(plt) => { - if self.0.remove(&plt).is_none() { + if self.playlists.remove(&plt).is_none() { log::error!("failed do delete playlist {}", plt.as_ref()) } Command::none() } Message::AddKaraToPlaylist(plt, kara) => { - match self.0.get_mut(&plt) { + match self.playlists.get_mut(&plt) { Some(plt) => plt.1.update(karalist::Message::Add(kara)), None => log::error!("can't add kara {} to playlist {}", kara.id, plt.as_ref()), } Command::none() } + + Message::ShowPlaylist(name) => { + self.to_show = Some(name); + Command::none() + } } } @@ -98,7 +107,7 @@ impl State { } pub fn view(&self, plt: &Arc<str>) -> Element<'_, Request> { - self.0 + self.playlists .get_key_value(plt) .map(|(plt, (_, content))| content.view().map(|req| Request::Inner(plt.clone(), req))) .unwrap_or(components::loading()) -- GitLab