feat(studio): app-wide i18n via flutter_localizations (v0.24.0)
Replaces the Store-only DE/EN toggle with an app-wide one parked in the sidebar footer next to the theme button. Pressing it flips every translated string at once: nav labels, page titles, common buttons, the bilingual store-index content. Implementation: - Adds `flutter_localizations` + `intl` to pubspec, plus `flutter.generate: true` so `flutter gen-l10n` runs in the build pipeline. - ARB sources at `lib/l10n/app_en.arb` and `app_de.arb`. The EN file is the template; DE carries the German strings. Initial coverage: navigation, common buttons, page titles, channels / store / audit / modules / approvals headers, hub-unreachable copy, MCP + n8n panel headers + hints. Rest of the UI strings are still English-literal — those fall in incrementally as we touch each surface. - Generated `AppLocalizations` lives at `lib/l10n/app_localizations*.dart` (regenerated via `flutter gen-l10n` on every ARB edit). - `StudioAppState` gains `localeNotifier` alongside `modeNotifier`; persisted via SharedPreferences key `locale.code`. - Sidebar `_LanguageToggle` reads/writes through the notifier. The Store's per-page locale state is gone: `_locale` now reads `Localizations.localeOf(context) .languageCode`, so the bilingual store-index content follows the global setting without a second toggle. - `_NavPage.label` becomes `_NavPage.id` + `labelOf(context)`; Cmd+K palette and Sidebar both read the localized label. Out of scope this iteration: localizing the remaining ~80% of UI strings (Settings dialog labels, Store search hint, error messages). Those land incrementally — the i18n infrastructure now means each is a one-line ARB edit + one call-site swap. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
d2a6ed32e2
commit
ee83eb851a
16 changed files with 1440 additions and 67 deletions
|
|
@ -6,6 +6,7 @@
|
|||
// protobuf imports.
|
||||
|
||||
import 'package:fai_dart_sdk/fai_dart_sdk.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class HubService {
|
||||
|
|
@ -53,6 +54,7 @@ class HubService {
|
|||
}
|
||||
|
||||
static const _kThemeKey = 'theme.mode';
|
||||
static const _kLocaleKey = 'locale.code';
|
||||
|
||||
/// Read the persisted theme mode (system / light / dark) for
|
||||
/// initial app startup. Defaults to system.
|
||||
|
|
@ -68,6 +70,22 @@ class HubService {
|
|||
await prefs.setString(_kThemeKey, mode.wire);
|
||||
}
|
||||
|
||||
/// Read the persisted UI locale. Defaults to English when
|
||||
/// nothing is stored — operators on a fresh install land in
|
||||
/// English; the sidebar toggle flips to German on demand.
|
||||
Future<Locale> loadLocale() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(_kLocaleKey);
|
||||
if (raw == 'de') return const Locale('de');
|
||||
return const Locale('en');
|
||||
}
|
||||
|
||||
/// Persist the locale code (`en` / `de`).
|
||||
Future<void> saveLocale(Locale locale) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(_kLocaleKey, locale.languageCode);
|
||||
}
|
||||
|
||||
Future<bool> healthy() => _client.healthy();
|
||||
|
||||
Future<List<ModuleSummary>> listModules() async {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue