From a42c08ed8412438746f7ab42d28e09b265c79dd8 Mon Sep 17 00:00:00 2001 From: Thomas <9749173+uhthomas@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:46:38 +0000 Subject: [PATCH] fix(mobile): reset asset index on timeline refresh (#25729) The current asset changes when the timeline refreshes, which can be quite jarring. Assets are tracked by their index, and that index becomes stale when the timeline refreshes. This can be resolved by updating the index of asset based on a unique identifier (like the hero tag). --- .../lib/domain/services/timeline.service.dart | 7 +++++++ .../asset_viewer/asset_viewer.page.dart | 20 ++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mobile/lib/domain/services/timeline.service.dart b/mobile/lib/domain/services/timeline.service.dart index 61e114762..bd36d0b56 100644 --- a/mobile/lib/domain/services/timeline.service.dart +++ b/mobile/lib/domain/services/timeline.service.dart @@ -227,6 +227,13 @@ class TimelineService { return _buffer.elementAt(index - _bufferOffset); } + /// Finds the index of an asset by its heroTag within the current buffer. + /// Returns null if the asset is not found in the buffer. + int? getIndex(String heroTag) { + final index = _buffer.indexWhere((a) => a.heroTag == heroTag); + return index >= 0 ? _bufferOffset + index : null; + } + Future dispose() async { await _bucketSubscription?.cancel(); _bucketSubscription = null; 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 2be2bdf76..9129d998e 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_viewer.page.dart @@ -451,21 +451,31 @@ class _AssetViewerState extends ConsumerState { } void _onTimelineReloadEvent() { - totalAssets = ref.read(timelineServiceProvider).totalAssets; + final timelineService = ref.read(timelineServiceProvider); + totalAssets = timelineService.totalAssets; + if (totalAssets == 0) { context.maybePop(); return; } + var index = pageController.page?.round() ?? 0; + final currentAsset = ref.read(currentAssetNotifier); + if (currentAsset != null) { + final newIndex = timelineService.getIndex(currentAsset.heroTag); + if (newIndex != null && newIndex != index) { + index = newIndex; + pageController.jumpToPage(index); + } + } + if (assetReloadRequested) { assetReloadRequested = false; - _onAssetReloadEvent(); - return; + _onAssetReloadEvent(index); } } - void _onAssetReloadEvent() async { - final index = pageController.page?.round() ?? 0; + void _onAssetReloadEvent(int index) async { final timelineService = ref.read(timelineServiceProvider); final newAsset = await timelineService.getAssetAsync(index);