diff --git a/mobile/lib/extensions/widgetref_extensions.dart b/mobile/lib/extensions/widgetref_extensions.dart deleted file mode 100644 index 3fb40b9bd..000000000 --- a/mobile/lib/extensions/widgetref_extensions.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/shared/providers/immich_loading_overlay.provider.dart'; - -extension LoadingOverlay on WidgetRef { - ValueNotifier useProcessingOverlay() { - final result = useState(false); - final immichOverlayController = - read(immichLoadingOverlayController.notifier); - useValueChanged( - result.value, - (_, __) => result.value - ? WidgetsBinding.instance - .addPostFrameCallback((_) => immichOverlayController.show()) - : WidgetsBinding.instance - .addPostFrameCallback((_) => immichOverlayController.hide()), - ); - return result; - } -} diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index a12c43b6c..ab3438d44 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -9,6 +9,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/shared/providers/theme.provider.dart'; import 'package:timezone/data/latest.dart'; import 'package:immich_mobile/constants/locales.dart'; import 'package:immich_mobile/modules/backup/background_service/background.service.dart'; diff --git a/mobile/lib/modules/activities/views/activities_page.dart b/mobile/lib/modules/activities/views/activities_page.dart index a3de7a96c..a78005829 100644 --- a/mobile/lib/modules/activities/views/activities_page.dart +++ b/mobile/lib/modules/activities/views/activities_page.dart @@ -51,7 +51,7 @@ class ActivitiesPage extends HookConsumerWidget { buildTitleWithTimestamp(Activity activity, {bool leftAlign = true}) { final textStyle = context.textTheme.bodyMedium?.copyWith( - color: context.textTheme.bodyMedium?.color?.withOpacity(0.6)); + color: context.textTheme.bodyMedium?.color?.withOpacity(0.6),); return Row( mainAxisAlignment: leftAlign diff --git a/mobile/lib/modules/album/ui/album_viewer_appbar.dart b/mobile/lib/modules/album/ui/album_viewer_appbar.dart index a941a7fea..5bddce724 100644 --- a/mobile/lib/modules/album/ui/album_viewer_appbar.dart +++ b/mobile/lib/modules/album/ui/album_viewer_appbar.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/widgetref_extensions.dart'; import 'package:immich_mobile/modules/activities/providers/activity.provider.dart'; import 'package:immich_mobile/modules/album/providers/album.provider.dart'; import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart'; @@ -15,6 +14,7 @@ import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/models/album.dart'; import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart'; +import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; class AlbumViewerAppbar extends HookConsumerWidget implements PreferredSizeWidget { diff --git a/mobile/lib/modules/album/views/album_options_part.dart b/mobile/lib/modules/album/views/album_options_part.dart index 420b7c232..b719ed05b 100644 --- a/mobile/lib/modules/album/views/album_options_part.dart +++ b/mobile/lib/modules/album/views/album_options_part.dart @@ -5,7 +5,6 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/color_extensions.dart'; -import 'package:immich_mobile/extensions/widgetref_extensions.dart'; import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/routing/router.dart'; @@ -13,6 +12,7 @@ import 'package:immich_mobile/shared/models/album.dart'; import 'package:immich_mobile/shared/models/user.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/ui/user_circle_avatar.dart'; +import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; class AlbumOptionsPage extends HookConsumerWidget { final Album album; @@ -27,7 +27,6 @@ class AlbumOptionsPage extends HookConsumerWidget { final activityEnabled = useState(album.activityEnabled); final isProcessing = useProcessingOverlay(); final isOwner = owner?.id == userId; - final immichOverlayController = ref.useProcessingOverlay(); void showErrorMessage() { context.pop(); diff --git a/mobile/lib/modules/album/views/album_viewer_page.dart b/mobile/lib/modules/album/views/album_viewer_page.dart index 856fe14e8..7166e4cd4 100644 --- a/mobile/lib/modules/album/views/album_viewer_page.dart +++ b/mobile/lib/modules/album/views/album_viewer_page.dart @@ -6,7 +6,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/widgetref_extensions.dart'; import 'package:immich_mobile/modules/album/models/asset_selection_page_result.model.dart'; import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart'; import 'package:immich_mobile/modules/album/services/album.service.dart'; @@ -20,6 +19,7 @@ import 'package:immich_mobile/shared/models/album.dart'; import 'package:immich_mobile/shared/models/asset.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart'; import 'package:immich_mobile/shared/ui/user_circle_avatar.dart'; +import 'package:immich_mobile/shared/views/immich_loading_overlay.dart'; class AlbumViewerPage extends HookConsumerWidget { final int albumId; diff --git a/mobile/lib/modules/album/views/library_page.dart b/mobile/lib/modules/album/views/library_page.dart index f5e0b0ec9..b512804d7 100644 --- a/mobile/lib/modules/album/views/library_page.dart +++ b/mobile/lib/modules/album/views/library_page.dart @@ -135,47 +135,45 @@ class LibraryPage extends HookConsumerWidget { Widget buildCreateAlbumButton() { return LayoutBuilder( builder: (context, constraints) { - var cardSize = constraints.maxWidth; - return GestureDetector( - onTap: () { - (context).autoPush(CreateAlbumRoute(isSharedAlbum: false)); - }, - child: Padding( - padding: const EdgeInsets.only(bottom: 32), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Container( - decoration: BoxDecoration( - color: context.themeData.cardColor, - borderRadius: - const BorderRadius.all(Radius.circular(20)), - ), - child: Center( - child: Icon( - Icons.add_rounded, - size: 28, - color: context.primaryColor, - ), + onTap: () => + context.autoPush(CreateAlbumRoute(isSharedAlbum: false)), + child: Padding( + padding: const EdgeInsets.only(bottom: 32), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + color: context.themeData.cardColor, + borderRadius: + const BorderRadius.all(Radius.circular(20)), + ), + child: Center( + child: Icon( + Icons.add_rounded, + size: 28, + color: context.primaryColor, ), ), ), - Padding( - padding: const EdgeInsets.only( - top: 8.0, - bottom: 16, - ), - child: Text( - 'library_page_new_album', - style: context.textTheme.labelLarge, - ).tr(), + ), + Padding( + padding: const EdgeInsets.only( + top: 8.0, + bottom: 16, ), - ], - ), - )); + child: Text( + 'library_page_new_album', + style: context.textTheme.labelLarge, + ).tr(), + ), + ], + ), + ), + ); }, ); } diff --git a/mobile/lib/modules/home/views/home_page.dart b/mobile/lib/modules/home/views/home_page.dart index 66428f569..58770ed5c 100644 --- a/mobile/lib/modules/home/views/home_page.dart +++ b/mobile/lib/modules/home/views/home_page.dart @@ -7,7 +7,6 @@ import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/widgetref_extensions.dart'; import 'package:immich_mobile/modules/album/providers/album.provider.dart'; import 'package:immich_mobile/modules/album/providers/album_detail.provider.dart'; import 'package:immich_mobile/modules/album/providers/shared_album.provider.dart'; diff --git a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart index f244b1e01..ad6b76620 100644 --- a/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart +++ b/mobile/lib/modules/settings/ui/asset_list_settings/asset_list_tiles_per_row.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; diff --git a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart index 8a1374697..4b882768f 100644 --- a/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart +++ b/mobile/lib/modules/settings/ui/theme_setting/theme_setting.dart @@ -5,7 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; -import 'package:immich_mobile/utils/immich_app_theme.dart'; +import 'package:immich_mobile/shared/providers/theme.provider.dart'; class ThemeSetting extends HookConsumerWidget { const ThemeSetting({ @@ -47,20 +47,26 @@ class ThemeSetting extends HookConsumerWidget { if (isSystem) { currentTheme.value = ThemeMode.system; - ref.watch(immichThemeProvider.notifier).state = ThemeMode.system; + ref + .watch(immichThemeProvider.notifier) + .updateTheme(ThemeMode.system); ref .watch(appSettingsServiceProvider) .setSetting(AppSettingsEnum.themeMode, "system"); } else { if (currentSystemBrightness == Brightness.light) { currentTheme.value = ThemeMode.light; - ref.watch(immichThemeProvider.notifier).state = ThemeMode.light; + ref + .watch(immichThemeProvider.notifier) + .updateTheme(ThemeMode.light); ref .watch(appSettingsServiceProvider) .setSetting(AppSettingsEnum.themeMode, "light"); } else if (currentSystemBrightness == Brightness.dark) { currentTheme.value = ThemeMode.dark; - ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark; + ref + .watch(immichThemeProvider.notifier) + .updateTheme(ThemeMode.dark); ref .watch(appSettingsServiceProvider) .setSetting(AppSettingsEnum.themeMode, "dark"); @@ -78,12 +84,16 @@ class ThemeSetting extends HookConsumerWidget { value: ref.watch(immichThemeProvider) == ThemeMode.dark, onChanged: (bool isDark) { if (isDark) { - ref.watch(immichThemeProvider.notifier).state = ThemeMode.dark; + ref + .watch(immichThemeProvider.notifier) + .updateTheme(ThemeMode.dark); ref .watch(appSettingsServiceProvider) .setSetting(AppSettingsEnum.themeMode, "dark"); } else { - ref.watch(immichThemeProvider.notifier).state = ThemeMode.light; + ref + .watch(immichThemeProvider.notifier) + .updateTheme(ThemeMode.light); ref .watch(appSettingsServiceProvider) .setSetting(AppSettingsEnum.themeMode, "light"); diff --git a/mobile/lib/modules/trash/views/trash_page.dart b/mobile/lib/modules/trash/views/trash_page.dart index 511a3570c..88fd32d01 100644 --- a/mobile/lib/modules/trash/views/trash_page.dart +++ b/mobile/lib/modules/trash/views/trash_page.dart @@ -5,7 +5,6 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/widgetref_extensions.dart'; import 'package:immich_mobile/modules/home/ui/asset_grid/immich_asset_grid.dart'; import 'package:immich_mobile/modules/home/ui/delete_dialog.dart'; import 'package:immich_mobile/modules/trash/providers/trashed_asset.provider.dart'; diff --git a/mobile/lib/shared/providers/theme.provider.dart b/mobile/lib/shared/providers/theme.provider.dart new file mode 100644 index 000000000..a8b270a2c --- /dev/null +++ b/mobile/lib/shared/providers/theme.provider.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; +import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'theme.provider.g.dart'; + +@Riverpod(keepAlive: true) +class ImmichTheme extends _$ImmichTheme { + @override + ThemeMode build() { + final themeMode = ref + .watch(appSettingsServiceProvider) + .getSetting(AppSettingsEnum.themeMode); + + switch (themeMode) { + case "light": + return ThemeMode.light; + case "dark": + return ThemeMode.dark; + default: + return ThemeMode.system; + } + } + + void updateTheme(ThemeMode newMode) => state = newMode; +} diff --git a/mobile/lib/shared/providers/theme.provider.g.dart b/mobile/lib/shared/providers/theme.provider.g.dart new file mode 100644 index 000000000..9b5b6ec60 --- /dev/null +++ b/mobile/lib/shared/providers/theme.provider.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'theme.provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$immichThemeHash() => r'22952207d5d5e6289a8244589e703c816501d6e3'; + +/// See also [ImmichTheme]. +@ProviderFor(ImmichTheme) +final immichThemeProvider = NotifierProvider.internal( + ImmichTheme.new, + name: r'immichThemeProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$immichThemeHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ImmichTheme = Notifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/mobile/lib/shared/ui/immich_toast.dart b/mobile/lib/shared/ui/immich_toast.dart index dff861996..318cdd1cd 100644 --- a/mobile/lib/shared/ui/immich_toast.dart +++ b/mobile/lib/shared/ui/immich_toast.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; -import 'package:immich_mobile/extensions/color_extensions.dart'; enum ToastType { info, success, error } diff --git a/mobile/lib/utils/immich_app_theme.dart b/mobile/lib/utils/immich_app_theme.dart index 6ec013aca..406fc7bdb 100644 --- a/mobile/lib/utils/immich_app_theme.dart +++ b/mobile/lib/utils/immich_app_theme.dart @@ -1,23 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/modules/settings/providers/app_settings.provider.dart'; -import 'package:immich_mobile/modules/settings/services/app_settings.service.dart'; - -final immichThemeProvider = StateProvider((ref) { - var themeMode = ref - .watch(appSettingsServiceProvider) - .getSetting(AppSettingsEnum.themeMode); - - debugPrint("Current themeMode $themeMode"); - - if (themeMode == "light") { - return ThemeMode.light; - } else if (themeMode == "dark") { - return ThemeMode.dark; - } else { - return ThemeMode.system; - } -}); ColorScheme _lightColorScheme = const ColorScheme( brightness: Brightness.light,