migrate theming to gpui-native-kit
This commit is contained in:
Generated
+191
-77
@@ -1707,12 +1707,6 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "configparser"
|
|
||||||
version = "3.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "031ad3d167622974ed636505ae4556267ed4aa2aea0464122fa6bc9698a32825"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console_error_panic_hook"
|
name = "console_error_panic_hook"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@@ -1811,8 +1805,7 @@ dependencies = [
|
|||||||
"auto_update",
|
"auto_update",
|
||||||
"chat",
|
"chat",
|
||||||
"chat_ui",
|
"chat_ui",
|
||||||
"flume 0.11.1",
|
"gpui-native-kit",
|
||||||
"gpui-kit",
|
|
||||||
"gpui-pre",
|
"gpui-pre",
|
||||||
"gpui-pre-linux",
|
"gpui-pre-linux",
|
||||||
"gpui-pre-macos",
|
"gpui-pre-macos",
|
||||||
@@ -1820,14 +1813,13 @@ dependencies = [
|
|||||||
"gpui-pre-reqwest-client",
|
"gpui-pre-reqwest-client",
|
||||||
"gpui-pre-windows",
|
"gpui-pre-windows",
|
||||||
"log",
|
"log",
|
||||||
"native-theme",
|
|
||||||
"native-theme-gpui",
|
|
||||||
"nip29",
|
"nip29",
|
||||||
"nip4e",
|
"nip4e",
|
||||||
"nip60",
|
"nip60",
|
||||||
"nostr-sdk",
|
"nostr-sdk",
|
||||||
"person",
|
"person",
|
||||||
"settings",
|
"settings",
|
||||||
|
"speech",
|
||||||
"state",
|
"state",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"ui",
|
"ui",
|
||||||
@@ -1846,7 +1838,7 @@ dependencies = [
|
|||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
"getrandom 0.4.3",
|
"getrandom 0.4.3",
|
||||||
"gpui-kit",
|
"gpui-native-kit",
|
||||||
"gpui-pre",
|
"gpui-pre",
|
||||||
"gpui-pre-platform",
|
"gpui-pre-platform",
|
||||||
"gpui-pre-web",
|
"gpui-pre-web",
|
||||||
@@ -1857,6 +1849,7 @@ dependencies = [
|
|||||||
"nip4e",
|
"nip4e",
|
||||||
"person",
|
"person",
|
||||||
"settings",
|
"settings",
|
||||||
|
"speech",
|
||||||
"state",
|
"state",
|
||||||
"tracing-wasm",
|
"tracing-wasm",
|
||||||
"ui",
|
"ui",
|
||||||
@@ -3638,6 +3631,114 @@ dependencies = [
|
|||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-icons",
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-native-utils",
|
||||||
|
"gpui-pre",
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-core",
|
||||||
|
"gpui-native-icons",
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-native-utils",
|
||||||
|
"gpui-pre",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-editor"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-core",
|
||||||
|
"gpui-native-icons",
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-native-utils",
|
||||||
|
"gpui-pre",
|
||||||
|
"pulldown-cmark",
|
||||||
|
"similar",
|
||||||
|
"tree-sitter",
|
||||||
|
"tree-sitter-javascript",
|
||||||
|
"tree-sitter-python",
|
||||||
|
"tree-sitter-rust",
|
||||||
|
"tree-sitter-typescript",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-icons"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"gpui-pre",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-kit"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-core",
|
||||||
|
"gpui-native-data",
|
||||||
|
"gpui-native-editor",
|
||||||
|
"gpui-native-icons",
|
||||||
|
"gpui-native-layout",
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-pre",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-layout"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-core",
|
||||||
|
"gpui-native-data",
|
||||||
|
"gpui-native-icons",
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-native-utils",
|
||||||
|
"gpui-pre",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-theme"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-channel",
|
||||||
|
"block2 0.6.2",
|
||||||
|
"gpui-pre",
|
||||||
|
"notify",
|
||||||
|
"objc2 0.6.5",
|
||||||
|
"objc2-app-kit 0.3.2",
|
||||||
|
"objc2-foundation 0.3.2",
|
||||||
|
"serde",
|
||||||
|
"toml 0.8.23",
|
||||||
|
"windows 0.62.2",
|
||||||
|
"windows-registry 0.6.1",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gpui-native-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.reya.info/reya/gpui-native-kit?rev=b75968ee0fecf78c3041248f1f6bfe8bfd85dee0#b75968ee0fecf78c3041248f1f6bfe8bfd85dee0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui-native-theme",
|
||||||
|
"gpui-pre",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gpui-pre"
|
name = "gpui-pre"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
@@ -3678,7 +3779,7 @@ dependencies = [
|
|||||||
"parking",
|
"parking",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"pollster 0.4.0",
|
"pollster",
|
||||||
"profiling",
|
"profiling",
|
||||||
"rand 0.9.5",
|
"rand 0.9.5",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
@@ -5918,62 +6019,6 @@ dependencies = [
|
|||||||
"thiserror 2.0.21",
|
"thiserror 2.0.21",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "native-theme"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ef2a6c2d7520b94d53802c0c94d0450280a7c10380246756661bd1c6ffc64dd1"
|
|
||||||
dependencies = [
|
|
||||||
"arc-swap",
|
|
||||||
"ashpd",
|
|
||||||
"async-io",
|
|
||||||
"async-trait",
|
|
||||||
"block2 0.6.2",
|
|
||||||
"configparser",
|
|
||||||
"fontdb",
|
|
||||||
"inventory",
|
|
||||||
"native-theme-derive",
|
|
||||||
"notify",
|
|
||||||
"objc2 0.6.5",
|
|
||||||
"objc2-app-kit 0.3.2",
|
|
||||||
"objc2-core-foundation",
|
|
||||||
"objc2-core-text",
|
|
||||||
"objc2-foundation 0.3.2",
|
|
||||||
"pollster 1.0.1",
|
|
||||||
"serde",
|
|
||||||
"serde_with",
|
|
||||||
"toml 1.1.8+spec-1.1.0",
|
|
||||||
"unicase",
|
|
||||||
"windows 0.62.2",
|
|
||||||
"windows-version",
|
|
||||||
"zbus",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "native-theme-derive"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ba9ec586e35be9d05bdd279adc9cbe213b5bd630536b8066b82caaaf4021dba7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 3.0.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "native-theme-gpui"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e13cbaa86f1f0a1ac947380f5d8d47a5e9f7f939c77afd05d7039041abae146"
|
|
||||||
dependencies = [
|
|
||||||
"gpui-base",
|
|
||||||
"gpui-component",
|
|
||||||
"gpui-kit",
|
|
||||||
"gpui-pre",
|
|
||||||
"image",
|
|
||||||
"native-theme",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "native-tls"
|
name = "native-tls"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
@@ -6781,8 +6826,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
|
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.2",
|
"bitflags 2.13.2",
|
||||||
"block2 0.6.2",
|
|
||||||
"libc",
|
|
||||||
"objc2 0.6.5",
|
"objc2 0.6.5",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-core-graphics",
|
"objc2-core-graphics",
|
||||||
@@ -7587,12 +7630,6 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
|
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pollster"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bc6355899e1c9462875b6757c79f3caa011a1fdae12bbb1a2e72dd1f234f8336"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "poly1305"
|
name = "poly1305"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@@ -7740,6 +7777,17 @@ dependencies = [
|
|||||||
"syn 2.0.119",
|
"syn 2.0.119",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.13.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3db2be46835f013dd3f4fa7f5f7402c537787b54ebb6fe2b94bbdd7e2669bb7b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.13.2",
|
||||||
|
"memchr",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulp"
|
name = "pulp"
|
||||||
version = "0.22.3"
|
version = "0.22.3"
|
||||||
@@ -9047,7 +9095,6 @@ version = "2.0.0-alpha3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
"gpui-kit",
|
|
||||||
"gpui-pre",
|
"gpui-pre",
|
||||||
"log",
|
"log",
|
||||||
"nostr-sdk",
|
"nostr-sdk",
|
||||||
@@ -9463,6 +9510,12 @@ version = "0.4.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6"
|
checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "streaming-iterator"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strength_reduce"
|
name = "strength_reduce"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@@ -10270,6 +10323,66 @@ dependencies = [
|
|||||||
"strength_reduce",
|
"strength_reduce",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter"
|
||||||
|
version = "0.25.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"regex",
|
||||||
|
"regex-syntax",
|
||||||
|
"serde_json",
|
||||||
|
"streaming-iterator",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-javascript"
|
||||||
|
version = "0.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf40bf599e0416c16c125c3cec10ee5ddc7d1bb8b0c60fa5c4de249ad34dc1b1"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-language"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0af592be68c579aa78a16846bd19422978c3c52e438523d45ff5d1bff1f9d4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-python"
|
||||||
|
version = "0.23.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d065aaa27f3aaceaf60c1f0e0ac09e1cb9eb8ed28e7bcdaa52129cffc7f4b04"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-rust"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439e577dbe07423ec2582ac62c7531120dbfccfa6e5f92406f93dd271a120e45"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-typescript"
|
||||||
|
version = "0.23.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c5f76ed8d947a75cc446d5fccd8b602ebf0cde64ccf2ffa434d873d7a575eff"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "triomphe"
|
name = "triomphe"
|
||||||
version = "0.1.17"
|
version = "0.1.17"
|
||||||
@@ -11957,6 +12070,7 @@ dependencies = [
|
|||||||
"common",
|
"common",
|
||||||
"gpui-base",
|
"gpui-base",
|
||||||
"gpui-kit",
|
"gpui-kit",
|
||||||
|
"gpui-native-kit",
|
||||||
"gpui-pre",
|
"gpui-pre",
|
||||||
"instant",
|
"instant",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ edition.workspace = true
|
|||||||
publish.workspace = true
|
publish.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gpui-kit.workspace = true
|
|
||||||
common = { path = "../common" }
|
common = { path = "../common" }
|
||||||
|
|
||||||
nostr-sdk.workspace = true
|
nostr-sdk.workspace = true
|
||||||
|
|||||||
+5
-104
@@ -3,7 +3,7 @@ use std::path::PathBuf;
|
|||||||
use anyhow::{Error, anyhow};
|
use anyhow::{Error, anyhow};
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use common::config_dir;
|
use common::config_dir;
|
||||||
use gpui::{App, AppContext, Context, Entity, Global, ImageSource, Subscription, Task, px};
|
use gpui::{App, AppContext, Context, Entity, Global, ImageSource, Subscription, Task};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{SmallVec, smallvec};
|
||||||
@@ -36,33 +36,6 @@ impl AppearanceMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The default base font size for the interface
|
|
||||||
pub const DEFAULT_FONT_SIZE: f32 = 16.0;
|
|
||||||
|
|
||||||
/// User tuning applied on top of the native OS theme
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct ThemeSettings {
|
|
||||||
/// The base UI font size in pixels
|
|
||||||
pub font_size: f32,
|
|
||||||
/// Draw a ring around focused controls
|
|
||||||
pub focus_ring: bool,
|
|
||||||
/// Corner radius for general elements; follows the OS theme when unset
|
|
||||||
pub radius: Option<f32>,
|
|
||||||
/// Corner radius for large elements like dialogs; follows the OS theme when unset
|
|
||||||
pub radius_lg: Option<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ThemeSettings {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
font_size: DEFAULT_FONT_SIZE,
|
|
||||||
focus_ring: false,
|
|
||||||
radius: None,
|
|
||||||
radius_lg: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
AppSettings::set_global(cx.new(AppSettings::new), cx)
|
AppSettings::set_global(cx.new(AppSettings::new), cx)
|
||||||
}
|
}
|
||||||
@@ -91,13 +64,6 @@ pub fn persisted_appearance_mode() -> AppearanceMode {
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the persisted theme tuning synchronously.
|
|
||||||
pub fn persisted_theme() -> ThemeSettings {
|
|
||||||
persisted_settings()
|
|
||||||
.map(|settings| settings.theme)
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_FILE_SERVER: &str = "https://nostr.download/";
|
const DEFAULT_FILE_SERVER: &str = "https://nostr.download/";
|
||||||
const LEGACY_FILE_SERVER: &str = "blossom.band";
|
const LEGACY_FILE_SERVER: &str = "blossom.band";
|
||||||
/// Minimum days between automatic encryption key rotations
|
/// Minimum days between automatic encryption key rotations
|
||||||
@@ -160,7 +126,6 @@ setting_accessors! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setting_getters! {
|
setting_getters! {
|
||||||
pub theme: ThemeSettings,
|
|
||||||
pub pinned_rooms: Vec<u64>,
|
pub pinned_rooms: Vec<u64>,
|
||||||
pub pinned_groups: Vec<String>,
|
pub pinned_groups: Vec<String>,
|
||||||
}
|
}
|
||||||
@@ -234,9 +199,6 @@ pub struct Settings {
|
|||||||
/// Hide the notice that messages in public groups are not encrypted
|
/// Hide the notice that messages in public groups are not encrypted
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub hide_group_notice: bool,
|
pub hide_group_notice: bool,
|
||||||
/// Tuning applied on top of the native OS theme
|
|
||||||
#[serde(default)]
|
|
||||||
pub theme: ThemeSettings,
|
|
||||||
/// Show an image behind chat and group panels
|
/// Show an image behind chat and group panels
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub panel_background: bool,
|
pub panel_background: bool,
|
||||||
@@ -265,7 +227,6 @@ impl Default for Settings {
|
|||||||
nip4e: false,
|
nip4e: false,
|
||||||
nip4e_rotation_days: None,
|
nip4e_rotation_days: None,
|
||||||
hide_group_notice: false,
|
hide_group_notice: false,
|
||||||
theme: ThemeSettings::default(),
|
|
||||||
panel_background: true,
|
panel_background: true,
|
||||||
panel_background_path: None,
|
panel_background_path: None,
|
||||||
trusted_relays: vec![],
|
trusted_relays: vec![],
|
||||||
@@ -330,52 +291,6 @@ impl AppSettings {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Edit the theme tuning
|
|
||||||
pub fn update_theme(edit: impl FnOnce(&mut ThemeSettings), cx: &mut App) {
|
|
||||||
Self::global(cx).update(cx, |this, cx| {
|
|
||||||
this.inner.update(cx, |inner, cx| {
|
|
||||||
edit(&mut inner.theme);
|
|
||||||
cx.notify();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_theme_style(cx: &mut App) {
|
|
||||||
Self::apply_theme_tuning(Self::get_theme(cx), cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_theme_tuning(tuning: ThemeSettings, cx: &mut App) {
|
|
||||||
use gpui_kit::component::Theme;
|
|
||||||
|
|
||||||
{
|
|
||||||
let styled = Theme::global_mut(cx);
|
|
||||||
styled.font_size = px(tuning.font_size);
|
|
||||||
styled.focus_ring = tuning.focus_ring;
|
|
||||||
if let Some(radius) = tuning.radius {
|
|
||||||
styled.radius = px(radius);
|
|
||||||
}
|
|
||||||
if let Some(radius_lg) = tuning.radius_lg {
|
|
||||||
styled.radius_lg = px(radius_lg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Theme::update(cx, |styled| {
|
|
||||||
let background = styled.background;
|
|
||||||
let foreground = styled.foreground;
|
|
||||||
let (hover_alpha, active_alpha) = if styled.is_dark() {
|
|
||||||
(0.08, 0.12)
|
|
||||||
} else {
|
|
||||||
(0.04, 0.06)
|
|
||||||
};
|
|
||||||
if styled.list_hover == background {
|
|
||||||
styled.list_hover = foreground.alpha(hover_alpha);
|
|
||||||
}
|
|
||||||
if styled.tab_active == background {
|
|
||||||
styled.tab_active = foreground.alpha(active_alpha);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load settings
|
/// Load settings
|
||||||
fn load(&mut self, cx: &mut Context<Self>) {
|
fn load(&mut self, cx: &mut Context<Self>) {
|
||||||
let task: Task<Result<Settings, Error>> = cx.background_spawn(async move {
|
let task: Task<Result<Settings, Error>> = cx.background_spawn(async move {
|
||||||
@@ -408,7 +323,6 @@ impl AppSettings {
|
|||||||
// Update settings
|
// Update settings
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.set_settings(settings, cx);
|
this.set_settings(settings, cx);
|
||||||
this.apply_theme(cx);
|
|
||||||
cx.refresh_windows();
|
cx.refresh_windows();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
@@ -434,20 +348,6 @@ impl AppSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the persisted appearance mode to the app
|
|
||||||
pub fn apply_theme(&mut self, cx: &mut Context<Self>) {
|
|
||||||
use gpui_kit::component::Theme;
|
|
||||||
|
|
||||||
let mode = self.inner.read(cx).appearance_mode;
|
|
||||||
match mode {
|
|
||||||
AppearanceMode::System => Theme::sync_system_appearance(None, cx),
|
|
||||||
AppearanceMode::Light => Theme::change(gpui_kit::component::ThemeMode::Light, None, cx),
|
|
||||||
AppearanceMode::Dark => Theme::change(gpui_kit::component::ThemeMode::Dark, None, cx),
|
|
||||||
}
|
|
||||||
let tuning = self.inner.read(cx).theme;
|
|
||||||
Self::apply_theme_tuning(tuning, cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check if decoupling encryption key is enabled
|
/// Check if decoupling encryption key is enabled
|
||||||
pub fn is_nip4e_enabled(&self, cx: &App) -> bool {
|
pub fn is_nip4e_enabled(&self, cx: &App) -> bool {
|
||||||
self.inner.read(cx).nip4e
|
self.inner.read(cx).nip4e
|
||||||
@@ -507,9 +407,9 @@ impl AppSettings {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Settings written before theme tuning existed must keep loading.
|
/// Settings written by older versions, including theme tuning, must keep loading.
|
||||||
#[test]
|
#[test]
|
||||||
fn settings_without_theme_keep_defaults() {
|
fn legacy_settings_keep_loading() {
|
||||||
let settings: Settings = serde_json::from_str(
|
let settings: Settings = serde_json::from_str(
|
||||||
r#"{
|
r#"{
|
||||||
"appearance_mode": "Dark",
|
"appearance_mode": "Dark",
|
||||||
@@ -517,12 +417,13 @@ mod tests {
|
|||||||
"screening": true,
|
"screening": true,
|
||||||
"wot_auto_trust": true,
|
"wot_auto_trust": true,
|
||||||
"nip4e": false,
|
"nip4e": false,
|
||||||
|
"theme": { "font_size": 18.0, "focus_ring": true },
|
||||||
"trusted_relays": [],
|
"trusted_relays": [],
|
||||||
"file_server": "https://nostr.download/"
|
"file_server": "https://nostr.download/"
|
||||||
}"#,
|
}"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(settings.theme, ThemeSettings::default());
|
assert_eq!(settings.appearance_mode, AppearanceMode::Dark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ pub fn recognizer() -> impl SpeechRecognizer {
|
|||||||
parakeet::ParakeetRecognizer
|
parakeet::ParakeetRecognizer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initializes the old component kit that the retained speech widgets still use.
|
||||||
|
pub fn init_compat(cx: &mut App) {
|
||||||
|
gpui_kit::init(cx);
|
||||||
|
}
|
||||||
|
|
||||||
/// The recognizer backing the composer's microphone button.
|
/// The recognizer backing the composer's microphone button.
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
pub fn recognizer() -> impl SpeechRecognizer {
|
pub fn recognizer() -> impl SpeechRecognizer {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ publish.workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ui = { path = "../ui" }
|
ui = { path = "../ui" }
|
||||||
gpui-kit.workspace = true
|
gpui-kit.workspace = true
|
||||||
|
gpui-native-kit.workspace = true
|
||||||
common = { path = "../common" }
|
common = { path = "../common" }
|
||||||
state = { path = "../state" }
|
state = { path = "../state" }
|
||||||
nip29 = { path = "../nip29" }
|
nip29 = { path = "../nip29" }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use gpui::{
|
|||||||
};
|
};
|
||||||
use gpui_kit::assets::IconName;
|
use gpui_kit::assets::IconName;
|
||||||
use gpui_kit::component::button::{Button, ButtonVariants};
|
use gpui_kit::component::button::{Button, ButtonVariants};
|
||||||
use gpui_kit::component::input::{Input, InputEvent, InputState, NumberInput};
|
use gpui_kit::component::input::{Input, InputState};
|
||||||
use gpui_kit::component::kbd::Kbd;
|
use gpui_kit::component::kbd::Kbd;
|
||||||
use gpui_kit::component::menu::{DropdownMenu, PopupMenuItem};
|
use gpui_kit::component::menu::{DropdownMenu, PopupMenuItem};
|
||||||
use gpui_kit::component::notification::Notification;
|
use gpui_kit::component::notification::Notification;
|
||||||
@@ -27,19 +27,12 @@ use settings::{AppSettings, AppearanceMode, NIP4E_ROTATION_DEFAULT_DAYS};
|
|||||||
use speech::model::{self as speech_model};
|
use speech::model::{self as speech_model};
|
||||||
use ui::{settings_block, settings_row};
|
use ui::{settings_block, settings_row};
|
||||||
|
|
||||||
/// Bounds for the theme number inputs
|
|
||||||
const FONT_SIZE_RANGE: (f32, f32) = (10., 32.);
|
|
||||||
const RADIUS_RANGE: (f32, f32) = (0., 24.);
|
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Preferences> {
|
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Preferences> {
|
||||||
cx.new(|cx| Preferences::new(window, cx))
|
cx.new(|cx| Preferences::new(window, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Preferences {
|
pub struct Preferences {
|
||||||
file_input: Entity<InputState>,
|
file_input: Entity<InputState>,
|
||||||
font_size_input: Entity<InputState>,
|
|
||||||
radius_input: Entity<InputState>,
|
|
||||||
radius_lg_input: Entity<InputState>,
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mint_input: Entity<InputState>,
|
mint_input: Entity<InputState>,
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
@@ -57,61 +50,9 @@ impl Preferences {
|
|||||||
.placeholder("https://myblossom.com")
|
.placeholder("https://myblossom.com")
|
||||||
});
|
});
|
||||||
|
|
||||||
let theme = AppSettings::get_theme(cx);
|
|
||||||
let font_size_input = cx.new(|cx| {
|
|
||||||
InputState::new(window, cx)
|
|
||||||
.default_value(theme.font_size.to_string())
|
|
||||||
.step(1.)
|
|
||||||
.min(FONT_SIZE_RANGE.0 as f64)
|
|
||||||
.max(FONT_SIZE_RANGE.1 as f64)
|
|
||||||
});
|
|
||||||
let radius_input = cx.new(|cx| {
|
|
||||||
InputState::new(window, cx)
|
|
||||||
.default_value(
|
|
||||||
theme
|
|
||||||
.radius
|
|
||||||
.map(|value| value.to_string())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
)
|
|
||||||
.placeholder("System")
|
|
||||||
.step(1.)
|
|
||||||
.min(RADIUS_RANGE.0 as f64)
|
|
||||||
.max(RADIUS_RANGE.1 as f64)
|
|
||||||
});
|
|
||||||
let radius_lg_input = cx.new(|cx| {
|
|
||||||
InputState::new(window, cx)
|
|
||||||
.default_value(
|
|
||||||
theme
|
|
||||||
.radius_lg
|
|
||||||
.map(|value| value.to_string())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
)
|
|
||||||
.placeholder("System")
|
|
||||||
.step(1.)
|
|
||||||
.min(RADIUS_RANGE.0 as f64)
|
|
||||||
.max(RADIUS_RANGE.1 as f64)
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let mint_input = cx.new(|cx| InputState::new(window, cx).placeholder("https://mint…"));
|
let mint_input = cx.new(|cx| InputState::new(window, cx).placeholder("https://mint…"));
|
||||||
|
|
||||||
let subscriptions = vec![
|
|
||||||
Self::wire_number_input(&font_size_input, FONT_SIZE_RANGE, cx, |value, cx| {
|
|
||||||
if let Some(font_size) = value {
|
|
||||||
AppSettings::update_theme(|theme| theme.font_size = font_size, cx);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
Self::wire_number_input(&radius_input, RADIUS_RANGE, cx, |value, cx| {
|
|
||||||
AppSettings::update_theme(|theme| theme.radius = value, cx);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}),
|
|
||||||
Self::wire_number_input(&radius_lg_input, RADIUS_RANGE, cx, |value, cx| {
|
|
||||||
AppSettings::update_theme(|theme| theme.radius_lg = value, cx);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let _speech_poll = cx.spawn_in(window, async move |this, cx| {
|
let _speech_poll = cx.spawn_in(window, async move |this, cx| {
|
||||||
let timer = Duration::from_millis(500);
|
let timer = Duration::from_millis(500);
|
||||||
@@ -141,43 +82,14 @@ impl Preferences {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
file_input,
|
file_input,
|
||||||
font_size_input,
|
|
||||||
radius_input,
|
|
||||||
radius_lg_input,
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mint_input,
|
mint_input,
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
_speech_poll,
|
_speech_poll,
|
||||||
_subscriptions: subscriptions,
|
_subscriptions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Persist a theme number as it changes; an empty value stores `None`
|
|
||||||
fn wire_number_input(
|
|
||||||
state: &Entity<InputState>,
|
|
||||||
range: (f32, f32),
|
|
||||||
cx: &mut Context<Self>,
|
|
||||||
persist: impl Fn(Option<f32>, &mut App) + 'static,
|
|
||||||
) -> Subscription {
|
|
||||||
let (min, max) = range;
|
|
||||||
let state = state.clone();
|
|
||||||
|
|
||||||
cx.subscribe(&state, move |_, state, event: &InputEvent, cx| {
|
|
||||||
if !matches!(event, InputEvent::Change) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = state
|
|
||||||
.read(cx)
|
|
||||||
.value()
|
|
||||||
.trim()
|
|
||||||
.parse::<f32>()
|
|
||||||
.ok()
|
|
||||||
.map(|value| value.clamp(min, max));
|
|
||||||
persist(value, cx);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the file server (blossom) URL
|
/// Update the file server (blossom) URL
|
||||||
fn update_file_server(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
fn update_file_server(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
let value = self.file_input.read(cx).value();
|
let value = self.file_input.read(cx).value();
|
||||||
@@ -245,9 +157,7 @@ impl Preferences {
|
|||||||
/// Set the appearance mode (system, light or dark)
|
/// Set the appearance mode (system, light or dark)
|
||||||
fn set_appearance_mode(mode: AppearanceMode, cx: &mut App) {
|
fn set_appearance_mode(mode: AppearanceMode, cx: &mut App) {
|
||||||
AppSettings::update_appearance_mode(mode, cx);
|
AppSettings::update_appearance_mode(mode, cx);
|
||||||
AppSettings::global(cx).update(cx, |settings, cx| {
|
crate::apply_appearance_mode(mode, cx);
|
||||||
settings.apply_theme(cx);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ask the user for an image to show behind chat and group panels
|
/// Ask the user for an image to show behind chat and group panels
|
||||||
@@ -388,11 +298,6 @@ impl Render for Preferences {
|
|||||||
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
||||||
const APPEARANCE: &str =
|
const APPEARANCE: &str =
|
||||||
"Choose whether the app follows the system theme or uses a light/dark theme.";
|
"Choose whether the app follows the system theme or uses a light/dark theme.";
|
||||||
const FONT_SIZE: &str = "The base font size for the interface.";
|
|
||||||
const RADIUS: &str = "Corner radius for UI elements. Empty follows the OS theme.";
|
|
||||||
const RADIUS_LG: &str =
|
|
||||||
"Corner radius for large elements like dialogs. Empty follows the OS theme.";
|
|
||||||
const FOCUS_RING: &str = "Draw a ring around focused controls.";
|
|
||||||
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
|
const NIP4E: &str = "Use a dedicated key to encrypt and decrypt messages.";
|
||||||
const NIP4E_ROTATION: &str = "Automatically rotate the encryption key every 30 days, keeping the previous key for messages still sealed to it.";
|
const NIP4E_ROTATION: &str = "Automatically rotate the encryption key every 30 days, keeping the previous key for messages still sealed to it.";
|
||||||
const BACKGROUND: &str = "Show an image behind chat and group panels.";
|
const BACKGROUND: &str = "Show an image behind chat and group panels.";
|
||||||
@@ -404,7 +309,6 @@ impl Render for Preferences {
|
|||||||
let nip4e = AppSettings::get_nip4e(cx);
|
let nip4e = AppSettings::get_nip4e(cx);
|
||||||
let nip4e_rotation_days = AppSettings::get_nip4e_rotation_days(cx);
|
let nip4e_rotation_days = AppSettings::get_nip4e_rotation_days(cx);
|
||||||
let appearance_mode = AppSettings::get_appearance_mode(cx);
|
let appearance_mode = AppSettings::get_appearance_mode(cx);
|
||||||
let theme = AppSettings::get_theme(cx);
|
|
||||||
let panel_background = AppSettings::get_panel_background(cx);
|
let panel_background = AppSettings::get_panel_background(cx);
|
||||||
let panel_background_path = AppSettings::get_panel_background_path(cx);
|
let panel_background_path = AppSettings::get_panel_background_path(cx);
|
||||||
|
|
||||||
@@ -472,44 +376,6 @@ impl Render for Preferences {
|
|||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(Separator::horizontal())
|
.child(Separator::horizontal())
|
||||||
.child(
|
|
||||||
v_flex()
|
|
||||||
.w_full()
|
|
||||||
.gap_3()
|
|
||||||
.child(settings_row(
|
|
||||||
"Font Size",
|
|
||||||
FONT_SIZE,
|
|
||||||
NumberInput::new(&self.font_size_input).w_24(),
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.child(settings_row(
|
|
||||||
"Corner Radius",
|
|
||||||
RADIUS,
|
|
||||||
NumberInput::new(&self.radius_input).w_24(),
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.child(settings_row(
|
|
||||||
"Large Corner Radius",
|
|
||||||
RADIUS_LG,
|
|
||||||
NumberInput::new(&self.radius_lg_input).w_24(),
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.child(settings_row(
|
|
||||||
"Focus Ring",
|
|
||||||
FOCUS_RING,
|
|
||||||
Switch::new("focus-ring")
|
|
||||||
.checked(theme.focus_ring)
|
|
||||||
.on_click(move |_, _window, cx| {
|
|
||||||
AppSettings::update_theme(
|
|
||||||
|theme| theme.focus_ring = !theme.focus_ring,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}),
|
|
||||||
cx,
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
.child(Separator::horizontal())
|
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ::settings::{AppSettings, AppearanceMode};
|
use ::settings::AppearanceMode;
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use auto_update::AutoUpdater;
|
use auto_update::AutoUpdater;
|
||||||
@@ -14,7 +14,7 @@ use gpui::{
|
|||||||
use gpui_kit::component::button::Button;
|
use gpui_kit::component::button::Button;
|
||||||
use gpui_kit::component::dock::{DockArea, DockLayout, DockPlacement, Panel, PanelHandle};
|
use gpui_kit::component::dock::{DockArea, DockLayout, DockPlacement, Panel, PanelHandle};
|
||||||
use gpui_kit::component::notification::{Notification, NotificationType};
|
use gpui_kit::component::notification::{Notification, NotificationType};
|
||||||
use gpui_kit::component::{ActiveTheme, Theme, WindowExt, v_flex};
|
use gpui_kit::component::{ActiveTheme, WindowExt, v_flex};
|
||||||
use nip4e::{DeviceEvent, DeviceRegistry};
|
use nip4e::{DeviceEvent, DeviceRegistry};
|
||||||
use nip29::{GroupId, GroupKey};
|
use nip29::{GroupId, GroupKey};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
@@ -42,6 +42,31 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
|
|||||||
cx.new(|cx| Workspace::new(window, cx))
|
cx.new(|cx| Workspace::new(window, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply the appearance mode to the kit and mirror it into the old theme
|
||||||
|
/// that the speech components still use.
|
||||||
|
pub fn apply_appearance_mode(mode: AppearanceMode, cx: &mut App) {
|
||||||
|
match mode {
|
||||||
|
AppearanceMode::System => {
|
||||||
|
gpui_native_kit::theme::follow_system(cx);
|
||||||
|
gpui_kit::component::Theme::sync_system_appearance(None, cx);
|
||||||
|
}
|
||||||
|
AppearanceMode::Light => {
|
||||||
|
gpui_native_kit::theme::set_mode_override(
|
||||||
|
Some(gpui_native_kit::theme::ThemeVariant::Light),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
gpui_kit::component::Theme::change(gpui_kit::component::ThemeMode::Light, None, cx);
|
||||||
|
}
|
||||||
|
AppearanceMode::Dark => {
|
||||||
|
gpui_native_kit::theme::set_mode_override(
|
||||||
|
Some(gpui_native_kit::theme::ThemeVariant::Dark),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
gpui_kit::component::Theme::change(gpui_kit::component::ThemeMode::Dark, None, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct DeviceNotifcation;
|
struct DeviceNotifcation;
|
||||||
struct MsgRelayNotification;
|
struct MsgRelayNotification;
|
||||||
|
|
||||||
@@ -93,10 +118,7 @@ impl Workspace {
|
|||||||
let mut subscriptions = smallvec![];
|
let mut subscriptions = smallvec![];
|
||||||
|
|
||||||
subscriptions.push(cx.observe_window_appearance(window, |_this, window, cx| {
|
subscriptions.push(cx.observe_window_appearance(window, |_this, window, cx| {
|
||||||
if AppSettings::get_appearance_mode(cx) == AppearanceMode::System {
|
gpui_native_kit::theme::Theme::sync_from_window(window, cx);
|
||||||
Theme::sync_system_appearance(Some(window), cx);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
subscriptions.push(
|
subscriptions.push(
|
||||||
@@ -536,8 +558,8 @@ impl Workspace {
|
|||||||
|
|
||||||
impl Render for Workspace {
|
impl Render for Workspace {
|
||||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
// Dialog, notification and tooltip layers are owned by the framework
|
// Dialog, notification and tooltip layers previously came from the
|
||||||
// Root that gpui_kit::open_window installed for this window.
|
// old kit's window root; they move to common dialogs and toasts.
|
||||||
div()
|
div()
|
||||||
.id("workspace")
|
.id("workspace")
|
||||||
.on_action(cx.listener(Self::on_command))
|
.on_action(cx.listener(Self::on_command))
|
||||||
|
|||||||
+2
-4
@@ -47,13 +47,11 @@ person = { path = "../crates/person" }
|
|||||||
|
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
gpui_platform.workspace = true
|
gpui_platform.workspace = true
|
||||||
gpui-kit.workspace = true
|
|
||||||
gpui_linux.workspace = true
|
gpui_linux.workspace = true
|
||||||
gpui_windows.workspace = true
|
gpui_windows.workspace = true
|
||||||
gpui_macos.workspace = true
|
gpui_macos.workspace = true
|
||||||
native-theme.workspace = true
|
gpui-native-kit.workspace = true
|
||||||
native-theme-gpui.workspace = true
|
speech = { path = "../crates/speech" }
|
||||||
flume.workspace = true
|
|
||||||
reqwest_client.workspace = true
|
reqwest_client.workspace = true
|
||||||
|
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
|
|||||||
+21
-90
@@ -2,18 +2,14 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use chat_ui::ToggleDictation;
|
use chat_ui::ToggleDictation;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, Bounds, Global, KeyBinding, Menu, MenuItem, SharedString, TitlebarOptions,
|
App, Bounds, KeyBinding, Menu, MenuItem, SharedString, TitlebarOptions, WindowBounds,
|
||||||
WindowBackgroundAppearance, WindowBounds, WindowDecorations, WindowKind, WindowOptions,
|
WindowDecorations, WindowKind, WindowOptions, actions, point, px, size,
|
||||||
actions, point, px, size,
|
|
||||||
};
|
};
|
||||||
use gpui_kit::component::{Theme, ThemeMode};
|
use gpui_native_kit::theme::ActiveTheme;
|
||||||
use gpui_platform::application;
|
use gpui_platform::application;
|
||||||
use native_theme::watch::ThemeSubscription;
|
|
||||||
use native_theme_gpui::apply_system_theme;
|
|
||||||
use nostr_sdk::prelude::SecretKey;
|
use nostr_sdk::prelude::SecretKey;
|
||||||
use settings::{AppSettings, AppearanceMode};
|
|
||||||
use state::{APP_ID, CLIENT_NAME};
|
use state::{APP_ID, CLIENT_NAME};
|
||||||
use workspace::TAB_BAR_HEIGHT;
|
use workspace::{TAB_BAR_HEIGHT, apply_appearance_mode};
|
||||||
|
|
||||||
actions!(coop, [Quit]);
|
actions!(coop, [Quit]);
|
||||||
|
|
||||||
@@ -34,8 +30,9 @@ fn main() {
|
|||||||
.with_assets(assets::CombinedAssets)
|
.with_assets(assets::CombinedAssets)
|
||||||
.with_http_client(Arc::new(reqwest_client::ReqwestClient::new()))
|
.with_http_client(Arc::new(reqwest_client::ReqwestClient::new()))
|
||||||
.run(move |cx| {
|
.run(move |cx| {
|
||||||
// Initialize the framework before anything renders
|
// Initialize the frameworks before anything renders
|
||||||
gpui_kit::init(cx);
|
gpui_native_kit::init(cx);
|
||||||
|
speech::init_compat(cx);
|
||||||
|
|
||||||
// Load embedded fonts in assets/fonts
|
// Load embedded fonts in assets/fonts
|
||||||
load_embedded_fonts(cx);
|
load_embedded_fonts(cx);
|
||||||
@@ -71,14 +68,7 @@ fn main() {
|
|||||||
settings::init(cx);
|
settings::init(cx);
|
||||||
|
|
||||||
let appearance = settings::persisted_appearance_mode();
|
let appearance = settings::persisted_appearance_mode();
|
||||||
let font_size = settings::persisted_theme().font_size;
|
apply_appearance_mode(appearance, cx);
|
||||||
|
|
||||||
if let Err(error) = apply_native_theme(appearance, font_size, cx) {
|
|
||||||
log::warn!("native theme unavailable ({error})");
|
|
||||||
apply_appearance(appearance, cx);
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
}
|
|
||||||
start_theme_watcher(cx);
|
|
||||||
|
|
||||||
// Initialize the nostr client
|
// Initialize the nostr client
|
||||||
state::init(cx, cli_key);
|
state::init(cx, cli_key);
|
||||||
@@ -110,7 +100,7 @@ fn main() {
|
|||||||
|
|
||||||
// Set up the window options
|
// Set up the window options
|
||||||
let opts = WindowOptions {
|
let opts = WindowOptions {
|
||||||
window_background: WindowBackgroundAppearance::Opaque,
|
window_background: cx.theme().window_background,
|
||||||
window_decorations: Some(WindowDecorations::Client),
|
window_decorations: Some(WindowDecorations::Client),
|
||||||
window_bounds: Some(WindowBounds::Windowed(bounds)),
|
window_bounds: Some(WindowBounds::Windowed(bounds)),
|
||||||
kind: WindowKind::Normal,
|
kind: WindowKind::Normal,
|
||||||
@@ -127,8 +117,18 @@ fn main() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
gpui_kit::open_window(opts, cx, workspace::init)
|
cx.open_window(opts, |window, cx| {
|
||||||
.expect("Failed to open window. Please restart the application.");
|
gpui_native_kit::theme::Theme::sync_from_window(window, cx);
|
||||||
|
gpui_native_kit::theme::Theme::sync_window_rem_size(window, cx);
|
||||||
|
window
|
||||||
|
.observe_window_appearance(|window, cx| {
|
||||||
|
gpui_native_kit::theme::Theme::sync_from_window(window, cx);
|
||||||
|
cx.refresh_windows();
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
workspace::init(window, cx)
|
||||||
|
})
|
||||||
|
.expect("Failed to open window. Please restart the application.");
|
||||||
|
|
||||||
cx.activate(true);
|
cx.activate(true);
|
||||||
});
|
});
|
||||||
@@ -181,72 +181,3 @@ fn quit(_ev: &Quit, cx: &mut App) {
|
|||||||
log::info!("Gracefully quitting the application . . .");
|
log::info!("Gracefully quitting the application . . .");
|
||||||
cx.quit();
|
cx.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Apply the native theme to the app, scaled to the user's font size,
|
|
||||||
/// then layer the persisted theme tuning on top
|
|
||||||
fn apply_native_theme(
|
|
||||||
appearance: AppearanceMode,
|
|
||||||
font_size: f32,
|
|
||||||
cx: &mut App,
|
|
||||||
) -> native_theme::Result<()> {
|
|
||||||
let mut system = native_theme_gpui::SystemTheme::from_system()?;
|
|
||||||
let native = system.light.defaults.font.size;
|
|
||||||
|
|
||||||
if native > 0.0 {
|
|
||||||
system.accessibility.text_scaling_factor *= font_size / native;
|
|
||||||
}
|
|
||||||
|
|
||||||
apply_system_theme(&system, cx);
|
|
||||||
apply_appearance(appearance, cx);
|
|
||||||
// Applying the native theme replaces the whole theme, so the user's
|
|
||||||
// tuning must be layered on afterwards.
|
|
||||||
AppSettings::apply_theme_style(cx);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Honor the appearance mode against the installed (native) palettes
|
|
||||||
fn apply_appearance(appearance: AppearanceMode, cx: &mut App) {
|
|
||||||
match appearance {
|
|
||||||
AppearanceMode::System => Theme::sync_system_appearance(None, cx),
|
|
||||||
AppearanceMode::Light => Theme::change(ThemeMode::Light, None, cx),
|
|
||||||
AppearanceMode::Dark => Theme::change(ThemeMode::Dark, None, cx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Holds the watcher subscription so it lives as long as the app.
|
|
||||||
struct ThemeWatcher {
|
|
||||||
_subscription: ThemeSubscription,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Global for ThemeWatcher {}
|
|
||||||
|
|
||||||
/// Start a background task to watch for OS theme changes and re-apply the native theme.
|
|
||||||
fn start_theme_watcher(cx: &mut App) {
|
|
||||||
let (sender, receiver) = flume::unbounded();
|
|
||||||
match native_theme::watch::on_theme_change(move |event| {
|
|
||||||
if let Err(error) = sender.send(event) {
|
|
||||||
log::warn!("theme change dropped ({error})");
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Ok(subscription) => {
|
|
||||||
cx.set_global(ThemeWatcher {
|
|
||||||
_subscription: subscription,
|
|
||||||
});
|
|
||||||
cx.spawn(async move |cx| {
|
|
||||||
while receiver.recv_async().await.is_ok() {
|
|
||||||
log::info!("OS theme changed; re-applying");
|
|
||||||
cx.update(|cx| {
|
|
||||||
let appearance = AppSettings::get_appearance_mode(cx);
|
|
||||||
let font_size = AppSettings::get_theme(cx).font_size;
|
|
||||||
if let Err(error) = apply_native_theme(appearance, font_size, cx) {
|
|
||||||
log::warn!("failed to apply updated OS theme ({error})");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
Err(error) => log::warn!("OS theme watching unavailable ({error})"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-1
@@ -22,7 +22,8 @@ person = { path = "../crates/person" }
|
|||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
gpui_platform.workspace = true
|
gpui_platform.workspace = true
|
||||||
gpui_web.workspace = true
|
gpui_web.workspace = true
|
||||||
gpui-kit.workspace = true
|
gpui-native-kit.workspace = true
|
||||||
|
speech = { path = "../crates/speech" }
|
||||||
|
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
instant = { workspace = true, features = ["wasm-bindgen"] }
|
instant = { workspace = true, features = ["wasm-bindgen"] }
|
||||||
|
|||||||
+18
-34
@@ -1,10 +1,10 @@
|
|||||||
#![cfg(target_arch = "wasm32")]
|
#![cfg(target_arch = "wasm32")]
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
|
use gpui_native_kit::theme::ActiveTheme;
|
||||||
use universal_time::{Instant, MonotonicClock, SystemTime, WallClock, define_time_provider};
|
use universal_time::{Instant, MonotonicClock, SystemTime, WallClock, define_time_provider};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@@ -83,16 +83,15 @@ pub fn run() -> Result<(), JsValue> {
|
|||||||
KeyBinding::new("ctrl-d", chat_ui::ToggleDictation, None),
|
KeyBinding::new("ctrl-d", chat_ui::ToggleDictation, None),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
gpui_kit::init(cx);
|
gpui_native_kit::init(cx);
|
||||||
|
speech::init_compat(cx);
|
||||||
|
|
||||||
load_embedded_fonts(cx);
|
load_embedded_fonts(cx);
|
||||||
apply_web_fonts(cx);
|
|
||||||
|
|
||||||
// Initialize settings
|
// Initialize settings
|
||||||
settings::init(cx);
|
settings::init(cx);
|
||||||
|
|
||||||
apply_appearance(settings::persisted_appearance_mode(), cx);
|
workspace::apply_appearance_mode(settings::persisted_appearance_mode(), cx);
|
||||||
settings::AppSettings::apply_theme_style(cx);
|
|
||||||
|
|
||||||
// Initialize the nostr client
|
// Initialize the nostr client
|
||||||
state::init(cx, None);
|
state::init(cx, None);
|
||||||
@@ -111,7 +110,20 @@ pub fn run() -> Result<(), JsValue> {
|
|||||||
// Initialize groups registry
|
// Initialize groups registry
|
||||||
nip29::init(cx);
|
nip29::init(cx);
|
||||||
|
|
||||||
gpui_kit::open_window(WindowOptions::default(), cx, |window, cx| {
|
let opts = WindowOptions {
|
||||||
|
window_background: cx.theme().window_background,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.open_window(opts, |window, cx| {
|
||||||
|
gpui_native_kit::theme::Theme::sync_from_window(window, cx);
|
||||||
|
gpui_native_kit::theme::Theme::sync_window_rem_size(window, cx);
|
||||||
|
window
|
||||||
|
.observe_window_appearance(|window, cx| {
|
||||||
|
gpui_native_kit::theme::Theme::sync_from_window(window, cx);
|
||||||
|
cx.refresh_windows();
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
workspace::init(window, cx)
|
workspace::init(window, cx)
|
||||||
})
|
})
|
||||||
.expect("Failed to open window. Please restart the application.");
|
.expect("Failed to open window. Please restart the application.");
|
||||||
@@ -139,31 +151,3 @@ fn load_embedded_fonts(cx: &mut App) {
|
|||||||
.add_fonts(fonts)
|
.add_fonts(fonts)
|
||||||
.expect("Failed to load bundled fonts");
|
.expect("Failed to load bundled fonts");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_web_fonts(cx: &mut App) {
|
|
||||||
use gpui_kit::component::Theme;
|
|
||||||
|
|
||||||
const UI_FONT: &str = "Inter";
|
|
||||||
|
|
||||||
Theme::update(cx, |theme| {
|
|
||||||
theme.font_family = UI_FONT.into();
|
|
||||||
theme.mono_font_family = UI_FONT.into();
|
|
||||||
|
|
||||||
for config in [&mut theme.light_theme, &mut theme.dark_theme] {
|
|
||||||
let config = Rc::make_mut(config);
|
|
||||||
config.font_family = Some(UI_FONT.into());
|
|
||||||
config.mono_font_family = Some(UI_FONT.into());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Honor the appearance mode against the default palettes
|
|
||||||
fn apply_appearance(appearance: settings::AppearanceMode, cx: &mut App) {
|
|
||||||
use gpui_kit::component::{Theme, ThemeMode};
|
|
||||||
|
|
||||||
match appearance {
|
|
||||||
settings::AppearanceMode::System => Theme::sync_system_appearance(None, cx),
|
|
||||||
settings::AppearanceMode::Light => Theme::change(ThemeMode::Light, None, cx),
|
|
||||||
settings::AppearanceMode::Dark => Theme::change(ThemeMode::Dark, None, cx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user