From 7a923659d1d78cc32e555bd94e535c79111c524e Mon Sep 17 00:00:00 2001 From: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Date: Tue, 21 Apr 2026 00:42:50 +0530 Subject: [PATCH] chore: riverpod v2 to v3 # Conflicts: # mobile/lib/presentation/widgets/asset_viewer/asset_page.widget.dart --- mobile/analysis_options.yaml | 6 +- mobile/lib/main.dart | 17 +- .../pages/drift_library.page.dart | 4 +- .../pages/search/drift_search.page.dart | 4 +- .../search/paginated_search.provider.dart | 1 + .../asset_viewer/asset_details.widget.dart | 2 +- .../asset_viewer/asset_stack.provider.dart | 8 +- .../asset_viewer/asset_viewer.page.dart | 7 +- .../bottom_sheet/map_bottom_sheet.widget.dart | 2 +- mobile/lib/providers/activity.provider.dart | 21 ++- .../providers/album/album_title.provider.dart | 2 +- .../album/current_album.provider.g.dart | 26 --- .../providers/app_life_cycle.provider.dart | 1 + .../asset_viewer/asset_viewer.provider.dart | 36 +++-- .../asset_viewer/download.provider.dart | 2 +- .../is_motion_video_playing.provider.dart | 1 + .../share_intent_upload.provider.dart | 4 +- .../asset_viewer/show_controls.provider.dart | 1 + .../asset_viewer/video_player_provider.dart | 2 +- mobile/lib/providers/auth.provider.dart | 3 +- .../asset_upload_progress.provider.dart | 1 + .../lib/providers/backup/backup.provider.dart | 2 +- .../backup/backup_album.provider.dart | 2 +- .../backup/drift_backup.provider.dart | 8 +- mobile/lib/providers/cast.provider.dart | 2 +- mobile/lib/providers/cleanup.provider.dart | 2 +- mobile/lib/providers/folder.provider.dart | 1 + .../gallery_permission.provider.dart | 2 +- .../providers/haptic_feedback.provider.dart | 1 + .../infrastructure/map.provider.dart | 2 +- .../infrastructure/timeline.provider.dart | 2 +- mobile/lib/providers/local_auth.provider.dart | 2 +- .../lib/providers/multiselect.provider.dart | 2 +- mobile/lib/providers/network.provider.dart | 2 +- .../notification_permission.provider.dart | 2 +- mobile/lib/providers/routes.provider.dart | 2 +- .../providers/secure_storage.provider.dart | 2 +- .../lib/providers/server_info.provider.dart | 1 + .../lib/providers/shared_link.provider.dart | 1 + mobile/lib/providers/tab.provider.dart | 2 +- mobile/lib/providers/theme.provider.dart | 9 +- .../upload_profile_image.provider.dart | 2 +- mobile/lib/providers/user.provider.dart | 2 +- mobile/lib/providers/websocket.provider.dart | 1 + mobile/lib/services/deep_link.service.dart | 1 + .../widgets/asset_viewer/video_controls.dart | 5 +- .../preference_settings/theme_setting.dart | 5 +- mobile/pubspec.lock | 150 +++++++++++++++++- mobile/pubspec.yaml | 25 ++- .../modules/map/map_theme_override_test.dart | 13 +- mobile/test/widget_tester_extensions.dart | 1 + 51 files changed, 288 insertions(+), 117 deletions(-) delete mode 100644 mobile/lib/providers/album/current_album.provider.g.dart diff --git a/mobile/analysis_options.yaml b/mobile/analysis_options.yaml index fafd1f40ec..e1e83b6429 100644 --- a/mobile/analysis_options.yaml +++ b/mobile/analysis_options.yaml @@ -45,12 +45,12 @@ analyzer: - lib/**/*.g.dart - lib/**/*.drift.dart - # TODO: Re-enable after upgrading custom_lint - # plugins: - # - custom_lint errors: unawaited_futures: warning +plugins: + riverpod_lint: ^3.1.3 + custom_lint: rules: - avoid_build_context_in_providers: false diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 4a284b9bda..5f0b2d95f1 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -55,9 +55,22 @@ void main() async { await workerManagerPatch.init(dynamicSpawning: true, isolatesCount: max(Platform.numberOfProcessors - 1, 5)); await migrateDatabaseIfNeeded(); - runApp(ProviderScope(overrides: [driftProvider.overrideWith(driftOverride(drift))], child: const MainWidget())); + runApp( + ProviderScope( + overrides: [driftProvider.overrideWith(driftOverride(drift))], + // Never retry any provider + retry: (retryCount, error) => null, + child: const MainWidget(), + ), + ); } catch (error, stack) { - runApp(BootstrapErrorWidget(error: error.toString(), stack: stack.toString())); + runApp( + ProviderScope( + // Never retry any provider + retry: (retryCount, error) => null, + child: BootstrapErrorWidget(error: error.toString(), stack: stack.toString()), + ), + ); } } diff --git a/mobile/lib/presentation/pages/drift_library.page.dart b/mobile/lib/presentation/pages/drift_library.page.dart index 4708b5e615..4a1c831a77 100644 --- a/mobile/lib/presentation/pages/drift_library.page.dart +++ b/mobile/lib/presentation/pages/drift_library.page.dart @@ -7,12 +7,12 @@ import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/images/local_album_thumbnail.widget.dart'; +import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart'; import 'package:immich_mobile/presentation/widgets/people/partner_user_avatar.widget.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/partner.provider.dart'; import 'package:immich_mobile/providers/infrastructure/people.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; -import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/image_url_builder.dart'; import 'package:immich_mobile/widgets/common/immich_sliver_app_bar.dart'; @@ -333,7 +333,7 @@ class _QuickAccessButtonList extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final partnerSharedWithAsync = ref.watch(driftSharedWithPartnerProvider); - final partners = partnerSharedWithAsync.valueOrNull ?? []; + final partners = partnerSharedWithAsync.value ?? []; return SliverPadding( padding: const EdgeInsets.only(left: 16, top: 12, right: 16, bottom: 32), diff --git a/mobile/lib/presentation/pages/search/drift_search.page.dart b/mobile/lib/presentation/pages/search/drift_search.page.dart index 881daf9d38..92ded2e11d 100644 --- a/mobile/lib/presentation/pages/search/drift_search.page.dart +++ b/mobile/lib/presentation/pages/search/drift_search.page.dart @@ -639,7 +639,7 @@ class DriftSearchPage extends HookConsumerWidget { label: 'search_filter_location'.t(context: context), currentFilter: locationCurrentFilterWidget.value, ), - if (userPreferences.valueOrNull?.tagsEnabled ?? false) + if (userPreferences.value?.tagsEnabled ?? false) SearchFilterChip( icon: Icons.sell_outlined, onTap: showTagPicker, @@ -665,7 +665,7 @@ class DriftSearchPage extends HookConsumerWidget { label: 'search_filter_media_type'.t(context: context), currentFilter: mediaTypeCurrentFilterWidget.value, ), - if (userPreferences.valueOrNull?.ratingsEnabled ?? false) + if (userPreferences.value?.ratingsEnabled ?? false) SearchFilterChip( icon: Icons.star_outline_rounded, onTap: showStarRatingPicker, diff --git a/mobile/lib/presentation/pages/search/paginated_search.provider.dart b/mobile/lib/presentation/pages/search/paginated_search.provider.dart index f65ca6b909..79758caa04 100644 --- a/mobile/lib/presentation/pages/search/paginated_search.provider.dart +++ b/mobile/lib/presentation/pages/search/paginated_search.provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/services/search.service.dart'; import 'package:immich_mobile/models/search/search_filter.model.dart'; diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_details.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_details.widget.dart index dd5743a2d0..defb944547 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_details.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_details.widget.dart @@ -19,7 +19,7 @@ class AssetDetails extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final exifInfo = ref.watch(assetExifProvider(asset)).valueOrNull; + final exifInfo = ref.watch(assetExifProvider(asset)).value; return Container( constraints: BoxConstraints(minHeight: minHeight), diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart index dae6db568c..fc5e695768 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart @@ -2,9 +2,13 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; -class StackChildrenNotifier extends AutoDisposeFamilyAsyncNotifier, BaseAsset> { +class StackChildrenNotifier extends AsyncNotifier> { + final BaseAsset asset; + StackChildrenNotifier(this.asset); + @override - Future> build(BaseAsset asset) { + Future> build() { + final asset = this.asset; if (asset is! RemoteAsset || asset.stackId == null) { return Future.value(const []); } diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart index 3308ae8295..cda015c501 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart @@ -5,6 +5,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/misc.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/events.model.dart'; @@ -17,9 +18,9 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/download_statu import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_page.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_preloader.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.provider.dart'; -import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; -import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_top_app_bar.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_bottom_app_bar.widget.dart'; +import 'package:immich_mobile/presentation/widgets/asset_viewer/viewer_top_app_bar.widget.dart'; +import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; @@ -105,6 +106,7 @@ class _AssetViewerState extends ConsumerState { final asset = ref.read(assetViewerProvider).currentAsset; assert(asset != null, "Current asset should not be null when opening the AssetViewer"); + // ignore: invalid_use_of_protected_member if (asset != null) _stackChildrenKeepAlive = ref.read(stackChildrenNotifier(asset).notifier).ref.keepAlive(); _reloadSubscription = EventStream.shared.listen(_onEvent); @@ -161,6 +163,7 @@ class _AssetViewerState extends ConsumerState { _preloader.preload(index, context.sizeData); _handleCasting(); _stackChildrenKeepAlive?.close(); + // ignore: invalid_use_of_protected_member _stackChildrenKeepAlive = ref.read(stackChildrenNotifier(asset).notifier).ref.keepAlive(); } diff --git a/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart index 3770c5d32d..1572872051 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart @@ -43,7 +43,7 @@ class _ScopedMapTimeline extends StatelessWidget { } final users = ref.watch(mapStateProvider).withPartners - ? ref.watch(timelineUsersProvider).valueOrNull ?? [user.id] + ? ref.watch(timelineUsersProvider).value ?? [user.id] : [user.id]; final timelineService = ref diff --git a/mobile/lib/providers/activity.provider.dart b/mobile/lib/providers/activity.provider.dart index b2cdbcf18c..5ed52b1ac6 100644 --- a/mobile/lib/providers/activity.provider.dart +++ b/mobile/lib/providers/activity.provider.dart @@ -3,20 +3,19 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/models/activities/activity.model.dart'; import 'package:immich_mobile/providers/activity_service.provider.dart'; -// ignore: unintended_html_in_doc_comment -/// Maintains the current list of all activities for +/// Maintains the current list of all activities for [share-album-id, asset] final albumActivityProvider = AsyncNotifierProvider.autoDispose - .family, (String albumId, String? assetId)>(AlbumActivity.new); + .family, (String, String?)>(AlbumActivity.new); -class AlbumActivity extends AutoDisposeFamilyAsyncNotifier, (String albumId, String? assetId)> { - late String albumId; - late String? assetId; +class AlbumActivity extends AsyncNotifier> { + final String albumId; + final String? assetId; + + AlbumActivity((String albumId, String? assetId) args) : albumId = args.$1, assetId = args.$2; @override - Future> build((String albumId, String? assetId) args) async { - albumId = args.$1; - assetId = args.$2; + Future> build() async { return ref.watch(activityServiceProvider).getAllActivities(albumId, assetId: assetId); } @@ -57,7 +56,7 @@ class AlbumActivity extends AutoDisposeFamilyAsyncNotifier, (Stri } void _addToState(Activity activity) { - final activities = state.valueOrNull ?? []; + final activities = state.value ?? []; if (activities.any((a) => a.id == activity.id)) { return; } @@ -65,7 +64,7 @@ class AlbumActivity extends AutoDisposeFamilyAsyncNotifier, (Stri } Activity? _removeFromState(String id) { - final activities = state.valueOrNull; + final activities = state.value; if (activities == null) { return null; } diff --git a/mobile/lib/providers/album/album_title.provider.dart b/mobile/lib/providers/album/album_title.provider.dart index bf812a01d8..6055c93628 100644 --- a/mobile/lib/providers/album/album_title.provider.dart +++ b/mobile/lib/providers/album/album_title.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; class AlbumTitleNotifier extends StateNotifier { AlbumTitleNotifier() : super(""); diff --git a/mobile/lib/providers/album/current_album.provider.g.dart b/mobile/lib/providers/album/current_album.provider.g.dart deleted file mode 100644 index b6d079231f..0000000000 --- a/mobile/lib/providers/album/current_album.provider.g.dart +++ /dev/null @@ -1,26 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'current_album.provider.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$currentAlbumHash() => r'61f00273d6b69da45add1532cc3d3a076ee55110'; - -/// See also [CurrentAlbum]. -@ProviderFor(CurrentAlbum) -final currentAlbumProvider = - AutoDisposeNotifierProvider.internal( - CurrentAlbum.new, - name: r'currentAlbumProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$currentAlbumHash, - dependencies: null, - allTransitiveDependencies: null, - ); - -typedef _$CurrentAlbum = AutoDisposeNotifier; -// ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package diff --git a/mobile/lib/providers/app_life_cycle.provider.dart b/mobile/lib/providers/app_life_cycle.provider.dart index a5f67215a8..a72a1fd4b7 100644 --- a/mobile/lib/providers/app_life_cycle.provider.dart +++ b/mobile/lib/providers/app_life_cycle.provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; diff --git a/mobile/lib/providers/asset_viewer/asset_viewer.provider.dart b/mobile/lib/providers/asset_viewer/asset_viewer.provider.dart index 96ff5f704a..fbf4961910 100644 --- a/mobile/lib/providers/asset_viewer/asset_viewer.provider.dart +++ b/mobile/lib/providers/asset_viewer/asset_viewer.provider.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; @@ -67,24 +69,41 @@ class AssetViewerState { } class AssetViewerStateNotifier extends Notifier { + StreamSubscription? _assetSub; + String? _watchedHeroTag; + @override AssetViewerState build() { - ref.listen(_watchedCurrentAssetProvider, (_, next) { - final updated = next.valueOrNull; - if (updated != null) { - state = state.copyWith(currentAsset: updated); - } + ref.onDispose(() { + _assetSub?.cancel(); + _assetSub = null; + _watchedHeroTag = null; }); return const AssetViewerState(); } + void _syncAssetSubscription(BaseAsset? asset) { + final heroTag = asset?.heroTag; + if (heroTag == _watchedHeroTag) return; + _watchedHeroTag = heroTag; + _assetSub?.cancel(); + _assetSub = null; + if (asset == null) return; + _assetSub = ref.read(assetServiceProvider).watchAsset(asset).listen((updated) { + if (updated == null || updated.heroTag != _watchedHeroTag) return; + state = state.copyWith(currentAsset: updated); + }); + } + void reset() { state = const AssetViewerState(); + _syncAssetSubscription(null); } void setAsset(BaseAsset asset) { if (asset == state.currentAsset) return; state = state.copyWith(currentAsset: asset, stackIndex: 0); + _syncAssetSubscription(asset); } void setOpacity(double opacity) { @@ -134,10 +153,3 @@ class AssetViewerStateNotifier extends Notifier { } final assetViewerProvider = NotifierProvider(AssetViewerStateNotifier.new); - -final _watchedCurrentAssetProvider = StreamProvider((ref) { - ref.watch(assetViewerProvider.select((s) => s.currentAsset?.heroTag)); - final asset = ref.read(assetViewerProvider).currentAsset; - if (asset == null) return const Stream.empty(); - return ref.read(assetServiceProvider).watchAsset(asset); -}); diff --git a/mobile/lib/providers/asset_viewer/download.provider.dart b/mobile/lib/providers/asset_viewer/download.provider.dart index 25db76b077..98e568df1e 100644 --- a/mobile/lib/providers/asset_viewer/download.provider.dart +++ b/mobile/lib/providers/asset_viewer/download.provider.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'package:background_downloader/background_downloader.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/models/download/download_state.model.dart'; import 'package:immich_mobile/models/download/livephotos_medatada.model.dart'; import 'package:immich_mobile/services/download.service.dart'; diff --git a/mobile/lib/providers/asset_viewer/is_motion_video_playing.provider.dart b/mobile/lib/providers/asset_viewer/is_motion_video_playing.provider.dart index 08722dc896..0cb1661db5 100644 --- a/mobile/lib/providers/asset_viewer/is_motion_video_playing.provider.dart +++ b/mobile/lib/providers/asset_viewer/is_motion_video_playing.provider.dart @@ -1,4 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; /// Whether to display the video part of a motion photo final isPlayingMotionVideoProvider = StateNotifierProvider((ref) { diff --git a/mobile/lib/providers/asset_viewer/share_intent_upload.provider.dart b/mobile/lib/providers/asset_viewer/share_intent_upload.provider.dart index 66a8deb466..ec5a3e0b07 100644 --- a/mobile/lib/providers/asset_viewer/share_intent_upload.provider.dart +++ b/mobile/lib/providers/asset_viewer/share_intent_upload.provider.dart @@ -1,10 +1,10 @@ import 'dart:io'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/models/upload/share_intent_attachment.model.dart'; import 'package:immich_mobile/routing/router.dart'; -import 'package:immich_mobile/services/share_intent_service.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart'; +import 'package:immich_mobile/services/share_intent_service.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; diff --git a/mobile/lib/providers/asset_viewer/show_controls.provider.dart b/mobile/lib/providers/asset_viewer/show_controls.provider.dart index f2d11b4506..86809d8fb2 100644 --- a/mobile/lib/providers/asset_viewer/show_controls.provider.dart +++ b/mobile/lib/providers/asset_viewer/show_controls.provider.dart @@ -1,4 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; final showControlsProvider = StateNotifierProvider((ref) { return ShowControls(ref); diff --git a/mobile/lib/providers/asset_viewer/video_player_provider.dart b/mobile/lib/providers/asset_viewer/video_player_provider.dart index 8093926873..6452938982 100644 --- a/mobile/lib/providers/asset_viewer/video_player_provider.dart +++ b/mobile/lib/providers/asset_viewer/video_player_provider.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:logging/logging.dart'; import 'package:native_video_player/native_video_player.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; diff --git a/mobile/lib/providers/auth.provider.dart b/mobile/lib/providers/auth.provider.dart index 825d9e7bc8..0bee90fdbc 100644 --- a/mobile/lib/providers/auth.provider.dart +++ b/mobile/lib/providers/auth.provider.dart @@ -1,5 +1,6 @@ import 'package:flutter_udid/flutter_udid.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; @@ -11,9 +12,9 @@ import 'package:immich_mobile/providers/api.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/auth.service.dart'; +import 'package:immich_mobile/services/background_upload.service.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart'; import 'package:immich_mobile/services/secure_storage.service.dart'; -import 'package:immich_mobile/services/background_upload.service.dart'; import 'package:immich_mobile/services/widget.service.dart'; import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/hash.dart'; diff --git a/mobile/lib/providers/backup/asset_upload_progress.provider.dart b/mobile/lib/providers/backup/asset_upload_progress.provider.dart index 60936ef871..7b9dd639ae 100644 --- a/mobile/lib/providers/backup/asset_upload_progress.provider.dart +++ b/mobile/lib/providers/backup/asset_upload_progress.provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; /// Tracks per-asset upload progress. /// Key: local asset ID, Value: upload progress 0.0 to 1.0, or -1.0 for error diff --git a/mobile/lib/providers/backup/backup.provider.dart b/mobile/lib/providers/backup/backup.provider.dart index a6dc272313..d829d25e26 100644 --- a/mobile/lib/providers/backup/backup.provider.dart +++ b/mobile/lib/providers/backup/backup.provider.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/models/server_info/server_disk_info.model.dart'; import 'package:immich_mobile/services/server_info.service.dart'; diff --git a/mobile/lib/providers/backup/backup_album.provider.dart b/mobile/lib/providers/backup/backup_album.provider.dart index f81f905c2f..409e41edfc 100644 --- a/mobile/lib/providers/backup/backup_album.provider.dart +++ b/mobile/lib/providers/backup/backup_album.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/services/local_album.service.dart'; import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart'; diff --git a/mobile/lib/providers/backup/drift_backup.provider.dart b/mobile/lib/providers/backup/drift_backup.provider.dart index 4507747c7d..70b2ea1fe4 100644 --- a/mobile/lib/providers/backup/drift_backup.provider.dart +++ b/mobile/lib/providers/backup/drift_backup.provider.dart @@ -2,16 +2,16 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:logging/logging.dart'; - +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/utils/upload_speed_calculator.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; -import 'package:immich_mobile/services/foreground_upload.service.dart'; import 'package:immich_mobile/services/background_upload.service.dart'; +import 'package:immich_mobile/services/foreground_upload.service.dart'; +import 'package:immich_mobile/utils/upload_speed_calculator.dart'; +import 'package:logging/logging.dart'; class EnqueueStatus { final int enqueueCount; diff --git a/mobile/lib/providers/cast.provider.dart b/mobile/lib/providers/cast.provider.dart index b298514d67..b02677baf9 100644 --- a/mobile/lib/providers/cast.provider.dart +++ b/mobile/lib/providers/cast.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/models/cast/cast_manager_state.dart'; import 'package:immich_mobile/services/gcast.service.dart'; diff --git a/mobile/lib/providers/cleanup.provider.dart b/mobile/lib/providers/cleanup.provider.dart index 4d0bdba301..cc97384fa3 100644 --- a/mobile/lib/providers/cleanup.provider.dart +++ b/mobile/lib/providers/cleanup.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; diff --git a/mobile/lib/providers/folder.provider.dart b/mobile/lib/providers/folder.provider.dart index 816a88996e..7b338346d5 100644 --- a/mobile/lib/providers/folder.provider.dart +++ b/mobile/lib/providers/folder.provider.dart @@ -1,4 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/models/folder/root_folder.model.dart'; diff --git a/mobile/lib/providers/gallery_permission.provider.dart b/mobile/lib/providers/gallery_permission.provider.dart index 6e4fc69926..ed80ab04c2 100644 --- a/mobile/lib/providers/gallery_permission.provider.dart +++ b/mobile/lib/providers/gallery_permission.provider.dart @@ -1,7 +1,7 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:permission_handler/permission_handler.dart'; class GalleryPermissionNotifier extends StateNotifier { diff --git a/mobile/lib/providers/haptic_feedback.provider.dart b/mobile/lib/providers/haptic_feedback.provider.dart index 711c6fa4e2..5879e13808 100644 --- a/mobile/lib/providers/haptic_feedback.provider.dart +++ b/mobile/lib/providers/haptic_feedback.provider.dart @@ -1,5 +1,6 @@ import 'package:flutter/services.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; diff --git a/mobile/lib/providers/infrastructure/map.provider.dart b/mobile/lib/providers/infrastructure/map.provider.dart index d9d261521e..f4d218d417 100644 --- a/mobile/lib/providers/infrastructure/map.provider.dart +++ b/mobile/lib/providers/infrastructure/map.provider.dart @@ -16,7 +16,7 @@ final mapServiceProvider = Provider( } final users = ref.watch(mapStateProvider).withPartners - ? ref.watch(timelineUsersProvider).valueOrNull ?? [user.id] + ? ref.watch(timelineUsersProvider).value ?? [user.id] : [user.id]; final mapService = ref.watch(mapFactoryProvider).remote(users, ref.watch(mapStateProvider).toOptions()); diff --git a/mobile/lib/providers/infrastructure/timeline.provider.dart b/mobile/lib/providers/infrastructure/timeline.provider.dart index 06ec0242b2..d3df6ce697 100644 --- a/mobile/lib/providers/infrastructure/timeline.provider.dart +++ b/mobile/lib/providers/infrastructure/timeline.provider.dart @@ -16,7 +16,7 @@ final timelineArgsProvider = Provider.autoDispose( final timelineServiceProvider = Provider( (ref) { - final timelineUsers = ref.watch(timelineUsersProvider).valueOrNull ?? []; + final timelineUsers = ref.watch(timelineUsersProvider).value ?? []; final timelineService = ref.watch(timelineFactoryProvider).main(timelineUsers); ref.onDispose(timelineService.dispose); return timelineService; diff --git a/mobile/lib/providers/local_auth.provider.dart b/mobile/lib/providers/local_auth.provider.dart index 44fc5ad80c..0883930ebf 100644 --- a/mobile/lib/providers/local_auth.provider.dart +++ b/mobile/lib/providers/local_auth.provider.dart @@ -1,7 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/models/auth/biometric_status.model.dart'; diff --git a/mobile/lib/providers/multiselect.provider.dart b/mobile/lib/providers/multiselect.provider.dart index 22210e88c9..e4c4cafe92 100644 --- a/mobile/lib/providers/multiselect.provider.dart +++ b/mobile/lib/providers/multiselect.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; final multiselectProvider = StateProvider((ref) { return false; diff --git a/mobile/lib/providers/network.provider.dart b/mobile/lib/providers/network.provider.dart index cd91ff6d56..d55c9a761e 100644 --- a/mobile/lib/providers/network.provider.dart +++ b/mobile/lib/providers/network.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/services/network.service.dart'; final networkProvider = StateNotifierProvider((ref) { diff --git a/mobile/lib/providers/notification_permission.provider.dart b/mobile/lib/providers/notification_permission.provider.dart index da0badd4ec..0f3fa41df4 100644 --- a/mobile/lib/providers/notification_permission.provider.dart +++ b/mobile/lib/providers/notification_permission.provider.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:permission_handler/permission_handler.dart'; class NotificationPermissionNotifier extends StateNotifier { diff --git a/mobile/lib/providers/routes.provider.dart b/mobile/lib/providers/routes.provider.dart index c51f67bc0e..df6a9a26b1 100644 --- a/mobile/lib/providers/routes.provider.dart +++ b/mobile/lib/providers/routes.provider.dart @@ -1,5 +1,5 @@ import 'package:flutter/widgets.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; final inLockedViewProvider = StateProvider((ref) => false); final currentRouteNameProvider = StateProvider((ref) => null); diff --git a/mobile/lib/providers/secure_storage.provider.dart b/mobile/lib/providers/secure_storage.provider.dart index 39813d1027..836bb7d4a6 100644 --- a/mobile/lib/providers/secure_storage.provider.dart +++ b/mobile/lib/providers/secure_storage.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; final secureStorageProvider = StateNotifierProvider((ref) { return SecureStorageProvider(); diff --git a/mobile/lib/providers/server_info.provider.dart b/mobile/lib/providers/server_info.provider.dart index 98300894f9..cca98498bf 100644 --- a/mobile/lib/providers/server_info.provider.dart +++ b/mobile/lib/providers/server_info.provider.dart @@ -1,4 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/models/server_info/server_config.model.dart'; import 'package:immich_mobile/models/server_info/server_disk_info.model.dart'; diff --git a/mobile/lib/providers/shared_link.provider.dart b/mobile/lib/providers/shared_link.provider.dart index fb44aea203..72c19b4565 100644 --- a/mobile/lib/providers/shared_link.provider.dart +++ b/mobile/lib/providers/shared_link.provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/models/shared_link/shared_link.model.dart'; import 'package:immich_mobile/services/shared_link.service.dart'; diff --git a/mobile/lib/providers/tab.provider.dart b/mobile/lib/providers/tab.provider.dart index d523e72c38..f03df44922 100644 --- a/mobile/lib/providers/tab.provider.dart +++ b/mobile/lib/providers/tab.provider.dart @@ -1,4 +1,4 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; enum TabEnum { home, search, albums, library } diff --git a/mobile/lib/providers/theme.provider.dart b/mobile/lib/providers/theme.provider.dart index 1d5511f1ff..bb04def3b5 100644 --- a/mobile/lib/providers/theme.provider.dart +++ b/mobile/lib/providers/theme.provider.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; - +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/colors.dart'; -import 'package:immich_mobile/theme/color_scheme.dart'; -import 'package:immich_mobile/theme/theme_data.dart'; -import 'package:immich_mobile/theme/dynamic_theme.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; +import 'package:immich_mobile/theme/color_scheme.dart'; +import 'package:immich_mobile/theme/dynamic_theme.dart'; +import 'package:immich_mobile/theme/theme_data.dart'; import 'package:immich_mobile/utils/debug_print.dart'; final immichThemeModeProvider = StateProvider((ref) { diff --git a/mobile/lib/providers/upload_profile_image.provider.dart b/mobile/lib/providers/upload_profile_image.provider.dart index a2b7a23f05..897c232e60 100644 --- a/mobile/lib/providers/upload_profile_image.provider.dart +++ b/mobile/lib/providers/upload_profile_image.provider.dart @@ -1,6 +1,6 @@ import 'dart:convert'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:image_picker/image_picker.dart'; import 'package:immich_mobile/domain/services/user.service.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; diff --git a/mobile/lib/providers/user.provider.dart b/mobile/lib/providers/user.provider.dart index 5a56b65793..c7d4de4e81 100644 --- a/mobile/lib/providers/user.provider.dart +++ b/mobile/lib/providers/user.provider.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/user.model.dart'; import 'package:immich_mobile/domain/services/user.service.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; diff --git a/mobile/lib/providers/websocket.provider.dart b/mobile/lib/providers/websocket.provider.dart index 60afcec2d2..3efe9b1ac5 100644 --- a/mobile/lib/providers/websocket.provider.dart +++ b/mobile/lib/providers/websocket.provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; diff --git a/mobile/lib/services/deep_link.service.dart b/mobile/lib/services/deep_link.service.dart index 5ff0fa8a4d..255258b956 100644 --- a/mobile/lib/services/deep_link.service.dart +++ b/mobile/lib/services/deep_link.service.dart @@ -25,6 +25,7 @@ final deepLinkServiceProvider = Provider( ref.watch(driftPeopleServiceProvider), ref.watch(currentUserProvider), ), + dependencies: [remoteAlbumServiceProvider], ); class DeepLinkService { diff --git a/mobile/lib/widgets/asset_viewer/video_controls.dart b/mobile/lib/widgets/asset_viewer/video_controls.dart index 89b0f0ec30..3cd1ec7a34 100644 --- a/mobile/lib/widgets/asset_viewer/video_controls.dart +++ b/mobile/lib/widgets/asset_viewer/video_controls.dart @@ -3,12 +3,13 @@ import 'dart:math'; import 'package:async/async.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/legacy.dart'; import 'package:immich_mobile/constants/colors.dart'; +import 'package:immich_mobile/extensions/duration_extensions.dart'; import 'package:immich_mobile/models/cast/cast_manager_state.dart'; import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; -import 'package:immich_mobile/extensions/duration_extensions.dart'; import 'package:immich_mobile/widgets/asset_viewer/animated_play_pause.dart'; class VideoControls extends ConsumerStatefulWidget { @@ -25,7 +26,7 @@ class VideoControls extends ConsumerStatefulWidget { class _VideoControlsState extends ConsumerState { late final RestartableTimer _hideTimer; - AutoDisposeStateNotifierProvider get _provider => + StateNotifierProvider get _provider => videoPlayerProvider(widget.videoPlayerName); @override diff --git a/mobile/lib/widgets/settings/preference_settings/theme_setting.dart b/mobile/lib/widgets/settings/preference_settings/theme_setting.dart index fc20fb7bed..c7c464281d 100644 --- a/mobile/lib/widgets/settings/preference_settings/theme_setting.dart +++ b/mobile/lib/widgets/settings/preference_settings/theme_setting.dart @@ -5,10 +5,10 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/theme.provider.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; +import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart'; import 'package:immich_mobile/widgets/settings/preference_settings/primary_color_setting.dart'; import 'package:immich_mobile/widgets/settings/setting_group_title.dart'; import 'package:immich_mobile/widgets/settings/settings_switch_list_tile.dart'; -import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart'; class ThemeSetting extends HookConsumerWidget { const ThemeSetting({super.key}); @@ -21,7 +21,8 @@ class ThemeSetting extends HookConsumerWidget { final isSystemTheme = useValueNotifier(currentTheme.value == ThemeMode.system); final applyThemeToBackgroundSetting = useAppSettingsState(AppSettingsEnum.colorfulInterface); - final applyThemeToBackgroundProvider = useValueNotifier(ref.read(colorfulInterfaceSettingProvider)); + final isColorfulInterface = ref.read(colorfulInterfaceSettingProvider); + final applyThemeToBackgroundProvider = useValueNotifier(isColorfulInterface); useValueChanged( currentThemeString.value, diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 5f7aa3a928..451e58ec71 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "93.0.0" + analysis_server_plugin: + dependency: transitive + description: + name: analysis_server_plugin + sha256: "5f3920acbd5765764ec9ef6c5bbdd102015424281232ee4fb4f5431c87abb4eb" + url: "https://pub.dev" + source: hosted + version: "0.3.7" analyzer: dependency: transitive description: @@ -17,6 +25,22 @@ packages: url: "https://pub.dev" source: hosted version: "10.0.1" + analyzer_buffer: + dependency: transitive + description: + name: analyzer_buffer + sha256: "5fcd06b0715ebeee99f03e3f437b3412249969d8d12b191ea8a1d76e42a4e4a1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + analyzer_plugin: + dependency: transitive + description: + name: analyzer_plugin + sha256: "7df504f0c9d6891bacc9f73a5a8c5f6fe4fc49c90ec8e3379916372906ba0b32" + url: "https://pub.dev" + source: hosted + version: "0.14.1" ansicolor: dependency: transitive description: @@ -209,6 +233,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.4" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" cli_util: dependency: transitive description: @@ -273,6 +305,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + url: "https://pub.dev" + source: hosted + version: "1.15.0" crop_image: dependency: "direct main" description: @@ -557,10 +597,10 @@ packages: dependency: transitive description: name: flutter_riverpod - sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1" + sha256: "4e166be88e1dbbaa34a280bdb744aeae73b7ef25fdf8db7a3bb776760a3648e2" url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "3.3.1" flutter_secure_storage: dependency: "direct main" description: @@ -659,6 +699,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.2.14" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" + url: "https://pub.dev" + source: hosted + version: "3.1.0" frontend_server_client: dependency: transitive description: @@ -780,10 +828,10 @@ packages: dependency: "direct main" description: name: hooks_riverpod - sha256: "70bba33cfc5670c84b796e6929c54b8bc5be7d0fe15bb28c2560500b9ad06966" + sha256: "08527ec06aaef75e4b78694e045ef0cd8346594eaf9cc18b0f866398b07b93b1" url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "3.3.1" hotreloader: dependency: transitive description: @@ -1149,6 +1197,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" objective_c: dependency: transitive description: @@ -1433,10 +1489,28 @@ packages: dependency: transitive description: name: riverpod - sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959" + sha256: "8c22216be8ad3ef2b44af3a329693558c98eca7b8bd4ef495c92db0bba279f83" url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "3.2.1" + riverpod_analyzer_utils: + dependency: "direct overridden" + description: + path: "packages/riverpod_analyzer_utils" + ref: e8b84952e40b395ef47ab1f581eddddf64f0b2fd + resolved-ref: e8b84952e40b395ef47ab1f581eddddf64f0b2fd + url: "https://github.com/rrousselGit/riverpod/" + source: git + version: "1.0.0-dev.9" + riverpod_lint: + dependency: "direct dev" + description: + path: "packages/riverpod_lint" + ref: e8b84952e40b395ef47ab1f581eddddf64f0b2fd + resolved-ref: e8b84952e40b395ef47ab1f581eddddf64f0b2fd + url: "https://github.com/rrousselGit/riverpod/" + source: git + version: "3.1.3" scroll_date_picker: dependency: "direct main" description: @@ -1565,6 +1639,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" shelf_web_socket: dependency: transitive description: @@ -1611,6 +1701,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.2" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" source_span: dependency: transitive description: @@ -1707,6 +1813,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.2" + test: + dependency: transitive + description: + name: test + sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" + url: "https://pub.dev" + source: hosted + version: "1.30.0" test_api: dependency: transitive description: @@ -1715,6 +1829,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.10" + test_core: + dependency: transitive + description: + name: test_core + sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" + url: "https://pub.dev" + source: hosted + version: "0.6.16" thumbhash: dependency: "direct main" description: @@ -1923,6 +2045,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" win32: dependency: transitive description: @@ -1987,6 +2117,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.3" + yaml_edit: + dependency: transitive + description: + name: yaml_edit + sha256: "07c9e63ba42519745182b88ca12264a7ba2484d8239958778dfe4d44fe760488" + url: "https://pub.dev" + source: hosted + version: "2.2.4" sdks: dart: ">=3.11.0 <4.0.0" flutter: "3.41.9" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 8cb7eb17eb..0ff5870363 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -35,7 +35,7 @@ dependencies: fluttertoast: ^8.2.14 geolocator: ^14.0.2 home_widget: ^0.8.1 - hooks_riverpod: ^2.6.1 + hooks_riverpod: ^3.3.1 http: ^1.6.0 image_picker: ^1.2.1 immich_ui: @@ -91,10 +91,9 @@ dependencies: dev_dependencies: auto_route_generator: ^10.5.0 build_runner: ^2.13.1 - # Drift generator drift_dev: ^2.32.1 fake_async: ^1.3.3 - file: ^7.0.1 # for MemoryFileSystem + file: ^7.0.1 flutter_launcher_icons: ^0.14.4 flutter_lints: ^5.0.0 flutter_native_splash: ^2.4.7 @@ -103,13 +102,27 @@ dev_dependencies: integration_test: sdk: flutter mocktail: ^1.0.5 - # Type safe platform code pigeon: ^26.3.4 + riverpod_lint: ^3.1.3 -# cast 2.1.0 declares a loose bonsoir range but its code targets the 5.x API. -# Pin bonsoir to 5.x until cast releases a version compatible with bonsoir 6.x. dependency_overrides: + # cast 2.1.0 declares a loose bonsoir range but its code targets the 5.x API. + # Pin bonsoir to 5.x until cast releases a version compatible with bonsoir 6.x. bonsoir: ^5.1.11 + # the pub version has an outdated analyzer dependency, and the git version is not published to pub.dev + # use the git version until the pub version is updated + riverpod_lint: + git: + url: https://github.com/rrousselGit/riverpod/ + ref: 'e8b84952e40b395ef47ab1f581eddddf64f0b2fd' + path: packages/riverpod_lint/ + # transitive dependency of riverpod_lint, and the pub version is outdated + # remove the override when the pub version of riverpod_lint is updated + riverpod_analyzer_utils: + git: + url: https://github.com/rrousselGit/riverpod/ + ref: 'e8b84952e40b395ef47ab1f581eddddf64f0b2fd' + path: packages/riverpod_analyzer_utils/ flutter: uses-material-design: true diff --git a/mobile/test/modules/map/map_theme_override_test.dart b/mobile/test/modules/map/map_theme_override_test.dart index 56efde98dd..9f8223d011 100644 --- a/mobile/test/modules/map/map_theme_override_test.dart +++ b/mobile/test/modules/map/map_theme_override_test.dart @@ -7,6 +7,7 @@ import 'package:drift/native.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/misc.dart'; import 'package:immich_mobile/domain/services/store.service.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; @@ -54,7 +55,7 @@ void main() { mapStateNotifier.state = mapState.copyWith(darkStyleFetched: const AsyncData("dark")); await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "dark"); + expect(mapStyle?.value, "dark"); }); testWidgets("Return error when style is not fetched", (tester) async { @@ -88,7 +89,7 @@ void main() { mapStateNotifier.state = mapState.copyWith(themeMode: ThemeMode.light, lightStyleFetched: const AsyncData("light")); await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "light"); + expect(mapStyle?.value, "light"); }); group("System mode", () { @@ -111,7 +112,7 @@ void main() { ); await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "dark"); + expect(mapStyle?.value, "dark"); }); testWidgets("Return light theme style when system is light", (tester) async { @@ -133,7 +134,7 @@ void main() { ); await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "light"); + expect(mapStyle?.value, "light"); }); testWidgets("Switches style when system brightness changes", (tester) async { @@ -155,11 +156,11 @@ void main() { darkStyleFetched: const AsyncData("dark"), ); await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "light"); + expect(mapStyle?.value, "light"); tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark; await tester.pumpAndSettle(); - expect(mapStyle?.valueOrNull, "dark"); + expect(mapStyle?.value, "dark"); }); }); } diff --git a/mobile/test/widget_tester_extensions.dart b/mobile/test/widget_tester_extensions.dart index bb3fc3f418..b290ecd470 100644 --- a/mobile/test/widget_tester_extensions.dart +++ b/mobile/test/widget_tester_extensions.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:hooks_riverpod/misc.dart'; extension PumpConsumerWidget on WidgetTester { /// Wraps the provided [widget] with Material app such that it becomes: