app

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

commit cc28645497dfb43210e3b61949048cb60bb90002
parent ab48eff6133f61f91240b08369bf4fbe98bde977
Author: triesap <tyson@radroots.org>
Date:   Sun,  7 Jun 2026 11:50:01 -0700

app: add settings about product section

Diffstat:
Mcrates/desktop/src/source_guards.rs | 15+++++++++++++++
Mcrates/desktop/src/window.rs | 115++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mcrates/i18n/src/keys.rs | 9+++++++++
Mcrates/i18n/src/lib.rs | 33+++++++++++++++++++++++++++++++++
Mi18n/locales/en/messages.json | 9+++++++++
5 files changed, 178 insertions(+), 3 deletions(-)

diff --git a/crates/desktop/src/source_guards.rs b/crates/desktop/src/source_guards.rs @@ -21,6 +21,7 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "2 bags", "2222222222222222222222222222222222222222222222222222222222222222", "3333333333333333333333333333333333333333333333333333333333333333", + "../../../platforms/macos/App/Resources/AppIconSource.png", "2026-04-23T15:00:00Z", "6", "6.", @@ -84,6 +85,7 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "bunker://466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27?relay=wss%3A%2F%2Frelay.radroots.example", "buyer.fulfillment_filter_update_failed", "buyer.search_query_update_failed", + "CARGO_PKG_VERSION", "clock", "customer_labels.txt", "desktop runtime paths should resolve", @@ -312,9 +314,13 @@ const ALLOWED_WINDOW_LITERALS: &[&str] = &[ "settings-nav-farm", "settings-nav-settings", "settings-panel-scroll", + "settings-about-acknowledgements", "settings-about-conflict-action", + "settings-about-privacy-policy", "settings-about-refresh-sync", "settings-about-refresh-sync-disabled", + "settings-about-report-issue", + "settings-about-terms", "settings-account-row", "settings-remove-blackout-period", "settings-remove-fulfillment-window", @@ -768,6 +774,15 @@ const REQUIRED_WINDOW_COPY_KEYS: &[&str] = &[ "AppTextKey::SettingsReadinessFieldBlackoutPeriodEndsBeforeStart", "AppTextKey::SettingsReadinessFieldBlackoutOverlapsFulfillmentWindow", "AppTextKey::SettingsReadinessReady", + "AppTextKey::SettingsAboutCompanyName", + "AppTextKey::SettingsAboutVersionLabel", + "AppTextKey::SettingsAboutVariantLabel", + "AppTextKey::SettingsAboutAcknowledgementsAction", + "AppTextKey::SettingsAboutPrivacyPolicyAction", + "AppTextKey::SettingsAboutTermsAction", + "AppTextKey::SettingsAboutReportIssueAction", + "AppTextKey::SettingsAboutCopyrightNotice", + "AppTextKey::SettingsAboutTrademarkNotice", "AppTextKey::SettingsAboutStatusSectionLabel", "AppTextKey::SettingsAboutConflictReviewSectionLabel", "AppTextKey::SettingsAboutRuntimeSectionLabel", diff --git a/crates/desktop/src/window.rs b/crates/desktop/src/window.rs @@ -1,8 +1,8 @@ use gpui::{ Animation, AnimationExt, AnyElement, App, AppContext, Bounds, ClickEvent, Context, ElementId, - Entity, InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, - Subscription, Timer, Window, WindowBounds, WindowOptions, div, prelude::FluentBuilder, px, - relative, rgb, size, + Entity, Image, ImageFormat, InteractiveElement, IntoElement, ObjectFit, ParentElement, Render, + SharedString, Styled, StyledImage, Subscription, Timer, Window, WindowBounds, WindowOptions, + div, img, prelude::FluentBuilder, px, relative, rgb, size, }; use gpui_component::{IconName, Root, input::InputEvent, input::InputState, menu::PopupMenuItem}; use radroots_app_i18n::{AppTextKey, app_text}; @@ -7486,6 +7486,7 @@ impl SettingsWindowView { app_stack_v(APP_UI_THEME.shells.settings_account_main_stack_gap_px) .size_full() .py_12() + .child(settings_about_product_section(cx)) .child(app_surface_card( app_stack_v(APP_UI_THEME.shells.home_stack_gap_px) .w_full() @@ -7613,6 +7614,114 @@ fn settings_account_more_actions_button(cx: &App) -> impl IntoElement { ) } +fn settings_about_product_section(cx: &mut Context<SettingsWindowView>) -> impl IntoElement { + let app_icon = Arc::new(Image::from_bytes( + ImageFormat::Png, + include_bytes!("../../../platforms/macos/App/Resources/AppIconSource.png").to_vec(), + )); + let version = format!( + "{} {}", + app_text(AppTextKey::SettingsAboutVersionLabel), + env!("CARGO_PKG_VERSION") + ); + + div() + .w_full() + .flex() + .flex_col() + .items_center() + .gap(px(APP_UI_THEME.shells.home_stack_gap_px)) + .child( + div() + .w_full() + .flex() + .items_start() + .justify_center() + .gap(px(APP_UI_THEME.shells.settings_account_main_padding_px)) + .child( + img(app_icon) + .w(px(128.0)) + .h(px(128.0)) + .object_fit(ObjectFit::Contain) + .flex_shrink_0(), + ) + .child( + app_stack_v(APP_UI_THEME.foundation.spacing.small_px) + .min_w_0() + .child( + div() + .text_size( + px(APP_UI_THEME.foundation.typography.body_text_px * 1.7), + ) + .font_weight(gpui::FontWeight::SEMIBOLD) + .text_color(rgb(APP_UI_THEME.foundation.text.primary)) + .child(app_shared_text(AppTextKey::AppName)), + ) + .child( + div() + .text_size(px(APP_UI_THEME.foundation.typography.body_text_px)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) + .child(version), + ) + .child( + div() + .text_size(px(APP_UI_THEME.foundation.typography.body_text_px)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) + .child(app_shared_text(AppTextKey::SettingsAboutVariantLabel)), + ) + .child( + div() + .text_size(px(APP_UI_THEME.foundation.typography.body_text_px)) + .font_weight(gpui::FontWeight::MEDIUM) + .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) + .child(app_shared_text(AppTextKey::SettingsAboutCompanyName)), + ) + .child(text_button( + "settings-about-acknowledgements", + app_shared_text(AppTextKey::SettingsAboutAcknowledgementsAction), + cx.listener(|_, _, _, _| {}), + cx, + )) + .child(text_button( + "settings-about-privacy-policy", + app_shared_text(AppTextKey::SettingsAboutPrivacyPolicyAction), + cx.listener(|_, _, _, _| {}), + cx, + )) + .child(text_button( + "settings-about-terms", + app_shared_text(AppTextKey::SettingsAboutTermsAction), + cx.listener(|_, _, _, _| {}), + cx, + )) + .child(action_button( + "settings-about-report-issue", + app_shared_text(AppTextKey::SettingsAboutReportIssueAction), + cx.listener(|_, _, _, _| {}), + cx, + )), + ), + ) + .child( + app_stack_v(APP_UI_THEME.foundation.spacing.small_px) + .items_center() + .child( + div() + .text_size(px(APP_UI_THEME.foundation.typography.body_text_px)) + .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) + .child(app_shared_text(AppTextKey::SettingsAboutCopyrightNotice)), + ) + .child( + div() + .text_size(px(APP_UI_THEME.foundation.typography.body_text_px)) + .text_color(rgb(APP_UI_THEME.foundation.text.secondary)) + .child(app_shared_text(AppTextKey::SettingsAboutTrademarkNotice)), + ), + ) +} + fn settings_account_detail_account( projection: &SettingsAccountProjection, ) -> Option<&AccountSummary> { diff --git a/crates/i18n/src/keys.rs b/crates/i18n/src/keys.rs @@ -560,6 +560,15 @@ define_app_text_keys! { SettingsGeneralLaunchAtLogin => "settings.general.launch_at_login", SettingsGeneralManageAction => "settings.general.action.manage", SettingsGeneralUseNip05Note => "settings.general.use_nip05.note", + SettingsAboutCompanyName => "settings.about.company.name", + SettingsAboutVersionLabel => "settings.about.version.label", + SettingsAboutVariantLabel => "settings.about.variant.label", + SettingsAboutAcknowledgementsAction => "settings.about.action.acknowledgements", + SettingsAboutPrivacyPolicyAction => "settings.about.action.privacy_policy", + SettingsAboutTermsAction => "settings.about.action.terms", + SettingsAboutReportIssueAction => "settings.about.action.report_issue", + SettingsAboutCopyrightNotice => "settings.about.copyright.notice", + SettingsAboutTrademarkNotice => "settings.about.trademark.notice", SettingsAboutStatusSectionLabel => "settings.about.status.section.label", SettingsAboutConflictReviewSectionLabel => "settings.about.conflict_review.section.label", SettingsAboutRuntimeSectionLabel => "settings.about.runtime.section.label", diff --git a/crates/i18n/src/lib.rs b/crates/i18n/src/lib.rs @@ -256,6 +256,39 @@ mod tests { #[test] fn english_about_copy_matches_the_runtime_status_contract() { assert_eq!( + app_text(AppTextKey::SettingsAboutCompanyName), + "Radroots, Inc." + ); + assert_eq!(app_text(AppTextKey::SettingsAboutVersionLabel), "Version"); + assert_eq!( + app_text(AppTextKey::SettingsAboutVariantLabel), + "Standalone local app" + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutAcknowledgementsAction), + "Acknowledgements" + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutPrivacyPolicyAction), + "Privacy Policy" + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutTermsAction), + "Terms of Service" + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutReportIssueAction), + "Report an Issue..." + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutCopyrightNotice), + "© 2026 Radroots, Inc. All rights reserved." + ); + assert_eq!( + app_text(AppTextKey::SettingsAboutTrademarkNotice), + "Radroots is a trademark of Radroots, Inc." + ); + assert_eq!( app_text(AppTextKey::SettingsAboutStatusSectionLabel), "Status" ); diff --git a/i18n/locales/en/messages.json b/i18n/locales/en/messages.json @@ -539,6 +539,15 @@ "settings.general.launch_at_login": "Launch Radroots at login", "settings.general.action.manage": "Manage", "settings.general.use_nip05.note": "Helps customers verify this farm profile through Radroots.", + "settings.about.company.name": "Radroots, Inc.", + "settings.about.version.label": "Version", + "settings.about.variant.label": "Standalone local app", + "settings.about.action.acknowledgements": "Acknowledgements", + "settings.about.action.privacy_policy": "Privacy Policy", + "settings.about.action.terms": "Terms of Service", + "settings.about.action.report_issue": "Report an Issue...", + "settings.about.copyright.notice": "© 2026 Radroots, Inc. All rights reserved.", + "settings.about.trademark.notice": "Radroots is a trademark of Radroots, Inc.", "settings.about.status.section.label": "Status", "settings.about.conflict_review.section.label": "Conflict review", "settings.about.runtime.section.label": "Runtime",