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