From cba3f976c6996e3c625b6c2e1eaa46e2f620fbbd Mon Sep 17 00:00:00 2001 From: reya Date: Thu, 26 Feb 2026 07:07:15 +0700 Subject: [PATCH] add preferences dialog --- Cargo.lock | 144 +++++++++++----------- crates/coop/src/dialogs/mod.rs | 1 + crates/coop/src/dialogs/settings.rs | 166 ++++++++++++++++++++++++++ crates/coop/src/workspace.rs | 14 ++- crates/settings/src/lib.rs | 10 ++ crates/ui/src/group_box.rs | 177 ++++++++++++++++++++++++++++ crates/ui/src/lib.rs | 1 + crates/ui/src/switch.rs | 2 +- 8 files changed, 443 insertions(+), 72 deletions(-) create mode 100644 crates/coop/src/dialogs/settings.rs create mode 100644 crates/ui/src/group_box.rs diff --git a/Cargo.lock b/Cargo.lock index 0cb320b..9c4e55c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,19 +220,16 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.12.3" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a3c86f3fd70c0ffa500ed189abfa90b5a52398a45d5dc372fcc38ebeb7a645" +checksum = "0848bedd08067dca1c02c31cbb371a94ad4f2f8a61a82f2c43d96ec36a395244" dependencies = [ - "async-fs", - "async-net", "enumflags2", "futures-channel", "futures-util", - "rand 0.9.2", + "getrandom 0.4.1", "serde", "serde_repr", - "url", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1192,7 +1189,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "indexmap", "rustc-hash 2.1.1", @@ -1586,7 +1583,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] @@ -1640,7 +1636,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "proc-macro2", "quote", @@ -1916,7 +1912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2562,7 +2558,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "async-task", @@ -2636,7 +2632,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2665,6 +2661,7 @@ dependencies = [ "smol", "strum", "swash", + "url", "util", "uuid", "wayland-backend", @@ -2684,7 +2681,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "async-task", @@ -2726,7 +2723,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2737,7 +2734,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "gpui", "gpui_linux", @@ -2748,7 +2745,7 @@ dependencies = [ [[package]] name = "gpui_tokio" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "gpui", @@ -2759,7 +2756,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "bytemuck", @@ -2778,7 +2775,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "collections", @@ -3022,7 +3019,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "async-compression", @@ -3047,7 +3044,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "rustls", "rustls-platform-verifier", @@ -3471,9 +3468,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.89" +version = "0.3.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4eacb0641a310445a4c513f2a5e23e19952e269c6a38887254d5f837a305506" +checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" dependencies = [ "once_cell", "wasm-bindgen", @@ -3521,9 +3518,6 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin 0.9.8", -] [[package]] name = "leak" @@ -3592,7 +3586,7 @@ checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.11.0", "libc", - "redox_syscall 0.7.1", + "redox_syscall 0.7.2", ] [[package]] @@ -3811,7 +3805,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "bindgen", @@ -4150,7 +4144,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4179,16 +4173,16 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.6" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +checksum = "a7f9a86e097b0d187ad0e65667c2f58b9254671e86e7dbb78036b16692eae099" dependencies = [ - "lazy_static", "libm", "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "once_cell", + "rand 0.9.2", "serde", "smallvec", "zeroize", @@ -4358,9 +4352,9 @@ checksum = "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" [[package]] name = "oo7" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3299dd401feaf1d45afd8fd1c0586f10fcfb22f244bb9afa942cec73503b89d" +checksum = "78f2bfed90f1618b4b48dcad9307f25e14ae894e2949642c87c351601d62cebd" dependencies = [ "aes", "ashpd", @@ -4374,15 +4368,15 @@ dependencies = [ "endi", "futures-lite 2.6.1", "futures-util", - "getrandom 0.3.4", + "getrandom 0.4.1", "hkdf", "hmac", "md-5", "num", "num-bigint-dig", "pbkdf2", - "rand 0.9.2", "serde", + "serde_bytes", "sha2", "subtle", "zbus", @@ -4555,7 +4549,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "collections", "serde", @@ -4983,7 +4977,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5189,9 +5183,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4" dependencies = [ "bitflags 2.11.0", ] @@ -5230,7 +5224,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "derive_refineable", ] @@ -5260,9 +5254,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "relay_auth" @@ -5329,7 +5323,7 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "bytes", @@ -5384,7 +5378,7 @@ dependencies = [ [[package]] name = "rope" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "arrayvec", "log", @@ -5497,14 +5491,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", "log", @@ -5646,7 +5640,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "async-task", "backtrace", @@ -5804,6 +5798,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -6228,7 +6232,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "arrayvec", "log", @@ -6466,7 +6470,7 @@ dependencies = [ "getrandom 0.4.1", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -7171,7 +7175,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "async-fs", @@ -7209,7 +7213,7 @@ dependencies = [ [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "perf", "quote", @@ -7365,9 +7369,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d7d0fce354c88b7982aec4400b3e7fcf723c32737cef571bd165f7613557ee" +checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" dependencies = [ "cfg-if", "once_cell", @@ -7378,9 +7382,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.62" +version = "0.4.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee85afca410ac4abba5b584b12e77ea225db6ee5471d0aebaae0861166f9378a" +checksum = "8a89f4650b770e4521aa6573724e2aed4704372151bd0de9d16a3bbabb87441a" dependencies = [ "cfg-if", "futures-util", @@ -7392,9 +7396,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55839b71ba921e4f75b674cb16f843f4b1f3b26ddfcb3454de1cf65cc021ec0f" +checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7402,9 +7406,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf2e969c2d60ff52e7e98b7392ff1588bffdd1ccd4769eba27222fd3d621571" +checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" dependencies = [ "bumpalo", "proc-macro2", @@ -7415,9 +7419,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0861f0dcdf46ea819407495634953cdcc8a8c7215ab799a7a7ce366be71c7b30" +checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" dependencies = [ "unicode-ident", ] @@ -7569,9 +7573,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.89" +version = "0.3.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10053fbf9a374174094915bbce141e87a6bf32ecd9a002980db4b638405e8962" +checksum = "705eceb4ce901230f8625bd1d665128056ccbe4b7408faa625eec1ba80f59a97" dependencies = [ "js-sys", "wasm-bindgen", @@ -7840,7 +7844,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -9000,7 +9004,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "anyhow", "chrono", @@ -9017,7 +9021,7 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" dependencies = [ "tracing", "tracing-subscriber", @@ -9028,7 +9032,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#0f21e2a5c608d3b4b0df8e50217397b53de3136b" +source = "git+https://github.com/zed-industries/zed#21bd74a0fb686b218cba856d4574ea6bf985608e" [[package]] name = "zune-core" @@ -9078,7 +9082,7 @@ dependencies = [ "endi", "enumflags2", "serde", - "url", + "serde_bytes", "winnow", "zvariant_derive", "zvariant_utils", diff --git a/crates/coop/src/dialogs/mod.rs b/crates/coop/src/dialogs/mod.rs index 7e8b4b2..d18f277 100644 --- a/crates/coop/src/dialogs/mod.rs +++ b/crates/coop/src/dialogs/mod.rs @@ -1 +1,2 @@ pub mod screening; +pub mod settings; diff --git a/crates/coop/src/dialogs/settings.rs b/crates/coop/src/dialogs/settings.rs new file mode 100644 index 0000000..fd2df6b --- /dev/null +++ b/crates/coop/src/dialogs/settings.rs @@ -0,0 +1,166 @@ +use gpui::http_client::Url; +use gpui::{ + div, px, App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, + Styled, Window, +}; +use settings::{AppSettings, AuthMode}; +use theme::ActiveTheme; +use ui::button::{Button, ButtonVariants}; +use ui::group_box::{GroupBox, GroupBoxVariants}; +use ui::input::{InputState, TextInput}; +use ui::menu::{DropdownMenu, PopupMenuItem}; +use ui::notification::Notification; +use ui::switch::Switch; +use ui::{h_flex, v_flex, IconName, Sizable, WindowExtension}; + +pub fn init(window: &mut Window, cx: &mut App) -> Entity { + cx.new(|cx| Preferences::new(window, cx)) +} + +pub struct Preferences { + file_input: Entity, +} + +impl Preferences { + pub fn new(window: &mut Window, cx: &mut Context) -> Self { + let server = AppSettings::get_file_server(cx); + let file_input = cx.new(|cx| { + InputState::new(window, cx) + .default_value(server.to_string()) + .placeholder("https://myblossom.com") + }); + + Self { file_input } + } + + fn update_file_server(&mut self, window: &mut Window, cx: &mut Context) { + let value = self.file_input.read(cx).value(); + + match Url::parse(&value) { + Ok(url) => { + AppSettings::update_file_server(url, cx); + } + Err(e) => { + window.push_notification(Notification::error(e.to_string()), cx); + } + } + } +} + +impl Render for Preferences { + fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { + const SCREENING: &str = + "When opening a request, a popup will appear to help you identify the sender."; + const AVATAR: &str = + "Hide all avatar pictures to improve performance and protect your privacy."; + const AUTH: &str = "Authentication before send events for some relays."; + + let screening = AppSettings::get_screening(cx); + let hide_avatar = AppSettings::get_hide_avatar(cx); + let auth_mode = AppSettings::get_auth_mode(cx); + + v_flex() + .gap_4() + .child( + GroupBox::new() + .id("general") + .title("General") + .fill() + .child( + Switch::new("screening") + .label("Screening") + .description(SCREENING) + .checked(screening) + .on_click(move |_, _window, cx| { + AppSettings::update_screening(!screening, cx); + }), + ) + .child( + Switch::new("avatar") + .label("Hide user avatar") + .description(AVATAR) + .checked(hide_avatar) + .on_click(move |_, _window, cx| { + AppSettings::update_hide_avatar(!hide_avatar, cx); + }), + ) + .child( + h_flex() + .gap_3() + .justify_between() + .child( + v_flex() + .child( + div() + .text_sm() + .child(SharedString::from("Relay authentication")), + ) + .child( + div() + .text_xs() + .text_color(cx.theme().text_muted) + .child(SharedString::from(AUTH)), + ), + ) + .child( + Button::new("auth") + .label(auth_mode.to_string()) + .ghost_alt() + .small() + .dropdown_menu(|this, _window, _cx| { + this.min_w(px(256.)) + .item( + PopupMenuItem::new("Auto authentication").on_click( + |_ev, _window, cx| { + AppSettings::update_auth_mode( + AuthMode::Auto, + cx, + ); + }, + ), + ) + .item(PopupMenuItem::new("Ask every time").on_click( + |_ev, _window, cx| { + AppSettings::update_auth_mode( + AuthMode::Manual, + cx, + ); + }, + )) + }), + ), + ), + ) + .child( + GroupBox::new() + .id("media") + .title("Media Upload Service") + .fill() + .child( + v_flex() + .gap_0p5() + .child( + h_flex() + .gap_1() + .child(TextInput::new(&self.file_input).text_xs().small()) + .child( + Button::new("update-file-server") + .icon(IconName::Check) + .ghost() + .size_8() + .on_click(cx.listener(move |this, _ev, window, cx| { + this.update_file_server(window, cx) + })), + ), + ) + .child( + div() + .text_size(px(10.)) + .italic() + .text_color(cx.theme().text_placeholder) + .child(SharedString::from("Only support blossom service")), + ), + ), + ) + } +} diff --git a/crates/coop/src/workspace.rs b/crates/coop/src/workspace.rs index 7de7051..b95de07 100644 --- a/crates/coop/src/workspace.rs +++ b/crates/coop/src/workspace.rs @@ -20,6 +20,7 @@ use ui::dock_area::{ClosePanel, DockArea, DockItem}; use ui::menu::DropdownMenu; use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension}; +use crate::dialogs::settings; use crate::panels::{backup, encryption_key, greeter, messaging_relays, profile, relay_list}; use crate::sidebar; @@ -187,6 +188,17 @@ impl Workspace { fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context) { match command { + Command::ShowSettings => { + let view = settings::init(window, cx); + + window.open_modal(cx, move |this, _window, _cx| { + this.width(px(520.)) + .show_close(true) + .pb_4() + .title("Preferences") + .child(view.clone()) + }); + } Command::ShowProfile => { let nostr = NostrRegistry::global(cx); let signer = nostr.read(cx).signer(); @@ -259,7 +271,7 @@ impl Workspace { this.ensure_messaging_relays(cx); }); } - _ => {} + Command::ToggleTheme => {} } } diff --git a/crates/settings/src/lib.rs b/crates/settings/src/lib.rs index b502f81..862abd6 100644 --- a/crates/settings/src/lib.rs +++ b/crates/settings/src/lib.rs @@ -1,4 +1,5 @@ use std::collections::{HashMap, HashSet}; +use std::fmt::Display; use anyhow::{anyhow, Error}; use common::config_dir; @@ -49,6 +50,15 @@ pub enum AuthMode { Manual, } +impl Display for AuthMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AuthMode::Auto => write!(f, "Auto authentication"), + AuthMode::Manual => write!(f, "Ask every time"), + } + } +} + /// Signer kind #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] pub enum SignerKind { diff --git a/crates/ui/src/group_box.rs b/crates/ui/src/group_box.rs new file mode 100644 index 0000000..031dc1f --- /dev/null +++ b/crates/ui/src/group_box.rs @@ -0,0 +1,177 @@ +use std::str::FromStr; + +use gpui::prelude::FluentBuilder; +use gpui::{ + div, relative, AnyElement, App, ElementId, InteractiveElement as _, IntoElement, ParentElement, + RenderOnce, StyleRefinement, Styled, Window, +}; +use smallvec::SmallVec; +use theme::ActiveTheme; + +use crate::{v_flex, StyledExt as _}; + +/// The variant of the GroupBox. +#[derive(Debug, Clone, Default, Copy, PartialEq, Eq, Hash)] +pub enum GroupBoxVariant { + #[default] + Normal, + Fill, +} + +/// Trait to add GroupBox variant methods to elements. +pub trait GroupBoxVariants: Sized { + /// Set the variant of the [`GroupBox`]. + #[must_use] + fn with_variant(self, variant: GroupBoxVariant) -> Self; + + /// Set to use [`GroupBoxVariant::Normal`] to GroupBox. + #[must_use] + fn normal(self) -> Self { + self.with_variant(GroupBoxVariant::Normal) + } + + /// Set to use [`GroupBoxVariant::Fill`] to GroupBox. + #[must_use] + fn fill(self) -> Self { + self.with_variant(GroupBoxVariant::Fill) + } +} + +impl GroupBoxVariant { + /// Convert the GroupBoxVariant to a string. + pub const fn as_str(&self) -> &str { + match self { + GroupBoxVariant::Normal => "normal", + GroupBoxVariant::Fill => "fill", + } + } +} + +impl FromStr for GroupBoxVariant { + type Err = (); + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "fill" => Ok(GroupBoxVariant::Fill), + _ => Ok(GroupBoxVariant::Normal), + } + } +} + +/// GroupBox is a styled container element that with +/// an optional title to groups related content together. +#[derive(IntoElement)] +pub struct GroupBox { + id: Option, + variant: GroupBoxVariant, + style: StyleRefinement, + title_style: StyleRefinement, + title: Option, + content_style: StyleRefinement, + children: SmallVec<[AnyElement; 1]>, +} + +impl GroupBox { + /// Create a new GroupBox. + pub fn new() -> Self { + Self { + id: None, + variant: GroupBoxVariant::default(), + style: StyleRefinement::default(), + title_style: StyleRefinement::default(), + content_style: StyleRefinement::default(), + title: None, + children: SmallVec::new(), + } + } + + /// Set the id of the group box, default is None. + #[must_use] + pub fn id(mut self, id: impl Into) -> Self { + self.id = Some(id.into()); + self + } + + /// Set the title of the group box, default is None. + #[must_use] + pub fn title(mut self, title: impl IntoElement) -> Self { + self.title = Some(title.into_any_element()); + self + } + + /// Set the style of the title of the group box to override the default style, default is None. + #[must_use] + pub fn title_style(mut self, style: StyleRefinement) -> Self { + self.title_style = style; + self + } + + /// Set the style of the content of the group box to override the default style, default is None. + #[must_use] + pub fn content_style(mut self, style: StyleRefinement) -> Self { + self.content_style = style; + self + } +} + +impl Default for GroupBox { + fn default() -> Self { + Self::new() + } +} + +impl ParentElement for GroupBox { + fn extend(&mut self, elements: impl IntoIterator) { + self.children.extend(elements); + } +} + +impl Styled for GroupBox { + fn style(&mut self) -> &mut StyleRefinement { + &mut self.style + } +} + +impl GroupBoxVariants for GroupBox { + fn with_variant(mut self, variant: GroupBoxVariant) -> Self { + self.variant = variant; + self + } +} + +impl RenderOnce for GroupBox { + fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { + let (bg, has_paddings) = match self.variant { + GroupBoxVariant::Normal => (None, false), + GroupBoxVariant::Fill => (Some(cx.theme().surface_background), true), + }; + + v_flex() + .id(self.id.unwrap_or("group-box".into())) + .w_full() + .when(has_paddings, |this| this.gap_3()) + .when(!has_paddings, |this| this.gap_4()) + .refine_style(&self.style) + .when_some(self.title, |this, title| { + this.child( + div() + .text_color(cx.theme().text_muted) + .line_height(relative(1.)) + .refine_style(&self.title_style) + .text_sm() + .font_semibold() + .child(title), + ) + }) + .child( + v_flex() + .when_some(bg, |this, bg| this.bg(bg)) + .text_color(cx.theme().text) + .when(has_paddings, |this| this.p_2()) + .gap_4() + .rounded(cx.theme().radius_lg) + .refine_style(&self.content_style) + .children(self.children), + ) + } +} diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index f66f0d7..3c9c10b 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -19,6 +19,7 @@ pub mod button; pub mod checkbox; pub mod divider; pub mod dock_area; +pub mod group_box; pub mod history; pub mod indicator; pub mod input; diff --git a/crates/ui/src/switch.rs b/crates/ui/src/switch.rs index 467d1d6..a13728f 100644 --- a/crates/ui/src/switch.rs +++ b/crates/ui/src/switch.rs @@ -233,7 +233,7 @@ impl Element for Switch { .when_some(self.description.clone(), |this, description| { this.child( div() - .pr_2() + .pr_3() .text_xs() .text_color(cx.theme().text_muted) .child(description),