From f4804faf5293d86045d0ab4a25c27587806b7973 Mon Sep 17 00:00:00 2001 From: nyne Date: Tue, 11 Feb 2025 18:51:27 +0800 Subject: [PATCH] Improve reader gesture. Close #185 --- lib/pages/reader/gesture.dart | 7 +++++- lib/pages/reader/images.dart | 43 +++++++++++++++++++++++++++++++++-- lib/pages/reader/reader.dart | 3 +++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lib/pages/reader/gesture.dart b/lib/pages/reader/gesture.dart index 7c513fb..72f7dac 100644 --- a/lib/pages/reader/gesture.dart +++ b/lib/pages/reader/gesture.dart @@ -24,6 +24,8 @@ class _ReaderGestureDetectorState extends State<_ReaderGestureDetector> { int fingers = 0; + late _ReaderState reader; + @override void initState() { _tapGestureRecognizer = TapGestureRecognizer() @@ -33,6 +35,7 @@ class _ReaderGestureDetectorState extends State<_ReaderGestureDetector> { }; super.initState(); context.readerScaffold._gestureDetectorState = this; + reader = context.reader; } @override @@ -166,7 +169,9 @@ class _ReaderGestureDetectorState extends State<_ReaderGestureDetector> { } void onTap(Offset location) { - if (context.readerScaffold.isOpen) { + if (reader._imageViewController!.handleOnTap(location)) { + return; + } else if (context.readerScaffold.isOpen) { context.readerScaffold.openOrClose(); } else { if (appdata.settings['enableTapToTurnPages']) { diff --git a/lib/pages/reader/images.dart b/lib/pages/reader/images.dart index 5bb1212..63493c8 100644 --- a/lib/pages/reader/images.dart +++ b/lib/pages/reader/images.dart @@ -335,6 +335,11 @@ class _GalleryModeState extends State<_GalleryMode> } } } + + @override + bool handleOnTap(Offset location) { + return false; + } } const Set _kTouchLikeDeviceTypes = { @@ -366,6 +371,18 @@ class _ContinuousModeState extends State<_ContinuousMode> var fingers = 0; bool disableScroll = false; + /// Whether the user was scrolling the page. + /// The gesture detector has a delay to detect tap event. + /// To handle the tap event, we need to know if the user was scrolling before the delay. + bool delayedIsScrolling = false; + + void delayedSetIsScrolling(bool value) { + Future.delayed( + const Duration(milliseconds: 300), + () => delayedIsScrolling = value, + ); + } + @override void initState() { reader = context.reader; @@ -374,6 +391,12 @@ class _ContinuousModeState extends State<_ContinuousMode> super.initState(); } + @override + void dispose() { + itemPositionsListener.itemPositions.removeListener(onPositionChanged); + super.dispose(); + } + void onPositionChanged() { var page = itemPositionsListener.itemPositions.value.first.index; page = page.clamp(1, reader.maxPage); @@ -516,8 +539,14 @@ class _ContinuousModeState extends State<_ContinuousMode> child: widget, ); - widget = NotificationListener( + widget = NotificationListener( onNotification: (notification) { + if (notification is ScrollStartNotification) { + delayedSetIsScrolling(true); + } else if (notification is ScrollEndNotification) { + delayedSetIsScrolling(false); + } + var length = reader.maxChapter; if (!scrollController.hasClients) return false; if (scrollController.position.pixels <= @@ -592,7 +621,7 @@ class _ContinuousModeState extends State<_ContinuousMode> @override void handleLongPressDown(Offset location) { - if (!appdata.settings['enableLongPressToZoom']) { + if (!appdata.settings['enableLongPressToZoom'] || delayedIsScrolling) { return; } double target = photoViewController.getInitialScale!.call()! * 1.75; @@ -667,6 +696,16 @@ class _ContinuousModeState extends State<_ContinuousMode> ); } } + + @override + bool handleOnTap(Offset location) { + if (delayedIsScrolling) { + print('isScrolling'); + return true; + } + print('isNotScrolling'); + return false; + } } ImageProvider _createImageProviderFromKey( diff --git a/lib/pages/reader/reader.dart b/lib/pages/reader/reader.dart index e38407b..34db62a 100644 --- a/lib/pages/reader/reader.dart +++ b/lib/pages/reader/reader.dart @@ -430,4 +430,7 @@ abstract interface class _ImageViewController { void handleLongPressUp(Offset location); void handleKeyEvent(KeyEvent event); + + /// Returns true if the event is handled. + bool handleOnTap(Offset location); }