From 91b1ad874d9f80267c590bcad2f5afd5cc60da8b Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 12:11:14 +0200 Subject: [PATCH] feat: add about drawer --- Cargo.lock | 37 ++++++++++++++++++++++++++++++ Cargo.toml | 3 ++- i18n/en/cosmic_player.ftl | 4 ++++ i18n/fr/cosmic_player.ftl | 4 ++++ src/main.rs | 48 +++++++++++++++++++++++++++++++++++++-- src/menu.rs | 7 ++++++ 6 files changed, 100 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b711e4d..166ba56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1110,6 +1110,7 @@ dependencies = [ "libcosmic-yoda", "log", "mpris-server", + "open", "rust-embed", "serde", "tempfile", @@ -3031,6 +3032,25 @@ dependencies = [ "unic-langid", ] +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -4043,6 +4063,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "open" +version = "5.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -4192,6 +4223,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5a797f0e07bdf071d15742978fc3128ec6c22891c31a3a931513263904c982a" +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + [[package]] name = "percent-encoding" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index d0aff17..2de6309 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ rust-embed = "8" # Logging env_logger = "0.11" log = "0.4" +open = "5.3.2" [dependencies.iced_video_player] path = "vendor/iced_video_player" @@ -39,7 +40,7 @@ default-features = false package = "libcosmic-yoda" path = "../libcosmic" default-features = false -features = ["advanced-shaping", "tokio", "winit", "multi-window"] +features = ["about", "advanced-shaping", "tokio", "winit", "multi-window"] [dependencies.mpris-server] version = "0.10" diff --git a/i18n/en/cosmic_player.ftl b/i18n/en/cosmic_player.ftl index 36cb2b2..2938403 100644 --- a/i18n/en/cosmic_player.ftl +++ b/i18n/en/cosmic_player.ftl @@ -39,6 +39,10 @@ repeat-disabled = Repeat disabled repeat-track = Repeat track playback = Playback +help = Help +menu-about = About COSMIC Media Player... +repository = Repository +support = Support next-frame = Next Frame previous-frame = Previous Frame ab-repeat = A-B Repeat diff --git a/i18n/fr/cosmic_player.ftl b/i18n/fr/cosmic_player.ftl index cb796bb..4517bbe 100644 --- a/i18n/fr/cosmic_player.ftl +++ b/i18n/fr/cosmic_player.ftl @@ -40,6 +40,10 @@ clear-recent = Effacer la liste récente repeat-disabled = Répétition désactivée repeat-track = Répéter la piste playback = Lecture +help = Aide +menu-about = À propos du lecteur multimédia COSMIC... +repository = Dépôt +support = Support next-frame = Prochaine image previous-frame = Image précédente ab-repeat = Répétition A-B diff --git a/src/main.rs b/src/main.rs index 836fc31..bb74ab4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use cosmic::app::{Core, Settings, Task}; +use cosmic::app::{Core, Settings, Task, context_drawer}; use cosmic::command::set_theme; use cosmic::cosmic_config::{self, CosmicConfigEntry}; use cosmic::iced::event::{self, Event}; @@ -12,7 +12,7 @@ use cosmic::iced::{ }; use cosmic::iced::window::set_mode; use cosmic::widget::menu::action::MenuAction; -use cosmic::widget::{self, Slider, nav_bar, segmented_button}; +use cosmic::widget::{self, Slider, about::About, nav_bar, segmented_button}; use cosmic::{Application, ApplicationExt, Element, action, cosmic_theme, executor, font, theme}; use iced_video_player::gst::prelude::*; use iced_video_player::{Video, VideoPlayer, gst, gst_pbutils}; @@ -167,6 +167,7 @@ fn main() -> Result<(), Box> { #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Action { + About, FileClose, FileOpen, FileClearRecents, @@ -192,6 +193,7 @@ impl MenuAction for Action { fn message(&self) -> Message { match self { + Self::About => Message::ToggleAbout, Self::FileClose => Message::FileClose, Self::FileOpen => Message::FileOpen, Self::FileClearRecents => Message::FileClearRecents, @@ -289,6 +291,7 @@ pub enum Message { FolderOpenRecent(usize), MultipleLoad(Vec), Fullscreen, + LaunchUrl(String), Key(Modifiers, Key), AudioCode(usize), AudioToggle, @@ -314,12 +317,14 @@ pub enum Message { AbRepeat, ShowControls, SystemThemeModeChange(cosmic_theme::ThemeMode), + ToggleAbout, WindowClose, } /// The [`App`] stores application-specific state. pub struct App { core: Core, + about: About, flags: Flags, album_art_opt: Option, controls: bool, @@ -883,8 +888,26 @@ impl Application for App { tx }; + let about = About::default() + .name(fl!("xdg-name")) + .icon(widget::icon::from_name(Self::APP_ID)) + .version(env!("CARGO_PKG_VERSION")) + .author("System76") + .comments(fl!("xdg-comment")) + .license("GPL-3.0-only") + .license_url("https://spdx.org/licenses/GPL-3.0-only") + .developers([("Jeremy Soller", "jeremy@system76.com")]) + .links([ + (fl!("repository"), "https://github.com/pop-os/cosmic-player"), + ( + fl!("support"), + "https://github.com/pop-os/cosmic-player/issues", + ), + ]); + let mut app = App { core, + about, flags, album_art_opt: None, controls: true, @@ -1202,6 +1225,12 @@ impl Application for App { ); } } + Message::LaunchUrl(url) => match open::that_detached(&url) { + Ok(()) => {} + Err(err) => { + log::warn!("failed to open URL {:?}: {}", url, err); + } + }, Message::Key(modifiers, key) => { for (key_bind, action) in self.key_binds.iter() { if key_bind.matches(modifiers, &key) { @@ -1611,6 +1640,9 @@ impl Application for App { Message::SystemThemeModeChange(_theme_mode) => { return self.update_config(); } + Message::ToggleAbout => { + self.core.set_show_context(!self.core.window.show_context); + } Message::WindowClose => { self.close(); return exit(); @@ -1630,6 +1662,18 @@ impl Application for App { )] } + fn context_drawer(&self) -> Option> { + if !self.core.window.show_context { + return None; + } + + Some(context_drawer::about( + &self.about, + |url| Message::LaunchUrl(url.to_string()), + Message::ToggleAbout, + )) + } + /// Creates a view after each update. fn view(&self) -> Element<'_, Self::Message> { let theme = theme::active(); diff --git a/src/menu.rs b/src/menu.rs index 0f21053..fd99206 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -132,6 +132,13 @@ pub fn menu_bar<'a>( RcElementWrapper::new(Element::from(menu::root(fl!("playback")))), menu::items(key_binds, playback), ), + menu::Tree::with_children( + RcElementWrapper::new(Element::from(menu::root(fl!("help")))), + menu::items( + key_binds, + vec![menu::Item::Button(fl!("menu-about"), None, Action::About)], + ), + ), ]) .item_height(ItemHeight::Dynamic(40)) .item_width(ItemWidth::Uniform(320))