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.
		
		
		
		
		
			
		
			
				
					
					
						
							188 lines
						
					
					
						
							6.6 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							188 lines
						
					
					
						
							6.6 KiB
						
					
					
				| 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/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/screen_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<LevelEvent, LevelState> { | |
|   /// ------------constructor------------ | |
|   LevelBloc( | |
|       this._getLeveslUseCase, | |
|       this._mainAudioService, | |
|       this._effectAudioService, | |
|       ) : super(const LevelState()) { | |
|     volumeStream = _mainAudioService.volumeStream(); | |
|     on<GetLevelListEvent>(_getLevelListEvent); | |
|     on<SetCurrentLevelEvent>(_setCurrentLevelEvent); | |
|     on<StartScrollEvent>(_startScrollEvent); | |
|     on<ChooseLevelEvent>(_chooseLevelEvent); | |
|   } | |
| 
 | |
|   @override | |
|   Future<void> close() { | |
|     scrollController.dispose(); | |
|     return super.close(); | |
|   } | |
| 
 | |
|   /// ------------UseCases------------ | |
|   final GetLevelsUseCase _getLeveslUseCase; | |
| 
 | |
|   /// ------------Variables------------ | |
|   final List<LevelLocation> locationList = [ | |
|     LevelLocation(bottom: 0.13.h, left: 0.2.w, index: 0), | |
|     LevelLocation(bottom: 0.25.h, left: 0.43.w, index: 1), | |
|     LevelLocation(bottom: 0.35.h, left: 0.22.w, index: 2), | |
|     LevelLocation(bottom: 0.5.h, left: 0.35.w, index: 3), | |
|     LevelLocation(bottom: 0.57.h, left: 0.6.w, index: 4), | |
|     LevelLocation(bottom: 0.65.h, left: 0.8.w, index: 5), | |
|     LevelLocation(bottom: 0.8.h, left: 0.82.w, index: 6), | |
|     LevelLocation(bottom: 1.0.h, left: 0.76.w, index: 7), | |
|     LevelLocation(bottom: 1.15.h, left: 0.6.w, index: 8), | |
|     LevelLocation(bottom: 1.2.h, left: 0.3.w, index: 9), | |
|     LevelLocation(bottom: 1.3.h, left: 0.07.w, index: 10), | |
|     LevelLocation(bottom: 1.38.h, left: 0.3.w, index: 11), | |
|     LevelLocation(bottom: 1.44.h, left: 0.55.w, index: 12), | |
|     LevelLocation(bottom: 1.54.h, left: 0.68.w, index: 13), | |
|     LevelLocation(bottom: 1.63.h, left: 0.6.w, index: 14), | |
|     LevelLocation(bottom: 1.75.h, left: 0.63.w, index: 15), | |
|     LevelLocation(bottom: 1.84.h, left: 0.43.w, index: 16), | |
|     LevelLocation(bottom: 1.82.h, left: 0.17.w, index: 17), | |
|     LevelLocation(bottom: 1.96.h, left: 0.05.w, index: 18), | |
|     LevelLocation(bottom: 2.08.h, left: 0.1.w, index: 19), | |
|     LevelLocation(bottom: 2.14.h, left: 0.3.w, index: 20), | |
|     LevelLocation(bottom: 2.24.h, left: 0.35.w, index: 21), | |
|     LevelLocation(bottom: 2.35.h, left: 0.2.w, index: 22), | |
|     LevelLocation(bottom: 2.44.h, left: 0.14.w, index: 23), | |
|     LevelLocation(bottom: 2.55.h, left: 0.28.w, index: 24), | |
|   ]; | |
| 
 | |
|   final List<LevelEntity> levelList = []; | |
| 
 | |
|   late final Stream<double> volumeStream; | |
| 
 | |
| 
 | |
| 
 | |
|   /// ------------Controllers------------ | |
|   final ScrollController scrollController = ScrollController(); | |
|   final AudioService _mainAudioService; | |
|   final AudioService _effectAudioService; | |
| 
 | |
|   /// ------------Functions------------ | |
|   void goToQuestionPage(BuildContext context, LevelEntity level){ | |
|     context.pushReplacementNamed( | |
|       Routes.questionPage, | |
|       pathParameters: { | |
|         'id': '${level.id}', | |
|       }, | |
|     ); | |
|   } | |
| 
 | |
|   void goToHomePage(BuildContext context){ | |
|     context.pop(); | |
|   } | |
| 
 | |
|   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<void> changeMute() async { | |
|     await Future.wait([ | |
|       _mainAudioService.changeMute(), | |
|       _effectAudioService.changeMute(), | |
|     ]); | |
|   } | |
| 
 | |
|   /// ------------Api Calls------------ | |
|   FutureOr<void> _getLevelListEvent(GetLevelListEvent event, | |
|       Emitter<LevelState> 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<void> _startScrollEvent( | |
|     StartScrollEvent event, | |
|     Emitter<LevelState> 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<void> _setCurrentLevelEvent(SetCurrentLevelEvent event, | |
|       Emitter<LevelState> 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<void> _chooseLevelEvent(ChooseLevelEvent event, | |
|       Emitter<LevelState> emit,) { | |
|     if (event.type != LevelType.unFinished) { | |
|       emit(state.copyWith(chooseLevel: event.level)); | |
|     } | |
|   } | |
| }
 |