diff --git a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart index e8a477deb..b7ce4f723 100644 --- a/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart +++ b/lib/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart @@ -44,8 +44,11 @@ class InteractiveviewerGallery extends StatefulWidget { this.onPageChanged, this.onDismissed, this.setStatusBar, + this.onClose, }); + final VoidCallback? onClose; + final bool? setStatusBar; /// The sources to show. @@ -222,6 +225,15 @@ class _InteractiveviewerGalleryState extends State ? '${widget.sources[index]}@${_quality}q.webp'.http2https : widget.sources[index].http2https; + void onClose() { + if (widget.onClose != null) { + widget.onClose!(); + } else { + Get.back(); + widget.onDismissed?.call(_pageController!.page!.floor()); + } + } + @override Widget build(BuildContext context) { return Stack( @@ -235,10 +247,7 @@ class _InteractiveviewerGalleryState extends State onNoBoundaryHit: _onNoBoundaryHit, maxScale: widget.maxScale, minScale: widget.minScale, - onDismissed: () { - Get.back(); - widget.onDismissed?.call(_pageController!.page!.floor()); - }, + onDismissed: onClose, onReset: () { if (!_enablePageView) { setState(() { @@ -255,7 +264,7 @@ class _InteractiveviewerGalleryState extends State itemBuilder: (BuildContext context, int index) { return GestureDetector( behavior: HitTestBehavior.opaque, - onTap: Get.back, + onTap: onClose, onDoubleTapDown: (TapDownDetails details) { _doubleTapLocalPosition = details.localPosition; }, @@ -301,10 +310,7 @@ class _InteractiveviewerGalleryState extends State children: [ IconButton( icon: const Icon(Icons.close, color: Colors.white), - onPressed: () { - Get.back(); - widget.onDismissed?.call(_pageController!.page!.floor()); - }, + onPressed: onClose, ), widget.sources.length > 1 ? Text( @@ -493,7 +499,7 @@ class _InteractiveviewerGalleryState extends State Get.back(); DownloadUtils.downloadImg( context, - widget.sources as List, + widget.sources, ); }, dense: true, diff --git a/lib/pages/dynamics/detail/view.dart b/lib/pages/dynamics/detail/view.dart index 0208fbdf7..15cff33e0 100644 --- a/lib/pages/dynamics/detail/view.dart +++ b/lib/pages/dynamics/detail/view.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:math'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; -import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'; import 'package:PiliPlus/common/widgets/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -61,17 +60,24 @@ class _DynamicDetailPageState extends State get _getImageCallback => _horizontalPreview ? (imgList, index) { - _key.currentState?.showBottomSheet( - (context) { - return InteractiveviewerGallery( - sources: imgList, - initIndex: index, - setStatusBar: false, - ); + final ctr = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 200), + )..forward(); + Utils.onHorizontalPreview( + _key, + AnimationController( + vsync: this, + duration: Duration.zero, + ), + ctr, + imgList, + index, + () async { + await ctr.reverse(); + ctr.dispose(); + Get.back(); }, - enableDrag: false, - elevation: 0, - backgroundColor: Colors.transparent, ); } : null; diff --git a/lib/pages/html/view.dart b/lib/pages/html/view.dart index 5cc1a8d34..89918c243 100644 --- a/lib/pages/html/view.dart +++ b/lib/pages/html/view.dart @@ -2,7 +2,6 @@ import 'dart:math'; import 'package:PiliPlus/common/widgets/article_content.dart'; import 'package:PiliPlus/common/widgets/http_error.dart'; -import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'; import 'package:PiliPlus/common/widgets/loading_widget.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/pages/video/detail/reply/widgets/reply_item.dart'; @@ -54,17 +53,24 @@ class _HtmlRenderPageState extends State get _getImageCallback => _horizontalPreview ? (imgList, index) { - _key.currentState?.showBottomSheet( - (context) { - return InteractiveviewerGallery( - sources: imgList, - initIndex: index, - setStatusBar: false, - ); + final ctr = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 200), + )..forward(); + Utils.onHorizontalPreview( + _key, + AnimationController( + vsync: this, + duration: Duration.zero, + ), + ctr, + imgList, + index, + () async { + await ctr.reverse(); + ctr.dispose(); + Get.back(); }, - enableDrag: false, - elevation: 0, - backgroundColor: Colors.transparent, ); } : null; diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index 801ae0233..5b6d14be2 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'; import 'package:PiliPlus/common/widgets/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/grpc/app/main/community/reply/v1/reply.pb.dart'; @@ -50,7 +49,8 @@ class VideoReplyReplyPanel extends StatefulWidget { State createState() => _VideoReplyReplyPanelState(); } -class _VideoReplyReplyPanelState extends State { +class _VideoReplyReplyPanelState extends State + with SingleTickerProviderStateMixin { late VideoReplyReplyController _videoReplyReplyController; late final _savedReplies = {}; late final itemPositionsListener = ItemPositionsListener.create(); @@ -280,17 +280,24 @@ class _VideoReplyReplyPanelState extends State { get _getImageCallback => _horizontalPreview ? (imgList, index) { - _key.currentState?.showBottomSheet( - (context) { - return InteractiveviewerGallery( - sources: imgList, - initIndex: index, - setStatusBar: false, - ); + final ctr = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 200), + )..forward(); + Utils.onHorizontalPreview( + _key, + AnimationController( + vsync: this, + duration: Duration.zero, + ), + ctr, + imgList, + index, + () async { + await ctr.reverse(); + ctr.dispose(); + Get.back(); }, - enableDrag: false, - elevation: 0, - backgroundColor: Colors.transparent, ); } : null; diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index b6a8f2966..f1cccb269 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -4,7 +4,6 @@ import 'dart:math'; import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/icon_button.dart'; -import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'; import 'package:PiliPlus/common/widgets/list_sheet.dart'; import 'package:PiliPlus/common/widgets/segment_progress_bar.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -1610,17 +1609,24 @@ class _VideoDetailPageState extends State onDismissed: videoDetailController.onDismissed, callback: _horizontalPreview ? (imgList, index) { - videoDetailController.childKey.currentState?.showBottomSheet( - (context) { - return InteractiveviewerGallery( - sources: imgList, - initIndex: index, - setStatusBar: false, - ); + final ctr = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 200), + )..forward(); + Utils.onHorizontalPreview( + videoDetailController.childKey, + AnimationController( + vsync: this, + duration: Duration.zero, + ), + ctr, + imgList, + index, + () async { + await ctr.reverse(); + ctr.dispose(); + Get.back(); }, - enableDrag: false, - elevation: 0, - backgroundColor: Colors.transparent, ); } : null, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 0257d5e22..f2bc864de 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:PiliPlus/build_config.dart'; +import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart'; import 'package:PiliPlus/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPlus/http/api.dart'; import 'package:PiliPlus/http/constants.dart'; @@ -40,6 +41,28 @@ class Utils { static const channel = MethodChannel("PiliPlus"); + static void onHorizontalPreview(GlobalKey key, + transitionAnimationController, ctr, imgList, index, onClose) { + key.currentState?.showBottomSheet( + (context) { + return FadeTransition( + opacity: Tween(begin: 0, end: 1).animate(ctr), + child: InteractiveviewerGallery( + sources: imgList, + initIndex: index, + setStatusBar: false, + onClose: onClose, + ), + ); + }, + enableDrag: false, + elevation: 0, + backgroundColor: Colors.transparent, + transitionAnimationController: transitionAnimationController, + sheetAnimationStyle: AnimationStyle(duration: Duration.zero), + ); + } + static void handleWebview(String url, {bool off = false}) { if (GStorage.openInBrowser) { launchURL(url);