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));
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 |