|
|
|
@ -3,6 +3,7 @@ import 'dart:async'; |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart'; |
|
|
|
import 'package:go_router/go_router.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_animations.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_audios.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/params/question_params.dart'; |
|
|
|
@ -44,6 +45,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
_backgroundAudioService.dispose(); |
|
|
|
answerAnimationController?.dispose(); |
|
|
|
imageAnimationController?.dispose(); |
|
|
|
globeAnimationController?.dispose(); |
|
|
|
scrollController.dispose(); |
|
|
|
return super.close(); |
|
|
|
} |
|
|
|
@ -66,6 +68,20 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
'hadith_key': GlobalKey(), |
|
|
|
'guide_key': GlobalKey(), |
|
|
|
}; |
|
|
|
final Map<String, double> globeStates = { |
|
|
|
MyAnimations.globeStateSpeaking: 0, |
|
|
|
MyAnimations.globeStateNormal: 0.25, |
|
|
|
MyAnimations.globeStateSuccess: 0.5, |
|
|
|
MyAnimations.globeStateWrong: 0.75, |
|
|
|
MyAnimations.globeStateAfterWrong: 1, |
|
|
|
}; |
|
|
|
final Map<double, String> statesGlobe = { |
|
|
|
0: MyAnimations.globeStateSpeaking, |
|
|
|
0.25: MyAnimations.globeStateNormal, |
|
|
|
0.5: MyAnimations.globeStateSuccess, |
|
|
|
0.75: MyAnimations.globeStateWrong, |
|
|
|
1: MyAnimations.globeStateAfterWrong, |
|
|
|
}; |
|
|
|
Stream<double>? volumeStream; |
|
|
|
bool showAnswerSequence = true; |
|
|
|
|
|
|
|
@ -75,6 +91,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
final AudioService _effectAudioService; |
|
|
|
AnimationController? answerAnimationController; |
|
|
|
AnimationController? imageAnimationController; |
|
|
|
AnimationController? globeAnimationController; |
|
|
|
final ScrollController scrollController = ScrollController(); |
|
|
|
|
|
|
|
/// ------------Functions------------ |
|
|
|
@ -163,6 +180,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
changeGlobeState(key: MyAnimations.globeStateNormal); |
|
|
|
} |
|
|
|
|
|
|
|
Future<void> showAnswerDialog({ |
|
|
|
@ -172,6 +190,9 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
bool showConfetti = false, |
|
|
|
bool autoClose = true, |
|
|
|
}) async { |
|
|
|
if(showConfetti == false){ |
|
|
|
changeGlobeState(key: MyAnimations.globeStateSpeaking); |
|
|
|
} |
|
|
|
await Navigator.of(context).push( |
|
|
|
HeroDialogRoute( |
|
|
|
builder: (dialogContext) { |
|
|
|
@ -184,6 +205,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
}, |
|
|
|
), |
|
|
|
); |
|
|
|
changeGlobeState(key: MyAnimations.globeStateNormal); |
|
|
|
} |
|
|
|
|
|
|
|
Future<void> getNextLevelEvent({required BuildContext context}) async { |
|
|
|
@ -213,6 +235,15 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
await _backgroundAudioService.play(); |
|
|
|
} |
|
|
|
|
|
|
|
void changeGlobeState({String? key}) { |
|
|
|
if (key?.isEmpty ?? true) return; |
|
|
|
|
|
|
|
globeAnimationController?.animateTo( |
|
|
|
globeStates[key] ?? 0, |
|
|
|
duration: const Duration(milliseconds: 0), |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
/// ------------Event Calls------------ |
|
|
|
FutureOr<void> _getLevelEvent(GetLevelEvent event, Emitter<QuestionState> emit) async { |
|
|
|
await _getLevelUseCase(QuestionParams(id: int.parse(event.id ?? '0'))).then( |
|
|
|
@ -236,6 +267,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
correctAnswer: false, |
|
|
|
)); |
|
|
|
imageAnimationController?.forward(); |
|
|
|
changeGlobeState(key: MyAnimations.globeStateSpeaking); |
|
|
|
await playQuestionAudio(); |
|
|
|
imageAnimationController?.reverse(); |
|
|
|
answerAnimationController?.forward().then((value) { |
|
|
|
@ -255,6 +287,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
emit(state.copyWith(correctAnswer: event.chooseCorrectAnswer)); |
|
|
|
|
|
|
|
if (event.chooseCorrectAnswer) { |
|
|
|
changeGlobeState(key: MyAnimations.globeStateSuccess); |
|
|
|
await showAnswerDialog( |
|
|
|
context: MyContext.get, |
|
|
|
correctAudio: state.currentQuestion?.correctAudio, |
|
|
|
@ -288,6 +321,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
await Future.delayed(const Duration(seconds: 1)); |
|
|
|
imageAnimationController?.forward(); |
|
|
|
scrollController.jumpTo(0); |
|
|
|
changeGlobeState(key: MyAnimations.globeStateSpeaking); |
|
|
|
await playQuestionAudio(); |
|
|
|
imageAnimationController?.reverse(); |
|
|
|
answerAnimationController?.forward().then((value) { |
|
|
|
@ -296,7 +330,11 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> { |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
changeGlobeState(key: MyAnimations.globeStateWrong); |
|
|
|
playWrongAudio(); |
|
|
|
await Future.delayed(const Duration(milliseconds: 1500), () { |
|
|
|
changeGlobeState(key: MyAnimations.globeStateAfterWrong); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |