use crate::player::{AudioBackend, SpotifyPlayerSettings}; use gio::prelude::SettingsExt; use libadwaita::ColorScheme; use librespot::playback::config::Bitrate; const SETTINGS: &str = "dev.alextren.Spot"; #[derive(Clone, Debug, Default)] pub struct WindowGeometry { pub width: i32, pub height: i32, pub is_maximized: bool, } impl WindowGeometry { pub fn new_from_gsettings() -> Self { let settings = gio::Settings::new(SETTINGS); Self { width: settings.int("window-width"), height: settings.int("window-height"), is_maximized: settings.boolean("window-is-maximized"), } } pub fn save(&self) -> Option<()> { let settings = gio::Settings::new(SETTINGS); settings.delay(); settings.set_int("window-width", self.width).ok()?; settings.set_int("window-height", self.height).ok()?; settings .set_boolean("window-is-maximized", self.is_maximized) .ok()?; settings.apply(); Some(()) } } // Player (librespot) settings impl SpotifyPlayerSettings { pub fn new_from_gsettings() -> Option { let settings = gio::Settings::new(SETTINGS); let bitrate = match settings.enum_("player-bitrate") { 0 => Some(Bitrate::Bitrate96), 1 => Some(Bitrate::Bitrate160), 2 => Some(Bitrate::Bitrate320), _ => None, }?; let backend = match settings.enum_("audio-backend") { 0 => Some(AudioBackend::PulseAudio), 1 => Some(AudioBackend::Alsa( settings.string("alsa-device").as_str().to_string(), )), 2 => Some(AudioBackend::GStreamer( "audioconvert dithering=none ! audioresample ! pipewiresink".to_string(), // This should be configurable eventually )), _ => None, }?; let gapless = settings.boolean("gapless-playback"); let ap_port_val = settings.uint("ap-port"); if ap_port_val > 65535 { panic!("Invalid access point port"); } // Access points usually use port 80, 443 or 4070. Since gsettings // does not allow optional values, we use 0 to indicate that any // port is OK and we should pass None to librespot's ap-port. let ap_port = match ap_port_val { 0 => None, x => Some(x as u16), }; Some(Self { bitrate, backend, gapless, ap_port, }) } } #[derive(Debug, Clone)] pub struct SpotSettings { pub theme_preference: ColorScheme, pub player_settings: SpotifyPlayerSettings, pub window: WindowGeometry, } // Application settings impl SpotSettings { pub fn new_from_gsettings() -> Option { let settings = gio::Settings::new(SETTINGS); let theme_preference = match settings.enum_("theme-preference") { 0 => Some(ColorScheme::ForceLight), 1 => Some(ColorScheme::ForceDark), 2 => Some(ColorScheme::Default), _ => None, }?; Some(Self { theme_preference, player_settings: SpotifyPlayerSettings::new_from_gsettings()?, window: WindowGeometry::new_from_gsettings(), }) } } impl Default for SpotSettings { fn default() -> Self { Self { theme_preference: ColorScheme::PreferDark, player_settings: Default::default(), window: Default::default(), } } }