WT 1.1.20(4) Training plan improvements
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/training_evaluation_exercise.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
part 'training_evaluation_event.dart';
|
||||
part 'training_evaluation_state.dart';
|
||||
|
||||
class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvaluationState> {
|
||||
final TrainingPlanBloc trainingPlanBloc;
|
||||
final String day;
|
||||
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial());
|
||||
|
||||
String duration = "-";
|
||||
String totalLift = "0";
|
||||
String maxTotalLift = "0";
|
||||
String maxRepeats = "0";
|
||||
DateTime? end;
|
||||
|
||||
List<TrainingEvaluationExercise> evaluationList = [];
|
||||
|
||||
@override
|
||||
Stream<TrainingEvaluationState> mapEventToState(
|
||||
TrainingEvaluationEvent event,
|
||||
) async* {
|
||||
try {
|
||||
if (event is TrainingEvaluationLoad) {
|
||||
yield TrainingEvaluationLoading();
|
||||
await saveResult();
|
||||
getDuration();
|
||||
getTotalLift();
|
||||
getMaxRepeats();
|
||||
createEvaluationData();
|
||||
//getMaxTotalLift();
|
||||
if (end == null || DateTime.now().difference(end!).inMinutes > 5) {
|
||||
yield TrainingEvaluationReady();
|
||||
} else {
|
||||
yield TrainingEvaluationVictoryReady();
|
||||
}
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield TrainingEvaluationError(message: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> saveResult() async {}
|
||||
|
||||
void createEvaluationData() {
|
||||
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||
if (!element.state.equalsTo(ExercisePlanDetailState.extra)) {
|
||||
if (!findExerciseInEvaluationList(element.exerciseTypeId!)) {
|
||||
addEvaluationExercise(element);
|
||||
} else {
|
||||
//editEvaluationExercise(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool findExerciseInEvaluationList(int exerciseTypeId) {
|
||||
bool found = false;
|
||||
for (var exercise in evaluationList) {
|
||||
if (exercise.exerciseTypeId == exerciseTypeId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void addEvaluationExercise(CustomerTrainingPlanDetails detail) {
|
||||
TrainingEvaluationExercise exercise = TrainingEvaluationExercise();
|
||||
exercise.exerciseTypeId = detail.exerciseTypeId!;
|
||||
exercise.name = detail.exerciseType!.nameTranslation;
|
||||
exercise.state = detail.state;
|
||||
|
||||
if (detail.state.equalsTo(ExercisePlanDetailState.skipped)) {
|
||||
TrainingEvaluationExercise exercise = TrainingEvaluationExercise();
|
||||
exercise.exerciseTypeId = detail.exerciseTypeId!;
|
||||
exercise.name = detail.exerciseType!.nameTranslation;
|
||||
exercise.state = ExercisePlanDetailState.skipped;
|
||||
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
||||
this.evaluationList.add(exercise);
|
||||
} else {
|
||||
if (detail.exerciseType!.unitQuantityUnit == null) {
|
||||
exercise.type = TrainingEvaluationExerciseType.repeatBased;
|
||||
exercise.repeats = detail.repeats;
|
||||
exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!);
|
||||
exercise.trend = getTrendEvaluationRepeats(exercise);
|
||||
} else {
|
||||
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
||||
exercise.oneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
exercise.max1RM = getMax1RMByExerciseType(detail.exerciseTypeId!);
|
||||
exercise.totalLift = (detail.weight! * detail.repeats!).round();
|
||||
exercise.maxTotalLift = getMaxTotalLiftByExerciseType(detail.exerciseTypeId!).round();
|
||||
exercise.trend = this.getTrendWeight(exercise.oneRepMax!, exercise.max1RM, exercise.totalLift, exercise.maxTotalLift);
|
||||
}
|
||||
exercise.trendText = getTrendText(exercise.trend!);
|
||||
exercise.trendColor = getTrendColor(exercise.trend!);
|
||||
this.evaluationList.add(exercise);
|
||||
}
|
||||
}
|
||||
|
||||
double getTrendEvaluationRepeats(TrainingEvaluationExercise exercise) {
|
||||
double rate = exercise.repeats! / exercise.maxRepeats!;
|
||||
return rate;
|
||||
}
|
||||
|
||||
String getTrendText(double rate) {
|
||||
if (rate > 1.10) {
|
||||
return "Strongly Growing";
|
||||
} else if (rate > 1.05) {
|
||||
return "Growing";
|
||||
} else if (rate < 0.90) {
|
||||
return "Strongly Sinking";
|
||||
} else if (rate < 0.95) {
|
||||
return "Sinking";
|
||||
} else {
|
||||
return "Stagnant";
|
||||
}
|
||||
}
|
||||
|
||||
Color getTrendColor(double rate) {
|
||||
if (rate > 1.10) {
|
||||
return Colors.green[900]!;
|
||||
} else if (rate > 1.05) {
|
||||
return Colors.green[300]!;
|
||||
} else if (rate < 0.90) {
|
||||
return Colors.red[900]!;
|
||||
} else if (rate < 0.95) {
|
||||
return Colors.green[400]!;
|
||||
} else {
|
||||
return Colors.white;
|
||||
}
|
||||
}
|
||||
|
||||
void getDuration() {
|
||||
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
|
||||
return;
|
||||
}
|
||||
int index = 0;
|
||||
DateTime? start;
|
||||
|
||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||
if (element.state.equalsTo(ExercisePlanDetailState.finished)) {
|
||||
if (index++ == 0) {
|
||||
start = element.exercises[0].dateAdd!;
|
||||
} else {
|
||||
if (element.exercises.length > 0) {
|
||||
this.end = element.exercises[element.exercises.length - 1].dateAdd!;
|
||||
}
|
||||
}
|
||||
//print("Exercise Date ${element.exercises[0].dateAdd!}");
|
||||
}
|
||||
});
|
||||
if (start == null) {
|
||||
this.duration = "00:00:00";
|
||||
} else if (this.end == null) {
|
||||
this.duration = "00:01:00";
|
||||
this.end = start;
|
||||
} else {
|
||||
this.duration = end!.difference(start!).inMinutes.toString();
|
||||
}
|
||||
}
|
||||
|
||||
void getTotalLift() {
|
||||
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
|
||||
return;
|
||||
}
|
||||
double total = 0;
|
||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||
if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unitQuantityUnit != null) {
|
||||
total += element.weight! * element.repeats!;
|
||||
}
|
||||
});
|
||||
totalLift = total.toStringAsFixed(0);
|
||||
}
|
||||
|
||||
void getMaxRepeats() {
|
||||
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
|
||||
return;
|
||||
}
|
||||
int max = 0;
|
||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||
if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unit != "second") {
|
||||
print("Repeats ${element.repeats}");
|
||||
if (max < element.repeats!) {
|
||||
max = element.repeats!;
|
||||
}
|
||||
}
|
||||
});
|
||||
maxRepeats = max.toStringAsFixed(0);
|
||||
}
|
||||
|
||||
double getMaxTotalLiftByExerciseType(int exerciseTypeId) {
|
||||
if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
double maxTotal = 0;
|
||||
Cache().getExercises()!.forEach((element) {
|
||||
if (element.exerciseTypeId == exerciseTypeId) {
|
||||
final double total = element.quantity! * element.unitQuantity!;
|
||||
if (maxTotal < total) {
|
||||
maxTotal = total;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return maxTotal;
|
||||
}
|
||||
|
||||
double getMax1RMByExerciseType(int exerciseTypeId) {
|
||||
if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
double max1RM = 0;
|
||||
Cache().getExercises()!.forEach((element) {
|
||||
if (element.exerciseTypeId == exerciseTypeId) {
|
||||
final double oneRepMax = Common.calculate1RM(element.unitQuantity!, element.quantity!);
|
||||
if (max1RM < oneRepMax) {
|
||||
max1RM = oneRepMax;
|
||||
}
|
||||
}
|
||||
});
|
||||
return max1RM;
|
||||
}
|
||||
|
||||
int getMaxRepeatsByExerciseType(int exerciseTypeId) {
|
||||
if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
int maxRepeats = 0;
|
||||
Cache().getExercises()!.forEach((element) {
|
||||
if (element.exerciseTypeId == exerciseTypeId) {
|
||||
final int repeats = element.quantity!.toInt();
|
||||
if (maxRepeats < repeats) {
|
||||
maxRepeats = repeats;
|
||||
}
|
||||
}
|
||||
});
|
||||
return maxRepeats;
|
||||
}
|
||||
|
||||
double getOneRepMax(CustomerTrainingPlanDetails detail) {
|
||||
if (detail.weight == null) {
|
||||
return 0;
|
||||
}
|
||||
return Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
}
|
||||
|
||||
double getTotalLiftExercise(CustomerTrainingPlanDetails detail) {
|
||||
if (detail.weight == null) {
|
||||
return 0;
|
||||
}
|
||||
return detail.weight! * detail.repeats!;
|
||||
}
|
||||
|
||||
double getTrendWeight(double oneRepMax, max1RM, totalLift, maxTotalLift) {
|
||||
double oneRepMaxRate = oneRepMax / max1RM;
|
||||
double totalLiftRate = totalLift / maxTotalLift;
|
||||
return (oneRepMaxRate + totalLiftRate) / 2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
part of 'training_evaluation_bloc.dart';
|
||||
|
||||
abstract class TrainingEvaluationEvent extends Equatable {
|
||||
const TrainingEvaluationEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class TrainingEvaluationLoad extends TrainingEvaluationEvent {
|
||||
const TrainingEvaluationLoad();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
part of 'training_evaluation_bloc.dart';
|
||||
|
||||
abstract class TrainingEvaluationState extends Equatable {
|
||||
const TrainingEvaluationState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class TrainingEvaluationInitial extends TrainingEvaluationState {
|
||||
const TrainingEvaluationInitial();
|
||||
}
|
||||
|
||||
class TrainingEvaluationLoading extends TrainingEvaluationState {
|
||||
const TrainingEvaluationLoading();
|
||||
}
|
||||
|
||||
class TrainingEvaluationReady extends TrainingEvaluationState {
|
||||
const TrainingEvaluationReady();
|
||||
}
|
||||
|
||||
class TrainingEvaluationVictoryReady extends TrainingEvaluationState {
|
||||
const TrainingEvaluationVictoryReady();
|
||||
}
|
||||
|
||||
class TrainingEvaluationError extends TrainingEvaluationState {
|
||||
final String message;
|
||||
const TrainingEvaluationError({required this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
Reference in New Issue
Block a user