From dbd6ac03ff3e14f7dbac7eca80b5a59da71209cf Mon Sep 17 00:00:00 2001 From: Avery Date: Thu, 18 Jan 2024 14:43:14 -0500 Subject: [PATCH] Save duration label display in config (fixes #57) --- delfin/src/config/versions/config_v1.rs | 1 + delfin/src/config/video_player_config.rs | 78 ++++++++++++-------- delfin/src/video_player/controls/scrubber.rs | 36 ++++----- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/delfin/src/config/versions/config_v1.rs b/delfin/src/config/versions/config_v1.rs index 6e076ae..58c5f19 100644 --- a/delfin/src/config/versions/config_v1.rs +++ b/delfin/src/config/versions/config_v1.rs @@ -242,6 +242,7 @@ impl Migrate for ConfigV1 { intro_skipper: self.video_player.intro_skipper, intro_skipper_auto_skip: self.video_player.intro_skipper_auto_skip, jellyscrub: self.video_player.jellyscrub, + ..Default::default() }, } } diff --git a/delfin/src/config/video_player_config.rs b/delfin/src/config/video_player_config.rs index 9ff6fc5..4823bc4 100644 --- a/delfin/src/config/video_player_config.rs +++ b/delfin/src/config/video_player_config.rs @@ -10,32 +10,6 @@ use crate::{ }, }; -#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)] -pub enum VideoPlayerBackendPreference { - Mpv, - Gst, -} - -impl From for Arc> { - fn from(val: VideoPlayerBackendPreference) -> Self { - match val { - VideoPlayerBackendPreference::Mpv => Arc::>::default(), - VideoPlayerBackendPreference::Gst => { - #[cfg(feature = "gst")] - { - Arc::>::default() - } - - #[cfg(not(feature = "gst"))] - { - println!("GStreamer backend not available, falling back to MPV backend"); - Arc::>::default() - } - } - } - } -} - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] #[serde(default)] pub struct VideoPlayerConfig { @@ -46,6 +20,7 @@ pub struct VideoPlayerConfig { pub skip_backwards_amount: VideoPlayerSkipAmount, pub skip_forwards_amount: VideoPlayerSkipAmount, pub on_left_click: VideoPlayerOnLeftClick, + pub duration_display: DurationDisplay, #[serde(serialize_with = "round_one_place")] pub subtitle_scale: f64, @@ -71,7 +46,8 @@ impl Default for VideoPlayerConfig { skip_backwards_amount: VideoPlayerSkipAmount::Ten, skip_forwards_amount: VideoPlayerSkipAmount::Thirty, - on_left_click: VideoPlayerOnLeftClick::PlayPause, + on_left_click: VideoPlayerOnLeftClick::default(), + duration_display: DurationDisplay::default(), subtitle_scale: 1.0, subtitle_colour: "#FFFFFFFF".into(), @@ -79,7 +55,7 @@ impl Default for VideoPlayerConfig { subtitle_position: 100, subtitle_font: VideoPlayerSubtitleFont::default(), - backend: VideoPlayerBackendPreference::Mpv, + backend: VideoPlayerBackendPreference::default(), hls_playback: false, intro_skipper: true, intro_skipper_auto_skip: true, @@ -101,8 +77,52 @@ impl From for Duration { } } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Copy)] +#[derive(Debug, Default, Deserialize, Serialize, PartialEq, Clone, Copy)] pub enum VideoPlayerOnLeftClick { + #[default] PlayPause, ToggleControls, } + +#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq)] +pub enum VideoPlayerBackendPreference { + #[default] + Mpv, + Gst, +} + +impl From for Arc> { + fn from(val: VideoPlayerBackendPreference) -> Self { + match val { + VideoPlayerBackendPreference::Mpv => Arc::>::default(), + VideoPlayerBackendPreference::Gst => { + #[cfg(feature = "gst")] + { + Arc::>::default() + } + + #[cfg(not(feature = "gst"))] + { + println!("GStreamer backend not available, falling back to MPV backend"); + Arc::>::default() + } + } + } + } +} + +#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq)] +pub enum DurationDisplay { + #[default] + Total, + Remaining, +} + +impl DurationDisplay { + pub fn toggle(&self) -> Self { + match self { + Self::Total => Self::Remaining, + Self::Remaining => Self::Total, + } + } +} diff --git a/delfin/src/video_player/controls/scrubber.rs b/delfin/src/video_player/controls/scrubber.rs index 72f934d..abdc5f3 100644 --- a/delfin/src/video_player/controls/scrubber.rs +++ b/delfin/src/video_player/controls/scrubber.rs @@ -7,6 +7,8 @@ use gtk::{gdk, gdk_pixbuf, graphene, prelude::*}; use relm4::prelude::*; use crate::{ + config::video_player_config::DurationDisplay, + globals::CONFIG, tr, utils::{bif::Thumbnail, message_broker::ResettableMessageBroker}, video_player::backends::VideoPlayerBackend, @@ -17,21 +19,6 @@ const TIMESTAMP_WIDTH: i32 = 80; pub(crate) static SCRUBBER_BROKER: ResettableMessageBroker = ResettableMessageBroker::new(); -#[derive(Clone, Copy, Debug)] -enum DurationDisplay { - Total, - Remaining, -} - -impl DurationDisplay { - fn toggle(&self) -> Self { - match self { - Self::Total => Self::Remaining, - Self::Remaining => Self::Total, - } - } -} - struct ScrubberPopover { position: f64, timestamp: usize, @@ -63,6 +50,7 @@ pub enum ScrubberInput { ScrubberMouseHover(f64), ScrubberMouseLeave, LoadedThumbnails(Option>), + DurationDisplayUpdated(DurationDisplay), } #[relm4::component(pub(crate))] @@ -202,12 +190,14 @@ impl Component for Scrubber { loading: true, position: 0, duration: 0, - duration_display: DurationDisplay::Total, + duration_display: CONFIG.read().video_player.duration_display, scrubbing: false, popover: None, thumbnails: None, }; + model.subscribe_to_config(&sender); + let widgets = view_output!(); relm4::ComponentParts { model, widgets } @@ -241,7 +231,13 @@ impl Component for Scrubber { self.loading = false; } ScrubberInput::ToggleDurationDisplay => { - self.duration_display = self.duration_display.toggle(); + let mut config = CONFIG.write(); + config.video_player.duration_display = + config.video_player.duration_display.toggle(); + config.save().expect("Failed to save duration display"); + } + ScrubberInput::DurationDisplayUpdated(duration_display) => { + self.duration_display = duration_display; } ScrubberInput::SetScrubbing(scrubbing) => { self.scrubbing = scrubbing; @@ -311,6 +307,12 @@ impl Scrubber { }; Some(Texture::for_pixbuf(&pixbuf)) } + + fn subscribe_to_config(&self, sender: &ComponentSender) { + CONFIG.subscribe(sender.input_sender(), |config| { + ScrubberInput::DurationDisplayUpdated(config.video_player.duration_display) + }); + } } fn seconds_to_timestamp(seconds: usize) -> String {