app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 471e21ca5e1480697ca18b1c77078ca73a705051
parent d6ce9b4323d1ee7d80064c457000ea2aa722fbaf
Author: triesap <tyson@radroots.org>
Date:   Tue,  9 Jun 2026 11:51:48 -0700

ui: update blossom settings status

Diffstat:
Mcrates/desktop/src/source_guards.rs | 9+++++++++
Mcrates/desktop/src/window.rs | 64+++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mcrates/i18n/src/keys.rs | 4++++
Mcrates/ui/src/primitives.rs | 1+
Mi18n/locales/en/messages.json | 4++++
5 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/crates/desktop/src/source_guards.rs b/crates/desktop/src/source_guards.rs @@ -16,6 +16,7 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "-", "0", "1111111111111111111111111111111111111111111111111111111111111111", + "127.0.0.1", "14", "14.5", "2 bags", @@ -32,6 +33,7 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "Farm Profile", "Salad mix", "USD", + "[::1]", "/tmp/radroots/data/apps/app", "/tmp/radroots/logs/apps/app", "{}.{:02}", @@ -200,11 +202,14 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "home-today-open-products-low-stock", "home-products-scroll", "home-today-scroll", + "http://", "http://localhost:8082", + "https://", "today-reminder-chip", "https://auth.example/challenge", "identity", "items need review", + "localhost", "npub1", "npub1qqqqq...qqqqqq", "npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", @@ -567,7 +572,11 @@ const REQUIRED_WINDOW_COPY_KEYS: &[&str] = &[ "AppTextKey::AccountSettingsBlossomProfileFarmMediaLabel", "AppTextKey::AccountSettingsResetBlossomServerAction", "AppTextKey::AccountSettingsBlossomConnectionHealthy", + "AppTextKey::AccountSettingsBlossomConnectionLocal", + "AppTextKey::AccountSettingsBlossomConnectionInvalid", "AppTextKey::AccountSettingsBlossomUploadsAvailable", + "AppTextKey::AccountSettingsBlossomUploadsPending", + "AppTextKey::AccountSettingsBlossomUploadsUnavailable", "AppTextKey::HomeSetupBackAction", "AppTextKey::HomeSetupBrowseMarketplaceAction", "AppTextKey::HomeSetupConnectSignerAction", diff --git a/crates/desktop/src/window.rs b/crates/desktop/src/window.rs @@ -11209,11 +11209,17 @@ fn account_settings_blossom_server_card( |_, _, _| {}, cx, ))) - .child(account_settings_blossom_health_card()), + .child(account_settings_blossom_health_card(form, cx)), ) } -fn account_settings_blossom_health_card() -> impl IntoElement { +fn account_settings_blossom_health_card( + form: &AccountSettingsFormState, + cx: &mut Context<HomeView>, +) -> impl IntoElement { + let status = + account_settings_blossom_status(form.blossom_server_input.read(cx).value().as_ref()); + div() .w_full() .border_1() @@ -11229,9 +11235,7 @@ fn account_settings_blossom_health_card() -> impl IntoElement { .flex() .items_center() .gap(px(APP_UI_THEME.foundation.spacing.medium_px)) - .child(status_indicator( - APP_UI_THEME.components.app_status_indicator.online, - )) + .child(status_indicator(status.indicator_color)) .child( app_stack_v(APP_UI_THEME.foundation.spacing.micro_px) .min_w_0() @@ -11243,9 +11247,7 @@ fn account_settings_blossom_health_card() -> impl IntoElement { .settings_row_text_px)) .font_weight(gpui::FontWeight::MEDIUM) .text_color(rgb(APP_UI_THEME.foundation.text.primary)) - .child(app_shared_text( - AppTextKey::AccountSettingsBlossomConnectionHealthy, - )), + .child(app_shared_text(status.title_key)), ) .child( div() @@ -11254,19 +11256,55 @@ fn account_settings_blossom_health_card() -> impl IntoElement { .typography .settings_row_text_px)) .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) - .child(app_shared_text( - AppTextKey::AccountSettingsBlossomUploadsAvailable, - )), + .child(app_shared_text(status.body_key)), ), ), ) .child( - Icon::new(IconName::CircleCheck) + Icon::new(status.icon_name) .with_size(gpui_component::Size::Size(px(18.0))) - .text_color(rgb(APP_UI_THEME.components.app_status_indicator.online)), + .text_color(rgb(status.indicator_color)), ) } +#[derive(Clone)] +struct AccountSettingsBlossomStatusPresentation { + indicator_color: u32, + icon_name: IconName, + title_key: AppTextKey, + body_key: AppTextKey, +} + +fn account_settings_blossom_status(server_url: &str) -> AccountSettingsBlossomStatusPresentation { + let trimmed = server_url.trim(); + let status = APP_UI_THEME.components.app_status_indicator; + + if trimmed.is_empty() || !(trimmed.starts_with("http://") || trimmed.starts_with("https://")) { + return AccountSettingsBlossomStatusPresentation { + indicator_color: status.attention, + icon_name: IconName::CircleX, + title_key: AppTextKey::AccountSettingsBlossomConnectionInvalid, + body_key: AppTextKey::AccountSettingsBlossomUploadsUnavailable, + }; + } + + if trimmed.contains("localhost") || trimmed.contains("127.0.0.1") || trimmed.contains("[::1]") { + return AccountSettingsBlossomStatusPresentation { + indicator_color: status.offline, + icon_name: IconName::TriangleAlert, + title_key: AppTextKey::AccountSettingsBlossomConnectionLocal, + body_key: AppTextKey::AccountSettingsBlossomUploadsPending, + }; + } + + AccountSettingsBlossomStatusPresentation { + indicator_color: status.online, + icon_name: IconName::CircleCheck, + title_key: AppTextKey::AccountSettingsBlossomConnectionHealthy, + body_key: AppTextKey::AccountSettingsBlossomUploadsAvailable, + } +} + fn account_settings_card(content: impl IntoElement) -> impl IntoElement { div() .w_full() diff --git a/crates/i18n/src/keys.rs b/crates/i18n/src/keys.rs @@ -217,7 +217,11 @@ define_app_text_keys! { AccountSettingsBlossomProfileFarmMediaLabel => "account.settings.blossom_profile_farm_media.label", AccountSettingsResetBlossomServerAction => "account.settings.reset_blossom_server.action", AccountSettingsBlossomConnectionHealthy => "account.settings.blossom_connection.healthy", + AccountSettingsBlossomConnectionLocal => "account.settings.blossom_connection.local", + AccountSettingsBlossomConnectionInvalid => "account.settings.blossom_connection.invalid", AccountSettingsBlossomUploadsAvailable => "account.settings.blossom_uploads.available", + AccountSettingsBlossomUploadsPending => "account.settings.blossom_uploads.pending", + AccountSettingsBlossomUploadsUnavailable => "account.settings.blossom_uploads.unavailable", HomeNavBrowse => "home.nav.browse", HomeNavSearch => "home.nav.search", HomeNavCart => "home.nav.cart", diff --git a/crates/ui/src/primitives.rs b/crates/ui/src/primitives.rs @@ -681,6 +681,7 @@ pub fn app_checkbox_field( ) .rounded(ButtonRounded::Size(px(0.0))) .w_full() + .p(px(0.0)) .on_click({ let on_change = Rc::clone(&on_change); move |_, window, cx| on_change(!checked, window, cx) diff --git a/i18n/locales/en/messages.json b/i18n/locales/en/messages.json @@ -196,7 +196,11 @@ "account.settings.blossom_profile_farm_media.label": "Use this server for profile and farm media", "account.settings.reset_blossom_server.action": "Reset default server", "account.settings.blossom_connection.healthy": "Connection status: Healthy", + "account.settings.blossom_connection.local": "Connection status: Local check needed", + "account.settings.blossom_connection.invalid": "Connection status: Needs setup", "account.settings.blossom_uploads.available": "Uploads available", + "account.settings.blossom_uploads.pending": "Uploads need a connection check", + "account.settings.blossom_uploads.unavailable": "Enter a valid HTTP(S) server URL", "home.nav.browse": "Browse", "home.nav.search": "Search", "home.nav.cart": "Cart",