diff --git a/lib/foundation/app_page_route.dart b/lib/foundation/app_page_route.dart index 158ced5..b1a0bfd 100644 --- a/lib/foundation/app_page_route.dart +++ b/lib/foundation/app_page_route.dart @@ -20,7 +20,6 @@ class AppPageRoute extends PageRoute with _AppRouteTransitionMixin{ super.allowSnapshotting = true, super.barrierDismissible = false, this.enableIOSGesture = true, - this.iosFullScreenPopGesture = true, this.preventRebuild = true, }) { assert(opaque); @@ -50,9 +49,6 @@ class AppPageRoute extends PageRoute with _AppRouteTransitionMixin{ @override final bool enableIOSGesture; - @override - final bool iosFullScreenPopGesture; - @override final bool preventRebuild; } @@ -79,8 +75,6 @@ mixin _AppRouteTransitionMixin on PageRoute { bool get enableIOSGesture; - bool get iosFullScreenPopGesture; - bool get preventRebuild; Widget? _child; @@ -140,7 +134,6 @@ mixin _AppRouteTransitionMixin on PageRoute { gestureWidth: _kBackGestureWidth, enabledCallback: () => _isPopGestureEnabled(this), onStartPopGesture: () => _startPopGesture(this), - fullScreen: iosFullScreenPopGesture, child: child, ) : child); @@ -210,32 +203,41 @@ class IOSBackGestureController { } class IOSBackGestureDetector extends StatefulWidget { - const IOSBackGestureDetector( - {required this.enabledCallback, - required this.child, - required this.gestureWidth, - required this.onStartPopGesture, - this.fullScreen = false, - super.key}); + const IOSBackGestureDetector({ + required this.enabledCallback, + required this.child, + required this.gestureWidth, + required this.onStartPopGesture, + super.key, + }); final double gestureWidth; - final bool Function() enabledCallback; - final IOSBackGestureController Function() onStartPopGesture; - final Widget child; - final bool fullScreen; - @override State createState() => _IOSBackGestureDetectorState(); } class _IOSBackGestureDetectorState extends State { IOSBackGestureController? _backGestureController; + late _BackSwipeRecognizer _recognizer; - late HorizontalDragGestureRecognizer _recognizer; + + @override + void initState() { + super.initState(); + _recognizer = _BackSwipeRecognizer( + debugOwner: this, + gestureWidth: widget.gestureWidth, + isPointerInHorizontal: _isPointerInHorizontalScrollable, + onStart: _handleDragStart, + onUpdate: _handleDragUpdate, + onEnd: _handleDragEnd, + onCancel: _handleDragCancel, + ); + } @override void dispose() { @@ -243,115 +245,208 @@ class _IOSBackGestureDetectorState extends State { super.dispose(); } - @override - void initState() { - super.initState(); - _recognizer = HorizontalDragGestureRecognizer(debugOwner: this) - ..onStart = _handleDragStart - ..onUpdate = _handleDragUpdate - ..onEnd = _handleDragEnd - ..onCancel = _handleDragCancel; - } - @override Widget build(BuildContext context) { - var dragAreaWidth = Directionality.of(context) == TextDirection.ltr - ? 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, - gestureListener, - ], + return RawGestureDetector( + behavior: HitTestBehavior.translucent, + gestures: { + _BackSwipeRecognizer: GestureRecognizerFactoryWithHandlers<_BackSwipeRecognizer>( + () => _recognizer, + (instance) { + instance.gestureWidth = widget.gestureWidth; + }, + ), + }, + child: widget.child, ); } - void _handlePointerDown(PointerDownEvent event) { - if (!widget.enabledCallback()) return; - if (widget.fullScreen && _isPointerOverHorizontalScrollable(event)) { - return; - } - _recognizer.addPointer(event); - } - - void _handleDragCancel() { - assert(mounted); - _backGestureController?.dragEnd(0.0); - _backGestureController = null; - } - - double _convertToLogical(double value) { - switch (Directionality.of(context)) { - case TextDirection.rtl: - return -value; - case TextDirection.ltr: - return value; - } - } - - void _handleDragEnd(DragEndDetails details) { - assert(mounted); - assert(_backGestureController != null); - _backGestureController!.dragEnd(_convertToLogical( - details.velocity.pixelsPerSecond.dx / context.size!.width)); - _backGestureController = null; - } - - void _handleDragStart(DragStartDetails details) { - assert(mounted); - assert(_backGestureController == null); - _backGestureController = widget.onStartPopGesture(); - } - - void _handleDragUpdate(DragUpdateDetails details) { - assert(mounted); - assert(_backGestureController != null); - _backGestureController!.dragUpdate( - _convertToLogical(details.primaryDelta! / context.size!.width)); - } - - bool _isPointerOverHorizontalScrollable(PointerDownEvent event) { + bool _isPointerInHorizontalScrollable(Offset globalPosition) { final HitTestResult result = HitTestResult(); - WidgetsBinding.instance.hitTest(result, event.position); + WidgetsBinding.instance.hitTest(result, globalPosition); + for (final entry in result.path) { final target = entry.target; if (target is RenderViewport) { - if (_isAxisHorizontal(target.axisDirection)) { + if (target.axisDirection == AxisDirection.left || + target.axisDirection == AxisDirection.right) { return true; } - } else if (target is RenderSliver) { - if (_isAxisHorizontal(target.constraints.axisDirection)) { + } + else if (target is RenderSliver) { + if (target.constraints.axisDirection == AxisDirection.left || + target.constraints.axisDirection == AxisDirection.right) { return true; } } + else if (target.runtimeType.toString() == '_RenderSingleChildViewport') { + try { + final dynamic renderObject = target; + if (renderObject.axis == Axis.horizontal) { + return true; + } + } catch (e) { + // protected + } + } + else if (target is RenderEditable) { + return true; + } } return false; } - bool _isAxisHorizontal(AxisDirection direction) { - return direction == AxisDirection.left || direction == AxisDirection.right; + void _handleDragStart(DragStartDetails details) { + if (!widget.enabledCallback()) return; + if (mounted && _backGestureController == null) { + _backGestureController = widget.onStartPopGesture(); + } } + + void _handleDragUpdate(DragUpdateDetails details) { + if (mounted && _backGestureController != null) { + _backGestureController!.dragUpdate( + _convertToLogical(details.primaryDelta! / context.size!.width)); + } + } + + void _handleDragEnd(DragEndDetails details) { + if (mounted && _backGestureController != null) { + _backGestureController!.dragEnd(_convertToLogical( + details.velocity.pixelsPerSecond.dx / context.size!.width)); + _backGestureController = null; + } + } + + void _handleDragCancel() { + if (mounted && _backGestureController != null) { + _backGestureController?.dragEnd(0.0); + _backGestureController = null; + } + } + + double _convertToLogical(double value) { + switch (Directionality.of(context)) { + case TextDirection.rtl: return -value; + case TextDirection.ltr: return value; + } + } +} + +class _BackSwipeRecognizer extends OneSequenceGestureRecognizer { + _BackSwipeRecognizer({ + required this.isPointerInHorizontal, + required this.gestureWidth, + required this.onStart, + required this.onUpdate, + required this.onEnd, + required this.onCancel, + super.debugOwner, + }); + + final bool Function(Offset globalPosition) isPointerInHorizontal; + double gestureWidth; + final ValueSetter onStart; + final ValueSetter onUpdate; + final ValueSetter onEnd; + final VoidCallback onCancel; + + Offset? _startGlobal; + bool _accepted = false; + bool _startedInHorizontal = false; + bool _startedNearLeftEdge = false; + + VelocityTracker? _velocityTracker; + + static const double _minDistance = 5.0; + + @override + void addPointer(PointerDownEvent event) { + startTrackingPointer(event.pointer); + _startGlobal = event.position; + _accepted = false; + + _startedInHorizontal = isPointerInHorizontal(event.position); + _startedNearLeftEdge = event.position.dx <= gestureWidth; + + _velocityTracker = VelocityTracker.withKind(event.kind); + _velocityTracker?.addPosition(event.timeStamp, event.position); + } + + @override + void handleEvent(PointerEvent event) { + if (event is PointerMoveEvent || event is PointerUpEvent) { + _velocityTracker?.addPosition(event.timeStamp, event.position); + } + + if (event is PointerMoveEvent) { + if (_startGlobal == null) return; + final delta = event.position - _startGlobal!; + final dx = delta.dx; + final dy = delta.dy.abs(); + + if (!_accepted) { + if (delta.distance < _minDistance) return; + + final isRight = dx > 0; + final isHorizontal = dx.abs() > dy * 1.5; + final bool eligible = _startedNearLeftEdge || (!_startedInHorizontal); + + if (isRight && isHorizontal && eligible) { + _accepted = true; + resolve(GestureDisposition.accepted); + onStart(DragStartDetails( + globalPosition: _startGlobal!, + localPosition: event.localPosition + )); + } else { + resolve(GestureDisposition.rejected); + stopTrackingPointer(event.pointer); + _startGlobal = null; + _velocityTracker = null; + } + } + + if (_accepted) { + onUpdate(DragUpdateDetails( + globalPosition: event.position, + localPosition: event.localPosition, + primaryDelta: event.delta.dx, + delta: event.delta, + )); + } + } else if (event is PointerUpEvent) { + if (_accepted) { + final Velocity velocity = _velocityTracker?.getVelocity() ?? Velocity.zero; + + onEnd(DragEndDetails( + velocity: velocity, + primaryVelocity: velocity.pixelsPerSecond.dx + )); + } + _reset(); + } else if (event is PointerCancelEvent) { + if (_accepted) { + onCancel(); + } + _reset(); + } + } + + void _reset() { + stopTrackingPointer(0); + _accepted = false; + _startGlobal = null; + _startedInHorizontal = false; + _startedNearLeftEdge = false; + _velocityTracker = null; + } + + @override + String get debugDescription => 'IOSBackSwipe'; + + @override + void didStopTrackingLastPointer(int pointer) {} } class SlidePageTransitionBuilder extends PageTransitionsBuilder { @@ -389,4 +484,4 @@ class SlidePageTransitionBuilder extends PageTransitionsBuilder { ), ); } -} +} \ No newline at end of file diff --git a/lib/foundation/comic_source/models.dart b/lib/foundation/comic_source/models.dart index c430090..ae9f848 100644 --- a/lib/foundation/comic_source/models.dart +++ b/lib/foundation/comic_source/models.dart @@ -541,8 +541,7 @@ class PageJumpTarget { text: attributes?["text"] ?? attributes?["keyword"] ?? "", sourceKey: sourceKey, options: List.from(attributes?["options"] ?? []), - ), - iosFullScreenGesture: false, + ) ); } else if (page == "category") { var key = ComicSource.find(sourceKey)!.categoryData!.key; diff --git a/lib/foundation/context.dart b/lib/foundation/context.dart index 4fd3198..3174167 100644 --- a/lib/foundation/context.dart +++ b/lib/foundation/context.dart @@ -14,20 +14,14 @@ extension Navigation on BuildContext { return Navigator.of(this).canPop(); } - Future to(Widget Function() builder, - {bool enableIOSGesture = true, bool iosFullScreenGesture = true}) { + Future to(Widget Function() builder,) { return Navigator.of(this).push(AppPageRoute( - builder: (context) => builder(), - enableIOSGesture: enableIOSGesture, - iosFullScreenPopGesture: iosFullScreenGesture)); + builder: (context) => builder())); } - Future toReplacement(Widget Function() builder, - {bool enableIOSGesture = true, bool iosFullScreenGesture = true}) { + Future toReplacement(Widget Function() builder) { return Navigator.of(this).pushReplacement(AppPageRoute( - builder: (context) => builder(), - enableIOSGesture: enableIOSGesture, - iosFullScreenPopGesture: iosFullScreenGesture)); + builder: (context) => builder())); } double get width => MediaQuery.of(this).size.width; diff --git a/lib/foundation/local.dart b/lib/foundation/local.dart index ce4b2b0..4411c41 100644 --- a/lib/foundation/local.dart +++ b/lib/foundation/local.dart @@ -153,9 +153,7 @@ class LocalComic with HistoryMixin implements Comic { ), author: subtitle, tags: tags, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); } diff --git a/lib/pages/aggregated_search_page.dart b/lib/pages/aggregated_search_page.dart index a5b2db2..75f66e2 100644 --- a/lib/pages/aggregated_search_page.dart +++ b/lib/pages/aggregated_search_page.dart @@ -170,7 +170,6 @@ class _SliverSearchResultState extends State<_SliverSearchResult> text: widget.keyword, sourceKey: widget.source.key, ), - iosFullScreenGesture: false, ); }, child: Column( diff --git a/lib/pages/comic_details_page/actions.dart b/lib/pages/comic_details_page/actions.dart index ad59ebb..ba76414 100644 --- a/lib/pages/comic_details_page/actions.dart +++ b/lib/pages/comic_details_page/actions.dart @@ -115,9 +115,7 @@ abstract mixin class _ComicPageActions { history: history ?? History.fromModel(model: comic, ep: 0, page: 0), 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 2a453eb..67708ba 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/comic_source_page.dart b/lib/pages/comic_source_page.dart index e136825..80af04a 100644 --- a/lib/pages/comic_source_page.dart +++ b/lib/pages/comic_source_page.dart @@ -200,7 +200,6 @@ class _BodyState extends State<_Body> { await ComicSourceManager().reload(); setState(() {}); }), - iosFullScreenGesture: false, ); } diff --git a/lib/pages/favorites/local_favorites_page.dart b/lib/pages/favorites/local_favorites_page.dart index 3a4cdfb..fc09ea7 100644 --- a/lib/pages/favorites/local_favorites_page.dart +++ b/lib/pages/favorites/local_favorites_page.dart @@ -574,9 +574,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { App.rootContext.to(() => ReaderWithLoading( id: c.id, sourceKey: c.sourceKey, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); }, ), @@ -589,9 +587,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { App.mainNavigatorKey?.currentContext?.to(() => ComicPage( id: c.id, sourceKey: c.sourceKey, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); }, ), @@ -693,9 +689,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { () => ReaderWithLoading( id: c.id, sourceKey: c.sourceKey, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); }, ), @@ -720,9 +714,7 @@ class _LocalFavoritesPageState extends State<_LocalFavoritesPage> { cover: c.cover, title: c.title, heroID: heroID, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); } else { App.mainNavigatorKey?.currentContext?.to( diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index c5be1fd..656bfdd 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -895,8 +895,7 @@ class _ImageFavoritesState extends State { borderRadius: BorderRadius.circular(8), onTap: () { context.to( - () => const ImageFavoritesPage(), - iosFullScreenGesture: false, + () => const ImageFavoritesPage() ); }, child: Column( @@ -1018,7 +1017,6 @@ class _ImageFavoritesState extends State { onTap: (text) { context.to( () => ImageFavoritesPage(initialKeyword: text), - 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 a33e474..120332b 100644 --- a/lib/pages/image_favorites_page/image_favorites_item.dart +++ b/lib/pages/image_favorites_page/image_favorites_item.dart @@ -37,8 +37,6 @@ 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 646857e..c68a269 100644 --- a/lib/pages/image_favorites_page/image_favorites_photo_view.dart +++ b/lib/pages/image_favorites_page/image_favorites_photo_view.dart @@ -243,9 +243,7 @@ class _ImageFavoritesPhotoViewState extends State { sourceKey: comic.sourceKey, initialEp: ep, initialPage: page, - ), - enableIOSGesture: false, - iosFullScreenGesture: false, + ) ); }, ), diff --git a/lib/pages/search_page.dart b/lib/pages/search_page.dart index 0a38336..f7273ce 100644 --- a/lib/pages/search_page.dart +++ b/lib/pages/search_page.dart @@ -50,8 +50,7 @@ class _SearchPageState extends State { if (aggregatedSearch) { context .to( - () => AggregatedSearchPage(keyword: text ?? controller.text), - iosFullScreenGesture: false, + () => AggregatedSearchPage(keyword: text ?? controller.text) ) .then((_) => update()); } else { @@ -61,8 +60,7 @@ class _SearchPageState extends State { text: text ?? controller.text, sourceKey: searchTarget, options: options, - ), - iosFullScreenGesture: false, + ) ) .then((_) => update()); } diff --git a/lib/pages/settings/reader.dart b/lib/pages/settings/reader.dart index e862c12..9fd8688 100644 --- a/lib/pages/settings/reader.dart +++ b/lib/pages/settings/reader.dart @@ -282,7 +282,7 @@ class _ReaderSettingsState extends State { ).toSliver(), _CallbackSetting( title: "Custom Image Processing".tl, - callback: () => context.to(() => _CustomImageProcessing(), iosFullScreenGesture: false), + callback: () => context.to(() => _CustomImageProcessing()), actionTitle: "Edit".tl, ).toSliver(), _SliderSetting( diff --git a/lib/pages/settings/settings_page.dart b/lib/pages/settings/settings_page.dart index 75884f0..eaa3e23 100644 --- a/lib/pages/settings/settings_page.dart +++ b/lib/pages/settings/settings_page.dart @@ -1,6 +1,5 @@ import 'dart:convert'; import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart'; @@ -41,7 +40,7 @@ class SettingsPage extends StatefulWidget { State createState() => _SettingsPageState(); } -class _SettingsPageState extends State implements PopEntry { +class _SettingsPageState extends State { int currentPage = -1; ColorScheme get colors => Theme.of(context).colorScheme; @@ -70,84 +69,14 @@ class _SettingsPageState extends State implements PopEntry { Icons.bug_report, ]; - double offset = 0; - - late final HorizontalDragGestureRecognizer gestureRecognizer; - - ModalRoute? _route; - - @override - void didChangeDependencies() { - super.didChangeDependencies(); - final ModalRoute? nextRoute = ModalRoute.of(context); - if (nextRoute != _route) { - _route?.unregisterPopEntry(this); - _route = nextRoute; - _route?.registerPopEntry(this); - } - } - @override void initState() { currentPage = widget.initialPage; - gestureRecognizer = HorizontalDragGestureRecognizer(debugOwner: this) - ..onUpdate = ((details) => setState(() => offset += details.delta.dx)) - ..onEnd = (details) async { - if (details.velocity.pixelsPerSecond.dx.abs() > 1 && - details.velocity.pixelsPerSecond.dx >= 0) { - setState(() { - Future.delayed(const Duration(milliseconds: 300), () => offset = 0); - currentPage = -1; - }); - } else if (offset > MediaQuery.of(context).size.width / 2) { - setState(() { - Future.delayed(const Duration(milliseconds: 300), () => offset = 0); - currentPage = -1; - }); - } else { - int i = 10; - while (offset != 0) { - setState(() { - offset -= i; - i *= 10; - if (offset < 0) { - offset = 0; - } - }); - await Future.delayed(const Duration(milliseconds: 10)); - } - } - } - ..onCancel = () async { - int i = 10; - while (offset != 0) { - setState(() { - offset -= i; - i *= 10; - if (offset < 0) { - offset = 0; - } - }); - await Future.delayed(const Duration(milliseconds: 10)); - } - }; super.initState(); } - @override - dispose() { - super.dispose(); - gestureRecognizer.dispose(); - _route?.unregisterPopEntry(this); - } - @override Widget build(BuildContext context) { - if (currentPage != -1) { - canPop.value = false; - } else { - canPop.value = true; - } return Material( child: buildBody(), ); @@ -209,55 +138,10 @@ class _SettingsPageState extends State implements PopEntry { ], ); } else { - return LayoutBuilder( - builder: (context, constrains) { - return Stack( - children: [ - Positioned.fill(child: buildLeft()), - Positioned( - left: offset, - width: constrains.maxWidth, - top: 0, - bottom: 0, - child: Listener( - onPointerDown: handlePointerDown, - child: AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - switchInCurve: Curves.fastOutSlowIn, - switchOutCurve: Curves.fastOutSlowIn, - transitionBuilder: (child, animation) { - var tween = Tween( - begin: const Offset(1, 0), end: const Offset(0, 0)); - - return SlideTransition( - position: tween.animate(animation), - child: child, - ); - }, - child: Material( - key: ValueKey(currentPage), - child: buildRight(), - ), - ), - ), - ) - ], - ); - }, - ); + return buildLeft(); } } - void handlePointerDown(PointerDownEvent event) { - if (!App.isIOS) { - return; - } - if (currentPage == -1) { - return; - } - gestureRecognizer.addPointer(event); - } - Widget buildLeft() { return Material( child: Column( @@ -334,7 +218,13 @@ class _SettingsPageState extends State implements PopEntry { ? const EdgeInsets.fromLTRB(8, 0, 8, 0) : EdgeInsets.zero, child: InkWell( - onTap: () => setState(() => currentPage = id), + onTap: () { + if (enableTwoViews) { + setState(() => currentPage = id); + } else { + context.to(() => _SettingsDetailPage(pageIndex: id)); + } + }, child: content, ).paddingVertical(4), ); @@ -348,8 +238,23 @@ class _SettingsPageState extends State implements PopEntry { } Widget buildRight() { - return switch (currentPage) { - -1 => const SizedBox(), + if (currentPage == -1) { + return const SizedBox(); + } + return Navigator( + onGenerateRoute: (settings) { + return PageRouteBuilder( + pageBuilder: (context, animation, secondaryAnimation) { + return _buildSettingsContent(currentPage); + }, + transitionDuration: Duration.zero, + ); + }, + ); + } + + Widget _buildSettingsContent(int pageIndex) { + return switch (pageIndex) { 0 => const ExploreSettings(), 1 => const ReaderSettings(), 2 => const AppearanceSettings(), @@ -362,26 +267,31 @@ class _SettingsPageState extends State implements PopEntry { }; } - var canPop = ValueNotifier(true); +} + +class _SettingsDetailPage extends StatelessWidget { + const _SettingsDetailPage({required this.pageIndex}); + + final int pageIndex; @override - ValueListenable get canPopNotifier => canPop; - - @override - void onPopInvokedWithResult(bool didPop, result) { - if (currentPage != -1) { - setState(() { - currentPage = -1; - }); - } + Widget build(BuildContext context) { + return Material( + child: _buildPage(), + ); } - @override - void onPopInvoked(bool didPop) { - if (currentPage != -1) { - setState(() { - currentPage = -1; - }); - } + Widget _buildPage() { + return switch (pageIndex) { + 0 => const ExploreSettings(), + 1 => const ReaderSettings(), + 2 => const AppearanceSettings(), + 3 => const LocalFavoritesSettings(), + 4 => const AppSettings(), + 5 => const NetworkSettings(), + 6 => const AboutSettings(), + 7 => const DebugPage(), + _ => throw UnimplementedError() + }; } }