diff --git a/firka/lib/routing/app_router.dart b/firka/lib/routing/app_router.dart index 115404d..1e1cfae 100644 --- a/firka/lib/routing/app_router.dart +++ b/firka/lib/routing/app_router.dart @@ -16,6 +16,7 @@ import 'package:firka/ui/phone/screens/login/login_screen.dart'; import 'package:firka/ui/phone/screens/message/message_screen.dart'; import 'package:firka/ui/phone/screens/home/home_screen.dart'; import 'package:firka/ui/phone/screens/settings/settings_screen.dart'; +import 'package:firka/routing/chart_interaction_scope.dart'; import 'package:firka/routing/shell_with_nav_bar.dart'; import 'package:firka/routing/swipable_navigator_container.dart'; import 'package:go_router/go_router.dart'; @@ -97,9 +98,11 @@ GoRouter createAppRouter() { ), ), navigatorContainerBuilder: (context, navigationShell, children) { - return SwipableNavigatorContainer( - navigationShell: navigationShell, - children: children, + return ChartInteractionScope( + child: SwipableNavigatorContainer( + navigationShell: navigationShell, + children: children, + ), ); }, branches: [ diff --git a/firka/lib/routing/chart_interaction_scope.dart b/firka/lib/routing/chart_interaction_scope.dart new file mode 100644 index 0000000..44c85c8 --- /dev/null +++ b/firka/lib/routing/chart_interaction_scope.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +class ChartInteractionScope extends StatefulWidget { + const ChartInteractionScope({super.key, required this.child}); + + final Widget child; + + static ValueNotifier of(BuildContext context) { + final data = context + .dependOnInheritedWidgetOfExactType<_ChartInteractionScopeData>(); + assert(data != null, 'ChartInteractionScope not found in context'); + return data!.isChartInteracting; + } + + @override + State createState() => _ChartInteractionScopeState(); +} + +class _ChartInteractionScopeState extends State { + final ValueNotifier _isChartInteracting = ValueNotifier(false); + + @override + void dispose() { + _isChartInteracting.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return _ChartInteractionScopeData( + isChartInteracting: _isChartInteracting, + child: widget.child, + ); + } +} + +class _ChartInteractionScopeData extends InheritedWidget { + const _ChartInteractionScopeData({ + required this.isChartInteracting, + required super.child, + }); + + final ValueNotifier isChartInteracting; + + @override + bool updateShouldNotify(_ChartInteractionScopeData oldWidget) => + isChartInteracting != oldWidget.isChartInteracting; +} diff --git a/firka/lib/routing/swipable_navigator_container.dart b/firka/lib/routing/swipable_navigator_container.dart index c973043..606388f 100644 --- a/firka/lib/routing/swipable_navigator_container.dart +++ b/firka/lib/routing/swipable_navigator_container.dart @@ -1,3 +1,4 @@ +import 'package:firka/routing/chart_interaction_scope.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:go_router/go_router.dart'; @@ -82,11 +83,19 @@ class _SwipableNavigatorContainerState @override Widget build(BuildContext context) { - return PageView( - controller: _pageController, - physics: const ClampingScrollPhysics(), - onPageChanged: _onPageChanged, - children: widget.children, + final isChartInteracting = ChartInteractionScope.of(context); + return ValueListenableBuilder( + valueListenable: isChartInteracting, + builder: (context, interacting, _) { + return PageView( + controller: _pageController, + physics: interacting + ? const NeverScrollableScrollPhysics() + : const ClampingScrollPhysics(), + onPageChanged: _onPageChanged, + children: widget.children, + ); + }, ); } } diff --git a/firka/lib/ui/phone/pages/home/home_grades.dart b/firka/lib/ui/phone/pages/home/home_grades.dart index 0dda304..d5e52a4 100644 --- a/firka/lib/ui/phone/pages/home/home_grades.dart +++ b/firka/lib/ui/phone/pages/home/home_grades.dart @@ -1,6 +1,7 @@ import 'package:firka/api/client/kreta_client.dart'; import 'package:firka/api/model/generic.dart'; import 'package:firka/core/average_helper.dart'; +import 'package:firka/routing/chart_interaction_scope.dart'; import 'package:firka/ui/components/firka_card.dart'; import 'package:firka/ui/components/grade_helpers.dart'; import 'package:firka/ui/phone/widgets/grade_chart.dart'; @@ -231,7 +232,16 @@ class _HomeGradesScreen extends FirkaState { ], ), // SizedBox(height: 16), // TODO: Add graphs here - GradeChart(grades: grades?.response ?? []), + Listener( + behavior: HitTestBehavior.opaque, + onPointerDown: (_) => + ChartInteractionScope.of(context).value = true, + onPointerUp: (_) => + ChartInteractionScope.of(context).value = false, + onPointerCancel: (_) => + ChartInteractionScope.of(context).value = false, + child: GradeChart(grades: grades?.response ?? []), + ), // ...gradeCards, Expanded( child: ListView(