use crate::model::settings;
use bezel::theme::{TextStyle, appearance::AppearanceMode};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, path::PathBuf};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Kind {
Session,
Board,
Article,
Table,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry {
pub kind: Kind,
pub id: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct State {
#[serde(default)]
pub projects: Vec<PathBuf>,
#[serde(default)]
pub active: usize,
#[serde(default)]
pub appearance: AppearanceMode,
#[serde(default)]
pub reduce_transparency: bool,
pub cursor_blink: bool,
pub text_size: f32,
pub hue: f32,
pub chroma: f32,
#[serde(default)]
pub last: BTreeMap<PathBuf, Entry>,
}
pub const TEXT_SIZE: (f32, f32) = (11., 17.);
impl Default for State {
fn default() -> Self {
Self {
projects: Vec::new(),
active: 0,
appearance: AppearanceMode::default(),
reduce_transparency: false,
cursor_blink: true,
text_size: TextStyle::Body.size(),
hue: 0.,
chroma: 0.,
last: BTreeMap::new(),
}
}
}
fn path() -> Option<PathBuf> {
settings::dir().ok().map(|dir| dir.join("state.toml"))
}
pub fn restore() -> State {
let stored: State = path()
.and_then(|path| std::fs::read_to_string(path).ok())
.and_then(|body| toml::from_str(&body).ok())
.unwrap_or_default();
let active = stored.projects.get(stored.active).cloned();
let projects: Vec<PathBuf> = stored
.projects
.into_iter()
.filter(|path| path.is_dir())
.collect();
let active = active
.and_then(|path| projects.iter().position(|open| *open == path))
.unwrap_or(0);
State {
projects,
active,
appearance: stored.appearance,
reduce_transparency: stored.reduce_transparency,
cursor_blink: stored.cursor_blink,
text_size: stored.text_size.clamp(TEXT_SIZE.0, TEXT_SIZE.1),
hue: stored.hue,
chroma: stored.chroma,
last: stored.last,
}
}
pub fn save(state: &State) {
let Some(path) = path() else {
return;
};
if let Ok(body) = toml::to_string_pretty(state)
&& let Some(dir) = path.parent()
{
let _ = std::fs::create_dir_all(dir);
let _ = std::fs::write(&path, body);
}
}