WT 1.1.25+3 flutter 2.8, activate training plan

This commit is contained in:
bossanyit
2021-12-12 16:17:47 +01:00
parent 72ae1c8f8c
commit 54a61fa585
96 changed files with 944 additions and 655 deletions
@@ -17,7 +17,6 @@ import 'package:intl/intl.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:fl_chart/fl_chart.dart';
part 'development_by_muscle_event.dart';
@@ -14,9 +14,7 @@ import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';
part 'exercise_new_event.dart';
-1
View File
@@ -18,7 +18,6 @@ import 'package:aitrainer_app/util/trans.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:meta/meta.dart';
import 'package:aitrainer_app/library/image_cache.dart' as wt;
part 'menu_event.dart';
+1 -1
View File
@@ -172,7 +172,7 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
try {
productSet = int.parse(productSetString);
} on Exception catch (e) {
log("Define the right productset!");
log("Define the right productset! $e");
productSet = 2;
}
+19 -61
View File
@@ -9,8 +9,6 @@ import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
//import 'package:health/health.dart';
import 'package:meta/meta.dart';
part 'settings_event.dart';
part 'settings_state.dart';
@@ -20,71 +18,31 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
Locale? _locale;
BuildContext? context;
SettingsBloc({this.context}) : super(SettingsInitial());
void setLocale(Locale locale) {
_locale = locale;
SettingsBloc({this.context}) : super(SettingsInitial()) {
on<SettingsChangeLanguage>(_onChangeLanguage);
on<SettingsGetLanguage>(_onGetLanguage);
on<SettingsSetServer>(_onSetServer);
}
Locale? getLocale() {
return _locale;
void setLocale(Locale locale) => _locale = locale;
Locale? getLocale() => _locale;
void _onChangeLanguage(SettingsChangeLanguage event, Emitter<SettingsState> emit) async {
emit(SettingsLoading());
await _changeLang(event.language);
emit(SettingsReady());
}
@override
Stream<SettingsState> mapEventToState(
SettingsEvent event,
) async* {
if (event is SettingsChangeLanguage) {
yield SettingsLoading();
await _changeLang(event.language);
yield SettingsReady();
} else if (event is SettingsGetLanguage) {
await AppLanguage().fetchLocale();
_locale = AppLanguage().appLocal;
yield SettingsReady();
} else if (event is SettingsSetServer) {
//yield SettingsLoading();
final bool live = event.live;
Cache().setServer(live);
Track().track(TrackingEvent.settings_server, eventValue: live.toString());
//yield SettingsReady(_locale);
} else if (event is SettingsSetHardware) {
yield SettingsLoading();
bool selectedHardwareBefore = await Cache().selectedHardwareBefore();
log("selectedBefore " + selectedHardwareBefore.toString());
final bool hasHardware = event.hasHardware;
await Cache().setHardware(hasHardware);
if (hasHardware == true) {
await _accessHealthData();
}
Cache().initBadges();
yield SettingsReady();
} else if (event is SettingsActivateTutorial) {
yield SettingsLoading();
Cache().activitiesDone[event.activity.toStr()] = false;
print(" ----------------- Setting ${event.activity} to false");
yield SettingsReady();
}
void _onGetLanguage(SettingsGetLanguage event, Emitter<SettingsState> emit) async {
await AppLanguage().fetchLocale();
_locale = AppLanguage().appLocal;
emit(SettingsReady());
}
Future<void> _accessHealthData() async {
/* final List<HealthDataType> types = [
HealthDataType.ACTIVE_ENERGY_BURNED,
HealthDataType.WATER,
HealthDataType.STEPS,
HealthDataType.HEART_RATE,
HealthDataType.BASAL_ENERGY_BURNED,
HealthDataType.BODY_TEMPERATURE,
HealthDataType.HIGH_HEART_RATE_EVENT,
HealthDataType.LOW_HEART_RATE_EVENT,
HealthDataType.RESTING_HEART_RATE
];
final HealthFactory health = HealthFactory(); */
//DateTime now = DateTime.now();
//List<HealthDataPoint> _healthDataList = await health.getHealthDataFromTypes(now.subtract(Duration(minutes: 5)), now, types);
//log(_healthDataList.toString());
void _onSetServer(SettingsSetServer event, Emitter<SettingsState> emit) async {
final bool live = event.live;
Cache().setServer(live);
Track().track(TrackingEvent.settings_server, eventValue: live.toString());
}
Future<void> _changeLang(String lang) async {
@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:intl/intl.dart';
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
@@ -16,7 +15,9 @@ 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());
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) {
on<TrainingEvaluationLoad>(_onLoad);
}
String duration = "-";
String totalLift = "0";
@@ -27,6 +28,21 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
List<TrainingEvaluationExercise> evaluationList = [];
void _onLoad(TrainingEvaluationLoad event, Emitter<TrainingEvaluationState> emit) async {
getDuration();
getTotalLift();
getMaxRepeats();
getTotalRepeats();
createEvaluationData();
getMaxLift();
if (end == null || DateTime.now().difference(end!).inMinutes > 5) {
emit(TrainingEvaluationReady());
} else {
emit(TrainingEvaluationVictoryReady());
}
}
/*
@override
Stream<TrainingEvaluationState> mapEventToState(
TrainingEvaluationEvent event,
@@ -50,9 +66,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
} on Exception catch (e) {
yield TrainingEvaluationError(message: e.toString());
}
}
Future<void> saveResult() async {}
} */
void createEvaluationData() {
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
@@ -118,11 +132,11 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
}
String getTrendText(double rate) {
if (rate > 1.10) {
if (rate > 1.20) {
return "Strongly Growing";
} else if (rate > 1.05) {
return "Growing";
} else if (rate < 0.90) {
} else if (rate < 0.80) {
return "Strongly Sinking";
} else if (rate < 0.95) {
return "Sinking";
@@ -132,11 +146,11 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
}
Color getTrendColor(double rate) {
if (rate > 1.10) {
if (rate > 1.20) {
return Colors.green[900]!;
} else if (rate > 1.05) {
return Colors.green[300]!;
} else if (rate < 0.90) {
} else if (rate < 0.80) {
return Colors.red[900]!;
} else if (rate < 0.95) {
return Colors.red[400]!;
+7 -1
View File
@@ -18,6 +18,7 @@ part 'training_log_state.dart';
class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
final ExerciseRepository exerciseRepository = ExerciseRepository();
TrainingLogBloc() : super(TrainingLogInitial()) {
on<TrainingLogLoad>(_onLoad);
on<TrainingLogDelete>(_onDelete);
@@ -49,6 +50,11 @@ class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
emit(TrainingLogLoading());
exerciseRepository.exerciseList!.remove(event.exercise);
await exerciseRepository.deleteExercise(event.exercise);
if (Cache().getExercises() != null) {
Cache().getExercises()!.remove(event.exercise);
}
_results.clear();
_results.addAll(getTrainingResults());
Track().track(TrackingEvent.exercise_log_delete);
emit(TrainingLogReady());
}
@@ -119,7 +125,7 @@ class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
Color color = exercise.trainingPlanDetailsId == null ? Colors.blue : Colors.orange;
if (exerciseTypeIdSearched == exercise.exerciseTypeId) {
color = Colors.redAccent;
color = Color(0xffb4f500);
}
trainings.add(TrainingResult(
+361 -246
View File
@@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
@@ -29,7 +28,25 @@ part 'training_plan_state.dart';
class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
final TrainingPlanRepository trainingPlanRepository;
final MenuBloc menuBloc;
TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial());
TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial()) {
on<TrainingPlanActivate>(_onActivate);
on<TrainingPlanWeightChangeRecalculate>(_onWeightChangeRecalculate);
on<TrainingPlanSaveExercise>(_onSaveExercise);
on<TrainingPlanSkipExercise>(_onSkipExercise);
on<TrainingPlanSkipEntireExercise>(_onSkipEntireExercise);
on<TrainingPlanFinishDropset>(_onFinishDropSet);
on<TrainingPlanFinishDay>(_onFinishDay);
on<TrainingPlanChangeCancel>(_onChangeCancel);
on<TrainingPlanAddLoad>(_onCustomLoad);
on<TrainingPlanDeleteExerciseType>(_onDeleteExerciseType);
on<TrainingPlanWeightChange>(_onCustomWeightChange);
on<TrainingPlanSetChange>(_onCustomPlanSetChange);
on<TrainingPlanRepeatsChange>(_onCustomPlanRepeatChange);
on<TrainingPlanAddExerciseType>(_onCustomPlanAddExerciseType);
// on<TrainingPlanError>(_onTrainingPlanError);
}
CustomerTrainingPlan? _myPlan;
CustomerTrainingPlanDetails? _myDetail;
@@ -55,264 +72,351 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
CustomerTrainingPlanDetails? getMyDetail() => this._myDetail;
setMyDetail(CustomerTrainingPlanDetails? value) => this._myDetail = value;
/// _onActivate
/// activating the training plan, calculating the weights to the given repeats
/// from previous exercises
///
/// event: TrainingPlanActivate
void _onActivate(TrainingPlanActivate event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
_myPlan = 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();
Track().track(TrackingEvent.training_plan_start, eventValue: event.trainingPlanId.toString());
emit(TrainingPlanFinished());
}
void _onWeightChangeRecalculate(TrainingPlanWeightChangeRecalculate event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanExerciseLoading());
if (event.detail.baseOneRepMax > 0 && event.detail.repeats != -1) {
if (_myTrainingPlan == null) {
setTrainingPlanFromCache();
}
final int originalRepeats = trainingPlanRepository.getOriginalRepeats(_myTrainingPlan!.trainingPlanId, event.detail);
event.detail.repeats = Common.calculateQuantityByChangedWeight(event.detail.baseOneRepMax, event.weight, originalRepeats.toDouble());
print("Base1RM ${event.detail.baseOneRepMax} repeats: ${event.detail.repeats}");
if (event.detail.repeats! < 1) {
event.detail.repeats = 1;
event.detail.weight = trainingPlanRepository.getOriginalWeight(_myTrainingPlan!.trainingPlanId, event.detail);
}
ExerciseSaveStream().repeats = event.detail.repeats!;
ExerciseSaveStream().getStreamController().add(true);
}
event.detail.weight = event.weight;
///yield TrainingPlanExerciseReady();
emit(TrainingPlanReady());
}
/// _onSaveExercise
/// - save the executed exercise to the DB
/// - recalculate, if necessary the next weight to the give repeats
/// - track this event
/// - send the data to Mautic
/// if [DropSet], the just set the state of the detail to finish
///
/// event: TrainingPlanWeightChange
void _onSaveExercise(TrainingPlanSaveExercise event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
if (event.detail.repeats == -1) {
emit(TrainingPlanReady());
throw Exception("Please type your repeats!");
}
print("SAVE for ExerciseTypeID: ${event.detail.exerciseTypeId} weight: ${event.detail.weight}");
if (event.detail.weight == -3) {
print("DropSet");
event.detail.state = ExercisePlanDetailState.finished;
emit(TrainingPlanReady());
} else {
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 (this.isAllDetailsSameExerciseFinished(event.detail)) {
event.detail.state = ExercisePlanDetailState.finished;
}
// recalculate the weight to the original planned repeats for the next details
int id = 0;
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
for (var nextDetail in _myPlan!.details) {
if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId) {
if (id == 0 && nextDetail.customerTrainingPlanDetailsId == event.detail.customerTrainingPlanDetailsId) {
id = nextDetail.customerTrainingPlanDetailsId!;
}
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
print("NextDetail detail: $nextDetail *** PlanWeight: $weightFromPlan");
if (nextDetail.weight == -2 && nextDetail.customerTrainingPlanDetailsId != event.detail.customerTrainingPlanDetailsId) {
print("Nr 1. - recalculating -2 ${event.detail.customerTrainingPlanDetailsId}");
trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} else if (weightFromPlan == -1 && nextDetail.set! > 1 && nextDetail.exercises.length == 1) {
print("Nr 2. recalculating -1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} else if (nextDetail.weight == -1 && nextDetail.set! == 1) {
print("Nr 3. recalculating -1, set 1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} else if (event.detail.set! == 1 &&
(weightFromPlan == -2 || weightFromPlan == -1) &&
nextDetail.customerTrainingPlanDetailsId! > id) {
print("Nr 4. recalculating after the first exercise ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
}
}
}
}
exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId;
// save Exercise
Exercise savedExercise = await ExerciseApi().addExercise(exercise);
Cache().addExercise(savedExercise);
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
}
if (!isInDebugMode) {
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
Track().track(TrackingEvent.training_plan_execute, eventValue: event.detail.exerciseType!.name);
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
emit(TrainingPlanReady());
}
}
void _onSkipExercise(TrainingPlanSkipExercise event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
event.detail.state = ExercisePlanDetailState.skipped;
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
emit(TrainingPlanReady());
}
}
void _onSkipEntireExercise(TrainingPlanSkipEntireExercise event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(event.detail);
list.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished)) {
element.state = ExercisePlanDetailState.skipped;
}
Cache().myTrainingPlan = _myPlan;
});
await Cache().saveMyTrainingPlan();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
emit(TrainingPlanReady());
}
}
void _onFinishDropSet(TrainingPlanFinishDropset event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
event.detail.state = ExercisePlanDetailState.finished;
emit(TrainingPlanReady());
}
void _onFinishDay(TrainingPlanFinishDay event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
celebrating = true;
Track().track(TrackingEvent.training_plan_finished);
emit(TrainingPlanDayFinished());
}
void _onChangeCancel(TrainingPlanChangeCancel event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
print("Backup $_backupDetail");
if (_backupDetail != null) {
event.detail.repeats = _backupDetail!.repeats;
event.detail.weight = _backupDetail!.weight;
}
emit(TrainingPlanReady());
}
void _onCustomLoad(TrainingPlanAddLoad event, Emitter<TrainingPlanState> emit) async {
emit(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;
}
Track().track(TrackingEvent.training_plan_custom, eventValue: event.exerciseType.name);
emit(TrainingPlanReady());
}
void _onDeleteExerciseType(TrainingPlanDeleteExerciseType event, Emitter<TrainingPlanState> emit) async {
if (_myPlan == null || _myPlan!.details.isEmpty) {
throw Exception("No MyPlan");
}
emit(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;
emit(TrainingPlanReady());
}
/// _onWeightChange
/// change the weight of the actual [CustomerTrainingPlanDetails] from the UI
///
/// event: TrainingPlanWeightChange
void _onCustomWeightChange(TrainingPlanWeightChange event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanExerciseLoading());
event.detail.weight = event.weight;
emit(TrainingPlanExerciseReady());
emit(TrainingPlanReady());
}
void _onCustomPlanSetChange(TrainingPlanSetChange event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
event.detail.set = event.set;
emit(TrainingPlanReady());
}
void _onCustomPlanRepeatChange(TrainingPlanRepeatsChange event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
event.detail.repeats = event.repeats;
emit(TrainingPlanReady());
}
void _onCustomPlanAddExerciseType(TrainingPlanAddExerciseType event, Emitter<TrainingPlanState> emit) async {
if (_myDetail == null) {
throw Exception("Create new Detail");
}
emit(TrainingPlanLoading());
_myDetail!.exerciseType!.trainingPlanState = ExerciseTypeTrainingPlanState.added;
_myPlan!.details.add(this._myDetail!);
emit(TrainingPlanReady());
}
/*
@override
Stream<TrainingPlanState> mapEventToState(TrainingPlanEvent event) async* {
try {
if (event is TrainingPlanActivate) {
yield TrainingPlanLoading();
_myPlan = 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();
Track().track(TrackingEvent.training_plan_start, eventValue: event.trainingPlanId.toString());
yield TrainingPlanFinished();
} else if (event is TrainingPlanWeightChange) {
yield TrainingPlanExerciseLoading();
print("New weight: ${event.weight}");
event.detail.weight = event.weight;
yield TrainingPlanExerciseReady();
yield TrainingPlanReady();
} else if (event is TrainingPlanWeightChangeUp) {
yield TrainingPlanExerciseLoading();
if (event.detail.weight != null) {
event.detail.repeats =
Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.detail.weight! + 1);
event.detail.weight = event.detail.weight! + 1;
ExerciseSaveStream().weight = event.detail.weight!;
ExerciseSaveStream().repeats = event.detail.repeats!;
ExerciseSaveStream().getStreamController().add(true);
}
yield TrainingPlanExerciseReady();
yield TrainingPlanReady();
} else if (event is TrainingPlanWeightChangeDown) {
yield TrainingPlanExerciseLoading();
if (event.detail.weight != null) {
event.detail.repeats =
Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.detail.weight! - 1);
event.detail.weight = event.detail.weight! - 1;
ExerciseSaveStream().weight = event.detail.weight!;
ExerciseSaveStream().repeats = event.detail.repeats!;
ExerciseSaveStream().getStreamController().add(true);
}
yield TrainingPlanExerciseReady();
yield TrainingPlanReady();
} else if (event is TrainingPlanWeightChangeRecalculate) {
yield TrainingPlanExerciseLoading();
if (event.detail.baseOneRepMax > 0 && event.detail.repeats != -1) {
if (_myTrainingPlan == null) {
setTrainingPlanFromCache();
}
final int originalRepeats = trainingPlanRepository.getOriginalRepeats(_myTrainingPlan!.trainingPlanId, event.detail);
event.detail.repeats =
Common.calculateQuantityByChangedWeight(event.detail.baseOneRepMax, event.weight, originalRepeats.toDouble());
print("Base1RM ${event.detail.baseOneRepMax} repeats: ${event.detail.repeats}");
if (event.detail.repeats! < 1) {
event.detail.repeats = 1;
event.detail.weight = trainingPlanRepository.getOriginalWeight(_myTrainingPlan!.trainingPlanId, event.detail);
}
ExerciseSaveStream().repeats = event.detail.repeats!;
ExerciseSaveStream().getStreamController().add(true);
}
event.detail.weight = event.weight;
yield TrainingPlanExerciseReady();
yield TrainingPlanReady();
} else if (event is TrainingPlanWeightChangeRecalculate) {
} else if (event is TrainingPlanRepeatsChange) {
yield TrainingPlanExerciseLoading();
event.detail.repeats = event.repeats;
yield TrainingPlanExerciseReady();
yield TrainingPlanReady();
} else if (event is TrainingPlanSetChange) {
yield TrainingPlanLoading();
event.detail.set = event.set;
yield TrainingPlanReady();
} else if (event is TrainingPlanSaveExercise) {
yield TrainingPlanLoading();
if (event.detail.repeats == -1) {
yield TrainingPlanReady();
throw Exception("Please type your repeats!");
}
print("SAVE for ExerciseTypeID: ${event.detail.exerciseTypeId} weight: ${event.detail.weight}");
if (event.detail.weight == -3) {
print("DropSet");
event.detail.state = ExercisePlanDetailState.finished;
yield TrainingPlanReady();
} else {
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 (this.isAllDetailsSameExerciseFinished(event.detail)) {
event.detail.state = ExercisePlanDetailState.finished;
}
// recalculate the weight to the original planned repeats for the next details
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
for (var nextDetail in _myPlan!.details) {
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
print("NextDetail detail: $nextDetail *** PlanWeight: $weightFromPlan");
if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId &&
nextDetail.weight == -2 &&
nextDetail.customerTrainingPlanDetailsId != event.detail.customerTrainingPlanDetailsId) {
print("recalculating -2 ${event.detail.customerTrainingPlanDetailsId}");
trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && weightFromPlan == -1 && nextDetail.set! > 1) {
print("recalculating -1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && nextDetail.weight == -1 && nextDetail.set! == 1) {
print("recalculating -1, set 1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
} /* else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId &&
weightFromPlan == -2 &&
nextDetail.set! == 1 &&
nextDetail.exercises.length == 0) {
print("recalculating -1/ no exercise, set 1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
}*/
}
}
exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId;
// save Exercise
Exercise savedExercise = await ExerciseApi().addExercise(exercise);
Cache().addExercise(savedExercise);
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
}
if (!isInDebugMode) {
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
Track().track(TrackingEvent.training_plan_execute, eventValue: event.detail.exerciseType!.name);
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
yield TrainingPlanReady();
}
} else if (event is TrainingPlanSkipExercise) {
yield TrainingPlanLoading();
event.detail.state = ExercisePlanDetailState.skipped;
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
yield TrainingPlanReady();
}
} else if (event is TrainingPlanSkipEntireExercise) {
yield TrainingPlanLoading();
List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(event.detail);
list.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished)) {
element.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;
Track().track(TrackingEvent.training_plan_finished);
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;
}
Track().track(TrackingEvent.training_plan_custom, eventValue: event.exerciseType.name);
yield TrainingPlanReady();
} else if (event is TrainingPlanChangeCancel) {
yield TrainingPlanLoading();
print("Backup $_backupDetail");
if (_backupDetail != null) {
event.detail.repeats = _backupDetail!.repeats;
event.detail.weight = _backupDetail!.weight;
}
yield TrainingPlanReady();
} else if (event is TrainingPlanFinishDropset) {
yield TrainingPlanLoading();
event.detail.state = ExercisePlanDetailState.finished;
yield TrainingPlanReady();
}
} on Exception catch (e) {
yield TrainingPlanError(message: e.toString());
}
} */
CustomerTrainingPlanDetails? createDetailFromExerciseType(ExerciseType exerciseType, CustomerTrainingPlanDetails origDetail) {
List<CustomerTrainingPlanDetails> list = [];
int index = 0;
TrainingPlanDetail? trainingPlanDetail;
if (_myTrainingPlan == null) {
setTrainingPlanFromCache();
}
for (var planDetail in _myTrainingPlan!.details!) {
if (planDetail.exerciseTypeId == origDetail.exerciseTypeId!) {
trainingPlanDetail = planDetail;
break;
}
index++;
}
if (trainingPlanDetail != null) {
list =
trainingPlanRepository.createDetail(_myPlan!, trainingPlanDetail, exerciseType.exerciseTypeId, index, changeExerciseType: true);
List<int> deleteIndicies = [];
index = 0;
_myPlan!.details.forEach((element) {
if (element.exerciseTypeId == origDetail.exerciseTypeId) {
deleteIndicies.add(index);
}
index++;
});
index = 0;
deleteIndicies.forEach((i) {
_myPlan!.details.removeAt(i - index);
index++;
});
_myPlan!.details.insertAll(deleteIndicies[0], list);
}
if (list.length > 0) {
return list[0];
} else {
return null;
}
}
void backupDetail(CustomerTrainingPlanDetails detail) {
@@ -380,7 +484,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
if (isDone100Percent()) {
this.add(TrainingPlanGoToRestart());
//this.add(TrainingPlanGoToRestart());
print("---------------- TrainingPlanGoToRestart");
}
dayNames.clear();
_myPlan!.days.clear();
@@ -556,20 +661,29 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
int getStep(CustomerTrainingPlanDetails detail) {
List<CustomerTrainingPlanDetails> details = getAllDetailsSameExercise(detail);
int step = 0;
int indexElement = 0;
details.forEach((element) {
if (indexElement == 0) {
if (element.exercises.length < element.set! && element.exercises.length > 0) {
step = element.exercises.length;
} else {
step += element.exercises.length;
}
indexElement++;
});
step++;
//print("STEP: $step ");
return step;
}
int getHighlightStep(CustomerTrainingPlanDetails detail) {
List<CustomerTrainingPlanDetails> details = getAllDetailsSameExercise(detail);
int step = 0;
details.forEach((element) {
//print("Highlight element $element");
if (element.exercises.length >= element.set!) {
step++;
}
});
//print("Highlight step: $step ");
return step;
}
CustomerTrainingPlanDetails? getNext() {
if (_myPlan == null || _myPlan!.details.isEmpty) {
return null;
@@ -655,8 +769,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
}
prev = detail;
}
int index = indexInStart > indexInProgress ? indexInStart : indexInProgress;
offset = (index) * 300;
double index = indexInStart > indexInProgress ? indexInStart.toDouble() : indexInProgress.toDouble();
offset = 325 * index;
print("Offset: $offset day: $day ($indexInStart, $indexInProgress)");
return offset;
}
@@ -706,7 +820,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
if (activeDayIndex >= dayNames.length) {
activeDayIndex = 0;
this.add(TrainingPlanGoToRestart());
//this.add(TrainingPlanGoToRestart());
print("---------------- TrainingPlanGoToRestart");
}
print("ActiveDayIndex $activeDayIndex");
return activeDayIndex;
+20 -11
View File
@@ -119,20 +119,13 @@ class TrainingPlanChangeCancel extends TrainingPlanEvent {
List<Object> get props => [detail];
}
class TrainingPlanDeleteExerciseType extends TrainingPlanEvent {
class TrainingPlanAlternateChange extends TrainingPlanEvent {
final int index;
final ExerciseType exerciseType;
const TrainingPlanDeleteExerciseType({required this.exerciseType});
const TrainingPlanAlternateChange({required this.index, 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];
List<Object> get props => [index, exerciseType];
}
class TrainingPlanFinishDropset extends TrainingPlanEvent {
@@ -142,3 +135,19 @@ class TrainingPlanFinishDropset extends TrainingPlanEvent {
@override
List<Object> get props => [detail];
}
class TrainingPlanAddLoad extends TrainingPlanEvent {
final ExerciseType exerciseType;
const TrainingPlanAddLoad({required this.exerciseType});
@override
List<Object> get props => [exerciseType];
}
class TrainingPlanDeleteExerciseType extends TrainingPlanEvent {
final ExerciseType exerciseType;
const TrainingPlanDeleteExerciseType({required this.exerciseType});
@override
List<Object> get props => [exerciseType];
}