fix(mobile): deeplinking to asset view while viewer is already open (#19812)
Some checks are pending
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Docker / pre-job (push) Waiting to run
Docker / Re-Tag ML () (push) Blocked by required conditions
Docker / Re-Tag ML (-armnn) (push) Blocked by required conditions
Docker / Re-Tag ML (-cuda) (push) Blocked by required conditions
Docker / Re-Tag ML (-openvino) (push) Blocked by required conditions
Docker / Re-Tag ML (-rknn) (push) Blocked by required conditions
Docker / Re-Tag ML (-rocm) (push) Blocked by required conditions
Docker / Re-Tag Server () (push) Blocked by required conditions
Docker / Build and Push ML (armnn, linux/arm64, -armnn) (push) Blocked by required conditions
Docker / Build and Push ML (cpu, ) (push) Blocked by required conditions
Docker / Build and Push ML (cuda, linux/amd64, -cuda) (push) Blocked by required conditions
Docker / Build and Push ML (openvino, linux/amd64, -openvino) (push) Blocked by required conditions
Docker / Build and Push ML (rknn, linux/arm64, -rknn) (push) Blocked by required conditions
Docker / Build and Push ML (rocm, linux/amd64, {"linux/amd64": "mich"}, -rocm) (push) Blocked by required conditions
Docker / Build and Push Server (push) Blocked by required conditions
Docker / Docker Build & Push Server Success (push) Blocked by required conditions
Docker / Docker Build & Push ML Success (push) Blocked by required conditions
Docs build / pre-job (push) Waiting to run
Docs build / Docs Build (push) Blocked by required conditions
Static Code Analysis / pre-job (push) Waiting to run
Static Code Analysis / Run Dart Code Analysis (push) Blocked by required conditions
Static Code Analysis / zizmor (push) Waiting to run
Test / pre-job (push) Waiting to run
Test / Test & Lint Server (push) Blocked by required conditions
Test / Unit Test CLI (push) Blocked by required conditions
Test / Unit Test CLI (Windows) (push) Blocked by required conditions
Test / Lint Web (push) Blocked by required conditions
Test / Test Web (push) Blocked by required conditions
Test / Test i18n (push) Blocked by required conditions
Test / End-to-End Lint (push) Blocked by required conditions
Test / Medium Tests (Server) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Server & CLI) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-24.04-arm) (push) Blocked by required conditions
Test / End-to-End Tests (Web) (ubuntu-latest) (push) Blocked by required conditions
Test / End-to-End Tests Success (push) Blocked by required conditions
Test / Unit Test Mobile (push) Blocked by required conditions
Test / Unit Test ML (push) Blocked by required conditions
Test / .github Files Formatting (push) Blocked by required conditions
Test / ShellCheck (push) Waiting to run
Test / OpenAPI Clients (push) Waiting to run
Test / SQL Schema Checks (push) Waiting to run

* initial attempt at new guard

* do not resolve the route when replaced

* Update gallery_guard.dart comment

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
Brandon Wees
2025-07-08 10:50:59 -05:00
committed by GitHub
parent a556de67b0
commit d03eb87058
3 changed files with 35 additions and 2 deletions

View File

@@ -0,0 +1,31 @@
import 'package:auto_route/auto_route.dart';
import 'package:immich_mobile/routing/router.dart';
/// Handles duplicate navigation to this route (primarily for deep linking)
class GalleryGuard extends AutoRouteGuard {
const GalleryGuard();
@override
void onNavigation(NavigationResolver resolver, StackRouter router) async {
final newRouteName = resolver.route.name;
final currentTopRouteName =
router.stack.isNotEmpty ? router.stack.last.name : null;
if (currentTopRouteName == newRouteName) {
// Replace instead of pushing duplicate
final args = resolver.route.args as GalleryViewerRouteArgs;
router.replace(
GalleryViewerRoute(
renderList: args.renderList,
initialIndex: args.initialIndex,
heroOffset: args.heroOffset,
showStack: args.showStack,
),
);
// Prevent further navigation since we replaced the route
resolver.next(false);
return;
}
resolver.next(true);
}
}

View File

@@ -91,6 +91,7 @@ import 'package:immich_mobile/routing/auth_guard.dart';
import 'package:immich_mobile/routing/backup_permission_guard.dart'; import 'package:immich_mobile/routing/backup_permission_guard.dart';
import 'package:immich_mobile/routing/custom_transition_builders.dart'; import 'package:immich_mobile/routing/custom_transition_builders.dart';
import 'package:immich_mobile/routing/duplicate_guard.dart'; import 'package:immich_mobile/routing/duplicate_guard.dart';
import 'package:immich_mobile/routing/gallery_guard.dart';
import 'package:immich_mobile/routing/locked_guard.dart'; import 'package:immich_mobile/routing/locked_guard.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/local_auth.service.dart'; import 'package:immich_mobile/services/local_auth.service.dart';
@@ -116,6 +117,7 @@ class AppRouter extends RootStackRouter {
late final DuplicateGuard _duplicateGuard; late final DuplicateGuard _duplicateGuard;
late final BackupPermissionGuard _backupPermissionGuard; late final BackupPermissionGuard _backupPermissionGuard;
late final LockedGuard _lockedGuard; late final LockedGuard _lockedGuard;
late final GalleryGuard _galleryGuard;
AppRouter( AppRouter(
ApiService apiService, ApiService apiService,
@@ -128,6 +130,7 @@ class AppRouter extends RootStackRouter {
_lockedGuard = _lockedGuard =
LockedGuard(apiService, secureStorageService, localAuthService); LockedGuard(apiService, secureStorageService, localAuthService);
_backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier); _backupPermissionGuard = BackupPermissionGuard(galleryPermissionNotifier);
_galleryGuard = const GalleryGuard();
} }
@override @override
@@ -197,7 +200,7 @@ class AppRouter extends RootStackRouter {
), ),
CustomRoute( CustomRoute(
page: GalleryViewerRoute.page, page: GalleryViewerRoute.page,
guards: [_authGuard, _duplicateGuard], guards: [_authGuard, _galleryGuard],
transitionsBuilder: CustomTransitionsBuilders.zoomedPage, transitionsBuilder: CustomTransitionsBuilders.zoomedPage,
), ),
AutoRoute( AutoRoute(

View File

@@ -106,7 +106,6 @@ class DeepLinkService {
Future<PageRouteInfo?> _buildAssetDeepLink(String assetId) async { Future<PageRouteInfo?> _buildAssetDeepLink(String assetId) async {
final asset = await _assetService.getAssetByRemoteId(assetId); final asset = await _assetService.getAssetByRemoteId(assetId);
if (asset == null) { if (asset == null) {
return null; return null;
} }