mirror of
https://github.com/immich-app/immich.git
synced 2025-12-04 05:39:46 +09:00
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
191 lines
6.9 KiB
Dart
191 lines
6.9 KiB
Dart
import 'package:auto_route/auto_route.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:immich_mobile/domain/services/asset.service.dart' as beta_asset_service;
|
|
import 'package:immich_mobile/domain/services/memory.service.dart';
|
|
import 'package:immich_mobile/domain/services/remote_album.service.dart';
|
|
import 'package:immich_mobile/domain/services/timeline.service.dart';
|
|
import 'package:immich_mobile/entities/store.entity.dart';
|
|
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.page.dart';
|
|
import 'package:immich_mobile/providers/album/current_album.provider.dart';
|
|
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart' as beta_asset_provider;
|
|
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
|
import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart';
|
|
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
|
|
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
|
|
import 'package:immich_mobile/routing/router.dart';
|
|
import 'package:immich_mobile/services/album.service.dart';
|
|
import 'package:immich_mobile/services/asset.service.dart';
|
|
import 'package:immich_mobile/services/memory.service.dart';
|
|
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
|
|
|
|
final deepLinkServiceProvider = Provider(
|
|
(ref) => DeepLinkService(
|
|
ref.watch(memoryServiceProvider),
|
|
ref.watch(assetServiceProvider),
|
|
ref.watch(albumServiceProvider),
|
|
ref.watch(currentAssetProvider.notifier),
|
|
ref.watch(currentAlbumProvider.notifier),
|
|
// Below is used for beta timeline
|
|
ref.watch(timelineFactoryProvider),
|
|
ref.watch(beta_asset_provider.assetServiceProvider),
|
|
ref.watch(currentRemoteAlbumProvider.notifier),
|
|
ref.watch(remoteAlbumServiceProvider),
|
|
ref.watch(driftMemoryServiceProvider),
|
|
),
|
|
);
|
|
|
|
class DeepLinkService {
|
|
/// TODO: Remove this when beta is default
|
|
final MemoryService _memoryService;
|
|
final AssetService _assetService;
|
|
final AlbumService _albumService;
|
|
final CurrentAsset _currentAsset;
|
|
final CurrentAlbum _currentAlbum;
|
|
|
|
/// Used for beta timeline
|
|
final TimelineFactory _betaTimelineFactory;
|
|
final beta_asset_service.AssetService _betaAssetService;
|
|
final CurrentAlbumNotifier _betaCurrentAlbumNotifier;
|
|
final RemoteAlbumService _betaRemoteAlbumService;
|
|
final DriftMemoryService _betaMemoryServiceProvider;
|
|
|
|
const DeepLinkService(
|
|
this._memoryService,
|
|
this._assetService,
|
|
this._albumService,
|
|
this._currentAsset,
|
|
this._currentAlbum,
|
|
this._betaTimelineFactory,
|
|
this._betaAssetService,
|
|
this._betaCurrentAlbumNotifier,
|
|
this._betaRemoteAlbumService,
|
|
this._betaMemoryServiceProvider,
|
|
);
|
|
|
|
DeepLink _handleColdStart(PageRouteInfo<dynamic> route, bool isColdStart) {
|
|
return DeepLink([
|
|
// we need something to segue back to if the app was cold started
|
|
// TODO: use MainTimelineRoute this when beta is default
|
|
if (isColdStart) (Store.isBetaTimelineEnabled) ? const TabShellRoute() : const PhotosRoute(),
|
|
route,
|
|
]);
|
|
}
|
|
|
|
Future<DeepLink> handleScheme(PlatformDeepLink link, WidgetRef ref, bool isColdStart) async {
|
|
// get everything after the scheme, since Uri cannot parse path
|
|
final intent = link.uri.host;
|
|
final queryParams = link.uri.queryParameters;
|
|
|
|
PageRouteInfo<dynamic>? deepLinkRoute = switch (intent) {
|
|
"memory" => await _buildMemoryDeepLink(queryParams['id'] ?? ''),
|
|
"asset" => await _buildAssetDeepLink(queryParams['id'] ?? '', ref),
|
|
"album" => await _buildAlbumDeepLink(queryParams['id'] ?? ''),
|
|
_ => null,
|
|
};
|
|
|
|
// Deep link resolution failed, safely handle it based on the app state
|
|
if (deepLinkRoute == null) {
|
|
if (isColdStart) {
|
|
return DeepLink.defaultPath;
|
|
}
|
|
|
|
return DeepLink.none;
|
|
}
|
|
|
|
return _handleColdStart(deepLinkRoute, isColdStart);
|
|
}
|
|
|
|
Future<DeepLink> handleMyImmichApp(PlatformDeepLink link, WidgetRef ref, bool isColdStart) async {
|
|
final path = link.uri.path;
|
|
|
|
const uuidRegex = r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
|
|
final assetRegex = RegExp('/photos/($uuidRegex)');
|
|
final albumRegex = RegExp('/albums/($uuidRegex)');
|
|
|
|
PageRouteInfo<dynamic>? deepLinkRoute;
|
|
if (assetRegex.hasMatch(path)) {
|
|
final assetId = assetRegex.firstMatch(path)?.group(1) ?? '';
|
|
deepLinkRoute = await _buildAssetDeepLink(assetId, ref);
|
|
} else if (albumRegex.hasMatch(path)) {
|
|
final albumId = albumRegex.firstMatch(path)?.group(1) ?? '';
|
|
deepLinkRoute = await _buildAlbumDeepLink(albumId);
|
|
}
|
|
|
|
// Deep link resolution failed, safely handle it based on the app state
|
|
if (deepLinkRoute == null) {
|
|
if (isColdStart) return DeepLink.defaultPath;
|
|
return DeepLink.none;
|
|
}
|
|
|
|
return _handleColdStart(deepLinkRoute, isColdStart);
|
|
}
|
|
|
|
Future<PageRouteInfo?> _buildMemoryDeepLink(String memoryId) async {
|
|
if (Store.isBetaTimelineEnabled) {
|
|
final memory = await _betaMemoryServiceProvider.get(memoryId);
|
|
|
|
if (memory == null) {
|
|
return null;
|
|
}
|
|
|
|
return DriftMemoryRoute(memories: [memory], memoryIndex: 0);
|
|
} else {
|
|
// TODO: Remove this when beta is default
|
|
final memory = await _memoryService.getMemoryById(memoryId);
|
|
|
|
if (memory == null) {
|
|
return null;
|
|
}
|
|
|
|
return MemoryRoute(memories: [memory], memoryIndex: 0);
|
|
}
|
|
}
|
|
|
|
Future<PageRouteInfo?> _buildAssetDeepLink(String assetId, WidgetRef ref) async {
|
|
if (Store.isBetaTimelineEnabled) {
|
|
final asset = await _betaAssetService.getRemoteAsset(assetId);
|
|
if (asset == null) {
|
|
return null;
|
|
}
|
|
|
|
AssetViewer.setAsset(ref, asset);
|
|
return AssetViewerRoute(initialIndex: 0, timelineService: _betaTimelineFactory.fromAssets([asset]));
|
|
} else {
|
|
// TODO: Remove this when beta is default
|
|
final asset = await _assetService.getAssetByRemoteId(assetId);
|
|
if (asset == null) {
|
|
return null;
|
|
}
|
|
|
|
_currentAsset.set(asset);
|
|
final renderList = await RenderList.fromAssets([asset], GroupAssetsBy.auto);
|
|
|
|
return GalleryViewerRoute(renderList: renderList, initialIndex: 0, heroOffset: 0, showStack: true);
|
|
}
|
|
}
|
|
|
|
Future<PageRouteInfo?> _buildAlbumDeepLink(String albumId) async {
|
|
if (Store.isBetaTimelineEnabled) {
|
|
final album = await _betaRemoteAlbumService.get(albumId);
|
|
|
|
if (album == null) {
|
|
return null;
|
|
}
|
|
|
|
_betaCurrentAlbumNotifier.setAlbum(album);
|
|
return RemoteAlbumRoute(album: album);
|
|
} else {
|
|
// TODO: Remove this when beta is default
|
|
final album = await _albumService.getAlbumByRemoteId(albumId);
|
|
|
|
if (album == null) {
|
|
return null;
|
|
}
|
|
|
|
_currentAlbum.set(album);
|
|
return AlbumViewerRoute(albumId: album.id);
|
|
}
|
|
}
|
|
}
|