Skip to content

Commit

Permalink
Feat/close quran when salah (#1408)
Browse files Browse the repository at this point in the history
* 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 <ghassen.benzahra@gmail.com>
  • Loading branch information
YassinNouh21 and ghassenbenzahra123 authored Nov 13, 2024
1 parent 11af471 commit 3c56857
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 110 deletions.
73 changes: 40 additions & 33 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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();

Expand All @@ -50,7 +52,7 @@ Future<void> main() async {
Hive.registerAdapter(ReciterModelAdapter());
Hive.registerAdapter(MoshafModelAdapter());
runApp(
ProviderScope(
riverpod.ProviderScope(
child: MyApp(),
observers: [
RiverpodLogger(),
Expand All @@ -62,9 +64,9 @@ Future<void> 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()),
Expand All @@ -88,35 +90,40 @@ class MyApp extends StatelessWidget {
return event;
}),
child: Consumer<ThemeNotifier>(
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(),
),
);
},
),
);
});
Expand Down
14 changes: 11 additions & 3 deletions lib/src/pages/home/sub_screens/AdhanSubScreen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand All @@ -27,10 +30,10 @@ class AdhanSubScreen extends StatefulWidget {
final bool forceAdhan;

@override
State<AdhanSubScreen> createState() => _AdhanSubScreenState();
ConsumerState<AdhanSubScreen> createState() => _AdhanSubScreenState();
}

class _AdhanSubScreenState extends State<AdhanSubScreen> {
class _AdhanSubScreenState extends ConsumerState<AdhanSubScreen> {
AudioManager? audioManager;

/// if mosque using Beb sound we will wait for minutes delay
Expand All @@ -46,6 +49,11 @@ class _AdhanSubScreenState extends State<AdhanSubScreen> {
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();
});
Expand Down
6 changes: 6 additions & 0 deletions lib/src/pages/home/sub_screens/JummuaLive.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -34,6 +35,11 @@ class _JummuaLiveState extends ConsumerState<JummuaLive> {
@override
void initState() {
invalidStreamUrl = context.read<MosqueManager>().mosque?.streamUrl == null;

WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(quranNotifierProvider.notifier).exitQuranMode();
});

log('JummuaLive: invalidStreamUrl: $invalidStreamUrl');
super.initState();
}
Expand Down
13 changes: 10 additions & 3 deletions lib/src/pages/home/workflow/salah_workflow.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -28,10 +29,16 @@ class SalahWorkflowScreen extends StatefulWidget {
final void Function() onDone;

@override
State<SalahWorkflowScreen> createState() => _SalahWorkflowScreenState();
ConsumerState<SalahWorkflowScreen> createState() => _SalahWorkflowScreenState();
}

class _SalahWorkflowScreenState extends State<SalahWorkflowScreen> {
class _SalahWorkflowScreenState extends ConsumerState<SalahWorkflowScreen> {
// Changed to ConsumerState
@override
void initState() {
super.initState();
}

calculateCurrentSalah(MosqueManager mosqueManger) {
if (mosqueManger.nextSalahAfter() < Duration(minutes: 5)) return mosqueManger.nextSalahIndex();

Expand Down
53 changes: 23 additions & 30 deletions lib/src/pages/quran/page/quran_mode_selection_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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});
Expand Down Expand Up @@ -41,7 +42,7 @@ class _QuranModeSelectionState extends ConsumerState<QuranModeSelection> {
super.dispose();
}

void _handleKeyEvent(RawKeyEvent event) {
Future<void> _handleKeyEvent(RawKeyEvent event) async {
if (event is RawKeyDownEvent) {
final isLtr = Directionality.of(context) == TextDirection.ltr;

Expand All @@ -65,26 +66,30 @@ class _QuranModeSelectionState extends ConsumerState<QuranModeSelection> {
}
} 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(
Expand Down Expand Up @@ -122,13 +127,7 @@ class _QuranModeSelectionState extends ConsumerState<QuranModeSelection> {
setState(() {
_selectedIndex = 0;
});
ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => QuranReadingScreen(),
),
);
_handleNavigation(0);
},
isSelected: _selectedIndex == 0,
focusNode: _readingFocusNode,
Expand All @@ -141,13 +140,7 @@ class _QuranModeSelectionState extends ConsumerState<QuranModeSelection> {
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,
Expand All @@ -172,7 +165,7 @@ class _QuranModeSelectionState extends ConsumerState<QuranModeSelection> {
return Focus(
focusNode: focusNode,
child: GestureDetector(
onTap: onPressed,
onTap: () => _handleNavigation(isSelected ? 0 : 1),
child: AnimatedContainer(
duration: Duration(milliseconds: 200),
width: 50.w,
Expand Down
16 changes: 7 additions & 9 deletions lib/src/pages/quran/page/reciter_selection_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -109,6 +110,11 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>
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(
Expand All @@ -125,15 +131,7 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>
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(
Expand Down
22 changes: 11 additions & 11 deletions lib/src/pages/quran/page/surah_selection_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,18 +92,17 @@ class _SurahSelectionScreenState extends ConsumerState<SurahSelectionScreen> {
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() {
Expand Down
Loading

0 comments on commit 3c56857

Please sign in to comment.