From 3c568579de3ebe298e01e6912f13a6318d3d41e7 Mon Sep 17 00:00:00 2001 From: Yassin Nouh <70436855+YassinNouh21@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:00:25 +0200 Subject: [PATCH] Feat/close quran when salah (#1408) * feat(routes): add Quran-specific routes and route generator * refactor(routes): migrate to named routes and simplify navigation logic in the quran * fix: Improve Quran mode selection navigation - Modify route generator to handle QuranModeSelection separately * fix: waiting for the handle push * fix the formating * fix: Pop the screen while it has dialog in reading * refactor: AdhanSubScreen to use ConsumerStatefulWidget and manage Quran mode - Updated AdhanSubScreen to use `ConsumerStatefulWidget` and `ConsumerState` for improved state management with Riverpod. - Moved Quran mode exit logic to AdhanSubScreen and JummuaLive components, removing redundant code from salah_workflow. - Added post-frame callback in AdhanSubScreen and JummuaLive to trigger `exitQuranMode` via `quranNotifierProvider`. * pause quran player when adhan begins --------- Co-authored-by: Ghassen Ben Zahra --- lib/main.dart | 73 +++++++------ .../home/sub_screens/AdhanSubScreen.dart | 14 ++- .../pages/home/sub_screens/JummuaLive.dart | 6 ++ .../pages/home/workflow/salah_workflow.dart | 13 ++- .../page/quran_mode_selection_screen.dart | 53 ++++------ .../quran/page/reciter_selection_screen.dart | 16 ++- .../quran/page/surah_selection_screen.dart | 22 ++-- .../quran/reading/quran_reading_screen.dart | 8 ++ .../widget/quran_floating_action_buttons.dart | 10 +- .../pages/quran/widget/quran_background.dart | 13 +-- lib/src/routes/route_generator.dart | 100 ++++++++++++++++++ lib/src/routes/routes_constant.dart | 15 +++ .../quran/quran/quran_notifier.dart | 8 ++ lib/src/widgets/MawaqitDrawer.dart | 12 +-- 14 files changed, 253 insertions(+), 110 deletions(-) create mode 100644 lib/src/routes/route_generator.dart create mode 100644 lib/src/routes/routes_constant.dart diff --git a/lib/main.dart b/lib/main.dart index d841da5a6..9dffcb2c6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,12 @@ import 'package:fast_cached_network_image/fast_cached_network_image.dart'; +import 'dart:async'; +import 'dart:developer' as developer; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_kurdish_localization/flutter_kurdish_localization.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart' - show ProviderBase, ProviderContainer, ProviderObserver, ProviderScope; +import 'package:flutter_riverpod/flutter_riverpod.dart' as riverpod; import 'package:hive_flutter/adapters.dart'; import 'package:logger/logger.dart'; import 'package:mawaqit/i18n/AppLanguage.dart'; @@ -33,6 +34,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:sizer/sizer.dart'; import 'package:timezone/data/latest.dart' as tz; +import 'package:mawaqit/src/routes/route_generator.dart'; final logger = Logger(); @@ -50,7 +52,7 @@ Future main() async { Hive.registerAdapter(ReciterModelAdapter()); Hive.registerAdapter(MoshafModelAdapter()); runApp( - ProviderScope( + riverpod.ProviderScope( child: MyApp(), observers: [ RiverpodLogger(), @@ -62,9 +64,9 @@ Future main() async { ); } -class MyApp extends StatelessWidget { +class MyApp extends riverpod.ConsumerWidget { @override - Widget build(BuildContext context) { + Widget build(BuildContext context, riverpod.WidgetRef ref) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (context) => ThemeNotifier()), @@ -88,35 +90,40 @@ class MyApp extends StatelessWidget { return event; }), child: Consumer( - builder: (context, theme, _) => Shortcuts( - shortcuts: {SingleActivator(LogicalKeyboardKey.select): ActivateIntent()}, - child: MaterialApp( - title: kAppName, - themeMode: theme.mode, - localeResolutionCallback: (locale, supportedLocales) { - if (locale?.languageCode.toLowerCase() == 'ba') return Locale('en'); + builder: (context, theme, _) { + return Shortcuts( + shortcuts: {SingleActivator(LogicalKeyboardKey.select): ActivateIntent()}, + child: MaterialApp( + title: kAppName, + themeMode: theme.mode, + localeResolutionCallback: (locale, supportedLocales) { + if (locale?.languageCode.toLowerCase() == 'ba') return Locale('en'); - return locale; - }, - theme: theme.lightTheme, - darkTheme: theme.darkTheme, - locale: model.appLocal, - navigatorKey: AppRouter.navigationKey, - navigatorObservers: [AnalyticsWrapper.observer()], - localizationsDelegates: [ - S.delegate, - GlobalCupertinoLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - KurdishMaterialLocalizations.delegate, - KurdishWidgetLocalizations.delegate, - KurdishCupertinoLocalizations.delegate - ], - supportedLocales: S.supportedLocales, - debugShowCheckedModeBanner: false, - home: Splash(), - ), - ), + return locale; + }, + theme: theme.lightTheme, + darkTheme: theme.darkTheme, + locale: model.appLocal, + navigatorKey: AppRouter.navigationKey, + navigatorObservers: [ + AnalyticsWrapper.observer(), + ], + localizationsDelegates: [ + S.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + KurdishMaterialLocalizations.delegate, + KurdishWidgetLocalizations.delegate, + KurdishCupertinoLocalizations.delegate + ], + supportedLocales: S.supportedLocales, + debugShowCheckedModeBanner: false, + onGenerateRoute: RouteGenerator.generateRoute, + home: Splash(), + ), + ); + }, ), ); }); diff --git a/lib/src/pages/home/sub_screens/AdhanSubScreen.dart b/lib/src/pages/home/sub_screens/AdhanSubScreen.dart index bde9c442c..233274827 100644 --- a/lib/src/pages/home/sub_screens/AdhanSubScreen.dart +++ b/lib/src/pages/home/sub_screens/AdhanSubScreen.dart @@ -2,6 +2,7 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mawaqit/i18n/l10n.dart'; import 'package:mawaqit/main.dart'; import 'package:mawaqit/src/helpers/RelativeSizes.dart'; @@ -12,13 +13,15 @@ import 'package:mawaqit/src/pages/home/widgets/mosque_background_screen.dart'; import 'package:mawaqit/src/pages/home/widgets/salah_items/responsive_mini_salah_bar_widget.dart'; import 'package:mawaqit/src/services/audio_manager.dart'; import 'package:mawaqit/src/services/mosque_manager.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; +import 'package:mawaqit/src/state_management/quran/recite/quran_audio_player_notifier.dart'; import 'package:mawaqit/src/themes/UIShadows.dart'; import 'package:provider/provider.dart'; import '../widgets/mosque_header.dart'; import '../widgets/salah_items/responsive_mini_salah_bar_turkish_widget.dart'; -class AdhanSubScreen extends StatefulWidget { +class AdhanSubScreen extends ConsumerStatefulWidget { const AdhanSubScreen({Key? key, this.onDone, this.forceAdhan = false}) : super(key: key); final VoidCallback? onDone; @@ -27,10 +30,10 @@ class AdhanSubScreen extends StatefulWidget { final bool forceAdhan; @override - State createState() => _AdhanSubScreenState(); + ConsumerState createState() => _AdhanSubScreenState(); } -class _AdhanSubScreenState extends State { +class _AdhanSubScreenState extends ConsumerState { AudioManager? audioManager; /// if mosque using Beb sound we will wait for minutes delay @@ -46,6 +49,11 @@ class _AdhanSubScreenState extends State { final isFajrPray = mosqueManager.salahIndex == 0; final duration = mosqueManager.getAdhanDuration(isFajrPray); + WidgetsBinding.instance.addPostFrameCallback((_) { + ref.read(quranPlayerNotifierProvider.notifier).pause(); + ref.read(quranNotifierProvider.notifier).exitQuranMode(); + }); + Future.delayed(Duration(minutes: 5), () { closeAdhanScreen(); }); diff --git a/lib/src/pages/home/sub_screens/JummuaLive.dart b/lib/src/pages/home/sub_screens/JummuaLive.dart index 1284cdd53..e4e2cc7f3 100644 --- a/lib/src/pages/home/sub_screens/JummuaLive.dart +++ b/lib/src/pages/home/sub_screens/JummuaLive.dart @@ -6,6 +6,7 @@ import 'package:mawaqit/i18n/l10n.dart'; import 'package:mawaqit/src/helpers/RelativeSizes.dart'; import 'package:mawaqit/src/models/address_model.dart'; import 'package:mawaqit/src/services/mosque_manager.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; import 'package:mawaqit/src/themes/UIShadows.dart'; import 'package:provider/provider.dart'; @@ -34,6 +35,11 @@ class _JummuaLiveState extends ConsumerState { @override void initState() { invalidStreamUrl = context.read().mosque?.streamUrl == null; + + WidgetsBinding.instance.addPostFrameCallback((_) { + ref.read(quranNotifierProvider.notifier).exitQuranMode(); + }); + log('JummuaLive: invalidStreamUrl: $invalidStreamUrl'); super.initState(); } diff --git a/lib/src/pages/home/workflow/salah_workflow.dart b/lib/src/pages/home/workflow/salah_workflow.dart index 3b38fbfb1..b60a40750 100644 --- a/lib/src/pages/home/workflow/salah_workflow.dart +++ b/lib/src/pages/home/workflow/salah_workflow.dart @@ -12,13 +12,14 @@ import 'package:mawaqit/src/pages/home/sub_screens/normal_home.dart'; import 'package:mawaqit/src/pages/home/widgets/workflows/repeating_workflow_widget.dart'; import 'package:mawaqit/src/services/mosque_manager.dart'; import 'package:mawaqit/src/services/user_preferences_manager.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:provider/provider.dart'; import '../sub_screens/AdhanSubScreen.dart'; import '../widgets/workflows/WorkFlowWidget.dart'; /// handling the logic form 5min before adhan -> the last of after salah azkar -class SalahWorkflowScreen extends StatefulWidget { +class SalahWorkflowScreen extends ConsumerStatefulWidget { const SalahWorkflowScreen({ Key? key, required this.onDone, @@ -28,10 +29,16 @@ class SalahWorkflowScreen extends StatefulWidget { final void Function() onDone; @override - State createState() => _SalahWorkflowScreenState(); + ConsumerState createState() => _SalahWorkflowScreenState(); } -class _SalahWorkflowScreenState extends State { +class _SalahWorkflowScreenState extends ConsumerState { + // Changed to ConsumerState + @override + void initState() { + super.initState(); + } + calculateCurrentSalah(MosqueManager mosqueManger) { if (mosqueManger.nextSalahAfter() < Duration(minutes: 5)) return mosqueManger.nextSalahIndex(); diff --git a/lib/src/pages/quran/page/quran_mode_selection_screen.dart b/lib/src/pages/quran/page/quran_mode_selection_screen.dart index fc8fd32d4..093ebdec1 100644 --- a/lib/src/pages/quran/page/quran_mode_selection_screen.dart +++ b/lib/src/pages/quran/page/quran_mode_selection_screen.dart @@ -8,6 +8,7 @@ import 'package:mawaqit/src/pages/quran/widget/quran_background.dart'; import 'package:mawaqit/src/state_management/quran/quran/quran_state.dart'; import 'package:sizer/sizer.dart'; import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; class QuranModeSelection extends ConsumerStatefulWidget { const QuranModeSelection({super.key}); @@ -41,7 +42,7 @@ class _QuranModeSelectionState extends ConsumerState { super.dispose(); } - void _handleKeyEvent(RawKeyEvent event) { + Future _handleKeyEvent(RawKeyEvent event) async { if (event is RawKeyDownEvent) { final isLtr = Directionality.of(context) == TextDirection.ltr; @@ -65,26 +66,30 @@ class _QuranModeSelectionState extends ConsumerState { } } else if (event.logicalKey == LogicalKeyboardKey.select) { if (_selectedIndex == 0) { - ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => QuranReadingScreen(), - ), - ); + await ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); + if (mounted) { + Navigator.pushReplacementNamed(context, Routes.quranReading); + } } else { - ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => ReciterSelectionScreen.withoutSurahName(), - ), - ); + await ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); + if (mounted) { + Navigator.pushReplacementNamed(context, Routes.quranReciter); + } } } } } + void _handleNavigation(int index) { + if (index == 0) { + ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); + Navigator.pushReplacementNamed(context, Routes.quranReading); + } else { + ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); + Navigator.pushReplacementNamed(context, Routes.quranReciter); + } + } + @override Widget build(BuildContext context) { return RawKeyboardListener( @@ -122,13 +127,7 @@ class _QuranModeSelectionState extends ConsumerState { setState(() { _selectedIndex = 0; }); - ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => QuranReadingScreen(), - ), - ); + _handleNavigation(0); }, isSelected: _selectedIndex == 0, focusNode: _readingFocusNode, @@ -141,13 +140,7 @@ class _QuranModeSelectionState extends ConsumerState { setState(() { _selectedIndex = 1; }); - ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => ReciterSelectionScreen.withoutSurahName(), - ), - ); + _handleNavigation(1); }, isSelected: _selectedIndex == 1, focusNode: _listeningFocusNode, @@ -172,7 +165,7 @@ class _QuranModeSelectionState extends ConsumerState { return Focus( focusNode: focusNode, child: GestureDetector( - onTap: onPressed, + onTap: () => _handleNavigation(isSelected ? 0 : 1), child: AnimatedContainer( duration: Duration(milliseconds: 200), width: 50.w, diff --git a/lib/src/pages/quran/page/reciter_selection_screen.dart b/lib/src/pages/quran/page/reciter_selection_screen.dart index 6cbcc3a5f..9929e00bb 100644 --- a/lib/src/pages/quran/page/reciter_selection_screen.dart +++ b/lib/src/pages/quran/page/reciter_selection_screen.dart @@ -24,6 +24,7 @@ import 'package:mawaqit/src/pages/quran/widget/reciter_list_view.dart'; import '../../../domain/model/quran/reciter_model.dart'; import '../reading/quran_reading_screen.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; class ReciterSelectionScreen extends ConsumerStatefulWidget { final String surahName; @@ -109,6 +110,11 @@ class _ReciterSelectionScreenState extends ConsumerState ref.read(reciteNotifierProvider.notifier).setSearchQuery(_searchController.text, isAllReciters); } + void _navigateToReading() { + ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); + Navigator.pushReplacementNamed(context, Routes.quranReading); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -125,15 +131,7 @@ class _ReciterSelectionScreenState extends ConsumerState color: Colors.white, size: 15.sp, ), - onPressed: () async { - ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => QuranReadingScreen(), - ), - ); - }, + onPressed: _navigateToReading, ), ), appBar: AppBar( diff --git a/lib/src/pages/quran/page/surah_selection_screen.dart b/lib/src/pages/quran/page/surah_selection_screen.dart index 1b98d7a96..f26549824 100644 --- a/lib/src/pages/quran/page/surah_selection_screen.dart +++ b/lib/src/pages/quran/page/surah_selection_screen.dart @@ -23,6 +23,7 @@ import '../../../models/address_model.dart'; import '../../../services/theme_manager.dart'; import '../../../state_management/quran/recite/download_audio_quran/download_audio_quran_notifier.dart'; import '../../../state_management/quran/recite/download_audio_quran/download_audio_quran_state.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; class SurahSelectionScreen extends ConsumerStatefulWidget { final MoshafModel selectedMoshaf; @@ -91,18 +92,17 @@ class _SurahSelectionScreenState extends ConsumerState { suwar: suwar, reciterId: widget.reciterId, ); - Navigator.push( + + Navigator.pushNamed( context, - MaterialPageRoute( - builder: (context) => QuranPlayerScreen( - reciterId: widget.reciterId, - selectedMoshaf: widget.selectedMoshaf, - surah: surah, - ), - ), - ).then((_) { - _isNavigating = false; - }); + Routes.quranPlayer, + arguments: { + 'reciterId': widget.reciterId, + 'selectedMoshaf': widget.selectedMoshaf, + 'surah': surah, + }, + ); + _isNavigating = false; } String _getKey() { diff --git a/lib/src/pages/quran/reading/quran_reading_screen.dart b/lib/src/pages/quran/reading/quran_reading_screen.dart index 16f8d24b2..74fda1aea 100644 --- a/lib/src/pages/quran/reading/quran_reading_screen.dart +++ b/lib/src/pages/quran/reading/quran_reading_screen.dart @@ -13,6 +13,8 @@ import 'package:mawaqit/src/pages/quran/widget/reading/quran_surah_selector.dart import 'package:mawaqit/src/services/user_preferences_manager.dart'; import 'package:mawaqit/src/state_management/quran/download_quran/download_quran_notifier.dart'; import 'package:mawaqit/src/state_management/quran/download_quran/download_quran_state.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_state.dart'; import 'package:mawaqit/src/state_management/quran/reading/auto_reading/auto_reading_notifier.dart'; import 'package:mawaqit/src/state_management/quran/reading/auto_reading/auto_reading_state.dart'; import 'package:mawaqit/src/state_management/quran/reading/quran_reading_notifer.dart'; @@ -22,6 +24,7 @@ import 'package:mawaqit/src/state_management/quran/reading/quran_reading_state.d import 'package:provider/provider.dart' as provider; import 'package:mawaqit/src/pages/quran/widget/reading/quran_reading_page_selector.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; abstract class QuranViewStrategy { Widget buildView(QuranReadingState state, WidgetRef ref, BuildContext context); @@ -281,6 +284,11 @@ class _QuranReadingScreenState extends ConsumerState { _surahSelectorNode.dispose(); } + void _navigateToListeningMode() { + ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); + Navigator.pushReplacementNamed(context, Routes.quranReciter); + } + @override Widget build(BuildContext context) { final quranReadingState = ref.watch(quranReadingNotifierProvider); diff --git a/lib/src/pages/quran/reading/widget/quran_floating_action_buttons.dart b/lib/src/pages/quran/reading/widget/quran_floating_action_buttons.dart index 7dd84a18b..3064b1944 100644 --- a/lib/src/pages/quran/reading/widget/quran_floating_action_buttons.dart +++ b/lib/src/pages/quran/reading/widget/quran_floating_action_buttons.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mawaqit/src/pages/quran/page/reciter_selection_screen.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; import 'package:mawaqit/src/state_management/quran/quran/quran_state.dart'; import 'package:mawaqit/src/state_management/quran/reading/auto_reading/auto_reading_notifier.dart'; @@ -98,14 +99,9 @@ class _QuranModeButton extends ConsumerWidget { color: Colors.white, size: iconSize, ), - onPressed: () async { + onPressed: () { ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.listening); - Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => ReciterSelectionScreen.withoutSurahName(), - ), - ); + Navigator.pushReplacementNamed(context, Routes.quranReciter); }, heroTag: null, ), diff --git a/lib/src/pages/quran/widget/quran_background.dart b/lib/src/pages/quran/widget/quran_background.dart index d991af318..a4ab8cf7e 100644 --- a/lib/src/pages/quran/widget/quran_background.dart +++ b/lib/src/pages/quran/widget/quran_background.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mawaqit/const/resource.dart'; import 'package:mawaqit/src/pages/quran/reading/quran_reading_screen.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; import 'package:mawaqit/src/services/theme_manager.dart'; import 'package:sizer/sizer.dart'; @@ -47,11 +48,9 @@ class QuranBackground extends ConsumerWidget { onPressed: () async { ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); log('quran: QuranBackground: Switch to reading'); - Navigator.pushReplacement( + Navigator.pushReplacementNamed( context, - MaterialPageRoute( - builder: (context) => QuranReadingScreen(), - ), + Routes.quranReading, ); }, ), @@ -90,11 +89,9 @@ class QuranBackground extends ConsumerWidget { ), onPressed: () async { ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading); - Navigator.pushReplacement( + Navigator.pushReplacementNamed( context, - MaterialPageRoute( - builder: (context) => QuranReadingScreen(), - ), + Routes.quranReading, ); }, ), diff --git a/lib/src/routes/route_generator.dart b/lib/src/routes/route_generator.dart new file mode 100644 index 000000000..1b08aeec9 --- /dev/null +++ b/lib/src/routes/route_generator.dart @@ -0,0 +1,100 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:mawaqit/src/domain/model/quran/moshaf_model.dart'; +import 'package:mawaqit/src/domain/model/quran/surah_model.dart'; +import 'package:mawaqit/src/pages/quran/page/quran_mode_selection_screen.dart'; +import 'package:mawaqit/src/pages/quran/page/quran_player_screen.dart'; +import 'package:mawaqit/src/pages/quran/page/reciter_selection_screen.dart'; +import 'package:mawaqit/src/pages/quran/page/surah_selection_screen.dart'; +import 'package:mawaqit/src/pages/quran/reading/quran_reading_screen.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; +import 'package:mawaqit/src/pages/SplashScreen.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_notifier.dart'; +import 'package:mawaqit/src/state_management/quran/quran/quran_state.dart'; + +class RouteGenerator { + static Route generateRoute(RouteSettings settings) { + // Special handling for QuranModeSelection + if (settings.name == Routes.quranModeSelection) { + return MaterialPageRoute( + builder: (context) => const QuranModeSelection(), + ); + } + + // Check if the route is a Quran screen + if (Routes.quranScreens.contains(settings.name)) { + return MaterialPageRoute( + builder: (context) { + return Consumer( + builder: (context, ref, child) { + final quranState = ref.watch(quranNotifierProvider); + if (quranState.value?.mode == QuranMode.none) { + WidgetsBinding.instance.addPostFrameCallback((_) { + // Get the navigator state + final navigator = Navigator.of(context); + // Pop until we reach the root or can't pop anymore + while (navigator.canPop()) { + // Pop both dialog and screen if in listening mode + if (Routes.quranScreens.contains(settings.name)) { + navigator.pop(); + } + } + }); + return const SizedBox(); // Return empty widget while popping + } + return _buildQuranScreen(settings, context); + }, + ); + }, + ); + } + + // Handle non-Quran routes + switch (settings.name) { + case '/': + return MaterialPageRoute(builder: (_) => Splash()); + default: + return _errorRoute(); + } + } + + static Widget _buildQuranScreen(RouteSettings settings, BuildContext context) { + switch (settings.name) { + case Routes.quranModeSelection: + return const QuranModeSelection(); + + case Routes.quranReading: + return const QuranReadingScreen(); + + case Routes.quranReciter: + return const ReciterSelectionScreen.withoutSurahName(); + + case Routes.quranSurah: + final args = settings.arguments as Map; + return SurahSelectionScreen( + selectedMoshaf: args['selectedMoshaf'] as MoshafModel, + reciterId: args['reciterId'] as String, + ); + + case Routes.quranPlayer: + final args = settings.arguments as Map; + return QuranPlayerScreen( + reciterId: args['reciterId'] as String, + selectedMoshaf: args['selectedMoshaf'] as MoshafModel, + surah: args['surah'] as SurahModel, + ); + + default: + return const SizedBox(); + } + } + + static Route _errorRoute() { + return MaterialPageRoute( + builder: (_) => Scaffold( + appBar: AppBar(title: const Text('Error')), + body: const Center(child: Text('Route not found')), + ), + ); + } +} diff --git a/lib/src/routes/routes_constant.dart b/lib/src/routes/routes_constant.dart new file mode 100644 index 000000000..97d8516e7 --- /dev/null +++ b/lib/src/routes/routes_constant.dart @@ -0,0 +1,15 @@ +class Routes { + static const String quranModeSelection = '/quran'; + static const String quranReading = '/quran/reading'; + static const String quranReciter = '/quran/reciter'; + static const String quranSurah = '/quran/surah'; + static const String quranPlayer = '/quran/player'; + + static const List quranScreens = [ + quranModeSelection, + quranReading, + quranReciter, + quranSurah, + quranPlayer, + ]; +} diff --git a/lib/src/state_management/quran/quran/quran_notifier.dart b/lib/src/state_management/quran/quran/quran_notifier.dart index 62e24a97d..c3c0892fb 100644 --- a/lib/src/state_management/quran/quran/quran_notifier.dart +++ b/lib/src/state_management/quran/quran/quran_notifier.dart @@ -83,6 +83,14 @@ class QuranNotifier extends AsyncNotifier { } }); } + + void exitQuranMode() { + try { + state = AsyncData(state.value!.copyWith(mode: QuranMode.none)); + } catch (err, stack) { + state = AsyncError(err, stack); + } + } } final quranNotifierProvider = AsyncNotifierProvider(QuranNotifier.new); diff --git a/lib/src/widgets/MawaqitDrawer.dart b/lib/src/widgets/MawaqitDrawer.dart index ae4fb65d3..6940a800d 100644 --- a/lib/src/widgets/MawaqitDrawer.dart +++ b/lib/src/widgets/MawaqitDrawer.dart @@ -20,6 +20,7 @@ import 'package:mawaqit/src/pages/AboutScreen.dart'; import 'package:mawaqit/src/pages/PageScreen.dart'; import 'package:mawaqit/src/pages/WebScreen.dart'; import 'package:mawaqit/src/pages/quran/page/reciter_selection_screen.dart'; +import 'package:mawaqit/src/routes/routes_constant.dart'; import 'package:mawaqit/src/services/mosque_manager.dart'; import 'package:mawaqit/src/services/settings_manager.dart'; import 'package:mawaqit/src/services/user_preferences_manager.dart'; @@ -174,20 +175,19 @@ class MawaqitDrawer extends ConsumerWidget { onTap: () async { await ref.read(quranNotifierProvider.notifier).getSelectedMode(); final state = ref.read(quranNotifierProvider); + Navigator.pop(context); + switch (state.value!.mode) { case QuranMode.reading: log('quran: MawaqitDrawer: build: quranNotifierProvider: mode: reading'); - Navigator.pop(context); - AppRouter.push(QuranReadingScreen()); + Navigator.pushNamed(context, Routes.quranReading); break; case QuranMode.listening: log('quran: MawaqitDrawer: build: quranNotifierProvider: mode: listening'); - Navigator.pop(context); - AppRouter.push(ReciterSelectionScreen.withoutSurahName()); + Navigator.pushNamed(context, Routes.quranReciter); break; case QuranMode.none: - Navigator.pop(context); - AppRouter.push(QuranModeSelection()); + Navigator.pushNamed(context, Routes.quranModeSelection); break; } },