WT1.1.8+3 custom plan and training plan fixes

This commit is contained in:
bossanyit
2021-06-02 17:25:35 +02:00
parent 2b206fff49
commit d5deaf48a9
24 changed files with 1561 additions and 614 deletions
+270 -2
View File
@@ -6,11 +6,15 @@ 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/exercise_type.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:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
part 'training_plan_event.dart';
part 'training_plan_state.dart';
@@ -21,18 +25,34 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial());
CustomerTrainingPlan? _myPlan;
CustomerTrainingPlanDetails? _myDetail;
bool started = false;
final List<String> dayNames = [];
bool restarting = false;
bool celebrating = false;
int activeDayIndex = 0;
CustomerTrainingPlan? getMyPlan() => this._myPlan;
setMyPlan(CustomerTrainingPlan? myPlan) => this._myPlan = myPlan;
CustomerTrainingPlanDetails? getMyDetail() => this._myDetail;
setMyDetail(CustomerTrainingPlanDetails? value) => this._myDetail = value;
@override
Stream<TrainingPlanState> mapEventToState(TrainingPlanEvent event) async* {
try {
if (event is TrainingPlanActivate) {
yield TrainingPlanLoading();
_myPlan = await trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
_myPlan!.type = CustomerTrainingPlanType.template;
menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
final List<WorkoutMenuTree> menuList = list as List<WorkoutMenuTree>;
menuList.forEach((element) {
element.exerciseType!.trainingPlanState = ExerciseTypeTrainingPlanState.none;
});
});
this.activateDays();
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
@@ -47,6 +67,12 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
event.detail.repeats = event.repeats;
yield TrainingPlanReady();
} else if (event is TrainingPlanSetChange) {
yield TrainingPlanLoading();
event.detail.set = event.set;
yield TrainingPlanReady();
} else if (event is TrainingPlanSaveExercise) {
yield TrainingPlanLoading();
@@ -74,12 +100,76 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
yield TrainingPlanReady();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
yield TrainingPlanReady();
}
} else if (event is TrainingPlanSkipExercise) {
yield TrainingPlanLoading();
print("Skipping ${event.detail.exerciseTypeId}");
event.detail.state = ExercisePlanDetailState.skipped;
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
yield TrainingPlanReady();
}
} else if (event is TrainingPlanFinishDay) {
yield TrainingPlanLoading();
celebrating = true;
yield TrainingPlanDayFinished();
} else if (event is TrainingPlanGoToRestart) {
yield TrainingPlanLoading();
restarting = true;
yield TrainingPlanDayReadyToRestart();
} else if (event is TrainingPlanAddExerciseType) {
if (_myDetail == null) {
throw Exception("Create new Detail");
}
yield TrainingPlanLoading();
_myDetail!.exerciseType!.trainingPlanState = ExerciseTypeTrainingPlanState.added;
_myPlan!.details.add(this._myDetail!);
yield TrainingPlanReady();
} else if (event is TrainingPlanDeleteExerciseType) {
if (_myPlan == null || _myPlan!.details.isEmpty) {
throw Exception("No MyPlan");
}
yield TrainingPlanLoading();
CustomerTrainingPlanDetails? remove;
for (var detail in _myPlan!.details) {
if (event.exerciseType.exerciseTypeId == detail.exerciseTypeId) {
remove = detail;
break;
}
}
if (remove != null) {
_myPlan!.details.remove(remove);
}
event.exerciseType.trainingPlanState = ExerciseTypeTrainingPlanState.none;
yield TrainingPlanReady();
} else if (event is TrainingPlanCustomAddLoad) {
yield TrainingPlanLoading();
addNewPlan();
_myDetail = CustomerTrainingPlanDetails();
_myDetail!.exerciseType = event.exerciseType;
_myDetail!.exerciseTypeId = event.exerciseType.exerciseTypeId;
_myDetail!.repeats = 12;
_myDetail!.weight = 30;
_myDetail!.set = 3;
_myDetail!.parallel = false;
_myDetail!.day = "";
_myDetail!.restingTime = 2;
_myDetail!.state = ExercisePlanDetailState.start;
if (_myDetail!.exerciseType!.unitQuantityUnit != null) {
_myDetail = trainingPlanRepository.getCalculatedWeightRepeats(event.exerciseType.exerciseTypeId, _myDetail!);
} else {
_myDetail!.weight = 0;
}
yield TrainingPlanReady();
}
} on Exception catch (e) {
@@ -87,10 +177,51 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
}
void addNewPlan() {
if (_myPlan == null) {
_myPlan = CustomerTrainingPlan();
} else {
if (!_myPlan!.type.equalsTo(CustomerTrainingPlanType.custom)) {
_myPlan!.details.clear();
}
}
_myPlan!.trainingPlanId = 0;
_myPlan!.name = "Custom";
_myPlan!.customerId = Cache().userLoggedIn == null ? Cache().userLoggedIn!.customerId : 0;
_myPlan!.type = CustomerTrainingPlanType.custom;
restart();
print("New custom plan: $_myPlan");
}
void restart() {
if (_myPlan == null) {
return;
}
for (var day in dayNames) {
_myPlan!.days[day]!.clear();
}
_myPlan!.details.forEach((element) {
element.state = ExercisePlanDetailState.start;
element.exercises.clear();
});
dayNames.clear();
Cache().myTrainingPlan = _myPlan;
Cache().saveMyTrainingPlan();
restarting = false;
print("Restarting finished");
}
void activateDays() {
if (_myPlan == null) {
return;
}
if (isDone100Percent()) {
this.add(TrainingPlanGoToRestart());
}
dayNames.clear();
_myPlan!.days.clear();
String dayName = ".";
@@ -113,6 +244,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
_myPlan!.days[""] = [];
_myPlan!.days[""]!.addAll(_myPlan!.details);
}
getActiveDayIndex();
}
CustomerTrainingPlanDetails? getTrainingPlanDetail(int trainingPlanDetailsId) {
@@ -177,6 +309,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
}
print("Next detail $next");
return next;
}
@@ -192,6 +325,18 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
}
bool isDayDone() {
bool isDone = true;
final String day = dayNames[activeDayIndex];
for (var detail in _myPlan!.days[day]!) {
if (!detail.state.equalsTo(ExercisePlanDetailState.finished) && !detail.state.equalsTo(ExercisePlanDetailState.skipped)) {
isDone = false;
}
}
print("Is Day '$day' done: $isDone");
return isDone;
}
double getOffset() {
double offset = 5;
if (_myPlan == null) {
@@ -199,7 +344,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
int indexInProgress = 0;
int indexInStart = 0;
for (var detail in _myPlan!.details) {
final String day = dayNames[this.activeDayIndex];
for (var detail in _myPlan!.days[day]!) {
if (detail.state == ExercisePlanDetailState.inProgress) {
break;
}
@@ -213,4 +359,126 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
offset = index * 80;
return offset;
}
bool isDone100Percent() {
bool done = true;
if (_myPlan == null || _myPlan!.details.isEmpty) {
return false;
}
_myPlan!.details.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished) && !element.state.equalsTo(ExercisePlanDetailState.skipped)) {
done = false;
}
});
return done;
}
int getActiveDayIndex() {
if (restarting) {
return 0;
}
if (_myPlan == null || _myPlan!.details.isEmpty) {
throw Exception("No defined Training Plan");
}
if (dayNames.isEmpty || dayNames.length == 1) {
return 0;
}
activeDayIndex = 0;
for (var day in dayNames) {
if (_myPlan!.days[day] == null) {
throw Exception("Wrong activated day: $day does not exist");
}
bool isDone = true;
_myPlan!.days[day]!.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished) && !element.state.equalsTo(ExercisePlanDetailState.skipped)) {
isDone = false;
}
});
if (!isDone) {
break;
}
activeDayIndex++;
}
print("Active Day Index: $activeDayIndex");
if (activeDayIndex >= dayNames.length) {
activeDayIndex = 0;
this.add(TrainingPlanGoToRestart());
}
return activeDayIndex;
}
String getCustomAddSummary() {
String summary = "";
if (_myDetail == null || _myDetail!.set == null || _myDetail!.repeats == null) {
return summary;
}
summary = getMyDetail()!.set!.toStringAsFixed(0) + " x " + getMyDetail()!.repeats!.toStringAsFixed(0);
return summary;
}
String getExerciseName(Locale locale) {
String exerciseName = "";
if (_myDetail == null || _myDetail!.exerciseType == null) {
return exerciseName;
}
exerciseName =
AppLanguage().appLocal == Locale("en") ? getMyDetail()!.exerciseType!.name : getMyDetail()!.exerciseType!.nameTranslation;
return exerciseName;
}
String getWeightByExerciseType(ExerciseType exerciseType) {
double weight = 0;
if (_myPlan == null || _myPlan!.details.isEmpty) {
return weight.toStringAsFixed(0);
}
for (var detail in _myPlan!.details) {
if (exerciseType.exerciseTypeId == detail.exerciseTypeId) {
weight = detail.weight!;
break;
}
}
int decimal = weight % weight.round() == 0 ? 0 : 1;
return weight.toStringAsFixed(decimal);
}
String getSetByExerciseType(ExerciseType exerciseType) {
int value = 0;
if (_myPlan == null || _myPlan!.details.isEmpty) {
return value.toStringAsFixed(0);
}
for (var detail in _myPlan!.details) {
if (exerciseType.exerciseTypeId == detail.exerciseTypeId) {
value = detail.set!;
break;
}
}
return value.toStringAsFixed(0);
}
String getRepeatsByExerciseType(ExerciseType exerciseType) {
int value = 0;
if (_myPlan == null || _myPlan!.details.isEmpty) {
return value.toStringAsFixed(0);
}
for (var detail in _myPlan!.details) {
if (exerciseType.exerciseTypeId == detail.exerciseTypeId) {
value = detail.repeats!;
break;
}
}
return value.toStringAsFixed(0);
}
}
@@ -37,6 +37,15 @@ class TrainingPlanRepeatsChange extends TrainingPlanEvent {
List<Object> get props => [repeats, detail];
}
class TrainingPlanSetChange extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail;
final int set;
const TrainingPlanSetChange({required this.set, required this.detail});
@override
List<Object> get props => [set, detail];
}
class TrainingPlanSaveExercise extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail;
const TrainingPlanSaveExercise({required this.detail});
@@ -45,8 +54,16 @@ class TrainingPlanSaveExercise extends TrainingPlanEvent {
List<Object> get props => [detail];
}
class TrainingPlanFinishTraining extends TrainingPlanEvent {
const TrainingPlanFinishTraining();
class TrainingPlanFinishDay extends TrainingPlanEvent {
const TrainingPlanFinishDay();
}
class TrainingPlanRestart extends TrainingPlanEvent {
const TrainingPlanRestart();
}
class TrainingPlanGoToRestart extends TrainingPlanEvent {
const TrainingPlanGoToRestart();
}
class TrainingPlanSkipExercise extends TrainingPlanEvent {
@@ -56,3 +73,23 @@ class TrainingPlanSkipExercise extends TrainingPlanEvent {
@override
List<Object> get props => [detail];
}
class TrainingPlanAddExerciseType extends TrainingPlanEvent {
const TrainingPlanAddExerciseType();
}
class TrainingPlanDeleteExerciseType extends TrainingPlanEvent {
final ExerciseType exerciseType;
const TrainingPlanDeleteExerciseType({required this.exerciseType});
@override
List<Object> get props => [exerciseType];
}
class TrainingPlanCustomAddLoad extends TrainingPlanEvent {
final ExerciseType exerciseType;
const TrainingPlanCustomAddLoad({required this.exerciseType});
@override
List<Object> get props => [exerciseType];
}
@@ -23,6 +23,14 @@ class TrainingPlanFinished extends TrainingPlanState {
const TrainingPlanFinished();
}
class TrainingPlanDayFinished extends TrainingPlanState {
const TrainingPlanDayFinished();
}
class TrainingPlanDayReadyToRestart extends TrainingPlanState {
const TrainingPlanDayReadyToRestart();
}
class TrainingPlanError extends TrainingPlanState {
final String message;
const TrainingPlanError({required this.message});