fix(mobile): prevent live photo from getting stuck during dismiss animation

This commit is contained in:
LeLunZ
2026-04-25 16:36:50 +02:00
parent 6b3e07dc52
commit 5271863291
@@ -48,6 +48,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
bool _showingDetails = false;
bool _isZoomed = false;
// Frozen during dismiss drag + settle to prevent widget tree swap mid-animation.
bool _frozenMotionPlaying = false;
bool _dismissSettling = false;
final _scrollController = SnapScrollController();
double _snapOffset = 0.0;
@@ -135,6 +138,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
> 0 => _DragIntent.dismiss,
_ => _DragIntent.none,
};
if (_dragIntent == _DragIntent.dismiss) {
_frozenMotionPlaying = ref.read(isPlayingMotionVideoProvider);
}
}
switch (_dragIntent) {
@@ -172,12 +178,18 @@ class _AssetPageState extends ConsumerState<AssetPage> {
context.maybePop();
return;
}
_viewController?.animateMultiple(
position: _initialPhotoViewState.position,
scale: _viewController?.initialScale ?? _initialPhotoViewState.scale,
rotation: _initialPhotoViewState.rotation,
);
_viewer.setOpacity(1.0);
_dismissSettling = true;
_viewController
?.animateMultiple(
position: _initialPhotoViewState.position,
scale: _viewController?.initialScale ?? _initialPhotoViewState.scale,
rotation: _initialPhotoViewState.rotation,
)
.whenComplete(() {
if (!mounted) return;
setState(() => _dismissSettling = false);
});
}
}
@@ -355,7 +367,10 @@ class _AssetPageState extends ConsumerState<AssetPage> {
final currentHeroTag = ref.watch(assetViewerProvider.select((s) => s.currentAsset?.heroTag));
_showingDetails = ref.watch(assetViewerProvider.select((s) => s.showingDetails));
final stackIndex = ref.watch(assetViewerProvider.select((s) => s.stackIndex));
final isPlayingMotionVideo = ref.watch(isPlayingMotionVideoProvider);
final liveMotionPlaying = ref.watch(isPlayingMotionVideoProvider);
final isPlayingMotionVideo = (_dragIntent == _DragIntent.dismiss || _dismissSettling)
? _frozenMotionPlaying
: liveMotionPlaying;
final asset = ref.read(timelineServiceProvider).getAssetSafe(widget.index);
if (asset == null) {