From 3a2e30e30ef5fe1c31fdee6a851670f3b91395c9 Mon Sep 17 00:00:00 2001 From: John Stef Date: Tue, 19 Nov 2024 20:09:29 +0200 Subject: [PATCH] fix(mobile): fixes on language change (#14089) * fix(mobile): make widgets rebuild on locale changes This will make the make the pages to instantly refresh the correct translated string, without the need to pop and push the settings page. * fix(mobile): set the default intl locale This is needed because across the app, you don't pass the context.locale to DateFormat, so by default it uses the system's locale. This will fix the issue without the need to refactor a lot of code. * feat(mobile): create localeProvider This provider can be used to refresh providers that provide UI elements and get cached. * fix(mobile): refresh asset providers on locale change This is necessary to update the locale on the already evaluated DateFormat. --------- Co-authored-by: Alex --- mobile/lib/main.dart | 6 ++++ mobile/lib/pages/common/settings.page.dart | 2 ++ mobile/lib/pages/library/library.page.dart | 1 + mobile/lib/providers/asset.provider.dart | 42 +++++++++++++--------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index e9ca8ceb6a..7729972aa2 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -192,6 +192,12 @@ class ImmichAppState extends ConsumerState await ref.read(localNotificationService).setup(); } + @override + void didChangeDependencies() { + super.didChangeDependencies(); + Intl.defaultLocale = context.locale.toLanguageTag(); + } + @override initState() { super.initState(); diff --git a/mobile/lib/pages/common/settings.page.dart b/mobile/lib/pages/common/settings.page.dart index 117b0aedc0..a6ca239962 100644 --- a/mobile/lib/pages/common/settings.page.dart +++ b/mobile/lib/pages/common/settings.page.dart @@ -46,6 +46,7 @@ class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { + context.locale; return Scaffold( appBar: AppBar( centerTitle: false, @@ -129,6 +130,7 @@ class SettingsSubPage extends StatelessWidget { @override Widget build(BuildContext context) { + context.locale; return Scaffold( appBar: AppBar( centerTitle: false, diff --git a/mobile/lib/pages/library/library.page.dart b/mobile/lib/pages/library/library.page.dart index 48d2c685ba..1161f068cf 100644 --- a/mobile/lib/pages/library/library.page.dart +++ b/mobile/lib/pages/library/library.page.dart @@ -23,6 +23,7 @@ class LibraryPage extends ConsumerWidget { const LibraryPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { + context.locale; final trashEnabled = ref.watch(serverInfoProvider.select((v) => v.serverFeatures.trash)); diff --git a/mobile/lib/providers/asset.provider.dart b/mobile/lib/providers/asset.provider.dart index 3855a00b76..9252de01bf 100644 --- a/mobile/lib/providers/asset.provider.dart +++ b/mobile/lib/providers/asset.provider.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/providers/locale_provider.dart'; import 'package:immich_mobile/providers/memory.provider.dart'; import 'package:immich_mobile/repositories/asset_media.repository.dart'; import 'package:immich_mobile/services/album.service.dart'; @@ -328,24 +329,31 @@ final assetWatcher = return db.assets.watchObject(asset.id, fireImmediately: true); }); -final assetsProvider = StreamProvider.family((ref, userId) { - if (userId == null) return const Stream.empty(); - final query = _commonFilterAndSort( - _assets(ref).where().ownerIdEqualToAnyChecksum(userId), - ); - return renderListGenerator(query, ref); -}); +final assetsProvider = StreamProvider.family( + (ref, userId) { + if (userId == null) return const Stream.empty(); + ref.watch(localeProvider); + final query = _commonFilterAndSort( + _assets(ref).where().ownerIdEqualToAnyChecksum(userId), + ); + return renderListGenerator(query, ref); + }, + dependencies: [localeProvider], +); -final multiUserAssetsProvider = - StreamProvider.family>((ref, userIds) { - if (userIds.isEmpty) return const Stream.empty(); - final query = _commonFilterAndSort( - _assets(ref) - .where() - .anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)), - ); - return renderListGenerator(query, ref); -}); +final multiUserAssetsProvider = StreamProvider.family>( + (ref, userIds) { + if (userIds.isEmpty) return const Stream.empty(); + ref.watch(localeProvider); + final query = _commonFilterAndSort( + _assets(ref) + .where() + .anyOf(userIds, (q, u) => q.ownerIdEqualToAnyChecksum(u)), + ); + return renderListGenerator(query, ref); + }, + dependencies: [localeProvider], +); QueryBuilder? getRemoteAssetQuery(WidgetRef ref) { final userId = ref.watch(currentUserProvider)?.isarId;