Skip to content

Commit

Permalink
Feat/ Scheduled listening(The user can chose the start time, the end …
Browse files Browse the repository at this point in the history
…time, the reciter, the sourate or random sourate) (#1385)

* schedule listening feature

* code format

* fix merge conflict

* fix save fields
  • Loading branch information
ghassenbenzahra123 authored Dec 18, 2024
1 parent 605345b commit 014daf2
Show file tree
Hide file tree
Showing 15 changed files with 1,547 additions and 17 deletions.
14 changes: 13 additions & 1 deletion lib/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -412,5 +412,17 @@
},
"ishaAndFajrOnly": "Fajr and Isha prayers only",
"minutesBeforeFajrPrayer": "minutes before fajr prayer time",
"minutesAfterIshaPrayer": "minutes afer isha prayer time"
"minutesAfterIshaPrayer": "minutes afer isha prayer time",
"scheduleSaved": "Your schedule has been saved.",
"completeAllFields": "Please complete all fields before saving.",
"endTimeAfter": "The end time must be after the start time.",
"scheduleListening": "Scheduled Listening",
"enableScheduling": "Enable Scheduling",
"scheduleDesc": "Enable this feature to automatically play a Surah at scheduled times.",
"startTime": "Start Time",
"endTime": "End Time",
"selectReciter": "Select a Reciter",
"selectMoshaf": "Select a Mushaf",
"randomSurahSelection": "Random Surah Selection",
"selectSurah": "Select a Surah"
}
15 changes: 13 additions & 2 deletions lib/l10n/intl_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,19 @@
}
}
},
"save": "Enregistrer",
"scheduleSaved": "Votre planification a été enregistré.",
"completeAllFields": "Veuillez remplir tous les champs avant de sauvegarder.",
"endTimeAfter": "L'heure de fin doit être postérieure à l'heure de début.",
"scheduleListening": "Écoute planifiée",
"enableScheduling": "Activer la planification",
"scheduleDesc": "Activez cette fonctionnalité pour lire automatiquement une Sourate aux heures planifiées.",
"startTime": "Heure de Début",
"endTime": "Heure de Fin",
"selectReciter": "Choisissez un Récitateur",
"selectMoshaf": "Choisissez un Moushaf",
"randomSurahSelection": "Sélection Aléatoire de Sourate",
"selectSurah": "Choisissez une Sourate",
"save": "Sauvegarder",
"enterRtspUrl": "Entrez l'URL RTSP ou YouTube Live",
"addRtspUrl": "Ajoutez l'URL de votre flux de caméra ci-dessous",
"enableRtspCamera": "Activer le flux de la caméra",
Expand Down Expand Up @@ -400,5 +412,4 @@
"ishaAndFajrOnly": "Seulement les prières Fajr et d'Isha",
"minutesBeforeFajrPrayer": "minutes avant l'heure de la prière de Fajr",
"minutesAfterIshaPrayer": "minutes après l'heure de la prière d'Isha"

}
18 changes: 18 additions & 0 deletions lib/src/const/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ abstract class SystemFeaturesConstant {
static const String kEthernet = 'android.hardware.ethernet';
}

class BackgroundScheduleAudioServiceConstant {
static const String kManualPause = 'manual_pause_enabled';
static const String kPendingSchedule = 'pending_schedule';
static const String kScheduleEnabled = 'schedule_enabled';
static const String kStartTime = 'start_time';
static const String kEndTime = 'end_time';
static const String kRandomEnabled = 'isRandomEnabled';
static const String kRandomUrls = 'random_urls';
static const String kSelectedSurah = 'selected_surah';
static const String kSelectedSurahUrl = 'selected_surah_url';
static const String kSelectedReciter = 'selected_reciter';
static const String kSelectedMoshaf = 'selected_moshaf';
static const String kAudioStateChanged = 'kAudioStateChanged';
static const String kGetPlaybackState = 'kGetPlaybackState';
static const String kStopAudio = 'kStopAudio';
static const String kResumeAudio = 'kResumeAudio';
}

abstract class MawaqitBackendSettingsConstant {
static const String kSettingsTitle = "Mawaqit";
static const String kSettingsShare =
Expand Down
110 changes: 97 additions & 13 deletions lib/src/pages/quran/page/reciter_selection_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import 'package:fluttertoast/fluttertoast.dart';
import 'package:mawaqit/const/resource.dart';
import 'package:mawaqit/src/helpers/RelativeSizes.dart';
import 'package:mawaqit/src/pages/quran/page/quran_reading_screen.dart';
import 'package:mawaqit/src/pages/quran/page/schedule_screen.dart';
import 'package:mawaqit/src/pages/quran/widget/recite_type_grid_view.dart';
import 'package:mawaqit/src/services/theme_manager.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/recite/recite_notifier.dart';
import 'package:mawaqit/src/state_management/quran/recite/recite_state.dart';
import 'package:mawaqit/src/state_management/quran/schedule_listening/audio_control_notifier.dart';
import 'package:mawaqit/src/state_management/quran/schedule_listening/audio_control_state.dart';
import 'package:shimmer/shimmer.dart';
import 'package:sizer/sizer.dart';
import 'package:mawaqit/i18n/l10n.dart';
Expand Down Expand Up @@ -46,6 +49,7 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>

late FocusNode favoriteFocusNode;
late FocusNode changeReadingModeFocusNode;
late FocusNode scheduleListeningFocusNode;

late FocusScopeNode reciteTypeFocusScopeNode;
late FocusScopeNode reciteFocusScopeNode;
Expand Down Expand Up @@ -79,7 +83,9 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>
}
}
});

changeReadingModeFocusNode = FocusNode(debugLabel: 'change_reading_mode_focus_node');
scheduleListeningFocusNode = FocusNode(debugLabel: 'scheduleListeningFocusNode');
favoriteFocusNode = FocusNode(debugLabel: 'favorite_focus_node');

reciteTypeFocusScopeNode = FocusScopeNode(debugLabel: 'reciter_type_focus_scope_node');
Expand All @@ -99,6 +105,7 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>

reciteTypeFocusScopeNode.dispose();
reciteFocusScopeNode.dispose();
scheduleListeningFocusNode.dispose();

_tabController.dispose();
_searchController.dispose();
Expand All @@ -117,22 +124,99 @@ class _ReciterSelectionScreenState extends ConsumerState<ReciterSelectionScreen>

@override
Widget build(BuildContext context) {
final audioState = ref.watch(audioControlProvider);

return Scaffold(
key: _scaffoldKey,
floatingActionButton: SizedBox(
width: 40.sp, // Set the desired width
height: 40.sp, // Set the desired height
child: FloatingActionButton(
focusNode: changeReadingModeFocusNode,
focusColor: Theme.of(context).primaryColor,
backgroundColor: Colors.black.withOpacity(.5),
child: Icon(
Icons.menu_book,
color: Colors.white,
size: 15.sp,
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
width: 30.sp, // Set the desired width
height: 30.sp, // Set the desired height
child: Consumer(
builder: (context, ref, child) {
return ref.watch(reciteNotifierProvider).when(
data: (reciter) {
return FloatingActionButton(
backgroundColor: Colors.black.withOpacity(.5),
child: Icon(
Icons.schedule,
color: Colors.white,
size: 15.sp,
),
onPressed: () async {
showDialog(
context: context,
builder: (BuildContext context) {
return ScheduleScreen(reciterList: reciter.reciters);
},
);
},
);
},
loading: () => CircularProgressIndicator(),
error: (error, stackTrace) => Icon(Icons.error, color: Colors.red),
);
},
),
),
onPressed: _navigateToReading,
),
SizedBox(
width: 5.sp,
),
SizedBox(
width: 30.sp, // Set the desired width
height: 30.sp, // Set the desired height
child: FloatingActionButton(
focusNode: changeReadingModeFocusNode,
focusColor: Theme.of(context).primaryColor,
backgroundColor: Colors.black.withOpacity(.5),
child: Icon(
Icons.menu_book,
color: Colors.white,
size: 15.sp,
),
onPressed: () async {
ref.read(quranNotifierProvider.notifier).selectModel(QuranMode.reading);
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => QuranReadingScreen(),
),
);
},
),
),
SizedBox(
width: 5.sp,
),
audioState.when(
data: (state) {
if (!state.shouldShowControls) {
return const SizedBox.shrink(); // Hide controls when scheduling is disabled
}

return SizedBox(
width: 30.sp, // Set the desired width
height: 30.sp, // Set the desired height
child: FloatingActionButton(
focusNode: scheduleListeningFocusNode,
focusColor: Theme.of(context).primaryColor,
backgroundColor: state.status == AudioStatus.playing ? Colors.red : Colors.black.withOpacity(.5),
child: Icon(
color: Colors.white,
state.status == AudioStatus.playing ? Icons.pause : Icons.play_arrow,
),
onPressed: () {
ref.read(audioControlProvider.notifier).togglePlayback();
},
),
);
},
loading: () => const CircularProgressIndicator(),
error: (error, stack) => Text('Error: $error'),
)
],
),
appBar: AppBar(
toolbarHeight: 40,
Expand Down
Loading

0 comments on commit 014daf2

Please sign in to comment.