diff --git a/lib/core/routers/my_routes.dart b/lib/core/routers/my_routes.dart index 406fe07..265e7a0 100644 --- a/lib/core/routers/my_routes.dart +++ b/lib/core/routers/my_routes.dart @@ -89,7 +89,7 @@ GoRouter get appPages => GoRouter( builder: (context, state) => BlocProvider( create: (context) => QuestionBloc(locator(), locator(), locator()) - ..add(GetLevelEvent(state.pathParameters['id'])), + ..add(GetLevelEvent(state.pathParameters['id'], context)), child: const QuestionPage(), ), ), diff --git a/lib/core/widgets/hadith_dialog/hadith_dialog.dart b/lib/core/widgets/hadith_dialog/hadith_dialog.dart index eaa2227..063a616 100644 --- a/lib/core/widgets/hadith_dialog/hadith_dialog.dart +++ b/lib/core/widgets/hadith_dialog/hadith_dialog.dart @@ -9,18 +9,24 @@ import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; import 'package:hadi_hoda_flutter/core/utils/check_platform.dart'; import 'package:hadi_hoda_flutter/core/widgets/about_us_dialog/styles/background.dart'; import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; +import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; -Future showHadithDialog({required BuildContext context}) async { +Future showHadithDialog({ + required BuildContext context, + required List hadith, +}) async { await showDialog( context: context, - builder: (context) => HadithDialog(), + builder: (context) => HadithDialog(hadith: hadith), barrierColor: MyColors.purple.withValues(alpha: 0.82), useSafeArea: false, ); } class HadithDialog extends StatelessWidget { - const HadithDialog({super.key}); + const HadithDialog({super.key, required this.hadith}); + + final List hadith; @override Widget build(BuildContext context) { @@ -42,7 +48,7 @@ class HadithDialog extends StatelessWidget { children: [ AboutUSDialogBackground( child: ListView.separated( - itemCount: 3, + itemCount: hadith.length, separatorBuilder: (context, index) => Divider( height: 40, thickness: 1, @@ -51,7 +57,7 @@ class HadithDialog extends StatelessWidget { color: Color(0xFFC2BDE4), ), itemBuilder: (context, index) => Text( - 'Prophet Muhammad (PBUH) said: "Teeth, which are smooth and beautiful, become dirty as a result of chewing food, and gradually the smell of the mouth changes and causes corruption in the nasal organs. When a person brushes her teeth, the corruption disappears and the teeth become clean and pure again."', + hadith[index].hadithText ?? '', style: Marhey.medium14.copyWith( color: Color(0XFF494178), ), diff --git a/lib/features/level/data/model/level_model.dart b/lib/features/level/data/model/level_model.dart index 2400039..c352a33 100644 --- a/lib/features/level/data/model/level_model.dart +++ b/lib/features/level/data/model/level_model.dart @@ -1,5 +1,7 @@ import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; +import 'package:hadi_hoda_flutter/features/question/data/model/hadith_model.dart'; import 'package:hadi_hoda_flutter/features/question/data/model/question_model.dart'; +import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart'; class LevelModel extends LevelEntity { @@ -8,6 +10,7 @@ class LevelModel extends LevelEntity { super.order, super.title, super.questions, + super.hadith, }); factory LevelModel.fromJson(Map json) { @@ -18,6 +21,9 @@ class LevelModel extends LevelEntity { questions: json['questions'] ?.map((e) => QuestionModel.fromJson(e)) .toList(), + hadith: json['hadiths'] + ?.map((e) => HadithModel.fromJson(e)) + .toList(), ); } } diff --git a/lib/features/level/domain/entity/level_entity.dart b/lib/features/level/domain/entity/level_entity.dart index cee3840..97718c8 100644 --- a/lib/features/level/domain/entity/level_entity.dart +++ b/lib/features/level/domain/entity/level_entity.dart @@ -1,3 +1,4 @@ +import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart'; import 'package:hive/hive.dart'; @@ -13,11 +14,14 @@ class LevelEntity extends HiveObject { String? title; @HiveField(3) List? questions; + @HiveField(4) + List? hadith; LevelEntity({ this.id, this.order, this.title, this.questions, + this.hadith, }); } diff --git a/lib/features/level/domain/entity/level_entity.g.dart b/lib/features/level/domain/entity/level_entity.g.dart index 22ae93a..9d13e75 100644 --- a/lib/features/level/domain/entity/level_entity.g.dart +++ b/lib/features/level/domain/entity/level_entity.g.dart @@ -21,13 +21,14 @@ class LevelEntityAdapter extends TypeAdapter { order: fields[1] as int?, title: fields[2] as String?, questions: (fields[3] as List?)?.cast(), + hadith: (fields[4] as List?)?.cast(), ); } @override void write(BinaryWriter writer, LevelEntity obj) { writer - ..writeByte(4) + ..writeByte(5) ..writeByte(0) ..write(obj.id) ..writeByte(1) @@ -35,7 +36,9 @@ class LevelEntityAdapter extends TypeAdapter { ..writeByte(2) ..write(obj.title) ..writeByte(3) - ..write(obj.questions); + ..write(obj.questions) + ..writeByte(4) + ..write(obj.hadith); } @override diff --git a/lib/features/question/data/model/hadith_model.dart b/lib/features/question/data/model/hadith_model.dart new file mode 100644 index 0000000..5ffc8c0 --- /dev/null +++ b/lib/features/question/data/model/hadith_model.dart @@ -0,0 +1,21 @@ +import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; + +class HadithModel extends HadithEntity { + HadithModel({ + super.id, + super.hadithText, + super.narratorName, + super.translation, + super.status, + }); + + factory HadithModel.fromJson(Map json) { + return HadithModel( + id: json['id'], + hadithText: json['hadith_text'], + narratorName: json['narrator_name'], + translation: json['translation'], + status: json['status'], + ); + } +} diff --git a/lib/features/question/domain/entity/hadith_entity.dart b/lib/features/question/domain/entity/hadith_entity.dart new file mode 100644 index 0000000..72abd4b --- /dev/null +++ b/lib/features/question/domain/entity/hadith_entity.dart @@ -0,0 +1,25 @@ +import 'package:hive/hive.dart'; + +part 'hadith_entity.g.dart'; + +@HiveType(typeId: 5) +class HadithEntity extends HiveObject { + @HiveField(0) + int? id; + @HiveField(1) + String? hadithText; + @HiveField(2) + String? narratorName; + @HiveField(3) + String? translation; + @HiveField(4) + String? status; + + HadithEntity({ + this.id, + this.hadithText, + this.narratorName, + this.translation, + this.status, + }); +} diff --git a/lib/features/question/domain/entity/hadith_entity.g.dart b/lib/features/question/domain/entity/hadith_entity.g.dart new file mode 100644 index 0000000..8ceaf78 --- /dev/null +++ b/lib/features/question/domain/entity/hadith_entity.g.dart @@ -0,0 +1,53 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'hadith_entity.dart'; + +// ************************************************************************** +// TypeAdapterGenerator +// ************************************************************************** + +class HadithEntityAdapter extends TypeAdapter { + @override + final int typeId = 5; + + @override + HadithEntity read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return HadithEntity( + id: fields[0] as int?, + hadithText: fields[1] as String?, + narratorName: fields[2] as String?, + translation: fields[3] as String?, + status: fields[4] as String?, + ); + } + + @override + void write(BinaryWriter writer, HadithEntity obj) { + writer + ..writeByte(5) + ..writeByte(0) + ..write(obj.id) + ..writeByte(1) + ..write(obj.hadithText) + ..writeByte(2) + ..write(obj.narratorName) + ..writeByte(3) + ..write(obj.translation) + ..writeByte(4) + ..write(obj.status); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is HadithEntityAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/lib/features/question/presentation/bloc/question_bloc.dart b/lib/features/question/presentation/bloc/question_bloc.dart index 975a973..3d5613f 100644 --- a/lib/features/question/presentation/bloc/question_bloc.dart +++ b/lib/features/question/presentation/bloc/question_bloc.dart @@ -68,7 +68,11 @@ class QuestionBloc extends Bloc { } void showHadith({required BuildContext context}) { - showHadithDialog(context: context); + if(isPlaying) return; + showHadithDialog( + context: context, + hadith: state.levelEntity?.hadith ?? [], + ); } void goToLevelPage({required BuildContext context}) { @@ -98,13 +102,13 @@ class QuestionBloc extends Bloc { ); } - Future playback() async { + Future playback(BuildContext context) async { if (isPlaying) return; for (int i = 0; i < 4; i++) { await Future.delayed(Duration(seconds: 1)); - if (ContextProvider.context.mounted) { + if (context.mounted) { await showAnswerDialog( - context: ContextProvider.context, + context: context, answerEntity: state.currentQuestion?.answers?[i] ?? AnswerEntity(), ); isPlaying = true; @@ -123,6 +127,7 @@ class QuestionBloc extends Bloc { id: data.id, order: data.order, title: data.title, + hadith: data.hadith, questions: [ ...?data.questions, QuestionEntity(order: (data.questions?.length ?? 0) + 1) @@ -134,7 +139,9 @@ class QuestionBloc extends Bloc { currentQuestion: data.questions?.first, )); await playVoice(); - playback(); + if(event.context.mounted){ + playback(event.context); + } }, (error) { emit(state.copyWith(getQuestionStatus: BaseError(error.errorMessage))); @@ -177,7 +184,9 @@ class QuestionBloc extends Bloc { } } else { await playVoice(); - playback(); + if(event.context.mounted){ + playback(event.context); + } } }); } diff --git a/lib/features/question/presentation/bloc/question_event.dart b/lib/features/question/presentation/bloc/question_event.dart index 57570dc..6f716d2 100644 --- a/lib/features/question/presentation/bloc/question_event.dart +++ b/lib/features/question/presentation/bloc/question_event.dart @@ -1,16 +1,20 @@ +import 'package:flutter/cupertino.dart'; + sealed class QuestionEvent { const QuestionEvent(); } class GetLevelEvent extends QuestionEvent { final String? id; - const GetLevelEvent(this.id); + final BuildContext context; + const GetLevelEvent(this.id, this.context); } class ChooseAnswerEvent extends QuestionEvent { final bool chooseCorrectAnswer; final int correctAnswer; - const ChooseAnswerEvent(this.chooseCorrectAnswer, this.correctAnswer); + final BuildContext context; + const ChooseAnswerEvent(this.chooseCorrectAnswer, this.correctAnswer, this.context); } class GetNextLevelEvent extends QuestionEvent { diff --git a/lib/features/question/presentation/ui/screens/answer_screen.dart b/lib/features/question/presentation/ui/screens/answer_screen.dart index b54b18d..b14cd3c 100644 --- a/lib/features/question/presentation/ui/screens/answer_screen.dart +++ b/lib/features/question/presentation/ui/screens/answer_screen.dart @@ -22,7 +22,7 @@ class _AnswerScreenState extends State { Future back() async { await Future.delayed(Duration(seconds: 2), () { - if (ContextProvider.context.mounted) { + if (context.mounted) { Navigator.pop(ContextProvider.context); } }); diff --git a/lib/features/question/presentation/ui/screens/question_screen.dart b/lib/features/question/presentation/ui/screens/question_screen.dart index 467ca8b..7f4d6d1 100644 --- a/lib/features/question/presentation/ui/screens/question_screen.dart +++ b/lib/features/question/presentation/ui/screens/question_screen.dart @@ -99,7 +99,7 @@ class QuestionScreen extends StatelessWidget { correctAnswer: state.currentQuestion?.correctAnswer ?? 0, onTap: (isCorrect, correctAnswer) => context.read().add( - ChooseAnswerEvent(isCorrect, correctAnswer), + ChooseAnswerEvent(isCorrect, correctAnswer, context), ), ), ), @@ -157,7 +157,7 @@ class QuestionScreen extends StatelessWidget { ), Spacer(), RefreshButton( - onTap: () => context.read().playback(), + onTap: () => context.read().playback(context), ), ], ); diff --git a/lib/init_bindings.dart b/lib/init_bindings.dart index 931d43b..bfce909 100644 --- a/lib/init_bindings.dart +++ b/lib/init_bindings.dart @@ -22,6 +22,7 @@ import 'package:hadi_hoda_flutter/features/question/data/datasource/question_dat import 'package:hadi_hoda_flutter/features/question/data/repository_impl/question_repository_impl.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/answer_entity.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/file_entity.dart'; +import 'package:hadi_hoda_flutter/features/question/domain/entity/hadith_entity.dart'; import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart'; import 'package:hadi_hoda_flutter/features/question/domain/repository/question_repository.dart'; import 'package:hadi_hoda_flutter/features/question/domain/usecases/get_level_usecase.dart'; @@ -78,6 +79,7 @@ Future initDataBase() async { ..registerAdapter(FileEntityAdapter()) ..registerAdapter(AnswerEntityAdapter()) ..registerAdapter(QuestionEntityAdapter()) + ..registerAdapter(HadithEntityAdapter()) ..registerAdapter(LevelEntityAdapter()) ..registerAdapter(TotalDataEntityAdapter());