import 'dart:async'; import 'dart:collection'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/exercise_device_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/cupertino.dart'; import 'package:aitrainer_app/library/image_cache.dart' as wt; part 'menu_event.dart'; part 'menu_state.dart'; class MenuBloc extends Bloc with Trans, Logging { final WorkoutTreeRepository menuTreeRepository; final ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository(); int parent = 0; WorkoutMenuTree? workoutItem; final List listFilterDevice = []; int missingParent = 0; String? missingTreeName = ""; late BuildContext context; ExerciseAbility? ability; MenuBloc({required this.menuTreeRepository}) : super(MenuInitial()) { parent = 0; on(_onCreate); on(_onRecreateTree); on(_onTreeDown); on(_onTreeUp); on(_onTreeJump); on(_onFilterExercise); } void _onCreate(MenuCreate event, Emitter emit) { emit(MenuLoading()); if (Cache().getDevices() != null) { exerciseDeviceRepository.setDevices(Cache().getDevices()!); } emit(MenuReady()); } void _onRecreateTree(MenuRecreateTree event, Emitter emit) { emit(MenuLoading()); // ie. at language changes menuTreeRepository.createTree(); emit(MenuReady()); } Future _onTreeDown(MenuTreeDown event, Emitter emit) async { emit(MenuLoading()); parent = event.parent; workoutItem = event.item; if (workoutItem != null) { setAbility(workoutItem!.internalName); } final LinkedHashMap branch = menuTreeRepository.getBranch(event.parent); await getImages(branch); emit(MenuReady()); } Future _onTreeUp(MenuTreeUp event, Emitter emit) async { emit(MenuLoading()); // get parent menus or exercises parent = event.parent; workoutItem = menuTreeRepository.getParentItem(parent); LinkedHashMap branch; if (workoutItem != null) { setAbility(workoutItem!.internalName); branch = menuTreeRepository.getBranch(workoutItem!.parent); await getImages(branch); } emit(MenuReady()); } Future _onTreeJump(MenuTreeJump event, Emitter emit) async { emit(MenuLoading()); parent = event.parent; workoutItem = menuTreeRepository.getParentItem(parent); if (workoutItem != null) { setAbility(workoutItem!.internalName); } final LinkedHashMap branch = menuTreeRepository.getBranch(workoutItem!.parent); await getImages(branch); emit(MenuReady()); } Future _onFilterExercise(MenuFilterExerciseType event, Emitter emit) async { emit(MenuLoading()); final int deviceId = event.deviceId; if (selectedDevice(deviceId)) { listFilterDevice.add(deviceId); } else { listFilterDevice.remove(deviceId); } emit(MenuReady()); } void setContext(BuildContext context) { this.context = context; } void setAbility(String name) { switch (name) { case "one_rep_max": ability = ExerciseAbility.oneRepMax; break; case "cardio": ability = ExerciseAbility.running; break; case "test_center": ability = ExerciseAbility.mini_test_set; break; case "training_plans": ability = ExerciseAbility.training; break; case "my_body": ability = ExerciseAbility.none; break; case "training_execute": ability = ExerciseAbility.training_execute; break; } log("Ability: " + ability.toString() + " name: " + name); } Future getImages(LinkedHashMap branch) async { wt.ImageCache().clearImageList(); await putBranchImageToHash(branch); log("downloaded image size in KB: " + wt.ImageCache().downloadSize.toString()); } Future putBranchImageToHash(LinkedHashMap branch) async { await Future.forEach(branch.keys, (key) async { final WorkoutMenuTree? value = branch[key]; if (value != null && !value.imageName.contains("asset")) { await wt.ImageCache().putImageToList(value.id, value.imageName); } }); } String? getImage(int id, String name) { String? imageString; if (name.contains("http")) { imageString = wt.ImageCache().getImageString(id, name); } return imageString; } bool selectedDevice(int deviceId) { return !listFilterDevice.contains(deviceId); } LinkedHashMap getFilteredBranch(int? parent) { if (parent == null) return LinkedHashMap(); LinkedHashMap branch = menuTreeRepository.getBranch(parent); if (!menuTreeRepository.isChild(parent) || ability.toString() == ExerciseAbility.none.toString() || listFilterDevice.isEmpty) { return branch; } LinkedHashMap filtered = LinkedHashMap(); branch.forEach((key, value) { final WorkoutMenuTree elem = value; if (elem.exerciseType != null) { for (int i = 0; i < elem.exerciseType!.devices.length; i++) { if (listFilterDevice.contains(elem.exerciseType!.devices[i])) { filtered[elem.name] = elem; } } } }); return filtered; } }