commit 95c96717c1f100115a5e70bf7bcc729d60042df1
parent 97acb226f9ecf55b8fa17854fc746660817a2cef
Author: triesap <tyson@radroots.org>
Date: Fri, 17 Apr 2026 16:40:55 +0000
app: restructure gpui workspace skeleton
- replace the root package with a small app-local cargo workspace
- add shared core ui and i18n crates beneath the desktop launcher
- keep the radroots_app launcher identity and placeholder shell bootable
- preserve the repo check and run flow against the new crate layout
Diffstat:
15 files changed, 196 insertions(+), 76 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3979,6 +3979,24 @@ name = "radroots_app"
version = "0.1.0"
dependencies = [
"gpui",
+ "radroots_app_core",
+ "radroots_app_ui",
+]
+
+[[package]]
+name = "radroots_app_core"
+version = "0.1.0"
+
+[[package]]
+name = "radroots_app_i18n"
+version = "0.1.0"
+
+[[package]]
+name = "radroots_app_ui"
+version = "0.1.0"
+dependencies = [
+ "gpui",
+ "radroots_app_i18n",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
@@ -1,5 +1,13 @@
-[package]
-name = "radroots_app"
+[workspace]
+members = [
+ "crates/shared/core",
+ "crates/shared/i18n",
+ "crates/shared/ui",
+ "crates/launchers/desktop",
+]
+resolver = "2"
+
+[workspace.package]
version = "0.1.0"
edition = "2024"
authors = ["Radroots Authors"]
@@ -8,12 +16,12 @@ license = "GPL-3.0"
repository = "https://github.com/radrootslabs/app"
homepage = "https://radroots.org"
readme = "README.md"
-publish = false
-
-[workspace]
-[dependencies]
+[workspace.dependencies]
gpui = "0.2.2"
+radroots_app_core = { path = "crates/shared/core", version = "0.1.0" }
+radroots_app_i18n = { path = "crates/shared/i18n", version = "0.1.0" }
+radroots_app_ui = { path = "crates/shared/ui", version = "0.1.0" }
-[lints.rust]
+[workspace.lints.rust]
unsafe_code = "forbid"
diff --git a/crates/launchers/desktop/Cargo.toml b/crates/launchers/desktop/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "radroots_app"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+rust-version.workspace = true
+license.workspace = true
+publish = false
+
+[dependencies]
+gpui.workspace = true
+radroots_app_core.workspace = true
+radroots_app_ui.workspace = true
+
+[lints]
+workspace = true
diff --git a/crates/launchers/desktop/src/app.rs b/crates/launchers/desktop/src/app.rs
@@ -0,0 +1,44 @@
+use gpui::{AppContext, Application, WindowOptions, px, size};
+use radroots_app_core::{APP_ID, HOME_WINDOW_METRICS};
+use radroots_app_ui::{HOME_WINDOW_MIN_HEIGHT_PX, HOME_WINDOW_MIN_WIDTH_PX, PlaceholderView};
+
+fn titlebar_options() -> gpui::TitlebarOptions {
+ gpui::TitlebarOptions {
+ title: None,
+ appears_transparent: true,
+ ..Default::default()
+ }
+}
+
+pub fn launch() {
+ let app = Application::new();
+
+ app.run(|cx| {
+ cx.on_window_closed(|cx| {
+ if cx.windows().is_empty() {
+ cx.quit();
+ }
+ })
+ .detach();
+
+ cx.spawn(async move |cx| {
+ cx.open_window(
+ WindowOptions {
+ app_id: Some(APP_ID.to_owned()),
+ window_min_size: Some(size(
+ px(HOME_WINDOW_METRICS.min_width_px.max(HOME_WINDOW_MIN_WIDTH_PX)),
+ px(HOME_WINDOW_METRICS.min_height_px.max(HOME_WINDOW_MIN_HEIGHT_PX)),
+ )),
+ titlebar: Some(titlebar_options()),
+ ..Default::default()
+ },
+ |_, cx| cx.new(|_| PlaceholderView),
+ )
+ .expect("main radroots app window should open");
+
+ cx.update(|cx| cx.activate(true))
+ .expect("radroots app activation should succeed");
+ })
+ .detach();
+ });
+}
diff --git a/crates/launchers/desktop/src/lib.rs b/crates/launchers/desktop/src/lib.rs
@@ -0,0 +1,7 @@
+#![forbid(unsafe_code)]
+
+mod app;
+
+pub fn run() {
+ app::launch();
+}
diff --git a/src/main.rs b/crates/launchers/desktop/src/main.rs
diff --git a/crates/shared/core/Cargo.toml b/crates/shared/core/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "radroots_app_core"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+rust-version.workspace = true
+license.workspace = true
+publish = false
+
+[lints]
+workspace = true
diff --git a/crates/shared/core/src/lib.rs b/crates/shared/core/src/lib.rs
@@ -0,0 +1,15 @@
+#![forbid(unsafe_code)]
+
+pub const APP_ID: &str = "org.radroots.app";
+pub const APP_NAME: &str = "radroots";
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct AppWindowMetrics {
+ pub min_width_px: f32,
+ pub min_height_px: f32,
+}
+
+pub const HOME_WINDOW_METRICS: AppWindowMetrics = AppWindowMetrics {
+ min_width_px: 640.0,
+ min_height_px: 480.0,
+};
diff --git a/crates/shared/i18n/Cargo.toml b/crates/shared/i18n/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "radroots_app_i18n"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+rust-version.workspace = true
+license.workspace = true
+publish = false
+
+[lints]
+workspace = true
diff --git a/crates/shared/i18n/src/lib.rs b/crates/shared/i18n/src/lib.rs
@@ -0,0 +1,12 @@
+#![forbid(unsafe_code)]
+
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum AppTextKey {
+ Brand,
+}
+
+pub fn app_text(key: AppTextKey) -> &'static str {
+ match key {
+ AppTextKey::Brand => "radroots",
+ }
+}
diff --git a/crates/shared/ui/Cargo.toml b/crates/shared/ui/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "radroots_app_ui"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+rust-version.workspace = true
+license.workspace = true
+publish = false
+
+[dependencies]
+gpui.workspace = true
+radroots_app_i18n.workspace = true
+
+[lints]
+workspace = true
diff --git a/crates/shared/ui/src/lib.rs b/crates/shared/ui/src/lib.rs
@@ -0,0 +1,32 @@
+#![forbid(unsafe_code)]
+
+use gpui::{
+ Context, FontWeight, IntoElement, ParentElement, Render, Styled, Window, div, px, rgb,
+};
+use radroots_app_i18n::{AppTextKey, app_text};
+
+pub const HOME_WINDOW_MIN_WIDTH_PX: f32 = 640.0;
+pub const HOME_WINDOW_MIN_HEIGHT_PX: f32 = 480.0;
+pub const WINDOW_BACKGROUND: u32 = 0xF5F1E8;
+pub const TEXT_PRIMARY: u32 = 0x1F2C23;
+pub const BRAND_TEXT_SIZE_PX: f32 = 20.0;
+
+pub struct PlaceholderView;
+
+impl Render for PlaceholderView {
+ fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
+ div()
+ .size_full()
+ .flex()
+ .items_center()
+ .justify_center()
+ .bg(rgb(WINDOW_BACKGROUND))
+ .child(
+ div()
+ .text_size(px(BRAND_TEXT_SIZE_PX))
+ .font_weight(FontWeight::SEMIBOLD)
+ .text_color(rgb(TEXT_PRIMARY))
+ .child(app_text(AppTextKey::Brand)),
+ )
+ }
+}
diff --git a/src/app.rs b/src/app.rs
@@ -1,40 +0,0 @@
-use gpui::{AppContext, Application, WindowOptions, px, size};
-
-fn titlebar_options() -> gpui::TitlebarOptions {
- gpui::TitlebarOptions {
- title: None,
- appears_transparent: true,
- ..Default::default()
- }
-}
-
-pub fn launch() {
- let app = Application::new();
-
- app.run(|cx| {
- cx.on_window_closed(|cx| {
- if cx.windows().is_empty() {
- cx.quit();
- }
- })
- .detach();
-
- cx.spawn(async move |cx| {
- cx.open_window(
- WindowOptions {
- app_id: Some("org.radroots.app".to_owned()),
- window_min_size: Some(size(px(640.0), px(480.0))),
- titlebar: Some(titlebar_options()),
- ..Default::default()
- },
- |_, cx| cx.new(|_| crate::window::PlaceholderView),
- )
- .expect("main radroots app window should open");
-
- cx.update(|cx| cx.activate(true))
- .expect("radroots app activation should succeed");
- })
- .detach();
- });
-
-}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,8 +0,0 @@
-#![forbid(unsafe_code)]
-
-mod app;
-mod window;
-
-pub fn run() {
- app::launch();
-}
diff --git a/src/window.rs b/src/window.rs
@@ -1,21 +0,0 @@
-use gpui::{Context, FontWeight, IntoElement, ParentElement, Render, Styled, Window, div, px, rgb};
-
-pub struct PlaceholderView;
-
-impl Render for PlaceholderView {
- fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
- div()
- .size_full()
- .flex()
- .items_center()
- .justify_center()
- .bg(rgb(0xF5F1E8))
- .child(
- div()
- .text_size(px(20.0))
- .font_weight(FontWeight::SEMIBOLD)
- .text_color(rgb(0x1F2C23))
- .child("radroots"),
- )
- }
-}