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:
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",