diff --git a/auth/lib/app/view/app.dart b/auth/lib/app/view/app.dart index 37967d75a6..b2abc6caa0 100644 --- a/auth/lib/app/view/app.dart +++ b/auth/lib/app/view/app.dart @@ -23,7 +23,7 @@ import 'package:tray_manager/tray_manager.dart'; import 'package:window_manager/window_manager.dart'; class App extends StatefulWidget { - final Locale locale; + final Locale? locale; const App({super.key, this.locale = const Locale("en")}); static void setLocale(BuildContext context, Locale newLocale) { diff --git a/auth/lib/locale.dart b/auth/lib/locale.dart index c3b33e2988..7b0a34d02a 100644 --- a/auth/lib/locale.dart +++ b/auth/lib/locale.dart @@ -26,6 +26,7 @@ const List appSupportedLocales = [ Locale("zh", "CN"), ]; +Locale? autoDetectedLocale; Locale localResolutionCallBack(locales, supportedLocales) { Locale? languageCodeMatch; final Map languageCodeToLocale = { @@ -35,12 +36,14 @@ Locale localResolutionCallBack(locales, supportedLocales) { for (Locale locale in locales) { if (appSupportedLocales.contains(locale)) { + autoDetectedLocale = locale; return locale; } if (languageCodeMatch == null && languageCodeToLocale.containsKey(locale.languageCode)) { languageCodeMatch = languageCodeToLocale[locale.languageCode]; + autoDetectedLocale = languageCodeMatch; } } @@ -48,7 +51,9 @@ Locale localResolutionCallBack(locales, supportedLocales) { return languageCodeMatch ?? const Locale('en'); } -Future getLocale() async { +Future getLocale({ + bool noFallback = false, +}) async { final String? savedValue = (await SharedPreferences.getInstance()).getString('locale'); // if savedLocale is not null and is supported by the app, return it @@ -64,6 +69,12 @@ Future getLocale() async { return savedLocale; } } + if (autoDetectedLocale != null) { + return autoDetectedLocale!; + } + if (noFallback) { + return null; + } return const Locale('en'); } diff --git a/auth/lib/main.dart b/auth/lib/main.dart index 6d21f371d6..f812960a9a 100644 --- a/auth/lib/main.dart +++ b/auth/lib/main.dart @@ -102,7 +102,7 @@ Future _runInForeground() async { return await _runWithLogs(() async { _logger.info("Starting app in foreground"); await _init(false, via: 'mainMethod'); - final Locale locale = await getLocale(); + final Locale? locale = await getLocale(noFallback: true); unawaited(UpdateService.instance.showUpdateNotification()); runApp( AppLock( diff --git a/auth/lib/onboarding/view/onboarding_page.dart b/auth/lib/onboarding/view/onboarding_page.dart index dff1fbc179..0061dacf3a 100644 --- a/auth/lib/onboarding/view/onboarding_page.dart +++ b/auth/lib/onboarding/view/onboarding_page.dart @@ -108,7 +108,7 @@ class _OnboardingPageState extends State { child: Text("Lang"), ), onTap: () async { - final locale = await getLocale(); + final locale = (await getLocale())!; // ignore: unawaited_futures routeToPage( context, diff --git a/auth/lib/ui/settings/general_section_widget.dart b/auth/lib/ui/settings/general_section_widget.dart index 2089b9f3ca..cb29d8483a 100644 --- a/auth/lib/ui/settings/general_section_widget.dart +++ b/auth/lib/ui/settings/general_section_widget.dart @@ -49,7 +49,7 @@ class _AdvancedSectionWidgetState extends State { trailingIcon: Icons.chevron_right_outlined, trailingIconIsMuted: true, onTap: () async { - final locale = await getLocale(); + final locale = (await getLocale())!; // ignore: unawaited_futures routeToPage( context, diff --git a/auth/lib/ui/tools/app_lock.dart b/auth/lib/ui/tools/app_lock.dart index 0d328218f1..1428c553c6 100644 --- a/auth/lib/ui/tools/app_lock.dart +++ b/auth/lib/ui/tools/app_lock.dart @@ -35,7 +35,7 @@ class AppLock extends StatefulWidget { final ThemeData? darkTheme; final ThemeData? lightTheme; final ThemeMode savedThemeMode; - final Locale locale; + final Locale? locale; const AppLock({ super.key, @@ -43,7 +43,7 @@ class AppLock extends StatefulWidget { required this.lockScreen, required this.savedThemeMode, this.enabled = true, - this.locale = const Locale('en', 'US'), + this.locale, this.backgroundLockLatency = const Duration(seconds: 0), this.darkTheme, this.lightTheme, diff --git a/mobile/lib/app.dart b/mobile/lib/app.dart index 1540a0d270..4f590e4399 100644 --- a/mobile/lib/app.dart +++ b/mobile/lib/app.dart @@ -25,7 +25,7 @@ class EnteApp extends StatefulWidget { final Future Function(String) runBackgroundTask; final Future Function(String) killBackgroundTask; final AdaptiveThemeMode? savedThemeMode; - final Locale locale; + final Locale? locale; const EnteApp( this.runBackgroundTask, @@ -46,7 +46,7 @@ class EnteApp extends StatefulWidget { class _EnteAppState extends State with WidgetsBindingObserver { final _logger = Logger("EnteAppState"); - late Locale locale; + late Locale? locale; @override void initState() { diff --git a/mobile/lib/l10n/l10n.dart b/mobile/lib/l10n/l10n.dart index 0a74a7f1da..f45e26995c 100644 --- a/mobile/lib/l10n/l10n.dart +++ b/mobile/lib/l10n/l10n.dart @@ -24,17 +24,26 @@ const List appSupportedLocales = [ Locale("zh", "CN"), ]; +Locale? autoDetectedLocale; + Locale localResolutionCallBack(locales, supportedLocales) { for (Locale locale in locales) { - if (appSupportedLocales.contains(locale)) { - return locale; + for (Locale supportedLocale in appSupportedLocales) { + if (supportedLocale == locale) { + autoDetectedLocale = supportedLocale; + return supportedLocale; + } else if (supportedLocale.languageCode == locale.languageCode) { + autoDetectedLocale = supportedLocale; + return supportedLocale; + } } } - // if device language is not supported by the app, use en as default return const Locale('en'); } -Future getLocale() async { +Future getLocale({ + bool noFallback = false, +}) async { final String? savedValue = (await SharedPreferences.getInstance()).getString('locale'); // if savedLocale is not null and is supported by the app, return it @@ -50,6 +59,12 @@ Future getLocale() async { return savedLocale; } } + if (autoDetectedLocale != null) { + return autoDetectedLocale!; + } + if (noFallback) { + return null; + } return const Locale('en'); } diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 9c9d42c6d8..f44a3d799f 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -95,7 +95,7 @@ Future _runInForeground(AdaptiveThemeMode? savedThemeMode) async { return await _runWithLogs(() async { _logger.info("Starting app in foreground"); await _init(false, via: 'mainMethod'); - final Locale locale = await getLocale(); + final Locale? locale = await getLocale(noFallback: true); runApp( AppLock( builder: (args) => diff --git a/mobile/lib/ui/home/landing_page_widget.dart b/mobile/lib/ui/home/landing_page_widget.dart index e341746ac6..cc19854ed6 100644 --- a/mobile/lib/ui/home/landing_page_widget.dart +++ b/mobile/lib/ui/home/landing_page_widget.dart @@ -89,7 +89,7 @@ class _LandingPageWidgetState extends State { child: Text("Lang"), ), onTap: () async { - final locale = await getLocale(); + final locale = (await getLocale())!; // ignore: unawaited_futures routeToPage( context, diff --git a/mobile/lib/ui/settings/general_section_widget.dart b/mobile/lib/ui/settings/general_section_widget.dart index ccc941b4ee..3532292551 100644 --- a/mobile/lib/ui/settings/general_section_widget.dart +++ b/mobile/lib/ui/settings/general_section_widget.dart @@ -70,7 +70,7 @@ class GeneralSectionWidget extends StatelessWidget { trailingIcon: Icons.chevron_right_outlined, trailingIconIsMuted: true, onTap: () async { - final locale = await getLocale(); + final locale = (await getLocale())!; await routeToPage( context, LanguageSelectorPage( diff --git a/mobile/lib/ui/tools/app_lock.dart b/mobile/lib/ui/tools/app_lock.dart index cbc716d7f8..19a718b7a0 100644 --- a/mobile/lib/ui/tools/app_lock.dart +++ b/mobile/lib/ui/tools/app_lock.dart @@ -35,7 +35,7 @@ class AppLock extends StatefulWidget { final ThemeData? darkTheme; final ThemeData? lightTheme; final ThemeMode savedThemeMode; - final Locale locale; + final Locale? locale; const AppLock({ Key? key, @@ -43,7 +43,7 @@ class AppLock extends StatefulWidget { required this.lockScreen, required this.savedThemeMode, this.enabled = true, - this.locale = const Locale("en", "US"), + this.locale, this.darkTheme, this.lightTheme, }) : super(key: key); diff --git a/mobile/lib/ui/viewer/file_details/creation_time_item_widget.dart b/mobile/lib/ui/viewer/file_details/creation_time_item_widget.dart index d4f08a66f9..90b6ab9d58 100644 --- a/mobile/lib/ui/viewer/file_details/creation_time_item_widget.dart +++ b/mobile/lib/ui/viewer/file_details/creation_time_item_widget.dart @@ -47,7 +47,7 @@ class _CreationTimeItemState extends State { } void _showDateTimePicker(EnteFile file) async { - final Locale locale = await getLocale(); + final Locale locale = (await getLocale())!; final localeType = getFromLocalString(locale); final dateResult = await DatePickerBdaya.showDatePicker( context, diff --git a/mobile/lib/ui/viewer/gallery/hooks/add_photos_sheet.dart b/mobile/lib/ui/viewer/gallery/hooks/add_photos_sheet.dart index 571b84424e..1dd6c5c8ab 100644 --- a/mobile/lib/ui/viewer/gallery/hooks/add_photos_sheet.dart +++ b/mobile/lib/ui/viewer/gallery/hooks/add_photos_sheet.dart @@ -218,7 +218,7 @@ class AddPhotosPhotoWidget extends StatelessWidget { // This custom method is required to enforce English as the default fallback // instead of Chinese. Future _getAssetPickerTextDelegate() async { - final Locale locale = await getLocale(); + final Locale locale = (await getLocale())!; switch (locale.languageCode.toLowerCase()) { case "en": return const EnglishAssetPickerTextDelegate();