Shuffle/app/lib/core/l10n/app_locale.dart
cschlaefke e5df79ee0a feat(app): add Flutter scaffold with config, logging, routing and l10n
Refs #31

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 20:17:24 +01:00

51 lines
1.7 KiB
Dart

import 'package:flutter/widgets.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shuffle/l10n/app_localizations.dart';
part 'app_locale.g.dart';
/// Fallback-Sprache, wenn die Gerätesprache nicht unterstützt wird
/// (QUE-05 Kriterium 4).
const fallbackLocale = Locale('en');
/// Bildet eine Gerätesprache auf eine unterstützte Sprache ab (de/en, sonst en).
///
/// Wird auch als `localeResolutionCallback` genutzt: gen-l10n sortiert die
/// unterstützten Sprachen alphabetisch, Flutter würde sonst auf Deutsch fallen.
Locale resolveAppLocale(Locale? deviceLocale) {
if (deviceLocale == null) {
return fallbackLocale;
}
for (final supported in AppLocalizations.supportedLocales) {
if (supported.languageCode == deviceLocale.languageCode) {
return Locale(supported.languageCode);
}
}
return fallbackLocale;
}
/// Aktive Oberflächensprache: Gerätesprache (de/en), sonst Englisch.
///
/// Folgt Änderungen der Gerätesprache. Eine manuelle Wahl folgt mit KTO-11.
@Riverpod(keepAlive: true)
class AppLocale extends _$AppLocale {
@override
Locale build() {
final binding = WidgetsBinding.instance;
final observer = _LocaleObserver(
(locales) => state = resolveAppLocale(locales?.firstOrNull),
);
binding.addObserver(observer);
ref.onDispose(() => binding.removeObserver(observer));
return resolveAppLocale(binding.platformDispatcher.locales.firstOrNull);
}
}
class _LocaleObserver with WidgetsBindingObserver {
_LocaleObserver(this._onChanged);
final void Function(List<Locale>? locales) _onChanged;
@override
void didChangeLocales(List<Locale>? locales) => _onChanged(locales);
}