mirror of
https://github.com/immich-app/immich.git
synced 2026-10-26 12:39:46 +08:00
fix(mobile): fallback localizations for unsupported locales
This commit is contained in:
@@ -40,6 +40,7 @@ import 'package:immich_mobile/theme/theme_data.dart';
|
||||
import 'package:immich_mobile/utils/bootstrap.dart';
|
||||
import 'package:immich_mobile/utils/cache/widgets_binding.dart';
|
||||
import 'package:immich_mobile/utils/debug_print.dart';
|
||||
import 'package:immich_mobile/utils/fallback_localizations.dart';
|
||||
import 'package:immich_mobile/utils/licenses.dart';
|
||||
import 'package:immich_mobile/utils/migration.dart';
|
||||
import 'package:immich_mobile/wm_executor.dart';
|
||||
@@ -283,7 +284,7 @@ class ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserve
|
||||
title: 'Immich',
|
||||
debugShowCheckedModeBanner: true,
|
||||
scaffoldMessengerKey: scaffoldMessengerKey,
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
localizationsDelegates: [...context.localizationDelegates, ...fallbackLocalizationDelegates],
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
themeMode: ref.watch(appConfigProvider.select((config) => config.theme.mode)),
|
||||
|
||||
@@ -24,6 +24,7 @@ import 'package:immich_mobile/providers/websocket.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/theme/color_scheme.dart';
|
||||
import 'package:immich_mobile/theme/theme_data.dart';
|
||||
import 'package:immich_mobile/utils/fallback_localizations.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_logo.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_title_text.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@@ -49,7 +50,7 @@ class BootstrapErrorWidget extends StatelessWidget {
|
||||
builder: (lCtx) => MaterialApp(
|
||||
title: 'Immich',
|
||||
debugShowCheckedModeBanner: true,
|
||||
localizationsDelegates: lCtx.localizationDelegates,
|
||||
localizationsDelegates: [...lCtx.localizationDelegates, ...fallbackLocalizationDelegates],
|
||||
supportedLocales: lCtx.supportedLocales,
|
||||
locale: lCtx.locale,
|
||||
themeMode: ThemeMode.system,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Flutter ships no Material or Cupertino strings for some of our languages, use English for those
|
||||
const List<LocalizationsDelegate> fallbackLocalizationDelegates = [
|
||||
_FallbackLocalizationsDelegate<MaterialLocalizations>(DefaultMaterialLocalizations.delegate),
|
||||
_FallbackLocalizationsDelegate<CupertinoLocalizations>(DefaultCupertinoLocalizations.delegate),
|
||||
];
|
||||
|
||||
class _FallbackLocalizationsDelegate<T> extends LocalizationsDelegate<T> {
|
||||
final LocalizationsDelegate<T> delegate;
|
||||
|
||||
const _FallbackLocalizationsDelegate(this.delegate);
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) => true;
|
||||
|
||||
@override
|
||||
Future<T> load(Locale locale) => delegate.load(locale);
|
||||
|
||||
@override
|
||||
bool shouldReload(_FallbackLocalizationsDelegate<T> old) => false;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../widget_tester_extensions.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Material and Cupertino widgets work in languages Flutter has no translations for', (tester) async {
|
||||
await tester.pumpConsumerWidget(
|
||||
const Column(children: [BackButton(), CupertinoSearchTextField()]),
|
||||
locale: const Locale('mi'),
|
||||
);
|
||||
|
||||
expect(find.byTooltip('Back'), findsOneWidget);
|
||||
expect(find.text('Search'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/constants/locales.dart';
|
||||
import 'package:immich_mobile/generated/codegen_loader.g.dart';
|
||||
import 'package:immich_mobile/utils/fallback_localizations.dart';
|
||||
|
||||
extension PumpConsumerWidget on WidgetTester {
|
||||
/// Wraps the provided [widget] with a localized Material app such that it
|
||||
@@ -20,12 +21,13 @@ extension PumpConsumerWidget on WidgetTester {
|
||||
Duration? duration,
|
||||
EnginePhase phase = EnginePhase.sendSemanticsUpdate,
|
||||
List<Override> overrides = const [],
|
||||
Locale? locale,
|
||||
}) async {
|
||||
await pumpWidget(
|
||||
EasyLocalization(
|
||||
supportedLocales: locales.values.toList(),
|
||||
path: translationsPath,
|
||||
startLocale: locales.values.first,
|
||||
startLocale: locale ?? locales.values.first,
|
||||
fallbackLocale: locales.values.first,
|
||||
saveLocale: false,
|
||||
useFallbackTranslations: true,
|
||||
@@ -35,7 +37,7 @@ extension PumpConsumerWidget on WidgetTester {
|
||||
child: Builder(
|
||||
builder: (context) => MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: context.localizationDelegates,
|
||||
localizationsDelegates: [...context.localizationDelegates, ...fallbackLocalizationDelegates],
|
||||
supportedLocales: context.supportedLocales,
|
||||
locale: context.locale,
|
||||
home: Material(child: widget),
|
||||
|
||||
Reference in New Issue
Block a user