import 'dart:async'; import 'package:bloc/bloc.dart'; import 'package:flutter/cupertino.dart'; import 'package:go_router/go_router.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/level_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/local_storage.dart'; import 'package:hadi_hoda_flutter/core/utils/my_context.dart'; import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; import 'package:hadi_hoda_flutter/features/level/domain/entity/level_location.dart'; import 'package:hadi_hoda_flutter/features/level/domain/usecases/get_levels_usecase.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_event.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/bloc/level_state.dart'; import 'package:hadi_hoda_flutter/features/level/presentation/ui/widgets/level_widget.dart'; class LevelBloc extends Bloc { /// ------------constructor------------ LevelBloc( this._getLeveslUseCase, this._mainAudioService, this._effectAudioService, ) : super(const LevelState()) { volumeStream = _mainAudioService.volumeStream(); playMusic(); on(_getLevelListEvent); on(_setCurrentLevelEvent); on(_startScrollEvent); on(_chooseLevelEvent); } @override Future close() { scrollController.dispose(); return super.close(); } /// ------------UseCases------------ final GetLevelsUseCase _getLeveslUseCase; /// ------------Variables------------ final List locationList = [ LevelLocation( bottom: setSize(context: MyContext.get, mobile: -0.03.h, tablet: -0.03.h), left: setSize(context: MyContext.get, mobile: 0.1.w, tablet: 0.2.w), index: 0, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.03.h, tablet: 0.1.h), left: setSize(context: MyContext.get, mobile: 0.28.w, tablet: 0.4.w), index: 1, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.1.h, tablet: 0.21.h), left: setSize(context: MyContext.get, mobile: 0.14.w, tablet: 0.2.w), index: 2, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.2.h, tablet: 0.38.h), left: setSize(context: MyContext.get, mobile: 0.3.w, tablet: 0.3.w), index: 3, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.24.h, tablet: 0.47.h), left: setSize(context: MyContext.get, mobile: 0.5.w, tablet: 0.5.w), index: 4, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.33.h, tablet: 0.55.h), left: setSize(context: MyContext.get, mobile: 0.65.w, tablet: 0.8.w), index: 5, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.45.h, tablet: 0.8.h), left: setSize(context: MyContext.get, mobile: 0.57.w, tablet: 0.8.w), index: 6, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.55.h, tablet: 1.1.h), left: setSize(context: MyContext.get, mobile: 0.57.w, tablet: 0.77.w), index: 7, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.6.h, tablet: 1.2.h), left: setSize(context: MyContext.get, mobile: 0.4.w, tablet: 0.65.w), index: 8, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.63.h, tablet: 1.25.h), left: setSize(context: MyContext.get, mobile: 0.2.w, tablet: 0.3.w), index: 9, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.7.h, tablet: 1.38.h), left: setSize(context: MyContext.get, mobile: 0, tablet: 0.04.w), index: 10, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.75.h, tablet: 1.46.h), left: setSize(context: MyContext.get, mobile: 0.15.w, tablet: 0.22.w), index: 11, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.78.h, tablet: 1.52.h), left: setSize(context: MyContext.get, mobile: 0.4.w, tablet: 0.45.w), index: 12, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.85.h, tablet: 1.68.h), left: setSize(context: MyContext.get, mobile: 0.5.w, tablet: 0.68.w), index: 13, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 0.94.h, tablet: 1.8.h), left: setSize(context: MyContext.get, mobile: 0.45.w, tablet: 0.6.w), index: 14, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.02.h, tablet: 1.95.h), left: setSize(context: MyContext.get, mobile: 0.45.w, tablet: 0.6.w), index: 15, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.02.h, tablet: 2.01.h), left: setSize(context: MyContext.get, mobile: 0.2.w, tablet: 0.4.w), index: 16, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.02.h, tablet: 2.0.h), left: setSize(context: MyContext.get, mobile: 0, tablet: 0.1.w), index: 17, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.1.h, tablet: 2.17.h), left: setSize(context: MyContext.get, mobile: 0, tablet: 0.04.w), index: 18, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.2.h, tablet: 2.32.h), left: setSize(context: MyContext.get, mobile: 0.05.w, tablet: 0.1.w), index: 19, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.23.h, tablet: 2.35.h), left: setSize(context: MyContext.get, mobile: 0.23.w, tablet: 0.25.w), index: 20, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.31.h, tablet: 2.5.h), left: setSize(context: MyContext.get, mobile: 0.2.w, tablet: 0.33.w), index: 21, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.37.h, tablet: 2.6.h), left: setSize(context: MyContext.get, mobile: 0.1.w, tablet: 0.2.w), index: 22, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.45.h, tablet: 2.7.h), left: setSize(context: MyContext.get, mobile: 0.1.w, tablet: 0.1.w), index: 23, ), LevelLocation( bottom: setSize(context: MyContext.get, mobile: 1.5.h, tablet: 2.8.h), left: setSize(context: MyContext.get, mobile: 0.2.w, tablet: 0.15.w), index: 24, ), ]; final List levelList = []; late final Stream volumeStream; /// ------------Controllers------------ final ScrollController scrollController = ScrollController(); final AudioService _mainAudioService; final AudioService _effectAudioService; /// ------------Functions------------ Future playMusic() async { await Future.wait([ _mainAudioService.setAudio(assetPath: MyAudios.question), _mainAudioService.setVolume(volume: MyConstants.musicAudioVolume), _mainAudioService.setLoopMode(isLoop: true), ]); await _mainAudioService.play(); } void goToQuestionPage(BuildContext context, LevelEntity level){ context.pushReplacementNamed( Routes.questionPage, pathParameters: { 'id': '${level.id}', }, ); } void goToHomePage(BuildContext context) { context.goNamed(Routes.homePage); } LevelType getLevelType(int index) { final int currentLevel = int.parse( LocalStorage.readData(key: MyConstants.currentLevel) ?? '1', ); if (index < currentLevel) { return LevelType.finished; } else if (index == currentLevel) { return LevelType.current; } else { return LevelType.unFinished; } } Future changeMute() async { await Future.wait([ _mainAudioService.changeMute(volume: MyConstants.musicAudioVolume), _effectAudioService.changeMute(volume: MyConstants.effectAudioVolume), ]); } int get diamonds { int currentLevel = int.parse( LocalStorage.readData(key: MyConstants.currentLevel) ?? '1', ); return currentLevel - 1; } /// ------------Api Calls------------ FutureOr _getLevelListEvent(GetLevelListEvent event, Emitter emit) async { final int currentLevel = int.parse( LocalStorage.readData(key: MyConstants.currentLevel) ?? '1', ); await _getLeveslUseCase(LevelParams()).then((value) { value.fold( (data) async { levelList.addAll(data); try { emit(state.copyWith( getLevelStatus: const BaseComplete(''), chooseLevel: data.singleWhere((e) => e.order == currentLevel), )); } catch (e) { emit(state.copyWith( getLevelStatus: const BaseComplete(''), chooseLevel: LevelEntity(), )); } add(StartScrollEvent()); }, (error) {}, ); }); } FutureOr _startScrollEvent( StartScrollEvent event, Emitter emit, ) async { final int currentLevel = int.parse( LocalStorage.readData(key: MyConstants.currentLevel) ?? '1', ); await Future.delayed(const Duration(seconds: 1)); if (scrollController.hasClients) { if(currentLevel >= 14){ scrollController.animateTo( scrollController.position.maxScrollExtent, duration: const Duration(milliseconds: 500), // Note: 500 seconds is very long. curve: Curves.easeInOut, ); } else if( currentLevel > 8 && currentLevel < 14){ scrollController.animateTo( scrollController.position.maxScrollExtent / 2, duration: const Duration(milliseconds: 500), // Note: 500 seconds is very long. curve: Curves.easeInOut, ); } } } FutureOr _setCurrentLevelEvent(SetCurrentLevelEvent event, Emitter emit) async { final String? currentLevel = LocalStorage.readData( key: MyConstants.currentLevel); if (currentLevel == null || currentLevel.isEmpty) { await LocalStorage.saveData(key: MyConstants.currentLevel, value: '1'); } add(GetLevelListEvent()); } FutureOr _chooseLevelEvent(ChooseLevelEvent event, Emitter emit,) { if (event.type != LevelType.unFinished) { emit(state.copyWith(chooseLevel: event.level)); } } }