feat: add new theme (#61)

Reviewed-on: #61
This commit was merged in pull request #61.
This commit is contained in:
2026-10-10 00:30:42 +00:00
parent 4ef764984b
commit 602a91b4f0
94 changed files with 3337 additions and 4456 deletions
+25 -51
View File
@@ -1,10 +1,10 @@
use gpui::http_client::Url;
use gpui::{
App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
Window, div, px,
Window, div,
};
use settings::AppSettings;
use theme::{ActiveTheme, Theme, ThemeMode};
use theme::{ActiveTheme, AppExt as _, AppearanceMode, TextStyle, Typeset as _};
use ui::button::{Button, ButtonVariants};
use ui::group_box::{GroupBox, GroupBoxVariants};
use ui::input::{Input, InputState};
@@ -47,10 +47,10 @@ impl Preferences {
}
}
/// Set the theme mode (light or dark)
fn set_theme_mode(mode: ThemeMode, window: &mut Window, cx: &mut App) {
AppSettings::update_theme_mode(mode, cx);
Theme::change(mode, Some(window), cx);
/// Set the appearance mode (system, light or dark)
fn set_appearance_mode(mode: AppearanceMode, cx: &mut App) {
AppSettings::update_appearance_mode(mode, cx);
cx.set_appearance_mode(mode);
}
}
@@ -58,14 +58,13 @@ impl Render for Preferences {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
const SCREENING: &str = "Show an screening dialog to verify the unknown sender.";
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
const MODE: &str = "Use the selected light or dark theme, or to follow the OS.";
const MODE: &str = "Follow the OS, or always use light or dark.";
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
const RESET: &str = "Reset the theme to the default one.";
let screening = AppSettings::get_screening(cx);
let hide_avatar = AppSettings::get_hide_avatar(cx);
let nip4e = AppSettings::get_nip4e(cx);
let theme_mode = AppSettings::get_theme_mode(cx);
let appearance_mode = AppSettings::get_appearance_mode(cx);
v_flex()
.gap_4()
@@ -104,55 +103,30 @@ impl Render for Preferences {
.justify_between()
.child(
v_flex()
.child(div().text_sm().child(SharedString::from("Mode")))
.child(
div()
.text_xs()
.text_style(TextStyle::Callout)
.child(SharedString::from("Mode")),
)
.child(
div()
.text_style(TextStyle::Caption)
.text_color(cx.theme().text_muted)
.child(SharedString::from(MODE)),
),
)
.child(
Button::new("theme-mode")
.label(theme_mode.name())
Button::new("appearance-mode")
.label(appearance_mode.label())
.ghost_alt()
.small()
.dropdown_menu(|this, _window, _cx| {
this.item(PopupMenuItem::new("Light").on_click(
|_, window, cx| {
Self::set_theme_mode(ThemeMode::Light, window, cx);
},
))
.item(
PopupMenuItem::new("Dark").on_click(|_, window, cx| {
Self::set_theme_mode(ThemeMode::Dark, window, cx);
}),
)
}),
),
)
.child(
h_flex()
.gap_3()
.justify_between()
.child(
v_flex()
.child(div().text_sm().child(SharedString::from("Reset theme")))
.child(
div()
.text_xs()
.text_color(cx.theme().text_muted)
.child(SharedString::from(RESET)),
),
)
.child(
Button::new("reset")
.label("Reset")
.ghost_alt()
.small()
.on_click(move |_ev, window, cx| {
AppSettings::global(cx).update(cx, |this, cx| {
this.reset_theme(window, cx);
AppearanceMode::ALL.iter().fold(this, |menu, mode| {
menu.item(PopupMenuItem::new(mode.label()).on_click(
move |_, _window, cx| {
Self::set_appearance_mode(*mode, cx);
},
))
})
}),
),
@@ -184,7 +158,7 @@ impl Render for Preferences {
.child(
h_flex()
.gap_1()
.child(Input::new(&self.file_input).text_xs().small())
.child(Input::new(&self.file_input).small())
.child(
Button::new("update-file-server")
.icon(IconName::Check)
@@ -197,9 +171,9 @@ impl Render for Preferences {
)
.child(
div()
.text_size(px(10.))
.text_style(TextStyle::Caption2)
.italic()
.text_color(cx.theme().text_placeholder)
.text_color(cx.theme().text_faint)
.child(SharedString::from("Only support blossom service")),
),
),