mirror of
https://github.com/immich-app/immich
synced 2026-08-29 13:15:45 +00:00
fix(mobile): prevent stale asset viewer state for view intents
This commit is contained in:
parent
45fdd20c41
commit
6cc8cdfa3e
3 changed files with 29 additions and 6 deletions
|
|
@ -23,6 +23,7 @@ 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';
|
||||
import 'package:immich_mobile/providers/view_intent/view_intent_current.provider.dart';
|
||||
import 'package:immich_mobile/widgets/photo_view/photo_view.dart';
|
||||
|
||||
@RoutePage()
|
||||
|
|
@ -89,6 +90,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
|
||||
StreamSubscription? _reloadSubscription;
|
||||
KeepAliveLink? _stackChildrenKeepAlive;
|
||||
bool _isDisposed = false;
|
||||
|
||||
void _onTapNavigate(int direction) {
|
||||
final page = _pageController.page?.toInt();
|
||||
|
|
@ -123,6 +125,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
_isDisposed = true;
|
||||
_pageController.dispose();
|
||||
_preloader.dispose();
|
||||
_reloadSubscription?.cancel();
|
||||
|
|
@ -203,6 +206,10 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
}
|
||||
|
||||
void _onEvent(Event event) {
|
||||
if (_isDisposed || !mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case TimelineReloadEvent():
|
||||
_onTimelineReloadEvent();
|
||||
|
|
@ -224,6 +231,10 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
}
|
||||
|
||||
void _onTimelineReloadEvent() {
|
||||
if (_isDisposed || !mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final timelineService = ref.read(timelineServiceProvider);
|
||||
final totalAssets = timelineService.totalAssets;
|
||||
|
||||
|
|
@ -239,7 +250,9 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
if (index != _currentPage) {
|
||||
_pageController.jumpToPage(index);
|
||||
_onAssetChanged(index);
|
||||
} else if (currentAsset != null && assetIndex == null && timelineService.origin != TimelineOrigin.deepLink) {
|
||||
} else if (currentAsset != null &&
|
||||
assetIndex == null &&
|
||||
!_shouldIgnoreMissingAssetOnTimelineReload(currentAsset, timelineService)) {
|
||||
_onAssetChanged(index);
|
||||
}
|
||||
|
||||
|
|
@ -250,6 +263,17 @@ class _AssetViewerState extends ConsumerState<AssetViewer> {
|
|||
}
|
||||
}
|
||||
|
||||
// A view intent can update currentAsset before the previous viewer route is
|
||||
// disposed. Do not let the old viewer's timeline reload restore its previous asset.
|
||||
bool _shouldIgnoreMissingAssetOnTimelineReload(BaseAsset currentAsset, TimelineService timelineService) {
|
||||
if (timelineService.origin == TimelineOrigin.deepLink) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final localAssetId = ref.read(viewIntentCurrentProvider)?.localAssetId;
|
||||
return localAssetId != null && currentAsset.localId == localAssetId;
|
||||
}
|
||||
|
||||
void _setSystemUIMode(bool controls, bool details) {
|
||||
final mode = !controls || (CurrentPlatform.isIOS && details)
|
||||
? SystemUiMode.immersiveSticky
|
||||
|
|
|
|||
|
|
@ -139,8 +139,8 @@ class AndroidViewIntentHandler implements ViewIntentHandler {
|
|||
if (asset.isVideo) {
|
||||
notifier.setControls(false);
|
||||
}
|
||||
notifier.setAsset(asset);
|
||||
_ref.read(viewIntentCurrentProvider.notifier).setPayload(attachment);
|
||||
notifier.setAsset(asset);
|
||||
|
||||
if (viewIntentFilePath != null) {
|
||||
_ref.read(viewIntentFilePathProvider.notifier).setPath(viewIntentFilePath);
|
||||
|
|
@ -150,9 +150,7 @@ class AndroidViewIntentHandler implements ViewIntentHandler {
|
|||
unawaited(_viewIntentService.cleanupManagedTempFile());
|
||||
}
|
||||
|
||||
await _router.replaceAll([
|
||||
const TabShellRoute(),
|
||||
AssetViewerRoute(initialIndex: 0, timelineService: timelineService),
|
||||
]);
|
||||
_router.popUntilRoot();
|
||||
await _router.push(AssetViewerRoute(initialIndex: 0, timelineService: timelineService));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ enum ActionButtonType {
|
|||
ActionButtonType.openInBrowser => context.asset.hasRemote && !context.isInLockedView,
|
||||
ActionButtonType.likeActivity =>
|
||||
!context.isInLockedView &&
|
||||
context.timelineOrigin != TimelineOrigin.deepLink &&
|
||||
context.currentAlbum != null &&
|
||||
context.currentAlbum!.isActivityEnabled &&
|
||||
context.currentAlbum!.isShared,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue