From 3053d84e49e2e0a8f7f54c51e5d236d1cdc2a8a2 Mon Sep 17 00:00:00 2001 From: Mert <101130780+mertalev@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:23:20 -0500 Subject: [PATCH] fix(mobile): not being able to zoom into live photos (#14608) fix live photo zoom --- .../lib/pages/common/gallery_viewer.page.dart | 6 ++-- .../common/native_video_viewer.page.dart | 35 +++---------------- .../asset_grid/immich_asset_grid_view.dart | 2 ++ 3 files changed, 10 insertions(+), 33 deletions(-) diff --git a/mobile/lib/pages/common/gallery_viewer.page.dart b/mobile/lib/pages/common/gallery_viewer.page.dart index 2ea446ea71..5f77f28d8e 100644 --- a/mobile/lib/pages/common/gallery_viewer.page.dart +++ b/mobile/lib/pages/common/gallery_viewer.page.dart @@ -61,6 +61,7 @@ class GalleryViewerPage extends HookConsumerWidget { final localPosition = useRef(null); final currentIndex = useValueNotifier(initialIndex); final loadAsset = renderList.loadAsset; + final isPlayingMotionVideo = ref.watch(isPlayingMotionVideoProvider); Future precacheNextImage(int index) async { if (!context.mounted) { @@ -249,7 +250,6 @@ class GalleryViewerPage extends HookConsumerWidget { } PhotoViewGalleryPageOptions buildAsset(BuildContext context, int index) { - ref.read(isPlayingMotionVideoProvider.notifier).playing = false; var newAsset = loadAsset(index); final stackId = newAsset.stackId; if (stackId != null && currentIndex.value == index) { @@ -260,7 +260,7 @@ class GalleryViewerPage extends HookConsumerWidget { } } - if (newAsset.isImage && !newAsset.isMotionPhoto) { + if (newAsset.isImage && !isPlayingMotionVideo) { return buildImage(context, newAsset); } return buildVideo(context, newAsset); @@ -275,7 +275,7 @@ class GalleryViewerPage extends HookConsumerWidget { body: Stack( children: [ PhotoViewGallery.builder( - key: const ValueKey('gallery'), + key: ValueKey(isPlayingMotionVideo), scaleStateChangedCallback: (state) { final asset = ref.read(currentAssetProvider); if (asset == null) { diff --git a/mobile/lib/pages/common/native_video_viewer.page.dart b/mobile/lib/pages/common/native_video_viewer.page.dart index 536c7f6303..33acad0fdf 100644 --- a/mobile/lib/pages/common/native_video_viewer.page.dart +++ b/mobile/lib/pages/common/native_video_viewer.page.dart @@ -40,7 +40,6 @@ class NativeVideoViewerPage extends HookConsumerWidget { final controller = useState(null); final lastVideoPosition = useRef(-1); final isBuffering = useRef(false); - final showMotionVideo = useState(false); // When a video is opened through the timeline, `isCurrent` will immediately be true. // When swiping from video A to video B, `isCurrent` will initially be true for video A and false for video B. @@ -50,30 +49,10 @@ class NativeVideoViewerPage extends HookConsumerWidget { final isCurrent = currentAsset.value == asset; // Used to show the placeholder during hero animations for remote videos to avoid a stutter - final isVisible = - useState((Platform.isIOS && asset.isLocal) || asset.isMotionPhoto); + final isVisible = useState(Platform.isIOS && asset.isLocal); final log = Logger('NativeVideoViewerPage'); - ref.listen(isPlayingMotionVideoProvider, (_, value) async { - final videoController = controller.value; - if (!asset.isMotionPhoto || videoController == null || !context.mounted) { - return; - } - - showMotionVideo.value = value; - try { - if (value) { - await videoController.seekTo(0); - await videoController.play(); - } else { - await videoController.pause(); - } - } catch (error) { - log.severe('Error toggling motion video: $error'); - } - }); - Future createSource() async { if (!context.mounted) { return null; @@ -81,7 +60,7 @@ class NativeVideoViewerPage extends HookConsumerWidget { try { final local = asset.local; - if (local != null && !asset.isMotionPhoto) { + if (local != null) { final file = await local.file; if (file == null) { throw Exception('No file found for the video'); @@ -204,9 +183,7 @@ class NativeVideoViewerPage extends HookConsumerWidget { ref.read(videoPlaybackValueProvider.notifier).value = videoPlayback; try { - if (asset.isVideo || showMotionVideo.value) { - await videoController.play(); - } + await videoController.play(); await videoController.setVolume(0.9); } catch (error) { log.severe('Error playing video: $error'); @@ -268,8 +245,7 @@ class NativeVideoViewerPage extends HookConsumerWidget { return; } - if (showMotionVideo.value && - videoController.playbackInfo?.status == PlaybackStatus.stopped && + if (videoController.playbackInfo?.status == PlaybackStatus.stopped && !ref .read(appSettingsServiceProvider) .getSetting(AppSettingsEnum.loopVideo)) { @@ -388,8 +364,7 @@ class NativeVideoViewerPage extends HookConsumerWidget { if (aspectRatio.value != null) Visibility.maintain( key: ValueKey(asset), - visible: - (asset.isVideo || showMotionVideo.value) && isVisible.value, + visible: isVisible.value, child: Center( key: ValueKey(asset), child: AspectRatio( diff --git a/mobile/lib/widgets/asset_grid/immich_asset_grid_view.dart b/mobile/lib/widgets/asset_grid/immich_asset_grid_view.dart index 5670aa388f..c38e61a473 100644 --- a/mobile/lib/widgets/asset_grid/immich_asset_grid_view.dart +++ b/mobile/lib/widgets/asset_grid/immich_asset_grid_view.dart @@ -13,6 +13,7 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart'; +import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart'; import 'package:immich_mobile/widgets/asset_grid/asset_drag_region.dart'; @@ -206,6 +207,7 @@ class ImmichAssetGridViewState extends ConsumerState { heroOffset: widget.heroOffset, onAssetTap: (asset) { ref.read(currentAssetProvider.notifier).set(asset); + ref.read(isPlayingMotionVideoProvider.notifier).playing = false; if (asset.isVideo) { ref.read(showControlsProvider.notifier).show = false; }