extract workspace crates and switch to gpui-native-kit
Rust / build (macos-latest, stable) (push) Waiting to run
Rust / build (ubuntu-latest, stable) (push) Waiting to run
Rust / build (windows-latest, stable) (push) Waiting to run
Rust / build (macos-latest, stable) (pull_request) Waiting to run
Rust / build (ubuntu-latest, stable) (pull_request) Waiting to run
Rust / build (windows-latest, stable) (pull_request) Waiting to run
Rust / build (macos-latest, stable) (push) Waiting to run
Rust / build (ubuntu-latest, stable) (push) Waiting to run
Rust / build (windows-latest, stable) (push) Waiting to run
Rust / build (macos-latest, stable) (pull_request) Waiting to run
Rust / build (ubuntu-latest, stable) (pull_request) Waiting to run
Rust / build (windows-latest, stable) (pull_request) Waiting to run
This commit is contained in:
@@ -6,8 +6,7 @@ publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
gpui.workspace = true
|
||||
gpui-component.workspace = true
|
||||
anyhow.workspace = true
|
||||
gpui-native-kit.workspace = true
|
||||
rust-embed.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -1,433 +0,0 @@
|
||||
{
|
||||
"$schema": "https://github.com/longbridge/gpui-component/raw/refs/heads/main/.theme-schema.json",
|
||||
"name": "Signed",
|
||||
"author": "Signed",
|
||||
"themes": [
|
||||
{
|
||||
"is_default": true,
|
||||
"name": "Signed Light",
|
||||
"mode": "light",
|
||||
"colors": {
|
||||
"accent.background": "#F0F0F0",
|
||||
"accent.foreground": "#202020",
|
||||
"accordion.background": "#FFFFFF",
|
||||
"background": "#FFFFFF",
|
||||
"border": "#E4E4E7",
|
||||
"caret": "#202020",
|
||||
"chart.1": "#93C5FD",
|
||||
"chart.2": "#3B82F6",
|
||||
"chart.3": "#2563EB",
|
||||
"chart.4": "#1D4ED8",
|
||||
"chart.5": "#1E40AF",
|
||||
"chart_bullish": "green-600",
|
||||
"chart_bearish": "red-600",
|
||||
"danger.background": "red-500",
|
||||
"danger.foreground": "neutral-50",
|
||||
"description_list.label.foreground": "#202020",
|
||||
"drag.border": "#65A30D",
|
||||
"drop_target.background": "#C6FF4D40",
|
||||
"foreground": "#18181B",
|
||||
"group_box.background": "#F0F0F0",
|
||||
"group_box.foreground": "#202020",
|
||||
"info.background": "cyan-500",
|
||||
"info.foreground": "neutral-50",
|
||||
"input.border": "#E4E4E7",
|
||||
"link": "#3F6212",
|
||||
"link.active": "#3F6212",
|
||||
"link.hover": "#65A30D",
|
||||
"list.background": "#FFFFFF",
|
||||
"list.active.background": "#C6FF4D33",
|
||||
"list.active.border": "#65A30D",
|
||||
"list.even.background": "#F9F9F9",
|
||||
"list.head.background": "#F9F9F9",
|
||||
"list.hover.background": "#F0F0F0",
|
||||
"muted.background": "#F9F9F9",
|
||||
"muted.foreground": "#646464",
|
||||
"overlay": "#0000000D",
|
||||
"popover.background": "#FFFFFF",
|
||||
"popover.foreground": "#18181B",
|
||||
"primary.background": "#C6FF4D",
|
||||
"primary.active.background": "#65A30D",
|
||||
"primary.active.foreground": "#F7FEE7",
|
||||
"primary.foreground": "#1A2E05",
|
||||
"primary.hover.background": "#B7F03E",
|
||||
"progress.bar.background": "#18181B",
|
||||
"ring": "#BBBBBB",
|
||||
"scrollbar.background": "#F9F9F900",
|
||||
"scrollbar.thumb.background": "#BBBBBBE6",
|
||||
"scrollbar.thumb.hover.background": "#BBBBBB",
|
||||
"secondary.background": "#F0F0F0",
|
||||
"secondary.active.background": "#E0E0E0",
|
||||
"secondary.foreground": "#202020",
|
||||
"secondary.hover.background": "#E8E8E8",
|
||||
"selection.background": "#55A0FC",
|
||||
"sidebar.background": "#F9F9F9",
|
||||
"sidebar.accent.background": "#F0F0F0",
|
||||
"sidebar.accent.foreground": "#202020",
|
||||
"sidebar.border": "#E8E8E8",
|
||||
"sidebar.foreground": "#202020",
|
||||
"sidebar.primary.background": "#C6FF4D",
|
||||
"sidebar.primary.foreground": "#1A2E05",
|
||||
"skeleton.background": "#F0F0F0",
|
||||
"slider.background": "#18181B",
|
||||
"slider.thumb.background": "#FFFFFF",
|
||||
"status_bar.background": "#F9F9F9",
|
||||
"status_bar.border": "#E8E8E8",
|
||||
"success.background": "#2FBF71",
|
||||
"success.foreground": "#052E16",
|
||||
"switch.background": "#CECECE",
|
||||
"switch.thumb.background": "#FFFFFF",
|
||||
"tab.background": "#E8E8E8",
|
||||
"tab.active.background": "#F5F5F5",
|
||||
"tab.active.foreground": "#18181B",
|
||||
"tab.foreground": "#646464",
|
||||
"tab_bar.background": "#F0F0F0",
|
||||
"tab_bar.segmented.background": "#F0F0F0",
|
||||
"table.background": "#FFFFFF",
|
||||
"table.active.background": "#C6FF4D33",
|
||||
"table.active.border": "#65A30D",
|
||||
"table.even.background": "#F9F9F9",
|
||||
"table.head.background": "#F9F9F9",
|
||||
"table.head.foreground": "#838383",
|
||||
"table.hover.background": "#F0F0F0",
|
||||
"table.row.border": "#E8E8E8B3",
|
||||
"tiles.background": "#F9F9F9",
|
||||
"title_bar.background": "#F9F9F9",
|
||||
"title_bar.border": "#E8E8E8",
|
||||
"warning.background": "yellow-500",
|
||||
"warning.foreground": "neutral-50",
|
||||
"window.border": "#E8E8E8",
|
||||
"base.red": "red-600",
|
||||
"base.red.light": "red-400",
|
||||
"base.green": "#16A34A",
|
||||
"base.green.light": "green-400",
|
||||
"base.blue": "blue-600",
|
||||
"base.blue.light": "blue-400",
|
||||
"base.yellow": "yellow-600",
|
||||
"base.yellow.light": "yellow-400",
|
||||
"base.magenta": "purple-600",
|
||||
"base.magenta.light": "purple-400",
|
||||
"base.cyan": "cyan-600",
|
||||
"base.cyan.light": "cyan-400"
|
||||
},
|
||||
"highlight": {
|
||||
"editor.foreground": "#000000",
|
||||
"editor.background": "#ffffff",
|
||||
"editor.active_line.background": "#F5F5F5",
|
||||
"editor.line_number": "#929292",
|
||||
"editor.active_line_number": "#000000",
|
||||
"editor.invisible": "#73737366",
|
||||
"conflict": "#C5060B",
|
||||
"created": "#1642FF",
|
||||
"hidden": "#6D6D6D",
|
||||
"hint": "#9e5dff",
|
||||
"modified": "#9e7008",
|
||||
"predictive": "#A4ABB6",
|
||||
"warning": "#C99401",
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#957931"
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#C5060B"
|
||||
},
|
||||
"comment": {
|
||||
"color": "#007fff"
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#007fff"
|
||||
},
|
||||
"constant": {
|
||||
"color": "#C5060B"
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#0433ff"
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#333333"
|
||||
},
|
||||
"emphasis": {
|
||||
"font_style": "italic"
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"font_weight": 700
|
||||
},
|
||||
"function": {
|
||||
"color": "#0000A2"
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#0433ff"
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#0000A2",
|
||||
"font_style": "normal"
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#6A7293",
|
||||
"font_style": "italic"
|
||||
},
|
||||
"number": {
|
||||
"color": "#0433ff"
|
||||
},
|
||||
"string": {
|
||||
"color": "#036A07"
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#036A07"
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#036A07"
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#d21f07"
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#d21f07"
|
||||
},
|
||||
"tag": {
|
||||
"color": "#0433ff"
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#6F42C1"
|
||||
},
|
||||
"text.code.span": {
|
||||
"color": "#6F42C1"
|
||||
},
|
||||
"title": {
|
||||
"color": "#0433FF"
|
||||
},
|
||||
"type": {
|
||||
"color": "#6f42c1"
|
||||
},
|
||||
"property": {
|
||||
"color": "#333333"
|
||||
},
|
||||
"variable": {
|
||||
"color": "#333333"
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#C5060B"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"is_default": true,
|
||||
"name": "Signed Dark",
|
||||
"mode": "dark",
|
||||
"colors": {
|
||||
"accent.background": "#222222",
|
||||
"accent.foreground": "#EEEEEE",
|
||||
"accordion.background": "#0A0A0A",
|
||||
"background": "#0A0A0A",
|
||||
"border": "#27272A",
|
||||
"caret": "#EEEEEE",
|
||||
"chart.1": "#93C5FD",
|
||||
"chart.2": "#3B82F6",
|
||||
"chart.3": "#2563EB",
|
||||
"chart.4": "#1D4ED8",
|
||||
"chart.5": "#1E40AF",
|
||||
"chart_bullish": "green-600",
|
||||
"chart_bearish": "red-600",
|
||||
"danger.background": "red-400",
|
||||
"danger.foreground": "red-600",
|
||||
"description_list.label.background": "#191919",
|
||||
"description_list.label.foreground": "#EEEEEE",
|
||||
"drag.border": "#C6FF4D",
|
||||
"drop_target.background": "#C6FF4D2E",
|
||||
"foreground": "#FAFAFA",
|
||||
"group_box.background": "#191919",
|
||||
"group_box.foreground": "#EEEEEE",
|
||||
"info.background": "cyan-400",
|
||||
"info.foreground": "cyan-600",
|
||||
"input.border": "#2F2F2F",
|
||||
"link": "#A3E635",
|
||||
"link.active": "#A3E635",
|
||||
"link.hover": "#C6FF4D",
|
||||
"list.background": "#0A0A0A",
|
||||
"list.active.background": "#C6FF4D33",
|
||||
"list.active.border": "#C6FF4D",
|
||||
"list.even.background": "#191919",
|
||||
"list.head.background": "#191919",
|
||||
"list.hover.background": "#222222",
|
||||
"muted.background": "#191919",
|
||||
"muted.foreground": "#B4B4B4",
|
||||
"overlay": "#00000033",
|
||||
"popover.background": "#0A0A0A",
|
||||
"popover.foreground": "#FAFAFA",
|
||||
"primary.background": "#C6FF4D",
|
||||
"primary.active.background": "#65A30D",
|
||||
"primary.active.foreground": "#F7FEE7",
|
||||
"primary.foreground": "#1A2E05",
|
||||
"primary.hover.background": "#D6FF7A",
|
||||
"progress.bar.background": "#FAFAFA",
|
||||
"ring": "#606060",
|
||||
"scrollbar.background": "#19191900",
|
||||
"scrollbar.thumb.background": "#606060E6",
|
||||
"scrollbar.thumb.hover.background": "#606060",
|
||||
"secondary.background": "#222222",
|
||||
"secondary.active.background": "#313131",
|
||||
"secondary.foreground": "#EEEEEE",
|
||||
"secondary.hover.background": "#2A2A2A",
|
||||
"selection.background": "#1D4ED8",
|
||||
"sidebar.background": "#111111",
|
||||
"sidebar.accent.background": "#222222",
|
||||
"sidebar.accent.foreground": "#EEEEEE",
|
||||
"sidebar.border": "#2A2A2A",
|
||||
"sidebar.foreground": "#EEEEEE",
|
||||
"sidebar.primary.background": "#C6FF4D",
|
||||
"sidebar.primary.foreground": "#1A2E05",
|
||||
"skeleton.background": "#222222",
|
||||
"slider.background": "#FAFAFA",
|
||||
"slider.thumb.background": "#0A0A0A",
|
||||
"status_bar.background": "#191919",
|
||||
"status_bar.border": "#2A2A2A",
|
||||
"success.background": "#2FBF71",
|
||||
"success.foreground": "#052E16",
|
||||
"switch.background": "#484848",
|
||||
"switch.thumb.background": "#0A0A0A",
|
||||
"tab.background": "#2E2E2E",
|
||||
"tab.active.background": "#2A2A2A",
|
||||
"tab.active.foreground": "#FAFAFA",
|
||||
"tab.foreground": "#B4B4B4",
|
||||
"tab_bar.background": "#191919",
|
||||
"tab_bar.segmented.background": "#191919",
|
||||
"table.background": "#0A0A0A",
|
||||
"table.active.background": "#C6FF4D33",
|
||||
"table.active.border": "#C6FF4D",
|
||||
"table.even.background": "#191919",
|
||||
"table.head.background": "#191919",
|
||||
"table.head.foreground": "#7B7B7B",
|
||||
"table.hover.background": "#222222",
|
||||
"table.row.border": "#2A2A2AB3",
|
||||
"tiles.background": "#191919",
|
||||
"title_bar.background": "#191919",
|
||||
"title_bar.border": "#2A2A2A",
|
||||
"warning.background": "yellow-400",
|
||||
"warning.foreground": "yellow-600",
|
||||
"window.border": "#2A2A2A",
|
||||
"base.red": "red-400",
|
||||
"base.red.light": "red-300",
|
||||
"base.green": "#22C55E",
|
||||
"base.green.light": "green-300",
|
||||
"base.blue": "blue-400",
|
||||
"base.blue.light": "blue-300",
|
||||
"base.yellow": "yellow-400",
|
||||
"base.yellow.light": "yellow-300",
|
||||
"base.magenta": "purple-400",
|
||||
"base.magenta.light": "purple-300",
|
||||
"base.cyan": "cyan-400",
|
||||
"base.cyan.light": "cyan-300"
|
||||
},
|
||||
"highlight": {
|
||||
"editor.foreground": "#CACCCA",
|
||||
"editor.background": "#0a0a0a",
|
||||
"editor.active_line.background": "#171717",
|
||||
"editor.line_number": "#8F8F8F",
|
||||
"editor.active_line_number": "#DDDDDD",
|
||||
"editor.invisible": "#73737366",
|
||||
"conflict": "#D2602D",
|
||||
"created": "#3f72e2",
|
||||
"created.background": "#0C4619",
|
||||
"deleted.background": "#46190C",
|
||||
"error.background": "#46190C",
|
||||
"error.border": "#E44A4F",
|
||||
"hidden": "#9E9E9E",
|
||||
"hint": "#b283f8",
|
||||
"hint.background": "#250c4b",
|
||||
"hint.border": "#3f0891",
|
||||
"info.background": "#0059D1",
|
||||
"info.border": "#0059D1",
|
||||
"modified": "#B0A878",
|
||||
"modified.background": "#3A310E",
|
||||
"predictive": "#5D5945",
|
||||
"success.background": "#0C4619",
|
||||
"warning.background": "#3A310E",
|
||||
"warning.border": "#7B6508",
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#7FAEF9"
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#CC9E00"
|
||||
},
|
||||
"comment": {
|
||||
"color": "#9D9D9D"
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#9D9D9D"
|
||||
},
|
||||
"constant": {
|
||||
"color": "#CC9E00"
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#CBA6F7"
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#CACCCA"
|
||||
},
|
||||
"emphasis": {
|
||||
"font_style": "italic"
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"font_weight": 700
|
||||
},
|
||||
"function": {
|
||||
"color": "#B3C5F3"
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#87B1F6"
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#419CFF",
|
||||
"font_style": "normal"
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#7faef9",
|
||||
"font_style": "italic"
|
||||
},
|
||||
"number": {
|
||||
"color": "#CC9E00"
|
||||
},
|
||||
"string": {
|
||||
"color": "#A3E09F"
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#68DC7C"
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#68DC7C"
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#A3E09F"
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#A3E09F"
|
||||
},
|
||||
"tag": {
|
||||
"color": "#419CFF"
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#A3E09F"
|
||||
},
|
||||
"text.code.span": {
|
||||
"color": "#A3E09F"
|
||||
},
|
||||
"title": {
|
||||
"color": "#CC9E00",
|
||||
"font_weight": 600
|
||||
},
|
||||
"type": {
|
||||
"color": "#CBA6F7"
|
||||
},
|
||||
"property": {
|
||||
"color": "#BCC4E0"
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#419CFF"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+11
-29
@@ -1,12 +1,10 @@
|
||||
use anyhow::Context;
|
||||
use gpui::{AssetSource, Result, SharedString};
|
||||
use gpui_component::IconNamed;
|
||||
use gpui_native_kit::icons::IconNamed;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "assets"]
|
||||
#[include = "icons/**/*.svg"]
|
||||
#[include = "themes/**/*.json"]
|
||||
#[include = "backgrounds/**/*.jpg"]
|
||||
#[include = "backgrounds/**/*.png"]
|
||||
#[exclude = "*.DS_Store"]
|
||||
@@ -14,35 +12,19 @@ pub struct Assets;
|
||||
|
||||
impl AssetSource for Assets {
|
||||
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
||||
Self::get(path)
|
||||
.map(|f| Some(f.data))
|
||||
.with_context(|| format!("loading asset at path {path:?}"))
|
||||
if let Some(file) = Self::get(path) {
|
||||
return Ok(Some(file.data));
|
||||
}
|
||||
gpui_native_kit::icons::IconAssets.load(path)
|
||||
}
|
||||
|
||||
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
||||
Ok(Self::iter()
|
||||
.filter_map(|p| {
|
||||
if p.starts_with(path) {
|
||||
Some(p.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl Assets {
|
||||
pub fn themes(&self) -> Vec<(String, String)> {
|
||||
Self::iter()
|
||||
.filter(|path| path.starts_with("themes/"))
|
||||
.filter_map(|path| {
|
||||
let data = Self::get(path.as_ref())?;
|
||||
let name = path.strip_prefix("themes/").unwrap_or(path.as_ref());
|
||||
let content = std::str::from_utf8(data.data.as_ref()).ok()?.to_owned();
|
||||
Some((name.to_owned(), content))
|
||||
})
|
||||
.collect()
|
||||
let mut paths: Vec<SharedString> = Self::iter()
|
||||
.filter(|p| p.starts_with(path))
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
paths.extend(gpui_native_kit::icons::IconAssets.list(path)?);
|
||||
Ok(paths)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,3 @@ serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
anyhow.workspace = true
|
||||
log.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
gpui = { workspace = true, features = ["test-support"] }
|
||||
|
||||
@@ -28,58 +28,6 @@ pub enum EventFetchingStrategy {
|
||||
Uncensored,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct ThemeSettings {
|
||||
/// Name of the light theme in the theme registry.
|
||||
pub light_theme: String,
|
||||
/// Name of the dark theme in the theme registry.
|
||||
pub dark_theme: String,
|
||||
/// The base font size in pixels.
|
||||
pub font_size: f32,
|
||||
/// The monospace font size in pixels.
|
||||
pub mono_font_size: f32,
|
||||
/// Corner radius for general elements in pixels.
|
||||
pub radius: f32,
|
||||
/// Corner radius for large elements, dialogs and notifications, in pixels.
|
||||
pub radius_lg: f32,
|
||||
/// Whether focused controls draw a ring outside their border.
|
||||
pub focus_ring: bool,
|
||||
/// Whether to apply a shadow to elements.
|
||||
pub shadow: bool,
|
||||
}
|
||||
|
||||
impl Default for ThemeSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
light_theme: "Signed Light".into(),
|
||||
dark_theme: "Signed Dark".into(),
|
||||
font_size: 16.0,
|
||||
mono_font_size: 13.0,
|
||||
radius: 4.0,
|
||||
radius_lg: 8.0,
|
||||
focus_ring: false,
|
||||
shadow: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tab bar chrome.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct TabBarSettings {
|
||||
/// Hide the previous and next tab buttons.
|
||||
pub hide_navigation_buttons: bool,
|
||||
}
|
||||
|
||||
impl Default for TabBarSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
hide_navigation_buttons: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct GraspServersSettings {
|
||||
@@ -151,8 +99,6 @@ pub struct CreateRepositorySettings {
|
||||
pub struct Settings {
|
||||
pub appearance: AppearanceMode,
|
||||
pub event_fetching: EventFetchingStrategy,
|
||||
pub theme: ThemeSettings,
|
||||
pub tab_bar: TabBarSettings,
|
||||
pub grasp_servers: GraspServersSettings,
|
||||
pub local_repos: LocalReposSettings,
|
||||
pub checkouts: CheckoutsSettings,
|
||||
@@ -168,10 +114,6 @@ mod tests {
|
||||
let settings = Settings {
|
||||
appearance: AppearanceMode::Dark,
|
||||
event_fetching: EventFetchingStrategy::Curated,
|
||||
theme: ThemeSettings {
|
||||
radius: 8.0,
|
||||
..Default::default()
|
||||
},
|
||||
create_repository: CreateRepositorySettings {
|
||||
default_folder: Some(PathBuf::from("/tmp/repos")),
|
||||
},
|
||||
@@ -185,18 +127,34 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn partial_json_merges_with_defaults() {
|
||||
let settings: Settings =
|
||||
serde_json::from_str(r#"{"appearance": "dark", "theme": {"radius": 4.0}}"#).unwrap();
|
||||
let settings: Settings = serde_json::from_str(
|
||||
r#"{"appearance": "dark", "grasp_servers": {"default_servers": []}}"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(settings.appearance, AppearanceMode::Dark);
|
||||
assert_eq!(settings.theme.radius, 4.0);
|
||||
assert_eq!(settings.grasp_servers.default_servers, Vec::<String>::new());
|
||||
// Unset fields fall back to their defaults, including the fetching strategy.
|
||||
assert_eq!(settings.event_fetching, EventFetchingStrategy::Uncensored);
|
||||
// The rest of the theme and the other groups keep their defaults.
|
||||
assert_eq!(settings.theme.light_theme, "Signed Light");
|
||||
assert_eq!(settings.grasp_servers, GraspServersSettings::default());
|
||||
assert_eq!(settings.local_repos, LocalReposSettings::default());
|
||||
assert_eq!(settings.create_repository.default_folder, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn legacy_theme_keys_are_ignored() {
|
||||
let settings: Settings = serde_json::from_str(
|
||||
r#"{"appearance": "light", "theme": {"radius": 8.0}, "tab_bar": {"hide_navigation_buttons": false}}"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(settings.appearance, AppearanceMode::Light);
|
||||
assert_eq!(
|
||||
settings,
|
||||
Settings {
|
||||
appearance: AppearanceMode::Light,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn event_fetching_uses_snake_case() {
|
||||
let json = serde_json::to_string(&EventFetchingStrategy::Curated).unwrap();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
[package]
|
||||
name = "signed_app"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
assets = { path = "../assets" }
|
||||
metadata = { path = "../metadata" }
|
||||
paths = { path = "../paths" }
|
||||
settings = { path = "../settings" }
|
||||
signed_core = { path = "../signed_core" }
|
||||
signed_git = { path = "../signed_git" }
|
||||
signed_nostr = { path = "../signed_nostr" }
|
||||
signed_state = { path = "../signed_state" }
|
||||
utils = { path = "../utils" }
|
||||
|
||||
gpui.workspace = true
|
||||
gpui-native-kit.workspace = true
|
||||
anyhow.workspace = true
|
||||
futures.workspace = true
|
||||
log.workspace = true
|
||||
@@ -0,0 +1,55 @@
|
||||
use gpui::{
|
||||
App, AppContext as _, Context, Entity, IntoElement, ParentElement as _, Render, Styled as _,
|
||||
Window, div,
|
||||
};
|
||||
use gpui_native_kit::empty_state::EmptyState;
|
||||
use gpui_native_kit::layout::dock::DockState;
|
||||
use gpui_native_kit::layout::shell::{LayoutState, Shell};
|
||||
use gpui_native_kit::theme::{ActiveTheme as _, ThemeVariant, follow_system, set_mode_override};
|
||||
use settings::{AppearanceMode, Settings};
|
||||
|
||||
use crate::dialogs::DialogHost;
|
||||
|
||||
pub struct AppRoot {
|
||||
layout: Entity<LayoutState>,
|
||||
dock: Entity<DockState>,
|
||||
dialogs: Entity<DialogHost>,
|
||||
}
|
||||
|
||||
impl AppRoot {
|
||||
pub fn new(_window: &mut Window, cx: &mut App) -> Self {
|
||||
let layout = LayoutState::new(cx);
|
||||
let dock = DockState::new(cx);
|
||||
let dialogs = cx.new(DialogHost::new);
|
||||
DialogHost::set_global(dialogs.clone(), cx);
|
||||
|
||||
Self {
|
||||
layout,
|
||||
dock,
|
||||
dialogs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for AppRoot {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let theme = cx.theme();
|
||||
div()
|
||||
.size_full()
|
||||
.font_family(".SystemUIFont")
|
||||
.text_color(theme.colors.foreground)
|
||||
.child(
|
||||
Shell::new("signed-shell", self.layout.clone())
|
||||
.center(EmptyState::new("Signed").hint("UI migration in progress")),
|
||||
)
|
||||
.child(self.dialogs.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_appearance(settings: &Settings, cx: &mut App) {
|
||||
match settings.appearance {
|
||||
AppearanceMode::System => follow_system(cx),
|
||||
AppearanceMode::Light => set_mode_override(Some(ThemeVariant::Light), cx),
|
||||
AppearanceMode::Dark => set_mode_override(Some(ThemeVariant::Dark), cx),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
use gpui::prelude::FluentBuilder as _;
|
||||
use gpui::{
|
||||
AnyView, App, Context, Entity, Global, IntoElement, ParentElement as _, Render, Styled as _,
|
||||
Window, div,
|
||||
};
|
||||
|
||||
struct GlobalDialogHost(Entity<DialogHost>);
|
||||
|
||||
impl Global for GlobalDialogHost {}
|
||||
|
||||
/// Owns the modal currently mounted at the window root.
|
||||
pub struct DialogHost {
|
||||
open: Option<AnyView>,
|
||||
}
|
||||
|
||||
impl DialogHost {
|
||||
pub fn new(_cx: &mut Context<Self>) -> Self {
|
||||
Self { open: None }
|
||||
}
|
||||
|
||||
pub fn set_global(entity: Entity<Self>, cx: &mut App) {
|
||||
cx.set_global(GlobalDialogHost(entity));
|
||||
}
|
||||
|
||||
pub fn global(cx: &App) -> Entity<Self> {
|
||||
cx.global::<GlobalDialogHost>().0.clone()
|
||||
}
|
||||
|
||||
pub fn open(&mut self, view: AnyView, cx: &mut Context<Self>) {
|
||||
self.open = Some(view);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn close(&mut self, cx: &mut Context<Self>) {
|
||||
self.open = None;
|
||||
cx.notify();
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for DialogHost {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.absolute()
|
||||
.inset_0()
|
||||
.when_some(self.open.clone(), |host, view| host.child(view))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
mod app;
|
||||
mod dialogs;
|
||||
mod panels;
|
||||
mod views;
|
||||
|
||||
pub use app::{AppRoot, apply_appearance};
|
||||
|
||||
use gpui::{App, AppContext as _, Entity, Window};
|
||||
|
||||
pub fn root(window: &mut Window, cx: &mut App) -> Entity<AppRoot> {
|
||||
cx.new(|cx| AppRoot::new(window, cx))
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user