From e9b0840f01cdd97abf622c3520f03277e9b99158 Mon Sep 17 00:00:00 2001 From: X Date: Thu, 10 Aug 2023 21:38:49 +0800 Subject: [PATCH] fix(mobile): improve hero animation (#3636) --- .../home/ui/asset_grid/thumbnail_image.dart | 129 +++++++++--------- .../ui/photo_view/photo_view_gallery.dart | 17 +-- .../photo_view/src/core/photo_view_core.dart | 8 +- 3 files changed, 73 insertions(+), 81 deletions(-) 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 3ba07de3e3..ab06ff2e83 100644 --- a/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart +++ b/mobile/lib/modules/home/ui/asset_grid/thumbnail_image.dart @@ -62,11 +62,17 @@ class ThumbnailImage extends HookConsumerWidget { } Widget buildImage(Asset asset) { - var image = ImmichImage( - asset, + var image = SizedBox( width: 300, height: 300, - useGrayBoxPlaceholder: useGrayBoxPlaceholder, + child: Hero( + tag: asset.id + heroOffset, + child: ImmichImage( + asset, + useGrayBoxPlaceholder: useGrayBoxPlaceholder, + fit: BoxFit.cover, + ), + ), ); if (!multiselectEnabled || !isSelected) { return image; @@ -114,73 +120,70 @@ class ThumbnailImage extends HookConsumerWidget { onSelect?.call(); HapticFeedback.heavyImpact(); }, - child: Hero( - tag: asset.id + heroOffset, - child: Stack( - children: [ - Container( - decoration: BoxDecoration( - border: multiselectEnabled && isSelected - ? Border.all( - color: onDeselect == null - ? Colors.grey - : assetContainerColor, - width: 8, - ) - : const Border(), - ), - child: buildImage(asset), + child: Stack( + children: [ + Container( + decoration: BoxDecoration( + border: multiselectEnabled && isSelected + ? Border.all( + color: onDeselect == null + ? Colors.grey + : assetContainerColor, + width: 8, + ) + : const Border(), ), - if (multiselectEnabled) - Padding( - padding: const EdgeInsets.all(3.0), - child: Align( - alignment: Alignment.topLeft, - child: buildSelectionIcon(asset), - ), + child: buildImage(asset), + ), + if (multiselectEnabled) + Padding( + padding: const EdgeInsets.all(3.0), + child: Align( + alignment: Alignment.topLeft, + child: buildSelectionIcon(asset), ), - if (showStorageIndicator) - Positioned( - right: 10, - bottom: 5, - child: Icon( - storageIcon(asset), - color: Colors.white, - size: 18, - ), + ), + if (showStorageIndicator) + Positioned( + right: 10, + bottom: 5, + child: Icon( + storageIcon(asset), + color: Colors.white, + size: 18, ), - if (asset.isFavorite) - const Positioned( - left: 10, - bottom: 5, - child: Icon( - Icons.favorite, - color: Colors.white, - size: 18, - ), + ), + if (asset.isFavorite) + const Positioned( + left: 10, + bottom: 5, + child: Icon( + Icons.favorite, + color: Colors.white, + size: 18, ), - if (!asset.isImage) - Positioned( - top: 5, - right: 5, - child: Row( - children: [ - Text( - asset.duration.toString().substring(0, 7), - style: const TextStyle( - color: Colors.white, - fontSize: 10, - ), - ), - const Icon( - Icons.play_circle_outline_rounded, + ), + if (!asset.isImage) + Positioned( + top: 5, + right: 5, + child: Row( + children: [ + Text( + asset.duration.toString().substring(0, 7), + style: const TextStyle( color: Colors.white, + fontSize: 10, ), - ], - ), + ), + const Icon( + Icons.play_circle_outline_rounded, + color: Colors.white, + ), + ], ), - ], - ), + ), + ], ), ); } 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 2b6dbda8ff..9012131ca3 100644 --- a/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart +++ b/mobile/lib/shared/ui/photo_view/photo_view_gallery.dart @@ -25,7 +25,7 @@ typedef PhotoViewGalleryPageChangedCallback = void Function(int index); /// A type definition for a [Function] that defines a page in [PhotoViewGallery.build] typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function( - BuildContext context, + BuildContext context, int index, ); @@ -276,6 +276,7 @@ class _PhotoViewGalleryState extends State { filterQuality: pageOption.filterQuality, basePosition: pageOption.basePosition, disableGestures: pageOption.disableGestures, + heroAttributes: pageOption.heroAttributes, child: pageOption.child, ) : PhotoView( @@ -306,21 +307,9 @@ class _PhotoViewGalleryState extends State { basePosition: pageOption.basePosition, disableGestures: pageOption.disableGestures, errorBuilder: pageOption.errorBuilder, + heroAttributes: pageOption.heroAttributes, ); - 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, ); diff --git a/mobile/lib/shared/ui/photo_view/src/core/photo_view_core.dart b/mobile/lib/shared/ui/photo_view/src/core/photo_view_core.dart index 5728301482..7db770bd61 100644 --- a/mobile/lib/shared/ui/photo_view/src/core/photo_view_core.dart +++ b/mobile/lib/shared/ui/photo_view/src/core/photo_view_core.dart @@ -359,13 +359,13 @@ class PhotoViewCoreState extends State onScaleStart: onScaleStart, onScaleUpdate: onScaleUpdate, onScaleEnd: onScaleEnd, - onDragStart: widget.onDragStart != null + onDragStart: widget.onDragStart != null ? (details) => widget.onDragStart!(context, details, value) : null, - onDragEnd: widget.onDragEnd != null + onDragEnd: widget.onDragEnd != null ? (details) => widget.onDragEnd!(context, details, value) : null, - onDragUpdate: widget.onDragUpdate != null + onDragUpdate: widget.onDragUpdate != null ? (details) => widget.onDragUpdate!(context, details, value) : null, hitDetector: this, @@ -405,7 +405,7 @@ class PhotoViewCoreState extends State gaplessPlayback: widget.gaplessPlayback ?? false, filterQuality: widget.filterQuality, width: scaleBoundaries.childSize.width * scale, - fit: BoxFit.contain, + fit: BoxFit.cover, ); } }