import 'dart:async'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/customer_training_plan.dart'; import 'package:aitrainer_app/model/customer_training_plan_details.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise_plan_detail.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/training_plan_repository.dart'; import 'package:aitrainer_app/service/exercise_service.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; part 'training_plan_event.dart'; part 'training_plan_state.dart'; class TrainingPlanBloc extends Bloc { final TrainingPlanRepository trainingPlanRepository; final MenuBloc menuBloc; TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial()); CustomerTrainingPlan? _myPlan; bool started = false; final List dayNames = []; CustomerTrainingPlan? getMyPlan() => this._myPlan; setMyPlan(CustomerTrainingPlan? myPlan) => this._myPlan = myPlan; @override Stream mapEventToState(TrainingPlanEvent event) async* { try { if (event is TrainingPlanActivate) { yield TrainingPlanLoading(); _myPlan = await trainingPlanRepository.activateTrainingPlan(event.trainingPlanId); this.activateDays(); Cache().myTrainingPlan = _myPlan; await Cache().saveMyTrainingPlan(); yield TrainingPlanFinished(); } else if (event is TrainingPlanWeightChange) { yield TrainingPlanLoading(); event.detail.weight = event.weight; yield TrainingPlanReady(); } else if (event is TrainingPlanRepeatsChange) { yield TrainingPlanLoading(); event.detail.repeats = event.repeats; yield TrainingPlanReady(); } else if (event is TrainingPlanSaveExercise) { yield TrainingPlanLoading(); event.detail.state = ExercisePlanDetailState.inProgress; final Exercise exercise = Exercise(); exercise.customerId = Cache().userLoggedIn!.customerId!; exercise.exerciseTypeId = event.detail.exerciseTypeId; exercise.quantity = event.detail.repeats!.toDouble(); exercise.unit = event.detail.exerciseType!.unit; exercise.unitQuantity = event.detail.weight; exercise.dateAdd = DateTime.now(); event.detail.exercises.add(exercise); if (event.detail.exercises.length >= event.detail.set!) { event.detail.state = ExercisePlanDetailState.finished; } else if (event.detail.exercises.length >= 0) { event.detail.state = ExercisePlanDetailState.inProgress; } exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId; // save Exercise await ExerciseApi().addExercise(exercise); Cache().addExercise(exercise); Cache().myTrainingPlan = _myPlan; await Cache().saveMyTrainingPlan(); yield TrainingPlanReady(); } else if (event is TrainingPlanSkipExercise) { yield TrainingPlanLoading(); event.detail.state = ExercisePlanDetailState.skipped; Cache().myTrainingPlan = _myPlan; await Cache().saveMyTrainingPlan(); yield TrainingPlanReady(); } } on Exception catch (e) { yield TrainingPlanError(message: e.toString()); } } void activateDays() { if (_myPlan == null) { return; } dayNames.clear(); _myPlan!.days.clear(); String dayName = "."; _myPlan!.details.forEach((element) { if (element.day != null && element.day != dayName) { dayNames.add(element.day!); dayName = element.day!; } if (_myPlan!.days[dayName] == null) { if (dayName == ".") { dayName = ""; } _myPlan!.days[dayName] = []; } _myPlan!.days[dayName]!.add(element); }); if (dayNames.length == 0) { dayNames.add(""); _myPlan!.days[""] = []; _myPlan!.days[""]!.addAll(_myPlan!.details); } } CustomerTrainingPlanDetails? getTrainingPlanDetail(int trainingPlanDetailsId) { CustomerTrainingPlanDetails? detail; if (_myPlan == null || _myPlan!.details.isEmpty) { return null; } for (final det in this._myPlan!.details) { if (det.customerTrainingPlanDetailsId == trainingPlanDetailsId) { detail = det; break; } } return detail; } int? getActualWorkoutTreeId(int exerciseTypeId) { final WorkoutMenuTree? workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId); if (workoutTree == null) { return null; } return workoutTree.id; } String getActualImageName(int exerciseTypeId) { if (exerciseTypeId <= 0) { return ""; } final WorkoutMenuTree? workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId); if (workoutTree == null) { return ""; } return workoutTree.imageName; } CustomerTrainingPlanDetails? getNext() { if (_myPlan == null || _myPlan!.details.isEmpty) { return null; } CustomerTrainingPlanDetails? next; int minStep = 99; for (final detail in this._myPlan!.details) { if (!detail.state.equalsTo(ExercisePlanDetailState.finished)) { if (detail.exercises.isEmpty && !detail.state.equalsTo(ExercisePlanDetailState.skipped)) { next = detail; minStep = 1; break; } else { final int step = detail.exercises.length; if (step < minStep && !detail.state.equalsTo(ExercisePlanDetailState.skipped)) { next = detail; minStep = step; if (detail.parallel != true) { break; } } } } } print("Next detail $next"); return next; } bool isStarted() { if (_myPlan == null || _myPlan!.details.isEmpty) { return false; } if (_myPlan!.details[0].state == ExercisePlanDetailState.start) { return false; } else { return true; } } double getOffset() { double offset = 5; if (_myPlan == null) { return offset; } int indexInProgress = 0; int indexInStart = 0; for (var detail in _myPlan!.details) { if (detail.state == ExercisePlanDetailState.inProgress) { break; } if (detail.state == ExercisePlanDetailState.start) { break; } indexInStart++; indexInProgress++; } int index = indexInStart > indexInProgress ? indexInStart : indexInProgress; offset = index * 80; return offset; } }