Added filter. Improved UI. Fixed settings window
This commit is contained in:
@@ -226,6 +226,11 @@ command = "DeleteSelected"
|
||||
key_sequence = "v"
|
||||
command = "ToggleViewMode"
|
||||
|
||||
[[keymaps]]
|
||||
key_sequence = "f"
|
||||
command = "OpenLibraryFilters"
|
||||
context = "library"
|
||||
|
||||
[[keymaps]]
|
||||
key_sequence = ":"
|
||||
command = "OpenCommandLine"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod keymap;
|
||||
pub mod logging;
|
||||
pub mod settings;
|
||||
|
||||
use directories::ProjectDirs;
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct LibraryFilters {
|
||||
#[serde(default)]
|
||||
pub hide_featured_only: bool,
|
||||
}
|
||||
|
||||
impl LibraryFilters {
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.hide_featured_only
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct AppSettings {
|
||||
#[serde(default = "default_volume")]
|
||||
pub volume: u8,
|
||||
#[serde(default)]
|
||||
pub library: LibraryFilters,
|
||||
}
|
||||
|
||||
impl Default for AppSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
volume: default_volume(),
|
||||
library: LibraryFilters::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppSettings {
|
||||
pub fn normalized(mut self) -> Self {
|
||||
self.volume = self.volume.min(100);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
fn default_volume() -> u8 {
|
||||
80
|
||||
}
|
||||
|
||||
pub fn load() -> (AppSettings, Option<String>) {
|
||||
let Some(path) = settings_path() else {
|
||||
return (AppSettings::default(), None);
|
||||
};
|
||||
match std::fs::read_to_string(&path) {
|
||||
Ok(text) => match toml::from_str::<AppSettings>(&text) {
|
||||
Ok(settings) => (settings.normalized(), None),
|
||||
Err(err) => (
|
||||
AppSettings::default(),
|
||||
Some(format!("settings.toml is malformed: {err}")),
|
||||
),
|
||||
},
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => (AppSettings::default(), None),
|
||||
Err(err) => (
|
||||
AppSettings::default(),
|
||||
Some(format!("settings.toml could not be read: {err}")),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(settings: &AppSettings) -> Result<()> {
|
||||
let path = settings_path().context("cannot determine the config directory")?;
|
||||
if let Some(parent) = path.parent() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
std::fs::write(
|
||||
&path,
|
||||
toml::to_string_pretty(&settings.clone().normalized())?,
|
||||
)
|
||||
.with_context(|| format!("writing {}", path.display()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn settings_path() -> Option<std::path::PathBuf> {
|
||||
crate::config::project_dirs().map(|dirs| dirs.config_dir().join("settings.toml"))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn settings_parse_and_normalize() {
|
||||
let settings: AppSettings = toml::from_str(
|
||||
r#"
|
||||
volume = 150
|
||||
|
||||
[library]
|
||||
hide_featured_only = true
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
let settings = settings.normalized();
|
||||
|
||||
assert_eq!(settings.volume, 100);
|
||||
assert!(settings.library.hide_featured_only);
|
||||
assert!(settings.library.is_active());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user