use gettextrs::gettext;
use log::{debug, error};
use serde::Deserialize;
use serde::Serialize;
use std::error::Error;
use std::path::PathBuf;
use crate::utils::filesystem_operations::obtain_preferences_file_path;
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(default)]
pub struct Preferences {
pub enable_notifications: Option<bool>,
pub enable_background: Option<bool>,
pub enable_systray: Option<bool>,
pub enable_autostart: Option<bool>,
pub start_minimized: Option<bool>,
pub enable_mpris: Option<bool>, pub enable_mpris_v2: Option<bool>,
pub no_duplicates: Option<bool>,
pub buffer_size_secs: Option<u64>, pub request_interval_secs: Option<u64>, pub request_interval_secs_v2: Option<u64>, pub request_interval_secs_v3: Option<u64>,
pub current_device_name: Option<String>,
pub website_search_url: Option<String>,
pub website_search_text: Option<String>,
}
impl Preferences {
pub fn new() -> Self {
Preferences {
enable_notifications: None,
enable_background: None,
enable_systray: None,
enable_autostart: None,
start_minimized: None,
enable_mpris: None,
enable_mpris_v2: None,
no_duplicates: None,
buffer_size_secs: None,
request_interval_secs: None,
request_interval_secs_v2: None,
request_interval_secs_v3: None,
current_device_name: None,
website_search_url: None,
website_search_text: None,
}
}
pub fn with_interval(interval: u64) -> Self {
Preferences {
enable_notifications: Some(true),
enable_background: Some(false),
enable_systray: Some(false),
enable_autostart: Some(false),
start_minimized: Some(false),
enable_mpris: None,
enable_mpris_v2: Some(true),
no_duplicates: Some(false),
buffer_size_secs: None,
request_interval_secs: None,
request_interval_secs_v2: None,
request_interval_secs_v3: Some(interval),
current_device_name: None,
website_search_url: Some("https://www.youtube.com/results?search_query=".to_string()),
website_search_text: Some(gettext("Search on YouTube".to_string())),
}
}
}
impl Default for Preferences {
fn default() -> Self {
Preferences {
enable_notifications: Some(true),
enable_background: Some(false),
enable_systray: Some(false),
enable_autostart: Some(false),
start_minimized: Some(false),
enable_mpris: None,
enable_mpris_v2: Some(true),
no_duplicates: Some(false),
buffer_size_secs: None,
request_interval_secs: None,
request_interval_secs_v2: None,
request_interval_secs_v3: Some(8),
current_device_name: None,
website_search_url: Some("https://www.youtube.com/results?search_query=".to_string()),
website_search_text: Some(gettext("Search on YouTube".to_string())),
}
}
}
#[derive(Clone, Debug)]
pub struct PreferencesInterface {
pub preferences_file_path: Option<PathBuf>,
pub preferences: Preferences,
}
impl PreferencesInterface {
pub fn new() -> Self {
match PreferencesInterface::load() {
Ok(preferences_interface) => preferences_interface,
Err(e) => {
error!("{} {}", gettext("When parsing the preferences file:"), e);
PreferencesInterface {
preferences_file_path: obtain_preferences_file_path().ok(),
preferences: Preferences::default(),
}
}
}
}
fn load() -> Result<PreferencesInterface, Box<dyn Error>> {
let preferences_file_path = obtain_preferences_file_path()?;
let contents = std::fs::read_to_string(&preferences_file_path).unwrap_or_default();
let preferences: Preferences = toml::from_str(&contents)?;
debug!(
"Loaded preferences from {}: {:?}",
preferences_file_path.display(),
preferences
);
Ok(PreferencesInterface {
preferences_file_path: Some(preferences_file_path),
preferences,
})
}
pub fn update(&mut self, update_preferences: Preferences) {
let current_preferences = &self.preferences;
self.preferences = Preferences {
enable_notifications: update_preferences
.enable_notifications
.or(current_preferences.enable_notifications),
enable_mpris: None,
enable_mpris_v2: update_preferences
.enable_mpris_v2
.or(current_preferences.enable_mpris_v2)
.or(current_preferences.enable_mpris),
enable_background: update_preferences
.enable_background
.or(current_preferences.enable_background),
enable_systray: update_preferences
.enable_systray
.or(current_preferences.enable_systray),
enable_autostart: update_preferences
.enable_autostart
.or(current_preferences.enable_autostart),
start_minimized: update_preferences
.start_minimized
.or(current_preferences.start_minimized),
no_duplicates: update_preferences
.no_duplicates
.or(current_preferences.no_duplicates),
buffer_size_secs: None,
request_interval_secs: None,
request_interval_secs_v2: None,
request_interval_secs_v3: update_preferences
.request_interval_secs_v3
.or(match current_preferences.request_interval_secs {
Some(4) => None,
Some(val) => Some(val),
None => None,
})
.or(match current_preferences.request_interval_secs_v2 {
Some(10) => None,
Some(val) => Some(val),
None => None,
})
.or(current_preferences.request_interval_secs_v3),
current_device_name: update_preferences
.current_device_name
.or_else(|| current_preferences.current_device_name.clone()),
website_search_url: update_preferences
.website_search_url
.or_else(|| current_preferences.website_search_url.clone()),
website_search_text: update_preferences
.website_search_text
.or_else(|| current_preferences.website_search_text.clone()),
};
if let Err(error) = self.write() {
error!("{} {}", gettext("When saving the preferences file:"), error);
}
}
fn write(&mut self) -> Result<(), Box<dyn Error>> {
if let Some(preferences_file_path) = &self.preferences_file_path {
let contents: String = toml::to_string(&self.preferences)?;
std::fs::write(preferences_file_path, contents)?;
}
Ok(())
}
}