wip
This commit is contained in:
+64
-32
@@ -1,12 +1,10 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use anyhow::{Error, anyhow};
|
||||
use common::config_dir;
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Task, Window};
|
||||
use nostr_sdk::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use theme::{Theme, ThemeFamily, ThemeMode};
|
||||
use theme::{AccentSelection, Appearance, SurfacePreference, Theme, ThemeSelection};
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
AppSettings::set_global(cx.new(AppSettings::new), cx)
|
||||
@@ -53,7 +51,10 @@ macro_rules! setting_getters {
|
||||
}
|
||||
|
||||
setting_accessors! {
|
||||
pub theme_mode: ThemeMode,
|
||||
pub appearance: Appearance,
|
||||
pub accent_selection: AccentSelection,
|
||||
pub surface_preference: SurfacePreference,
|
||||
pub theme_selection: ThemeSelection,
|
||||
pub hide_avatar: bool,
|
||||
pub screening: bool,
|
||||
pub nip4e: bool,
|
||||
@@ -119,11 +120,26 @@ impl RoomConfig {
|
||||
/// Settings
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Settings {
|
||||
/// Theme
|
||||
pub theme: Option<String>,
|
||||
/// The per-appearance theme variant selection
|
||||
#[serde(default)]
|
||||
pub theme_selection: ThemeSelection,
|
||||
|
||||
/// Theme mode
|
||||
pub theme_mode: ThemeMode,
|
||||
/// The active appearance; persisted under the legacy `theme_mode` key so
|
||||
/// old settings files ("Light"/"Dark") keep loading
|
||||
#[serde(
|
||||
default,
|
||||
rename = "theme_mode",
|
||||
deserialize_with = "deserialize_appearance"
|
||||
)]
|
||||
pub appearance: Appearance,
|
||||
|
||||
/// The accent color override applied on top of the selected theme
|
||||
#[serde(default)]
|
||||
pub accent_selection: AccentSelection,
|
||||
|
||||
/// The preferred surface treatment
|
||||
#[serde(default)]
|
||||
pub surface_preference: SurfacePreference,
|
||||
|
||||
/// Hide user avatars
|
||||
pub hide_avatar: bool,
|
||||
@@ -152,8 +168,10 @@ pub struct Settings {
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
theme: None,
|
||||
theme_mode: ThemeMode::default(),
|
||||
theme_selection: ThemeSelection::default(),
|
||||
appearance: Appearance::default(),
|
||||
accent_selection: AccentSelection::default(),
|
||||
surface_preference: SurfacePreference::default(),
|
||||
hide_avatar: false,
|
||||
screening: true,
|
||||
nip4e: false,
|
||||
@@ -165,6 +183,21 @@ impl Default for Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Accept the legacy "Light"/"Dark" capitalization alongside "light"/"dark".
|
||||
fn deserialize_appearance<'de, D>(deserializer: D) -> Result<Appearance, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let value = String::deserialize(deserializer)?;
|
||||
match value.to_lowercase().as_str() {
|
||||
"light" => Ok(Appearance::Light),
|
||||
"dark" => Ok(Appearance::Dark),
|
||||
_ => Err(serde::de::Error::custom(format!(
|
||||
"unknown appearance: {value}"
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
struct GlobalAppSettings(Entity<AppSettings>);
|
||||
|
||||
impl Global for GlobalAppSettings {}
|
||||
@@ -264,44 +297,43 @@ impl AppSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set theme
|
||||
pub fn set_theme<T>(&mut self, theme: T, window: &mut Window, cx: &mut Context<Self>)
|
||||
where
|
||||
T: Into<String>,
|
||||
{
|
||||
// Update settings
|
||||
/// Set the theme variant for the current appearance
|
||||
pub fn set_theme_variant(&mut self, id: String, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.inner.update(cx, |this, cx| {
|
||||
this.theme = Some(theme.into());
|
||||
let mut selection = this.theme_selection.clone();
|
||||
selection.set_variant(this.appearance, id);
|
||||
this.theme_selection = selection;
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
// Apply the new theme
|
||||
self.apply_theme(Some(window), cx);
|
||||
}
|
||||
|
||||
/// Reset theme
|
||||
/// Reset the theme selection to the defaults
|
||||
pub fn reset_theme(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.inner.update(cx, |this, cx| {
|
||||
this.theme = None;
|
||||
this.theme_selection = ThemeSelection::default();
|
||||
cx.notify();
|
||||
});
|
||||
self.apply_theme(Some(window), cx);
|
||||
}
|
||||
|
||||
/// Apply theme
|
||||
pub fn apply_theme(&mut self, mut window: Option<&mut Window>, cx: &mut Context<Self>) {
|
||||
if let Some(name) = self.inner.read(cx).theme.as_ref() {
|
||||
let mode = self.inner.read(cx).theme_mode;
|
||||
pub fn apply_theme(&mut self, window: Option<&mut Window>, cx: &mut Context<Self>) {
|
||||
let (selection, accent, surface, appearance) = {
|
||||
let settings = self.inner.read(cx);
|
||||
(
|
||||
settings.theme_selection.clone(),
|
||||
settings.accent_selection,
|
||||
settings.surface_preference,
|
||||
settings.appearance,
|
||||
)
|
||||
};
|
||||
|
||||
if let Ok(new_theme) = ThemeFamily::from_assets(name) {
|
||||
Theme::apply_theme(Rc::new(new_theme), window.as_deref_mut(), cx);
|
||||
Theme::change(mode, window, cx);
|
||||
} else {
|
||||
log::info!("Failed to load theme: {name}");
|
||||
}
|
||||
} else {
|
||||
Theme::apply_theme(Rc::new(ThemeFamily::default()), window, cx);
|
||||
}
|
||||
Theme::set_selection(selection, cx);
|
||||
Theme::set_accent_selection(accent, cx);
|
||||
Theme::set_surface_preference(surface, cx);
|
||||
Theme::change(appearance, window, cx);
|
||||
}
|
||||
|
||||
/// Check if decoupling encryption key is enabled
|
||||
|
||||
Reference in New Issue
Block a user