From f38c7a4b7e8b08caa0f9d8e03ec87b0786dca09d Mon Sep 17 00:00:00 2001 From: martyfuhry Date: Sun, 5 Feb 2023 07:57:07 -0500 Subject: [PATCH] feat(mobile): Tap to enter immersive mode on gallery viewer (#1546) --- .../asset_viewer/views/gallery_viewer.dart | 21 ++++++++++++++----- .../asset_viewer/views/video_viewer_page.dart | 16 ++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart index 0a9097dd2d..be3d2c2c35 100644 --- a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart +++ b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart @@ -52,6 +52,7 @@ class GalleryViewerPage extends HookConsumerWidget { final showAppBar = useState(true); final indexOfAsset = useState(assetList.indexOf(asset)); final isPlayingMotionVideo = useState(false); + final isPlayingVideo = useState(false); late Offset localPosition; final authToken = 'Bearer ${box.get(accessTokenKey)}'; @@ -233,9 +234,13 @@ class GalleryViewerPage extends HookConsumerWidget { } buildAppBar() { + final show = (showAppBar.value || // onTap has the final say + (showAppBar.value && !isZoomed.value)) && + !isPlayingVideo.value; + return AnimatedOpacity( duration: const Duration(milliseconds: 100), - opacity: (showAppBar.value || !isZoomed.value) ? 1.0 : 0.0, + opacity: show ? 1.0 : 0.0, child: Container( color: Colors.black.withOpacity(0.4), child: TopControlAppBar( @@ -312,8 +317,14 @@ class GalleryViewerPage extends HookConsumerWidget { // Use the WEBP Thumbnail as a placeholder for the JPEG thumbnail to acheive // Three-Stage Loading (WEBP -> JPEG -> Original) final webPThumbnail = CachedNetworkImage( - imageUrl: getThumbnailUrl(asset), - cacheKey: getThumbnailCacheKey(asset), + imageUrl: getThumbnailUrl( + asset, + type: api.ThumbnailFormat.WEBP, + ), + cacheKey: getThumbnailCacheKey( + asset, + type: api.ThumbnailFormat.WEBP, + ), httpHeaders: {'Authorization': authToken}, progressIndicatorBuilder: (_, __, ___) => const Center( child: ImmichLoadingIndicator(), @@ -377,14 +388,14 @@ class GalleryViewerPage extends HookConsumerWidget { onDragStart: (_, details, __) => localPosition = details.localPosition, onDragUpdate: (_, details, __) => handleSwipeUpDown(details), - onTapDown: (_, __, ___) => - showAppBar.value = !showAppBar.value, heroAttributes: PhotoViewHeroAttributes(tag: assetList[index].id), maxScale: 1.0, minScale: 1.0, child: SafeArea( child: VideoViewerPage( + onPlaying: () => isPlayingVideo.value = true, + onPaused: () => isPlayingVideo.value = false, asset: assetList[index], isMotionVideo: isPlayingMotionVideo.value, onVideoEnded: () { diff --git a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart index adf2cfa324..0dfa7ea802 100644 --- a/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart +++ b/mobile/lib/modules/asset_viewer/views/video_viewer_page.dart @@ -17,12 +17,16 @@ class VideoViewerPage extends HookConsumerWidget { final Asset asset; final bool isMotionVideo; final VoidCallback onVideoEnded; + final VoidCallback? onPlaying; + final VoidCallback? onPaused; const VideoViewerPage({ Key? key, required this.asset, required this.isMotionVideo, required this.onVideoEnded, + this.onPlaying, + this.onPaused, }) : super(key: key); @override @@ -63,6 +67,8 @@ class VideoViewerPage extends HookConsumerWidget { jwtToken: jwtToken, isMotionVideo: isMotionVideo, onVideoEnded: onVideoEnded, + onPaused: onPaused, + onPlaying: onPlaying, ), if (downloadAssetStatus == DownloadAssetStatus.loading) const Center( @@ -89,6 +95,9 @@ class VideoThumbnailPlayer extends StatefulWidget { final bool isMotionVideo; final VoidCallback onVideoEnded; + final Function()? onPlaying; + final Function()? onPaused; + const VideoThumbnailPlayer({ Key? key, this.url, @@ -96,6 +105,8 @@ class VideoThumbnailPlayer extends StatefulWidget { this.file, required this.onVideoEnded, required this.isMotionVideo, + this.onPlaying, + this.onPaused, }) : super(key: key); @override @@ -112,6 +123,11 @@ class _VideoThumbnailPlayerState extends State { initializePlayer(); videoPlayerController.addListener(() { + if (videoPlayerController.value.isPlaying) { + widget.onPlaying?.call(); + } else if (!videoPlayerController.value.isPlaying) { + widget.onPaused?.call(); + } if (videoPlayerController.value.position == videoPlayerController.value.duration) { widget.onVideoEnded();