You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							161 lines
						
					
					
						
							5.3 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							161 lines
						
					
					
						
							5.3 KiB
						
					
					
				
								import 'dart:async';
							 | 
						|
								
							 | 
						|
								import 'package:bloc/bloc.dart';
							 | 
						|
								import 'package:confetti/confetti.dart';
							 | 
						|
								import 'package:flutter/cupertino.dart';
							 | 
						|
								import 'package:go_router/go_router.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/constants/my_constants.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/params/question_params.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/routers/my_routes.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/services/audio_service.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/status/base_status.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/utils/context_provider.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/utils/local_storage.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/core/widgets/hadith_dialog/hadith_dialog.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/question/domain/usecases/get_level_usecase.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/question/domain/usecases/get_next_level_usecase.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/question/presentation/bloc/question_event.dart';
							 | 
						|
								import 'package:hadi_hoda_flutter/features/question/presentation/bloc/question_state.dart';
							 | 
						|
								import 'package:showcaseview/showcaseview.dart';
							 | 
						|
								
							 | 
						|
								class QuestionBloc extends Bloc<QuestionEvent, QuestionState> {
							 | 
						|
								  /// ------------constructor------------
							 | 
						|
								  QuestionBloc(
							 | 
						|
								      this._getLevelUseCase,
							 | 
						|
								      this._getNextLevelUseCase,
							 | 
						|
								      this._audioService,
							 | 
						|
								      ) : super(QuestionState()) {
							 | 
						|
								    volumeStream = _audioService.volumeStream();
							 | 
						|
								    on<GetLevelEvent>(_getLevelEvent);
							 | 
						|
								    on<ChooseAnswerEvent>(_chooseAnswerEvent);
							 | 
						|
								    on<GetNextLevelEvent>(_getNextLevelEvent);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  @override
							 | 
						|
								  Future<void> close() {
							 | 
						|
								    confettiController.dispose();
							 | 
						|
								    return super.close();
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /// ------------UseCases------------
							 | 
						|
								  final GetLevelUseCase _getLevelUseCase;
							 | 
						|
								  final GetNextLevelUseCase _getNextLevelUseCase;
							 | 
						|
								
							 | 
						|
								  /// ------------Variables------------
							 | 
						|
								  final List<GlobalKey> keys = [
							 | 
						|
								    GlobalKey(),
							 | 
						|
								    GlobalKey(),
							 | 
						|
								    GlobalKey(),
							 | 
						|
								    GlobalKey(),
							 | 
						|
								  ];
							 | 
						|
								  late final Stream<double> volumeStream;
							 | 
						|
								
							 | 
						|
								  /// ------------Controllers------------
							 | 
						|
								  final AudioService _audioService;
							 | 
						|
								  final ConfettiController confettiController = ConfettiController(
							 | 
						|
								    duration: Duration(seconds: 1),
							 | 
						|
								  );
							 | 
						|
								
							 | 
						|
								  /// ------------Functions------------
							 | 
						|
								  void startShowCase({required BuildContext context}) {
							 | 
						|
								    ShowCaseWidget.of(context).startShowCase([keys[1]]);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  void showHadith({required BuildContext context}) {
							 | 
						|
								    showHadithDialog(context: context);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  void goToLevelPage({required BuildContext context}) {
							 | 
						|
								    context.pushReplacement(Routes.levelPage);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  Future<void> playVoice() async {
							 | 
						|
								    await _audioService.setAudio(filePath: state.currentQuestion?.audio);
							 | 
						|
								    await _audioService.play();
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  Future<void> changeMute() async {
							 | 
						|
								    await _audioService.changeMute();
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  /// ------------Event Calls------------
							 | 
						|
								  FutureOr<void> _getLevelEvent(GetLevelEvent event, Emitter<QuestionState> emit) async {
							 | 
						|
								    await _getLevelUseCase(QuestionParams(id: int.parse(event.id ?? '0'))).then(
							 | 
						|
								      (value) {
							 | 
						|
								        value.fold(
							 | 
						|
								          (data) {
							 | 
						|
								            final LevelEntity level = LevelEntity(
							 | 
						|
								              id: data.id,
							 | 
						|
								              order: data.order,
							 | 
						|
								              title: data.title,
							 | 
						|
								              questions: [
							 | 
						|
								                ...?data.questions,
							 | 
						|
								                QuestionEntity(order: (data.questions?.length ?? 0) + 1)
							 | 
						|
								              ],
							 | 
						|
								            );
							 | 
						|
								            emit(state.copyWith(
							 | 
						|
								              getQuestionStatus: BaseComplete(''),
							 | 
						|
								              levelEntity: level,
							 | 
						|
								              currentQuestion: data.questions?.first,
							 | 
						|
								            ));
							 | 
						|
								            playVoice();
							 | 
						|
								          },
							 | 
						|
								          (error) {
							 | 
						|
								            emit(state.copyWith(getQuestionStatus: BaseError(error.errorMessage)));
							 | 
						|
								          },
							 | 
						|
								        );
							 | 
						|
								      },
							 | 
						|
								    );
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  FutureOr<void> _chooseAnswerEvent(ChooseAnswerEvent event,
							 | 
						|
								      Emitter<QuestionState> emit,) async {
							 | 
						|
								    emit(state.copyWith(correctAnswer: event.chooseCorrectAnswer));
							 | 
						|
								
							 | 
						|
								    if (event.chooseCorrectAnswer) {
							 | 
						|
								      confettiController.play();
							 | 
						|
								      await Future.delayed(Duration(seconds: 2), () async {
							 | 
						|
								        final QuestionEntity? findPreQuestion = state.currentQuestion;
							 | 
						|
								        final int findIndex = (findPreQuestion?.order ?? 1);
							 | 
						|
								        emit(
							 | 
						|
								          state.copyWith(
							 | 
						|
								            currentQuestion: state.levelEntity?.questions?[findIndex],
							 | 
						|
								          ),
							 | 
						|
								        );
							 | 
						|
								        if (state.currentQuestion?.order ==
							 | 
						|
								            state.levelEntity?.questions?.length) {
							 | 
						|
								           int currentLevel = int.parse(
							 | 
						|
								              LocalStorage.readData(key: MyConstants.currentLevel) ?? '1');
							 | 
						|
								           ++currentLevel;
							 | 
						|
								          await LocalStorage.saveData(
							 | 
						|
								            key: MyConstants.currentLevel,
							 | 
						|
								            value: '$currentLevel',
							 | 
						|
								          );
							 | 
						|
								        } else {
							 | 
						|
								          await playVoice();
							 | 
						|
								        }
							 | 
						|
								      });
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  FutureOr<void> _getNextLevelEvent(GetNextLevelEvent event,
							 | 
						|
								      Emitter<QuestionState> emit) async {
							 | 
						|
								    await _getNextLevelUseCase(QuestionParams()).then((value) =>
							 | 
						|
								        value.fold(
							 | 
						|
								          (data) {
							 | 
						|
								            ContextProvider.context.pushReplacementNamed(
							 | 
						|
								              Routes.questionPage,
							 | 
						|
								              pathParameters: {
							 | 
						|
								                'id': '${data.id}'
							 | 
						|
								              },
							 | 
						|
								            );
							 | 
						|
								          },
							 | 
						|
								          (error) {
							 | 
						|
								            goToLevelPage(context: ContextProvider.context);
							 | 
						|
								          },
							 | 
						|
								        ),
							 | 
						|
								    );
							 | 
						|
								  }
							 | 
						|
								}
							 |