app

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

commit 453c7a9ff4a4501b6a49d201d931898d9eb17894
parent 7524cfba1ee4fc18ce30379dd0f3b9bb25fbeb1b
Author: triesap <tyson@radroots.org>
Date:   Mon,  2 Feb 2026 16:19:44 +0000

app: localize settings and ui demo

- add settings message keys for appearance and actions
- localize ui demo list, input, and select labels
- translate ui demo sheet text and headings
- regenerate i18n build artifacts

Diffstat:
Mapp/i18n/build/i18n.catalog.json | 242+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mapp/i18n/build/id_map.json | 22++++++++++++++++++++++
Mapp/i18n/build/id_map_hash | 2+-
Mapp/i18n/build/manifest.json | 4++--
Mapp/i18n/build/packs/en.mf2pack | 0
Mapp/i18n/locales/en/messages.mf2 | 46++++++++++++++++++++++++++++++++++++++++++++++
Mapp/src/settings.rs | 30++++++++++++++++++++----------
Mapp/src/ui_demo.rs | 33+++++++++++++++++----------------
8 files changed, 350 insertions(+), 29 deletions(-)

diff --git a/app/i18n/build/i18n.catalog.json b/app/i18n/build/i18n.catalog.json @@ -1160,6 +1160,94 @@ } }, { + "key": "app.settings.actions.export_db", + "id": 4012031673, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.actions.logout", + "id": 1314061244, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.appearance.color_mode.label", + "id": 4036414159, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.appearance.color_mode.option.dark", + "id": 1500556587, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.appearance.color_mode.option.light", + "id": 2964032561, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.appearance.color_mode.option.system", + "id": 116103587, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.appearance.title", + "id": 410103833, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.settings.title", + "id": 2068161917, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { "key": "app.setup.eula.acceptance.body", "id": 2382792662, "args": [], @@ -1600,6 +1688,160 @@ } }, { + "key": "app.ui_demo.input.label", + "id": 184074538, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.input.placeholder", + "id": 2226709883, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.item.notifications", + "id": 428578162, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.list.title", + "id": 2975877094, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sheet.close", + "id": 3592615847, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sheet.description", + "id": 3475136064, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sheet.open", + "id": 3618188646, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sheet.title", + "id": 17449068, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.status.enabled", + "id": 2298608892, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sync.label", + "id": 1130669379, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sync.option.daily", + "id": 410854867, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sync.option.never", + "id": 635139478, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.sync.option.weekly", + "id": 2766276811, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { + "key": "app.ui_demo.title", + "id": 570973545, + "args": [], + "features": { + "select": false, + "plural_cardinal": false, + "plural_ordinal": false, + "formatters": [] + } + }, + { "key": "error.app.init.assets", "id": 172100683, "args": [], diff --git a/app/i18n/build/id_map.json b/app/i18n/build/id_map.json @@ -104,6 +104,14 @@ "app.nav.setup": 2066290074, "app.nav.ui": 2416341108, "app.not_found": 3182331848, + "app.settings.actions.export_db": 4012031673, + "app.settings.actions.logout": 1314061244, + "app.settings.appearance.color_mode.label": 4036414159, + "app.settings.appearance.color_mode.option.dark": 1500556587, + "app.settings.appearance.color_mode.option.light": 2964032561, + "app.settings.appearance.color_mode.option.system": 116103587, + "app.settings.appearance.title": 410103833, + "app.settings.title": 2068161917, "app.setup.eula.acceptance.body": 2382792662, "app.setup.eula.acceptance.title": 3507789532, "app.setup.eula.changes.body": 951360382, @@ -144,6 +152,20 @@ "app.setup.profile.nip05.suffix": 853057844, "app.setup.profile.placeholder": 321152177, "app.setup.profile.title": 103377718, + "app.ui_demo.input.label": 184074538, + "app.ui_demo.input.placeholder": 2226709883, + "app.ui_demo.item.notifications": 428578162, + "app.ui_demo.list.title": 2975877094, + "app.ui_demo.sheet.close": 3592615847, + "app.ui_demo.sheet.description": 3475136064, + "app.ui_demo.sheet.open": 3618188646, + "app.ui_demo.sheet.title": 17449068, + "app.ui_demo.status.enabled": 2298608892, + "app.ui_demo.sync.label": 1130669379, + "app.ui_demo.sync.option.daily": 410854867, + "app.ui_demo.sync.option.never": 635139478, + "app.ui_demo.sync.option.weekly": 2766276811, + "app.ui_demo.title": 570973545, "error.app.init.assets": 172100683, "error.app.init.config": 3737196850, "error.app.init.datastore": 1124445179, diff --git a/app/i18n/build/id_map_hash b/app/i18n/build/id_map_hash @@ -1 +1 @@ -sha256:1402a9727c23f2b6b70fd54bcb04138b40bfe0f8a9b464bcce626d9f0b48517d +sha256:8fcc5219c69f901ff56bf3890c0127b9a7a3e324f1c4475efed91fd28a54bf64 diff --git a/app/i18n/build/manifest.json b/app/i18n/build/manifest.json @@ -1 +1 @@ -{"schema":1,"release_id":"dev","generated_at":"2026-02-02T00:00:00Z","default_locale":"en","supported_locales":["en"],"id_map_hash":"sha256:1402a9727c23f2b6b70fd54bcb04138b40bfe0f8a9b464bcce626d9f0b48517d","mf2_packs":{"en":{"kind":"base","url":"packs/en.mf2pack","hash":"sha256:95aaf5fadb5d1f0f26d4b59d43a96858bd7bceb60894b5f9e18e7b5f57632c95","size":9683,"content_encoding":"identity","pack_schema":0}}} -\ No newline at end of file +{"schema":1,"release_id":"dev","generated_at":"2026-02-02T00:00:00Z","default_locale":"en","supported_locales":["en"],"id_map_hash":"sha256:8fcc5219c69f901ff56bf3890c0127b9a7a3e324f1c4475efed91fd28a54bf64","mf2_packs":{"en":{"kind":"base","url":"packs/en.mf2pack","hash":"sha256:4c050faaa27e4d6ed0203d1da1ecf344fa70eab12a747935ad918f752c3c930b","size":10709,"content_encoding":"identity","pack_schema":0}}} +\ No newline at end of file diff --git a/app/i18n/build/packs/en.mf2pack b/app/i18n/build/packs/en.mf2pack Binary files differ. diff --git a/app/i18n/locales/en/messages.mf2 b/app/i18n/locales/en/messages.mf2 @@ -296,6 +296,52 @@ app.logs.support.instructions.share = 2) share the file with support app.logs.support.instructions.notes = 3) include notes about the issue and time window +# settings +app.settings.title = settings + +app.settings.appearance.title = appearance + +app.settings.appearance.color_mode.label = color mode + +app.settings.appearance.color_mode.option.system = system + +app.settings.appearance.color_mode.option.light = light + +app.settings.appearance.color_mode.option.dark = dark + +app.settings.actions.export_db = export database + +app.settings.actions.logout = logout + +# ui demo +app.ui_demo.title = ui demo + +app.ui_demo.list.title = list preview + +app.ui_demo.item.notifications = notifications + +app.ui_demo.status.enabled = enabled + +app.ui_demo.input.placeholder = add a note + +app.ui_demo.input.label = note + +app.ui_demo.sync.label = sync frequency + +app.ui_demo.sync.option.daily = daily + +app.ui_demo.sync.option.weekly = weekly + +app.ui_demo.sync.option.never = never + +app.ui_demo.sheet.open = open sheet + +app.ui_demo.sheet.title = sheet preview + +app.ui_demo.sheet.description = this is a placeholder sheet for iOS styling. + +app.ui_demo.sheet.close = close + # errors error.app.init.idb = storage unavailable diff --git a/app/src/settings.rs b/app/src/settings.rs @@ -8,6 +8,7 @@ use crate::{ app_theme_mode_from_value, app_theme_read_mode, app_theme_store_mode, + t, RadrootsAppThemeMode, }; use radroots_app_ui_components::{ @@ -44,12 +45,12 @@ fn settings_touch_callback(action: &'static str) -> Callback<MouseEvent> { Callback::new(move |_| log_settings_action(action)) } -fn settings_label(value: &str, classes: Option<&str>) -> RadrootsAppUiListLabelValue { +fn settings_label(value: String, classes: Option<&str>) -> RadrootsAppUiListLabelValue { RadrootsAppUiListLabelValue { classes_wrap: None, hide_truncate: false, value: RadrootsAppUiListLabelValueKind::Text(RadrootsAppUiListLabelText { - value: value.to_string(), + value, classes: classes.map(str::to_string), }), } @@ -72,7 +73,7 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { view: Some("settings".to_string()), classes: None, title: Some(RadrootsAppUiListTitle { - value: RadrootsAppUiListTitleValue::Text("Appearance".to_string()), + value: RadrootsAppUiListTitleValue::Text(t!("app.settings.appearance.title")), classes: None, mod_value: None, link: None, @@ -85,17 +86,17 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { value: color_mode_value, options: vec![ RadrootsAppUiListSelectOption { - label: "System".to_string(), + label: t!("app.settings.appearance.color_mode.option.system"), value: "system".to_string(), classes: None, }, RadrootsAppUiListSelectOption { - label: "Light".to_string(), + label: t!("app.settings.appearance.color_mode.option.light"), value: "light".to_string(), classes: None, }, RadrootsAppUiListSelectOption { - label: "Dark".to_string(), + label: t!("app.settings.appearance.color_mode.option.dark"), value: "dark".to_string(), classes: None, }, @@ -106,7 +107,10 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { on_change: Some(color_mode_callback), }, label: RadrootsAppUiListLabel { - left: vec![settings_label("color mode", Some("capitalize"))], + left: vec![settings_label( + t!("app.settings.appearance.color_mode.label"), + Some("capitalize"), + )], right: Vec::new(), }, display: None, @@ -139,7 +143,10 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { Some(RadrootsAppUiListItem { kind: RadrootsAppUiListItemKind::Touch(RadrootsAppUiListTouch { label: RadrootsAppUiListLabel { - left: vec![settings_label("export database", Some("capitalize"))], + left: vec![settings_label( + t!("app.settings.actions.export_db"), + Some("capitalize"), + )], right: Vec::new(), }, display: None, @@ -161,7 +168,10 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { Some(RadrootsAppUiListItem { kind: RadrootsAppUiListItemKind::Touch(RadrootsAppUiListTouch { label: RadrootsAppUiListLabel { - left: vec![settings_label("logout", Some("capitalize"))], + left: vec![settings_label( + t!("app.settings.actions.logout"), + Some("capitalize"), + )], right: Vec::new(), }, display: None, @@ -187,7 +197,7 @@ pub fn RadrootsAppSettingsPage() -> impl IntoView { view! { <main id="app-settings" class="app-page app-page-scroll" style="padding: 16px;"> <header id="app-settings-header" style="font: var(--type-title2); margin-bottom: 12px;"> - <h1 id="app-settings-title">"settings"</h1> + <h1 id="app-settings-title">{t!("app.settings.title")}</h1> </header> <section id="app-settings-content" style="display:flex;flex-direction:column;gap:16px;"> <RadrootsAppUiListView basis=appearance_list /> diff --git a/app/src/ui_demo.rs b/app/src/ui_demo.rs @@ -1,5 +1,6 @@ use leptos::prelude::*; +use crate::t; use radroots_app_ui_components::{ RadrootsAppUiList, RadrootsAppUiListDisplay, @@ -43,11 +44,11 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { let select_value = RwSignal::new("daily".to_string()); let on_input = Callback::new(move |value| input_value.set(value)); let on_select = Callback::new(move |value| select_value.set(value)); - let text_label = |value: &str| RadrootsAppUiListLabelValue { + let text_label = |value: String| RadrootsAppUiListLabelValue { classes_wrap: None, hide_truncate: false, value: RadrootsAppUiListLabelValueKind::Text(RadrootsAppUiListLabelText { - value: value.to_string(), + value, classes: None, }), }; @@ -56,7 +57,7 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { view: Some("ui-demo".to_string()), classes: None, title: Some(RadrootsAppUiListTitle { - value: RadrootsAppUiListTitleValue::Text("List Preview".to_string()), + value: RadrootsAppUiListTitleValue::Text(t!("app.ui_demo.list.title")), classes: None, mod_value: None, link: None, @@ -67,12 +68,12 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { Some(RadrootsAppUiListItem { kind: RadrootsAppUiListItemKind::Touch(RadrootsAppUiListTouch { label: RadrootsAppUiListLabel { - left: vec![text_label("Notifications")], + left: vec![text_label(t!("app.ui_demo.item.notifications"))], right: Vec::new(), }, display: Some(RadrootsAppUiListDisplay { value: RadrootsAppUiListDisplayValue::Label(RadrootsAppUiListLabelText { - value: "Enabled".to_string(), + value: t!("app.ui_demo.status.enabled"), classes: None, }), loading: false, @@ -97,14 +98,14 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { kind: RadrootsAppUiListItemKind::Input(RadrootsAppUiListInput { field: RadrootsAppUiListInputField { value: input_value.get_untracked(), - placeholder: Some("Add a note".to_string()), + placeholder: Some(t!("app.ui_demo.input.placeholder")), disabled: false, classes: None, id: Some("ui-demo-note".to_string()), on_input: Some(on_input), }, line_label: Some(RadrootsAppUiListInputLineLabel { - value: "Note".to_string(), + value: t!("app.ui_demo.input.label"), classes: None, }), action: Some(RadrootsAppUiListInputAction { @@ -129,17 +130,17 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { value: select_value.get_untracked(), options: vec![ RadrootsAppUiListSelectOption { - label: "Daily".to_string(), + label: t!("app.ui_demo.sync.option.daily"), value: "daily".to_string(), classes: None, }, RadrootsAppUiListSelectOption { - label: "Weekly".to_string(), + label: t!("app.ui_demo.sync.option.weekly"), value: "weekly".to_string(), classes: None, }, RadrootsAppUiListSelectOption { - label: "Never".to_string(), + label: t!("app.ui_demo.sync.option.never"), value: "never".to_string(), classes: None, }, @@ -150,7 +151,7 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { on_change: Some(on_select), }, label: RadrootsAppUiListLabel { - left: vec![text_label("Sync Frequency")], + left: vec![text_label(t!("app.ui_demo.sync.label"))], right: Vec::new(), }, display: None, @@ -183,7 +184,7 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { view! { <main id="app-ui-demo" class="app-page app-page-scroll" style="padding: 16px;"> <header id="app-ui-demo-header" style="font: var(--type-title2); margin-bottom: 12px;"> - <h1 id="app-ui-demo-title">"UI Demo"</h1> + <h1 id="app-ui-demo-title">{t!("app.ui_demo.title")}</h1> </header> <section id="app-ui-demo-content"> <RadrootsAppUiListView basis=list /> @@ -200,7 +201,7 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { id=None style=Some("padding:12px 16px; width: 100%; text-align: left;".to_string()) > - "Open Sheet" + {t!("app.ui_demo.sheet.open")} </RadrootsAppUiSheetTrigger> <RadrootsAppUiSheetPortal> <RadrootsAppUiSheetOverlay @@ -221,21 +222,21 @@ pub fn RadrootsAppUiDemoPage() -> impl IntoView { id=None style=None > - "Sheet Preview" + {t!("app.ui_demo.sheet.title")} </RadrootsAppUiSheetTitle> <RadrootsAppUiSheetDescription class=None id=None style=Some("margin-top: 6px;".to_string()) > - "This is a placeholder sheet for iOS styling." + {t!("app.ui_demo.sheet.description")} </RadrootsAppUiSheetDescription> <RadrootsAppUiSheetClose class=Some("ui-card".to_string()) id=None style=Some("margin-top: 16px; padding: 10px 14px;".to_string()) > - "Close" + {t!("app.ui_demo.sheet.close")} </RadrootsAppUiSheetClose> </RadrootsAppUiSheetContent> </RadrootsAppUiSheetPortal>