commit 471e21ca5e1480697ca18b1c77078ca73a705051
parent d6ce9b4323d1ee7d80064c457000ea2aa722fbaf
Author: triesap <tyson@radroots.org>
Date: Tue, 9 Jun 2026 11:51:48 -0700
ui: update blossom settings status
Diffstat:
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",