diff --git a/lib/foundation/app_page_route.dart b/lib/foundation/app_page_route.dart index bbb8135..558cda1 100644 --- a/lib/foundation/app_page_route.dart +++ b/lib/foundation/app_page_route.dart @@ -19,6 +19,7 @@ class AppPageRoute extends PageRoute with _AppRouteTransitionMixin{ super.allowSnapshotting = true, super.barrierDismissible = false, this.enableIOSGesture = true, + this.iosFullScreenPopGesture = true, this.preventRebuild = true, }) { assert(opaque); @@ -48,6 +49,9 @@ class AppPageRoute extends PageRoute with _AppRouteTransitionMixin{ @override final bool enableIOSGesture; + @override + final bool iosFullScreenPopGesture; + @override final bool preventRebuild; } @@ -74,6 +78,8 @@ mixin _AppRouteTransitionMixin on PageRoute { bool get enableIOSGesture; + bool get iosFullScreenPopGesture; + bool get preventRebuild; Widget? _child; @@ -121,20 +127,22 @@ mixin _AppRouteTransitionMixin on PageRoute { builder = PredictiveBackPageTransitionsBuilder(); } else { builder = SlidePageTransitionBuilder(); - } + } - return builder.buildTransitions( + return builder.buildTransitions( this, context, animation, secondaryAnimation, - enableIOSGesture && App.isIOS - ? IOSBackGestureDetector( - gestureWidth: _kBackGestureWidth, - enabledCallback: () => _isPopGestureEnabled(this), - onStartPopGesture: () => _startPopGesture(this), - child: child) - : child); + enableIOSGesture && App.isIOS + ? IOSBackGestureDetector( + gestureWidth: _kBackGestureWidth, + enabledCallback: () => _isPopGestureEnabled(this), + onStartPopGesture: () => _startPopGesture(this), + fullScreen: iosFullScreenPopGesture, + child: child, + ) + : child); } IOSBackGestureController _startPopGesture(PageRoute route) { @@ -206,6 +214,7 @@ class IOSBackGestureDetector extends StatefulWidget { required this.child, required this.gestureWidth, required this.onStartPopGesture, + this.fullScreen = false, super.key}); final double gestureWidth; @@ -216,6 +225,8 @@ class IOSBackGestureDetector extends StatefulWidget { final Widget child; + final bool fullScreen; + @override State createState() => _IOSBackGestureDetectorState(); } @@ -247,20 +258,30 @@ class _IOSBackGestureDetectorState extends State { ? MediaQuery.of(context).padding.left : MediaQuery.of(context).padding.right; dragAreaWidth = max(dragAreaWidth, widget.gestureWidth); + final Widget gestureListener = widget.fullScreen + ? Positioned.fill( + child: Listener( + onPointerDown: _handlePointerDown, + behavior: HitTestBehavior.translucent, + ), + ) + : Positioned( + width: dragAreaWidth, + top: 0.0, + bottom: 0.0, + left: Directionality.of(context) == TextDirection.ltr ? 0.0 : null, + right: Directionality.of(context) == TextDirection.rtl ? 0.0 : null, + child: Listener( + onPointerDown: _handlePointerDown, + behavior: HitTestBehavior.translucent, + ), + ); + return Stack( fit: StackFit.passthrough, children: [ widget.child, - Positioned( - width: dragAreaWidth, - top: 0.0, - bottom: 0.0, - left: 0, - child: Listener( - onPointerDown: _handlePointerDown, - behavior: HitTestBehavior.translucent, - ), - ), + gestureListener, ], ); } @@ -314,30 +335,31 @@ class SlidePageTransitionBuilder extends PageTransitionsBuilder { Animation animation, Animation secondaryAnimation, Widget child) { + final Animation primaryAnimation = App.isIOS + ? animation + : CurvedAnimation(parent: animation, curve: Curves.ease); + final Animation secondaryCurve = App.isIOS + ? secondaryAnimation + : CurvedAnimation(parent: secondaryAnimation, curve: Curves.ease); + return SlideTransition( + position: Tween( + begin: const Offset(1, 0), + end: Offset.zero, + ).animate(primaryAnimation), + child: SlideTransition( position: Tween( - begin: const Offset(1, 0), - end: Offset.zero, - ).animate(CurvedAnimation( - parent: animation, - curve: Curves.ease, - )), - child: SlideTransition( - position: Tween( - begin: Offset.zero, - end: const Offset(-0.4, 0), - ).animate(CurvedAnimation( - parent: secondaryAnimation, - curve: Curves.ease, - )), - child: PhysicalModel( - color: Colors.transparent, - borderRadius: BorderRadius.zero, - clipBehavior: Clip.hardEdge, - elevation: 6, - child: Material(child: child,), - ), - ) + begin: Offset.zero, + end: const Offset(-0.4, 0), + ).animate(secondaryCurve), + child: PhysicalModel( + color: Colors.transparent, + borderRadius: BorderRadius.zero, + clipBehavior: Clip.hardEdge, + elevation: 6, + child: Material(child: child), + ), + ), ); } } diff --git a/lib/foundation/context.dart b/lib/foundation/context.dart index b8b1a58..4fd3198 100644 --- a/lib/foundation/context.dart +++ b/lib/foundation/context.dart @@ -14,14 +14,20 @@ extension Navigation on BuildContext { return Navigator.of(this).canPop(); } - Future to(Widget Function() builder) { - return Navigator.of(this) - .push(AppPageRoute(builder: (context) => builder())); + Future to(Widget Function() builder, + {bool enableIOSGesture = true, bool iosFullScreenGesture = true}) { + return Navigator.of(this).push(AppPageRoute( + builder: (context) => builder(), + enableIOSGesture: enableIOSGesture, + iosFullScreenPopGesture: iosFullScreenGesture)); } - Future toReplacement(Widget Function() builder) { - return Navigator.of(this) - .pushReplacement(AppPageRoute(builder: (context) => builder())); + Future toReplacement(Widget Function() builder, + {bool enableIOSGesture = true, bool iosFullScreenGesture = true}) { + return Navigator.of(this).pushReplacement(AppPageRoute( + builder: (context) => builder(), + enableIOSGesture: enableIOSGesture, + iosFullScreenPopGesture: iosFullScreenGesture)); } double get width => MediaQuery.of(this).size.width; diff --git a/lib/foundation/local.dart b/lib/foundation/local.dart index 1d21c61..ce4b2b0 100644 --- a/lib/foundation/local.dart +++ b/lib/foundation/local.dart @@ -154,6 +154,8 @@ class LocalComic with HistoryMixin implements Comic { author: subtitle, tags: tags, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ); } diff --git a/lib/pages/comic_details_page/actions.dart b/lib/pages/comic_details_page/actions.dart index 4360e08..ad59ebb 100644 --- a/lib/pages/comic_details_page/actions.dart +++ b/lib/pages/comic_details_page/actions.dart @@ -116,6 +116,8 @@ abstract mixin class _ComicPageActions { author: comic.findAuthor() ?? '', tags: comic.plainTags, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ) .then((_) { onReadEnd(); diff --git a/lib/pages/comic_details_page/comic_page.dart b/lib/pages/comic_details_page/comic_page.dart index 67708ba..2a453eb 100644 --- a/lib/pages/comic_details_page/comic_page.dart +++ b/lib/pages/comic_details_page/comic_page.dart @@ -236,7 +236,7 @@ class _ComicPageState extends LoadingState author: localComic.subTitle ?? '', tags: localComic.tags, ); - }); + }, enableIOSGesture: false, iosFullScreenGesture: false); App.mainNavigatorKey!.currentContext!.pop(); }); isFirst = false; diff --git a/lib/pages/favorites/local_favorites_page.dart b/lib/pages/favorites/local_favorites_page.dart index 3002158..6f4a702 100644 --- a/lib/pages/favorites/local_favorites_page.dart +++ b/lib/pages/favorites/local_favorites_page.dart @@ -521,7 +521,9 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { App.rootContext.to(() => ReaderWithLoading( id: c.id, sourceKey: c.sourceKey, - )); + ), + enableIOSGesture: false, + iosFullScreenGesture: false); }, ), ]), @@ -622,6 +624,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { id: c.id, sourceKey: c.sourceKey, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ); }, ), @@ -647,6 +651,8 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { id: c.id, sourceKey: c.sourceKey, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ); } }, diff --git a/lib/pages/image_favorites_page/image_favorites_item.dart b/lib/pages/image_favorites_page/image_favorites_item.dart index 120332b..a33e474 100644 --- a/lib/pages/image_favorites_page/image_favorites_item.dart +++ b/lib/pages/image_favorites_page/image_favorites_item.dart @@ -37,6 +37,8 @@ class _ImageFavoritesItemState extends State<_ImageFavoritesItem> { initialEp: ep, initialPage: page, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ); } diff --git a/lib/pages/image_favorites_page/image_favorites_photo_view.dart b/lib/pages/image_favorites_page/image_favorites_photo_view.dart index 51768e6..646857e 100644 --- a/lib/pages/image_favorites_page/image_favorites_photo_view.dart +++ b/lib/pages/image_favorites_page/image_favorites_photo_view.dart @@ -244,6 +244,8 @@ class _ImageFavoritesPhotoViewState extends State { initialEp: ep, initialPage: page, ), + enableIOSGesture: false, + iosFullScreenGesture: false, ); }, ), diff --git a/lib/pages/settings/settings_page.dart b/lib/pages/settings/settings_page.dart index 6adbfca..75884f0 100644 --- a/lib/pages/settings/settings_page.dart +++ b/lib/pages/settings/settings_page.dart @@ -252,9 +252,10 @@ class _SettingsPageState extends State implements PopEntry { if (!App.isIOS) { return; } - if (event.position.dx < 20) { - gestureRecognizer.addPointer(event); + if (currentPage == -1) { + return; } + gestureRecognizer.addPointer(event); } Widget buildLeft() {