diff --git a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart index 5127728c31..8a9a5e8643 100644 --- a/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart +++ b/mobile/lib/modules/asset_viewer/views/gallery_viewer.dart @@ -123,7 +123,10 @@ class GalleryViewerPage extends HookConsumerWidget { /// Original (large) image of a local asset. Required asset.isLocal ImageProvider localImageProvider(Asset asset) { - return AssetEntityImageProvider(asset.local!); + return AssetEntityImageProvider( + isOriginal: true, + asset.local!, + ); } void precacheNextImage(int index) { @@ -385,8 +388,11 @@ class GalleryViewerPage extends HookConsumerWidget { onTapDown: (_, __, ___) => showAppBar.value = !showAppBar.value, imageProvider: provider, - heroAttributes: - PhotoViewHeroAttributes(tag: assetList[index].id), + heroAttributes: PhotoViewHeroAttributes( + tag: assetList[index].id, + ), + filterQuality: FilterQuality.high, + tightMode: true, minScale: PhotoViewComputedScale.contained, ); } else { @@ -394,8 +400,10 @@ class GalleryViewerPage extends HookConsumerWidget { onDragStart: (_, details, __) => localPosition = details.localPosition, onDragUpdate: (_, details, __) => handleSwipeUpDown(details), - heroAttributes: - PhotoViewHeroAttributes(tag: assetList[index].id), + heroAttributes: PhotoViewHeroAttributes( + tag: assetList[index].id, + ), + filterQuality: FilterQuality.high, maxScale: 1.0, minScale: 1.0, child: SafeArea( diff --git a/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart index ab7183d4dc..d5fe564203 100644 --- a/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart @@ -67,6 +67,31 @@ class ThumbnailImage extends HookConsumerWidget { HapticFeedback.heavyImpact(); }, child: Hero( + createRectTween: (begin, end) { + double? top; + // Uses the [BoxFit.contain] algorithm + if (asset.width != null && asset.height != null) { + final assetAR = asset.width! / asset.height!; + final w = MediaQuery.of(context).size.width; + final deviceAR = MediaQuery.of(context).size.aspectRatio; + if (deviceAR < assetAR) { + top = asset.height! * w / asset.width!; + } else { + top = 0; + } + // get the height offset + } + + return MaterialRectCenterArcTween( + begin: Rect.fromLTRB( + 0, + top ?? 0.0, + MediaQuery.of(context).size.width, + MediaQuery.of(context).size.height, + ), + end: end, + ); + }, tag: asset.id, child: Stack( children: [ diff --git a/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart b/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart index 6cbdb259c9..2b6dbda8ff 100644 --- a/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart +++ b/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart @@ -259,7 +259,6 @@ class _PhotoViewGalleryState extends State { controller: pageOption.controller, scaleStateController: pageOption.scaleStateController, customSize: widget.customSize, - heroAttributes: pageOption.heroAttributes, scaleStateChangedCallback: scaleStateChangedCallback, enableRotation: widget.enableRotation, initialScale: pageOption.initialScale, @@ -289,7 +288,6 @@ class _PhotoViewGalleryState extends State { scaleStateController: pageOption.scaleStateController, customSize: widget.customSize, gaplessPlayback: widget.gaplessPlayback, - heroAttributes: pageOption.heroAttributes, scaleStateChangedCallback: scaleStateChangedCallback, enableRotation: widget.enableRotation, initialScale: pageOption.initialScale, @@ -310,6 +308,19 @@ class _PhotoViewGalleryState extends State { errorBuilder: pageOption.errorBuilder, ); + if (pageOption.heroAttributes != null) { + return Hero( + tag: pageOption.heroAttributes!.tag, + createRectTween: pageOption.heroAttributes!.createRectTween, + flightShuttleBuilder: pageOption.heroAttributes!.flightShuttleBuilder, + placeholderBuilder: pageOption.heroAttributes!.placeholderBuilder, + transitionOnUserGestures: pageOption.heroAttributes!.transitionOnUserGestures, + child: ClipRect( + child: photoView, + ), + ); + } + return ClipRect( child: photoView, );