diff --git a/mobile/lib/constants/constants.dart b/mobile/lib/constants/constants.dart index 10f4e88f0..03acd6a54 100644 --- a/mobile/lib/constants/constants.dart +++ b/mobile/lib/constants/constants.dart @@ -53,3 +53,8 @@ const int kMinMonthsToEnableScrubberSnap = 12; const String kImmichAppStoreLink = "https://apps.apple.com/app/immich/id6449244941"; const String kImmichPlayStoreLink = "https://play.google.com/store/apps/details?id=app.alextran.immich"; const String kImmichLatestRelease = "https://github.com/immich-app/immich/releases/latest"; + +const int kPhotoTabIndex = 0; +const int kSearchTabIndex = 1; +const int kAlbumTabIndex = 2; +const int kLibraryTabIndex = 3; diff --git a/mobile/lib/pages/common/tab_shell.page.dart b/mobile/lib/pages/common/tab_shell.page.dart index c4bf19fe3..b04a379e4 100644 --- a/mobile/lib/pages/common/tab_shell.page.dart +++ b/mobile/lib/pages/common/tab_shell.page.dart @@ -4,6 +4,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/timeline.model.dart'; import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; @@ -13,6 +14,7 @@ import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/memory.provider.dart'; import 'package:immich_mobile/providers/infrastructure/people.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; +import 'package:immich_mobile/providers/routes.provider.dart'; import 'package:immich_mobile/providers/search/search_input_focus.provider.dart'; import 'package:immich_mobile/providers/tab.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; @@ -106,31 +108,33 @@ class _TabShellPageState extends ConsumerState { } void _onNavigationSelected(TabsRouter router, int index, WidgetRef ref) { + ref.read(currentTabIndexProvider.notifier).state = index; + // On Photos page menu tapped - if (router.activeIndex == 0 && index == 0) { + if (router.activeIndex == kPhotoTabIndex && index == kPhotoTabIndex) { EventStream.shared.emit(const ScrollToTopEvent()); } - if (index == 0) { + if (index == kPhotoTabIndex) { ref.invalidate(driftMemoryFutureProvider); } - if (router.activeIndex != 1 && index == 1) { + if (router.activeIndex != kSearchTabIndex && index == kSearchTabIndex) { ref.read(searchPreFilterProvider.notifier).clear(); } // On Search page tapped - if (router.activeIndex == 1 && index == 1) { + if (router.activeIndex == kSearchTabIndex && index == kSearchTabIndex) { ref.read(searchInputFocusProvider).requestFocus(); } // Album page - if (index == 2) { + if (index == kAlbumTabIndex) { ref.read(remoteAlbumProvider.notifier).refresh(); } // Library page - if (index == 3) { + if (index == kLibraryTabIndex) { ref.invalidate(localAlbumProvider); ref.invalidate(driftGetAllPeopleProvider); } diff --git a/mobile/lib/presentation/widgets/action_buttons/similar_photos_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/similar_photos_action_button.widget.dart index f9ba31e8b..acfeb131d 100644 --- a/mobile/lib/presentation/widgets/action_buttons/similar_photos_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/similar_photos_action_button.widget.dart @@ -3,12 +3,14 @@ import 'dart:async'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/models/search/search_filter.model.dart'; import 'package:immich_mobile/presentation/pages/search/paginated_search.provider.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/base_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; +import 'package:immich_mobile/providers/routes.provider.dart'; import 'package:immich_mobile/routing/router.dart'; class SimilarPhotosActionButton extends ConsumerWidget { @@ -35,7 +37,21 @@ class SimilarPhotosActionButton extends ConsumerWidget { mediaType: AssetType.image, ), ); - unawaited(context.router.popAndPush(const DriftSearchRoute())); + + /// Using and currentTabIndex to make sure we are using the correct + /// navigation behavior. We want to be able to navigate back to the + /// main timline using View In Timeline button without the need of + /// waiting for the timeline to be rebuild. At the same time, we want + /// to refresh the search page when tapping the Similar Photos button + /// while already in the Search tab. + final currentTabIndex = (ref.read(currentTabIndexProvider.notifier).state); + + if (currentTabIndex != kSearchTabIndex) { + unawaited(context.router.navigate(const DriftSearchRoute())); + ref.read(currentTabIndexProvider.notifier).state = kSearchTabIndex; + } else { + unawaited(context.router.popAndPush(const DriftSearchRoute())); + } } @override diff --git a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart index 5f1e7f27b..70dd15bf7 100644 --- a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart +++ b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart @@ -228,6 +228,8 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { curve: Curves.easeInOut, ) .whenComplete(() => ref.read(timelineStateProvider.notifier).setScrubbing(false)); + } else { + ref.read(timelineStateProvider.notifier).setScrubbing(false); } }); } diff --git a/mobile/lib/providers/routes.provider.dart b/mobile/lib/providers/routes.provider.dart index c51f67bc0..57b375d22 100644 --- a/mobile/lib/providers/routes.provider.dart +++ b/mobile/lib/providers/routes.provider.dart @@ -5,3 +5,4 @@ final inLockedViewProvider = StateProvider((ref) => false); final currentRouteNameProvider = StateProvider((ref) => null); final previousRouteNameProvider = StateProvider((ref) => null); final previousRouteDataProvider = StateProvider((ref) => null); +final currentTabIndexProvider = StateProvider((ref) => 0);