opt: horizontal preview

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-12 11:54:31 +08:00
parent 130bf36115
commit 2fad0d38a7
6 changed files with 109 additions and 55 deletions

View File

@@ -44,8 +44,11 @@ class InteractiveviewerGallery<T> extends StatefulWidget {
this.onPageChanged, this.onPageChanged,
this.onDismissed, this.onDismissed,
this.setStatusBar, this.setStatusBar,
this.onClose,
}); });
final VoidCallback? onClose;
final bool? setStatusBar; final bool? setStatusBar;
/// The sources to show. /// The sources to show.
@@ -222,6 +225,15 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
? '${widget.sources[index]}@${_quality}q.webp'.http2https ? '${widget.sources[index]}@${_quality}q.webp'.http2https
: widget.sources[index].http2https; : widget.sources[index].http2https;
void onClose() {
if (widget.onClose != null) {
widget.onClose!();
} else {
Get.back();
widget.onDismissed?.call(_pageController!.page!.floor());
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Stack(
@@ -235,10 +247,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
onNoBoundaryHit: _onNoBoundaryHit, onNoBoundaryHit: _onNoBoundaryHit,
maxScale: widget.maxScale, maxScale: widget.maxScale,
minScale: widget.minScale, minScale: widget.minScale,
onDismissed: () { onDismissed: onClose,
Get.back();
widget.onDismissed?.call(_pageController!.page!.floor());
},
onReset: () { onReset: () {
if (!_enablePageView) { if (!_enablePageView) {
setState(() { setState(() {
@@ -255,7 +264,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return GestureDetector( return GestureDetector(
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
onTap: Get.back, onTap: onClose,
onDoubleTapDown: (TapDownDetails details) { onDoubleTapDown: (TapDownDetails details) {
_doubleTapLocalPosition = details.localPosition; _doubleTapLocalPosition = details.localPosition;
}, },
@@ -301,10 +310,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
children: [ children: [
IconButton( IconButton(
icon: const Icon(Icons.close, color: Colors.white), icon: const Icon(Icons.close, color: Colors.white),
onPressed: () { onPressed: onClose,
Get.back();
widget.onDismissed?.call(_pageController!.page!.floor());
},
), ),
widget.sources.length > 1 widget.sources.length > 1
? Text( ? Text(
@@ -493,7 +499,7 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
Get.back(); Get.back();
DownloadUtils.downloadImg( DownloadUtils.downloadImg(
context, context,
widget.sources as List<String>, widget.sources,
); );
}, },
dense: true, dense: true,

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; 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/loading_widget.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
@@ -61,17 +60,24 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
get _getImageCallback => _horizontalPreview get _getImageCallback => _horizontalPreview
? (imgList, index) { ? (imgList, index) {
_key.currentState?.showBottomSheet( final ctr = AnimationController(
(context) { vsync: this,
return InteractiveviewerGallery( duration: const Duration(milliseconds: 200),
sources: imgList, )..forward();
initIndex: index, Utils.onHorizontalPreview(
setStatusBar: false, _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; : null;

View File

@@ -2,7 +2,6 @@ import 'dart:math';
import 'package:PiliPlus/common/widgets/article_content.dart'; import 'package:PiliPlus/common/widgets/article_content.dart';
import 'package:PiliPlus/common/widgets/http_error.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/common/widgets/loading_widget.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/pages/video/detail/reply/widgets/reply_item.dart'; import 'package:PiliPlus/pages/video/detail/reply/widgets/reply_item.dart';
@@ -54,17 +53,24 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
get _getImageCallback => _horizontalPreview get _getImageCallback => _horizontalPreview
? (imgList, index) { ? (imgList, index) {
_key.currentState?.showBottomSheet( final ctr = AnimationController(
(context) { vsync: this,
return InteractiveviewerGallery( duration: const Duration(milliseconds: 200),
sources: imgList, )..forward();
initIndex: index, Utils.onHorizontalPreview(
setStatusBar: false, _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; : null;

View File

@@ -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/loading_widget.dart';
import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
import 'package:PiliPlus/grpc/app/main/community/reply/v1/reply.pb.dart'; import 'package:PiliPlus/grpc/app/main/community/reply/v1/reply.pb.dart';
@@ -50,7 +49,8 @@ class VideoReplyReplyPanel extends StatefulWidget {
State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState(); State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState();
} }
class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> { class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
with SingleTickerProviderStateMixin {
late VideoReplyReplyController _videoReplyReplyController; late VideoReplyReplyController _videoReplyReplyController;
late final _savedReplies = {}; late final _savedReplies = {};
late final itemPositionsListener = ItemPositionsListener.create(); late final itemPositionsListener = ItemPositionsListener.create();
@@ -280,17 +280,24 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
get _getImageCallback => _horizontalPreview get _getImageCallback => _horizontalPreview
? (imgList, index) { ? (imgList, index) {
_key.currentState?.showBottomSheet( final ctr = AnimationController(
(context) { vsync: this,
return InteractiveviewerGallery( duration: const Duration(milliseconds: 200),
sources: imgList, )..forward();
initIndex: index, Utils.onHorizontalPreview(
setStatusBar: false, _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; : null;

View File

@@ -4,7 +4,6 @@ import 'dart:math';
import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/icon_button.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/list_sheet.dart';
import 'package:PiliPlus/common/widgets/segment_progress_bar.dart'; import 'package:PiliPlus/common/widgets/segment_progress_bar.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
@@ -1610,17 +1609,24 @@ class _VideoDetailPageState extends State<VideoDetailPage>
onDismissed: videoDetailController.onDismissed, onDismissed: videoDetailController.onDismissed,
callback: _horizontalPreview callback: _horizontalPreview
? (imgList, index) { ? (imgList, index) {
videoDetailController.childKey.currentState?.showBottomSheet( final ctr = AnimationController(
(context) { vsync: this,
return InteractiveviewerGallery( duration: const Duration(milliseconds: 200),
sources: imgList, )..forward();
initIndex: index, Utils.onHorizontalPreview(
setStatusBar: false, 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, : null,

View File

@@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:PiliPlus/build_config.dart'; 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/grpc/app/main/community/reply/v1/reply.pb.dart';
import 'package:PiliPlus/http/api.dart'; import 'package:PiliPlus/http/api.dart';
import 'package:PiliPlus/http/constants.dart'; import 'package:PiliPlus/http/constants.dart';
@@ -40,6 +41,28 @@ class Utils {
static const channel = MethodChannel("PiliPlus"); static const channel = MethodChannel("PiliPlus");
static void onHorizontalPreview(GlobalKey<ScaffoldState> key,
transitionAnimationController, ctr, imgList, index, onClose) {
key.currentState?.showBottomSheet(
(context) {
return FadeTransition(
opacity: Tween<double>(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}) { static void handleWebview(String url, {bool off = false}) {
if (GStorage.openInBrowser) { if (GStorage.openInBrowser) {
launchURL(url); launchURL(url);