WT 1.1.25 Training Plan Exercise Alternatives

This commit is contained in:
bossanyit 2021-12-18 18:03:52 +01:00
parent 54a61fa585
commit 05cace39bf
15 changed files with 297 additions and 734 deletions

View File

@ -388,7 +388,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -531,7 +531,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -566,7 +566,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 4;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (

View File

@ -1,43 +0,0 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
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:meta/meta.dart';
part 'exercise_log_event.dart';
part 'exercise_log_state.dart';
class ExerciseLogBloc extends Bloc<ExerciseLogEvent, ExerciseLogState> {
final ExerciseRepository exerciseRepository;
@override
ExerciseLogBloc({required this.exerciseRepository}) : super(ExerciseLogInitial());
@override
Stream<ExerciseLogState> mapEventToState(ExerciseLogEvent event) async* {
try {
if (event is ExerciseLogLoad) {
yield ExerciseLogLoading();
await Cache().setActivityDonePrefs(ActivityDone.isExerciseLogSeen);
Track().track(TrackingEvent.exercise_log_open);
yield ExerciseLogReady();
} else if (event is ExerciseLogDelete) {
yield ExerciseLogLoading();
exerciseRepository.exerciseList!.remove(event.exercise);
await exerciseRepository.deleteExercise(event.exercise);
Track().track(TrackingEvent.exercise_log_delete);
yield ExerciseLogReady();
} else if (event is ExerciseResult) {
yield ExerciseLogLoading();
Track().track(TrackingEvent.exercise_log_result);
yield ExerciseLogReady();
}
} on Exception catch (e) {
yield ExerciseLogError(message: e.toString());
}
}
}

View File

@ -1,25 +0,0 @@
part of 'exercise_log_bloc.dart';
@immutable
abstract class ExerciseLogEvent extends Equatable {
const ExerciseLogEvent();
@override
List<Object> get props => [];
}
class ExerciseLogLoad extends ExerciseLogEvent {
const ExerciseLogLoad();
}
class ExerciseLogDelete extends ExerciseLogEvent {
final Exercise exercise;
const ExerciseLogDelete({required this.exercise});
@override
List<Object> get props => [exercise];
}
class ExerciseResult extends ExerciseLogEvent {
const ExerciseResult();
}

View File

@ -1,29 +0,0 @@
part of 'exercise_log_bloc.dart';
@immutable
abstract class ExerciseLogState extends Equatable {
const ExerciseLogState();
@override
List<Object> get props => [];
}
class ExerciseLogInitial extends ExerciseLogState {
const ExerciseLogInitial();
}
class ExerciseLogLoading extends ExerciseLogState {
const ExerciseLogLoading();
}
class ExerciseLogReady extends ExerciseLogState {
const ExerciseLogReady();
}
class ExerciseLogError extends ExerciseLogState {
final String message;
const ExerciseLogError({required this.message});
@override
List<Object> get props => [message];
}

View File

@ -114,6 +114,7 @@ class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
to: DateTime(exercise.dateAdd!.year, exercise.dateAdd!.month, exercise.dateAdd!.day, exercise.dateAdd!.hour + 2, to: DateTime(exercise.dateAdd!.year, exercise.dateAdd!.month, exercise.dateAdd!.day, exercise.dateAdd!.hour + 2,
exercise.dateAdd!.minute, 0), exercise.dateAdd!.minute, 0),
background: Colors.orange[800]!, background: Colors.orange[800]!,
color: Colors.white,
isAllDay: false, isAllDay: false,
isTest: false, isTest: false,
isExercise: false, isExercise: false,
@ -123,9 +124,14 @@ class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
final ExerciseType? exerciseType = exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!); final ExerciseType? exerciseType = exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!);
final String exerciseName = isEnglish ? exerciseType!.name : exerciseType!.nameTranslation; final String exerciseName = isEnglish ? exerciseType!.name : exerciseType!.nameTranslation;
Color color = exercise.trainingPlanDetailsId == null ? Colors.blue : Colors.orange; Color background = exercise.trainingPlanDetailsId == null ? Colors.blue : Colors.orange;
if (exerciseTypeIdSearched == exercise.exerciseTypeId) { if (exerciseTypeIdSearched == exercise.exerciseTypeId) {
color = Color(0xffb4f500); background = Color(0xffb4f500);
}
Color color = Colors.white;
if (exerciseTypeIdSearched == exercise.exerciseTypeId) {
color = Colors.black;
} }
trainings.add(TrainingResult( trainings.add(TrainingResult(
@ -133,7 +139,8 @@ class TrainingLogBloc extends Bloc<TrainingLogEvent, TrainingLogState> {
eventName: exerciseName, eventName: exerciseName,
from: start, from: start,
to: end, to: end,
background: color, background: background,
color: color,
isAllDay: false, isAllDay: false,
isTest: exercise.trainingPlanDetailsId == null ? true : false, isTest: exercise.trainingPlanDetailsId == null ? true : false,
isExercise: true, isExercise: true,

View File

@ -1,3 +1,5 @@
import 'dart:collection';
import 'package:aitrainer_app/main.dart'; import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
@ -29,9 +31,12 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
final TrainingPlanRepository trainingPlanRepository; final TrainingPlanRepository trainingPlanRepository;
final MenuBloc menuBloc; final MenuBloc menuBloc;
TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial()) { TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial()) {
on<TrainingPlanCreateException>(_onCreateException);
on<TrainingPlanActivate>(_onActivate); on<TrainingPlanActivate>(_onActivate);
on<TrainingPlanWeightChangeRecalculate>(_onWeightChangeRecalculate); on<TrainingPlanWeightChangeRecalculate>(_onWeightChangeRecalculate);
on<TrainingPlanSaveExercise>(_onSaveExercise); on<TrainingPlanSaveExercise>(_onSaveExercise);
on<TrainingPlanAlternateChange>(_onChangeAlternate);
on<TrainingPlanSkipExercise>(_onSkipExercise); on<TrainingPlanSkipExercise>(_onSkipExercise);
on<TrainingPlanSkipEntireExercise>(_onSkipEntireExercise); on<TrainingPlanSkipEntireExercise>(_onSkipEntireExercise);
on<TrainingPlanFinishDropset>(_onFinishDropSet); on<TrainingPlanFinishDropset>(_onFinishDropSet);
@ -44,6 +49,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
on<TrainingPlanSetChange>(_onCustomPlanSetChange); on<TrainingPlanSetChange>(_onCustomPlanSetChange);
on<TrainingPlanRepeatsChange>(_onCustomPlanRepeatChange); on<TrainingPlanRepeatsChange>(_onCustomPlanRepeatChange);
on<TrainingPlanAddExerciseType>(_onCustomPlanAddExerciseType); on<TrainingPlanAddExerciseType>(_onCustomPlanAddExerciseType);
on<TrainingPlanGoToRestart>(_onRestarting);
// on<TrainingPlanError>(_onTrainingPlanError); // on<TrainingPlanError>(_onTrainingPlanError);
} }
@ -72,6 +78,9 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
CustomerTrainingPlanDetails? getMyDetail() => this._myDetail; CustomerTrainingPlanDetails? getMyDetail() => this._myDetail;
setMyDetail(CustomerTrainingPlanDetails? value) => this._myDetail = value; setMyDetail(CustomerTrainingPlanDetails? value) => this._myDetail = value;
HashMap<int, List<CustomerTrainingPlanDetails>> _alternatives = HashMap();
get alternatives => this._alternatives;
/// _onActivate /// _onActivate
/// activating the training plan, calculating the weights to the given repeats /// activating the training plan, calculating the weights to the given repeats
/// from previous exercises /// from previous exercises
@ -81,6 +90,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
emit(TrainingPlanLoading()); emit(TrainingPlanLoading());
_myPlan = trainingPlanRepository.activateTrainingPlan(event.trainingPlanId); _myPlan = trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
_myPlan!.type = CustomerTrainingPlanType.template; _myPlan!.type = CustomerTrainingPlanType.template;
this.createAlternatives();
menuBloc.menuTreeRepository.sortedTree.forEach((name, list) { menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
final List<WorkoutMenuTree> menuList = list as List<WorkoutMenuTree>; final List<WorkoutMenuTree> menuList = list as List<WorkoutMenuTree>;
@ -129,82 +139,129 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
/// event: TrainingPlanWeightChange /// event: TrainingPlanWeightChange
void _onSaveExercise(TrainingPlanSaveExercise event, Emitter<TrainingPlanState> emit) async { void _onSaveExercise(TrainingPlanSaveExercise event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading()); emit(TrainingPlanLoading());
if (event.detail.repeats == -1) { try {
emit(TrainingPlanReady()); if (event.detail.repeats == -1) {
throw Exception("Please type your repeats!"); 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;
} }
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 // recalculate the weight to the original planned repeats for the next details
int id = 0; int id = 0;
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) { if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
for (var nextDetail in _myPlan!.details) { double calculatedWeight = 0;
if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId) { for (var nextDetail in _myPlan!.details) {
if (id == 0 && nextDetail.customerTrainingPlanDetailsId == event.detail.customerTrainingPlanDetailsId) { if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId) {
id = nextDetail.customerTrainingPlanDetailsId!; 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"); double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
if (nextDetail.weight == -2 && nextDetail.customerTrainingPlanDetailsId != event.detail.customerTrainingPlanDetailsId) { print("NextDetail detail: $nextDetail *** PlanWeight: $weightFromPlan");
print("Nr 1. - recalculating -2 ${event.detail.customerTrainingPlanDetailsId}"); if (nextDetail.weight == -2 && nextDetail.customerTrainingPlanDetailsId != event.detail.customerTrainingPlanDetailsId) {
trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail); print("Nr 1. - recalculating -2 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble()); trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail);
} else if (weightFromPlan == -1 && nextDetail.set! > 1 && nextDetail.exercises.length == 1) { nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
print("Nr 2. recalculating -1 ${event.detail.customerTrainingPlanDetailsId}"); } else if (weightFromPlan == -1 && nextDetail.set! > 1 && nextDetail.exercises.length == 1) {
nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail); print("Nr 2. recalculating -1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble()); nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail);
} else if (nextDetail.weight == -1 && nextDetail.set! == 1) { nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
print("Nr 3. recalculating -1, set 1 ${event.detail.customerTrainingPlanDetailsId}"); } else if (nextDetail.weight == -1 && nextDetail.set! == 1) {
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail); print("Nr 3. recalculating -1, set 1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble()); nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
} else if (event.detail.set! == 1 && nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
(weightFromPlan == -2 || weightFromPlan == -1) && } else if (event.detail.set! == 1 &&
nextDetail.customerTrainingPlanDetailsId! > id) { (weightFromPlan == -2 || weightFromPlan == -1) &&
print("Nr 4. recalculating after the first exercise ${event.detail.customerTrainingPlanDetailsId}"); nextDetail.customerTrainingPlanDetailsId! == id + 1) {
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail); print("Nr 4. recalculating after the first exercise ${event.detail.customerTrainingPlanDetailsId}");
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble()); nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
calculatedWeight = nextDetail.weight!;
} else if (event.detail.set! == 1 &&
(weightFromPlan == -2 || weightFromPlan == -1) &&
nextDetail.customerTrainingPlanDetailsId! > id + 1) {
print("Nr 5. recalculating after the second exercise ${event.detail.customerTrainingPlanDetailsId}");
nextDetail.weight = calculatedWeight;
}
} }
} }
} }
exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId;
// save Exercise
Exercise savedExercise = await ExerciseApi().addExercise(exercise);
Cache().addExercise(savedExercise);
Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan();
} }
exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId; 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);
// save Exercise if (isDayDone()) {
Exercise savedExercise = await ExerciseApi().addExercise(exercise); this.add(TrainingPlanFinishDay());
Cache().addExercise(savedExercise); } else {
emit(TrainingPlanReady());
Cache().myTrainingPlan = _myPlan; }
await Cache().saveMyTrainingPlan(); } on Exception catch (e) {
emit(TrainingPlanError(message: e.toString()));
} }
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()) { void _onChangeAlternate(TrainingPlanAlternateChange event, Emitter<TrainingPlanState> emit) {
this.add(TrainingPlanFinishDay()); emit(TrainingPlanLoading());
} else { if (_myPlan == null || _myPlan!.details.length == 0) {
emit(TrainingPlanReady()); emit(TrainingPlanReady());
return;
}
int index = 0;
for (var planDetail in _myPlan!.details) {
int key = planDetail.customerTrainingPlanDetailsId!;
if (_alternatives[key]!.length >= event.index + 1 && _alternatives[key]![event.index].exerciseTypeId == event.detail.exerciseTypeId) {
CustomerTrainingPlanDetails alternative = _alternatives[key]![event.index];
_myPlan!.details[index] = alternative;
changeExerciseInDayNames(planDetail.exerciseTypeId!, planDetail.day!, alternative);
print("Changed alternative $alternative");
}
index++;
}
emit(TrainingPlanReady());
}
void changeExerciseInDayNames(int exerciseTypeId, String dayName, CustomerTrainingPlanDetails alternative) {
if (_myPlan != null && _myPlan!.days[dayName] != null) {
int index = 0;
for (var detail in _myPlan!.days[dayName]!) {
if (detail.exerciseTypeId == exerciseTypeId) {
_myPlan!.days[dayName]![index] = alternative;
}
index++;
}
} }
} }
@ -333,90 +390,80 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
} }
emit(TrainingPlanLoading()); emit(TrainingPlanLoading());
_myDetail!.exerciseType!.trainingPlanState = ExerciseTypeTrainingPlanState.added; _myDetail!.exerciseType!.trainingPlanState = ExerciseTypeTrainingPlanState.added;
_myDetail!.customerTrainingPlanDetailsId = _myPlan!.details.length + 1;
_myPlan!.details.add(this._myDetail!); _myPlan!.details.add(this._myDetail!);
emit(TrainingPlanReady()); emit(TrainingPlanReady());
} }
/*
@override
Stream<TrainingPlanState> mapEventToState(TrainingPlanEvent event) async* {
try {
if (event is TrainingPlanActivate) {
} else if (event is TrainingPlanWeightChange) {
} else if (event is TrainingPlanWeightChangeRecalculate) {
} else if (event is TrainingPlanRepeatsChange) {
} else if (event is TrainingPlanSetChange) {
} else if (event is TrainingPlanSaveExercise) {
} else if (event is TrainingPlanSkipExercise) {
} else if (event is TrainingPlanSkipEntireExercise) {
} else if (event is TrainingPlanFinishDay) {
} else if (event is TrainingPlanGoToRestart) {
yield TrainingPlanLoading();
restarting = true;
yield TrainingPlanDayReadyToRestart();
} else if (event is TrainingPlanAddExerciseType) {
} else if (event is TrainingPlanDeleteExerciseType) {
} else if (event is TrainingPlanCustomAddLoad) {
} else if (event is TrainingPlanChangeCancel) {
} else if (event is TrainingPlanFinishDropset) {
}
} on Exception catch (e) {
yield TrainingPlanError(message: e.toString());
}
} */
CustomerTrainingPlanDetails? createDetailFromExerciseType(ExerciseType exerciseType, CustomerTrainingPlanDetails origDetail) { void _onRestarting(TrainingPlanGoToRestart event, Emitter<TrainingPlanState> emit) async {
List<CustomerTrainingPlanDetails> list = []; emit(TrainingPlanLoading());
int index = 0; restarting = true;
TrainingPlanDetail? trainingPlanDetail; emit(TrainingPlanDayReadyToRestart());
if (_myTrainingPlan == null) { }
setTrainingPlanFromCache();
void _onCreateException(TrainingPlanCreateException event, Emitter<TrainingPlanState> emit) async {
emit(TrainingPlanLoading());
print("Bloc execption caught: ${event.message}");
emit(TrainingPlanError(message: event.message));
}
/* ***************************************************
* Helper Functions
******************************************************/
void createAlternatives() {
if (_myPlan == null || _myPlan!.details.length == 0 || _myPlan!.trainingPlanId == null) {
return;
} }
for (var planDetail in _myTrainingPlan!.details!) { _alternatives.clear();
if (planDetail.exerciseTypeId == origDetail.exerciseTypeId!) { TrainingPlanDetail? trainingPlanDetail;
trainingPlanDetail = planDetail; _myTrainingPlan = trainingPlanRepository.getTrainingPlanById(_myPlan!.trainingPlanId!);
_myPlan!.details.forEach((detail) {
if (detail.alternatives.length > 0) {
detail.alternatives.forEach((alternative) {
if (_myTrainingPlan != null) {
for (var planDetail in _myTrainingPlan!.details!) {
if (planDetail.exerciseTypeId == detail.exerciseTypeId!) {
trainingPlanDetail = planDetail;
CustomerTrainingPlanDetails alternativeDetail =
trainingPlanRepository.createAlternativeDetail(_myPlan!, detail, trainingPlanDetail!, alternative.exerciseTypeId);
if (_alternatives[alternativeDetail.customerTrainingPlanDetailsId!] == null) {
_alternatives[alternativeDetail.customerTrainingPlanDetailsId!] = [];
_alternatives[detail.customerTrainingPlanDetailsId!]!.add(detail); // element zero
}
if (!existsAlternativeExercise(detail.customerTrainingPlanDetailsId!, alternativeDetail)) {
_alternatives[alternativeDetail.customerTrainingPlanDetailsId!]!.add(alternativeDetail);
}
}
}
} else {
if (_alternatives[detail.customerTrainingPlanDetailsId!] == null) {
_alternatives[detail.customerTrainingPlanDetailsId!] = [];
_alternatives[detail.customerTrainingPlanDetailsId!]!.add(detail); // element zero
}
}
});
} else {
if (_alternatives[detail.customerTrainingPlanDetailsId!] == null) {
_alternatives[detail.customerTrainingPlanDetailsId!] = [];
}
_alternatives[detail.customerTrainingPlanDetailsId!]!.add(detail);
}
print(
"Created alternaties for ${detail.exerciseTypeId} and repeat ${detail.repeats} -- ${_alternatives[detail.customerTrainingPlanDetailsId!]}");
});
}
bool existsAlternativeExercise(int customerTrainingPlanDetailsId, CustomerTrainingPlanDetails alternative) {
bool exists = false;
for (var actual in _alternatives[customerTrainingPlanDetailsId]!) {
if (actual.exerciseTypeId == alternative.exerciseTypeId) {
exists = true;
break; 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;
} }
return exists;
} }
void backupDetail(CustomerTrainingPlanDetails detail) { void backupDetail(CustomerTrainingPlanDetails detail) {
@ -484,7 +531,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
} }
if (isDone100Percent()) { if (isDone100Percent()) {
//this.add(TrainingPlanGoToRestart()); this.add(TrainingPlanGoToRestart());
print("---------------- TrainingPlanGoToRestart"); print("---------------- TrainingPlanGoToRestart");
} }
dayNames.clear(); dayNames.clear();
@ -519,6 +566,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
_myPlan!.days[dayName]!.addAll(_myPlan!.details); _myPlan!.days[dayName]!.addAll(_myPlan!.details);
} }
getActiveDayIndex(); getActiveDayIndex();
createAlternatives();
} }
void activateTrainingPlanDays() { void activateTrainingPlanDays() {
@ -820,7 +869,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
if (activeDayIndex >= dayNames.length) { if (activeDayIndex >= dayNames.length) {
activeDayIndex = 0; activeDayIndex = 0;
//this.add(TrainingPlanGoToRestart()); this.add(TrainingPlanGoToRestart());
print("---------------- TrainingPlanGoToRestart"); print("---------------- TrainingPlanGoToRestart");
} }
print("ActiveDayIndex $activeDayIndex"); print("ActiveDayIndex $activeDayIndex");

View File

@ -28,22 +28,6 @@ class TrainingPlanWeightChange extends TrainingPlanEvent {
List<Object> get props => [weight, detail]; List<Object> get props => [weight, detail];
} }
class TrainingPlanWeightChangeUp extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail;
const TrainingPlanWeightChangeUp({required this.detail});
@override
List<Object> get props => [detail];
}
class TrainingPlanWeightChangeDown extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail;
const TrainingPlanWeightChangeDown({required this.detail});
@override
List<Object> get props => [detail];
}
class TrainingPlanWeightChangeRecalculate extends TrainingPlanEvent { class TrainingPlanWeightChangeRecalculate extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail; final CustomerTrainingPlanDetails detail;
final double weight; final double weight;
@ -121,11 +105,11 @@ class TrainingPlanChangeCancel extends TrainingPlanEvent {
class TrainingPlanAlternateChange extends TrainingPlanEvent { class TrainingPlanAlternateChange extends TrainingPlanEvent {
final int index; final int index;
final ExerciseType exerciseType; final CustomerTrainingPlanDetails detail;
const TrainingPlanAlternateChange({required this.index, required this.exerciseType}); const TrainingPlanAlternateChange({required this.index, required this.detail});
@override @override
List<Object> get props => [index, exerciseType]; List<Object> get props => [index, detail];
} }
class TrainingPlanFinishDropset extends TrainingPlanEvent { class TrainingPlanFinishDropset extends TrainingPlanEvent {
@ -151,3 +135,11 @@ class TrainingPlanDeleteExerciseType extends TrainingPlanEvent {
@override @override
List<Object> get props => [exerciseType]; List<Object> get props => [exerciseType];
} }
class TrainingPlanCreateException extends TrainingPlanEvent {
final String message;
const TrainingPlanCreateException({required this.message});
@override
List<Object> get props => [message];
}

View File

@ -22,7 +22,6 @@ import 'package:aitrainer_app/view/customer_weight_page.dart';
import 'package:aitrainer_app/view/customer_welcome_page.dart'; import 'package:aitrainer_app/view/customer_welcome_page.dart';
import 'package:aitrainer_app/view/evaluation_page.dart'; import 'package:aitrainer_app/view/evaluation_page.dart';
import 'package:aitrainer_app/view/exercise_control_page.dart'; import 'package:aitrainer_app/view/exercise_control_page.dart';
import 'package:aitrainer_app/view/exercise_log_page.dart';
import 'package:aitrainer_app/view/faq_page.dart'; import 'package:aitrainer_app/view/faq_page.dart';
import 'package:aitrainer_app/view/login.dart'; import 'package:aitrainer_app/view/login.dart';
import 'package:aitrainer_app/view/exercise_new_page.dart'; import 'package:aitrainer_app/view/exercise_new_page.dart';
@ -279,7 +278,6 @@ class WorkoutTestApp extends StatelessWidget {
'account': (context) => AccountPage(), 'account': (context) => AccountPage(),
'settings': (context) => SettingsPage(), 'settings': (context) => SettingsPage(),
'myDevelopment': (context) => MyDevelopmentPage(), 'myDevelopment': (context) => MyDevelopmentPage(),
'exerciseLogPage': (context) => ExerciseLogPage(),
'mydevelopmentLog': (context) => MyDevelopmentLog(), 'mydevelopmentLog': (context) => MyDevelopmentLog(),
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(), 'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(), 'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),

View File

@ -7,6 +7,7 @@ class TrainingResult {
final DateTime from; final DateTime from;
final DateTime to; final DateTime to;
Color background; Color background;
Color color;
final bool isAllDay; final bool isAllDay;
final bool isTest; final bool isTest;
final bool isExercise; final bool isExercise;
@ -18,6 +19,7 @@ class TrainingResult {
required this.from, required this.from,
required this.to, required this.to,
required this.background, required this.background,
required this.color,
required this.isAllDay, required this.isAllDay,
required this.exercise, required this.exercise,
required this.isTest, required this.isTest,

View File

@ -60,85 +60,58 @@ class TrainingPlanRepository {
plan.active = true; plan.active = true;
plan.status = "open"; plan.status = "open";
plan.dateAdd = DateTime.now(); plan.dateAdd = DateTime.now();
plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations[AppLanguage().appLocal.toString()];
TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId); TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
if (trainingPlan == null || trainingPlan.details == null) { if (trainingPlan == null || trainingPlan.details == null) {
print("trainingPlan null"); print("trainingPlan null");
return null; return null;
} }
plan.name = trainingPlan.nameTranslations[AppLanguage().appLocal.toString()];
// 3 calculate weights // 3 calculate weights
int index = 0; int index = 0;
int exerciseTypeIdOrig = 0; int exerciseTypeIdOrig = 0;
trainingPlan.details!.forEach((elem) { trainingPlan.details!.forEach((elem) {
List<CustomerTrainingPlanDetails> list = createDetail(plan, elem, exerciseTypeIdOrig, index); List<CustomerTrainingPlanDetails> list = createDetail(plan, elem, exerciseTypeIdOrig, index);
exerciseTypeIdOrig = elem.exerciseTypeId;
list.forEach((element) { list.forEach((element) {
plan.details.add(element); plan.details.add(element);
index++;
}); });
/* CustomerTrainingPlanDetails detail = CustomerTrainingPlanDetails();
detail.customerTrainingPlanDetailsId = ++index;
detail.trainingPlanDetailsId = elem.trainingPlanDetailId;
detail.exerciseTypeId = elem.exerciseTypeId;
detail.repeats = elem.repeats;
detail.set = elem.set;
detail.dayId = elem.dayId;
TrainingPlanDayRepository trainingPlanDayRepository = TrainingPlanDayRepository();
detail.day = trainingPlanDayRepository.getNameById(elem.dayId);
detail.parallel = elem.parallel;
detail.restingTime = elem.restingTime;
detail.exerciseType = Cache().getExerciseTypeById(detail.exerciseTypeId!);
detail.alternatives = Common.getExerciseTypeAlternatives(detail.exerciseTypeId);
if (elem.weight == -1) {
if (detail.exerciseType!.unitQuantityUnit != null) {
detail = getCalculatedWeightRepeats(elem.exerciseTypeId, detail);
} else {
detail.weight = 0;
}
} else if (elem.weight == -2) {
final CustomerTrainingPlanDetails calculated = this.isWeightCalculatedByExerciseType(elem.exerciseTypeId, detail, plan);
if (calculated.weight != -1) {
detail.weight = calculated.weight;
} else {
detail.weight = -2;
}
} else {
detail.weight = elem.weight;
}
print("Detail $detail exerciseType: ${detail.exerciseType!.exerciseTypeId}");
detail.state = ExercisePlanDetailState.start;
if (detail.weight != null && detail.weight! > 0) {
detail.baseOneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
}
detail.alternatives = Common.getExerciseTypeAlternatives(detail.exerciseTypeId);
// first repeat: 50% more
if (detail.weight != null && detail.weight! > 0 && exerciseTypeIdOrig != detail.exerciseTypeId && detail.repeats! > 0) {
CustomerTrainingPlanDetails firstDetail = CustomerTrainingPlanDetails();
firstDetail.copy(detail);
firstDetail.repeats = (detail.repeats! * 1.5).round();
firstDetail.set = 1;
detail.set = detail.set! - 1;
if (detail.set! > 0) {
index++;
}
detail.customerTrainingPlanDetailsId = index;
plan.details.add(firstDetail);
exerciseTypeIdOrig = detail.exerciseTypeId!;
}
if (detail.set! > 0) {
plan.details.add(detail);
} */
}); });
Cache().myTrainingPlan = plan; Cache().myTrainingPlan = plan;
//TrainingPlanApi().saveCustomerTrainingPlan(plan);
return plan; return plan;
} }
CustomerTrainingPlanDetails createAlternativeDetail(
CustomerTrainingPlan plan, CustomerTrainingPlanDetails detail, TrainingPlanDetail elem, int exerciseTypeId) {
CustomerTrainingPlanDetails alternativeDetail = CustomerTrainingPlanDetails();
alternativeDetail.copy(detail);
alternativeDetail.exerciseTypeId = exerciseTypeId;
alternativeDetail.exerciseType = Cache().getExerciseTypeById(exerciseTypeId);
if (elem.weight == -1) {
if (alternativeDetail.exerciseType!.unitQuantityUnit != null) {
alternativeDetail = getCalculatedWeightRepeats(elem.exerciseTypeId, alternativeDetail);
} else {
alternativeDetail.weight = 0;
}
} else if (elem.weight == -2) {
final CustomerTrainingPlanDetails calculated = this.isWeightCalculatedByExerciseType(elem.exerciseTypeId, alternativeDetail, plan);
if (calculated.weight != -1) {
alternativeDetail.weight = calculated.weight;
} else {
alternativeDetail.weight = -2;
}
} else {
alternativeDetail.weight = elem.weight;
}
//print("Detail $alternativeDetail exerciseType: ${alternativeDetail.exerciseType!.exerciseTypeId}");
return alternativeDetail;
}
List<CustomerTrainingPlanDetails> createDetail(CustomerTrainingPlan plan, TrainingPlanDetail elem, int exerciseTypeIdOrig, int index, List<CustomerTrainingPlanDetails> createDetail(CustomerTrainingPlan plan, TrainingPlanDetail elem, int exerciseTypeIdOrig, int index,
{bool changeExerciseType = false}) { {bool changeExerciseType = false}) {
List<CustomerTrainingPlanDetails> list = []; List<CustomerTrainingPlanDetails> list = [];
@ -183,19 +156,17 @@ class TrainingPlanRepository {
CustomerTrainingPlanDetails firstDetail = CustomerTrainingPlanDetails(); CustomerTrainingPlanDetails firstDetail = CustomerTrainingPlanDetails();
firstDetail.copy(detail); firstDetail.copy(detail);
firstDetail.repeats = (detail.repeats! * 1.5).round(); firstDetail.repeats = (detail.repeats! * 1.5).round();
firstDetail.baseOneRepMax = Common.calculate1RM(firstDetail.weight!, firstDetail.repeats!.toDouble());
firstDetail.set = 1; firstDetail.set = 1;
detail.set = detail.set! - 1; detail.set = detail.set! - 1;
if (detail.set! > 0) { if (detail.set! > 0) {
index++; index++;
} }
detail.customerTrainingPlanDetailsId = index; detail.customerTrainingPlanDetailsId = index;
//plan.details.add(firstDetail);
list.add(firstDetail); list.add(firstDetail);
exerciseTypeIdOrig = detail.exerciseTypeId!;
} }
if (detail.set! > 0) { if (detail.set! > 0) {
//plan.details.add(detail);
list.add(detail); list.add(detail);
} }
return list; return list;
@ -237,7 +208,7 @@ class TrainingPlanRepository {
} }
for (var trainingPlan in Cache().getTrainingPlans()!) { for (var trainingPlan in Cache().getTrainingPlans()!) {
print("internal ${trainingPlan.internalName}"); //print("internal ${trainingPlan.internalName}");
if (trainingPlan.internalName == internalName) { if (trainingPlan.internalName == internalName) {
id = trainingPlan.trainingPlanId; id = trainingPlan.trainingPlanId;
break; break;
@ -266,7 +237,7 @@ class TrainingPlanRepository {
if (exercise.exerciseTypeId == exerciseTypeId && exercise.dateAdd!.compareTo(dt) >= 0) { if (exercise.exerciseTypeId == exerciseTypeId && exercise.dateAdd!.compareTo(dt) >= 0) {
detail.weight = weight; detail.weight = weight;
lastExercise1RM = exercise; lastExercise1RM = exercise;
print("last exercise: $exercise"); //print("last exercise: $exercise");
} }
}); });
@ -278,9 +249,9 @@ class TrainingPlanRepository {
double oneRepMax = calculateMax1RMSameDay(lastExercise1RM!); double oneRepMax = calculateMax1RMSameDay(lastExercise1RM!);
// Common.calculate1RM(lastExercise1RM!.unitQuantity!, lastExercise1RM!.quantity!); // Common.calculate1RM(lastExercise1RM!.unitQuantity!, lastExercise1RM!.quantity!);
print("Exercise $exerciseTypeId - 1RM : $oneRepMax"); //print("Exercise $exerciseTypeId - 1RM : $oneRepMax");
weight = oneRepMax * Common.get1RMPercent(detail.repeats!); weight = oneRepMax * Common.get1RMPercent(detail.repeats!);
print("Exercise $exerciseTypeId - weight : $weight"); //print("Exercise $exerciseTypeId - weight : $weight");
//weight = Common.roundWeight(weight); //weight = Common.roundWeight(weight);
//detail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), lastExercise1RM!.quantity!); //detail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), lastExercise1RM!.quantity!);
//weight = lastExercise1RM!.unitQuantity! * detail.repeats! / lastExercise1RM!.quantity!; //weight = lastExercise1RM!.unitQuantity! * detail.repeats! / lastExercise1RM!.quantity!;

View File

@ -153,7 +153,7 @@ mixin Common {
double rmWendler = weight * repeat * 0.0333 + weight; double rmWendler = weight * repeat * 0.0333 + weight;
double rmOconner = weight * (1 + repeat / 40); double rmOconner = weight * (1 + repeat / 40);
print("Weight: $weight repeat: $repeat, $rmWendler, Oconner: $rmOconner"); //print("Weight: $weight repeat: $repeat, $rmWendler, Oconner: $rmOconner");
double average = (rmWendler + rmOconner) / 2; double average = (rmWendler + rmOconner) / 2;
return average; return average;

View File

@ -1,362 +0,0 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_log/exercise_log_bloc.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:badges/badges.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/library/tree_view.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/material.dart';
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
// ignore: must_be_immutable
class ExerciseLogPage extends StatelessWidget with Trans, Common {
@override
Widget build(BuildContext context) {
LinkedHashMap arguments = ModalRoute.of(context)!.settings.arguments as LinkedHashMap;
final int customerId = arguments['customerId'];
setContext(context);
return BlocProvider(
create: (context) => ExerciseLogBloc(exerciseRepository: ExerciseRepository())..add(ExerciseLogLoad()),
child: BlocConsumer<ExerciseLogBloc, ExerciseLogState>(listener: (context, state) {
if (state is ExerciseLogError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
}, builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseLogBloc>(context);
return ModalProgressHUD(
child: getExerciseLog(customerId, exerciseBloc),
inAsyncCall: state is ExerciseLogLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}));
}
Widget getExerciseLog(int customerId, ExerciseLogBloc exerciseLogBloc) {
return Scaffold(
appBar: AppBarNav(depth: 1),
body: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
image: DecorationImage(
image: customerId == Cache().userLoggedIn!.customerId
? AssetImage('asset/image/WT_black_background.jpg')
: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: exerciseWidget(exerciseLogBloc, customerId),
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
);
}
Widget exerciseWidget(ExerciseLogBloc exerciseLogBloc, int customerId) {
return TreeView(
startExpanded: false,
children: _getTreeChildren(exerciseLogBloc, customerId),
);
}
List<Widget> _getTreeChildren(ExerciseLogBloc exerciseLogBloc, int customerId) {
final ExerciseRepository exerciseRepository = exerciseLogBloc.exerciseRepository;
if (customerId == Cache().userLoggedIn!.customerId) {
exerciseRepository.exerciseList = exerciseRepository.getExerciseList();
} else if (Cache().getTrainee() != null && customerId == Cache().getTrainee()!.customerId) {
exerciseRepository.exerciseList = exerciseRepository.getExerciseListTrainee();
}
//print("ExerciseList ${exerciseRepository.exerciseList}");
exerciseRepository.sortByDate();
List<Widget> listWidget = [];
Card explanation = Card(
color: Colors.white60,
child: Container(
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
children: [
Icon(
Icons.info,
color: Colors.orangeAccent,
),
Text(" "),
Text(
t("My Exercise Logs"),
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
],
),
Divider(
color: Colors.transparent,
),
Text(
t("In this list you will find all your executed exercises grouped by the date."),
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
),
],
)));
listWidget.add(explanation);
List<Exercise> listExercises = [];
String origDate = "";
exerciseRepository.exerciseLogList!.forEach((exercise) {
String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!);
if (origDate != exerciseDate) {
if (origDate.length == 0) {
listExercises.add(exercise);
origDate = exerciseDate;
} else {
listWidget.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: false,
parent: TreeviewParentWidget(text: origDate),
children: _getChildList(listExercises, exerciseRepository, exerciseLogBloc),
)));
listExercises = [];
listExercises.add(exercise);
origDate = exerciseDate;
}
} else {
listExercises.add(exercise);
origDate = exerciseDate;
}
});
//print("ListExerices $listExercises");
if (listExercises.length > 0) {
listWidget.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: true,
parent: TreeviewParentWidget(text: origDate),
children: _getChildList(listExercises, exerciseRepository, exerciseLogBloc),
)));
}
return listWidget;
}
List<Widget> _getChildList(List<Exercise> listExercises, ExerciseRepository exerciseRepository, ExerciseLogBloc exerciseLogBloc) {
List<Widget> list = [];
bool isEnglish = AppLanguage().appLocal == Locale('en');
listExercises.forEach((exercise) {
ExerciseType? exerciseType = exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!);
String exerciseName = isEnglish ? exerciseType!.name : exerciseType!.nameTranslation;
list.add(
Card(
margin: EdgeInsets.only(left: 10, top: 5),
color: Colors.white54,
child: Container(
padding: const EdgeInsets.only(left: 15, top: 0, right: 5, bottom: 0),
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Flexible(
fit: FlexFit.tight,
flex: 20,
child: Text(
exerciseName,
style: TextStyle(fontSize: 12, color: Colors.black),
),
),
Flexible(
fit: FlexFit.tight,
child: SizedBox(
width: 5,
)),
Flexible(
fit: FlexFit.tight,
flex: 20,
child: Text(
exercise.summary == null ? "" : exercise.summary!,
style: TextStyle(fontSize: 12, color: Colors.blue[800]),
)),
GestureDetector(
onTap: () => evaluation(exerciseRepository, exercise),
child: Badge(
elevation: 0,
padding: EdgeInsets.all(0),
position: BadgePosition.topStart(top: -5, start: -10),
animationDuration: Duration(milliseconds: 1500),
animationType: BadgeAnimationType.fade,
badgeColor: Colors.transparent,
showBadge: true,
badgeContent: /* IconButton(
iconSize: 36,
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
title: t("Premium function"),
descriptions: Cache().canTrial()
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
: t("This is a premium function, you can reach it only with a valid subscription"),
onCancel: () => Navigator.of(context).pop(),
onTap: () => Navigator.of(context).pop(),
text: '',
);
}),
icon: */
Icon(
Icons.star,
size: 14,
color: Colors.orange[400],
),
child: Image.asset(
"asset/image/kupa.png",
width: 35,
))),
Badge(
elevation: 0,
padding: EdgeInsets.all(0),
position: BadgePosition.topStart(top: 2, start: 5),
animationDuration: Duration(milliseconds: 1500),
animationType: BadgeAnimationType.fade,
badgeColor: Colors.transparent,
showBadge: true,
badgeContent: /* Icon(
iconSize: 36,
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
title: t("Premium function"),
descriptions: Cache().canTrial()
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
: t("This is a premium function, you can reach it only with a valid subscription"),
onCancel: () => Navigator.of(context).pop(),
onTap: () => Navigator.of(context).pop(),
text: '',
);
}), */
Icon(
Icons.star,
size: 14,
color: Colors.orange[400],
),
child: IconButton(
icon: Icon(Icons.delete, color: Colors.black12),
onPressed: () {
confirmationDialog(exerciseLogBloc, exercise);
},
)),
]),
)),
);
});
return list;
}
void evaluation(ExerciseRepository exerciseRepository, Exercise exercise) {
if (Cache().userLoggedIn != null) {
if (!Cache().hasPurchased) {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogPremium(
unlocked: Cache().hasPurchased,
unlockRound: 1,
unlockedText: t("Enjoy also this premium feature to show all old evaluation data of your successful exercises."),
function: "My Exercise Logs",
onTap: () => {Navigator.of(context).pop()},
onCancel: () => {Navigator.of(context).pop()},
);
});
} else {
LinkedHashMap args = LinkedHashMap();
args['exerciseRepository'] = exerciseRepository;
args['exercise'] = exercise;
args['past'] = true;
Navigator.of(context).pushNamed('evaluationPage', arguments: args);
}
}
}
void confirmationDialog(ExerciseLogBloc bloc, Exercise exercise) {
ExerciseType? exerciseType = bloc.exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!);
String exerciseName = AppLanguage().appLocal == Locale("en") ? exerciseType!.name : exerciseType!.nameTranslation;
String strDate = AppLanguage().appLocal == Locale("en")
? "on the " + DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(exercise.dateAdd!.toUtc())
: DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(exercise.dateAdd!.toUtc()) + "-n";
final String unitQuantity = exercise.unitQuantity == null ? "" : "x" + exercise.unitQuantity!.toStringAsFixed(0);
showCupertinoDialog(
useRootNavigator: true,
context: context,
//barrierDismissible: false,
builder: (_) => CupertinoAlertDialog(
title: Text(t("Are you sure to delete this exercise?")),
content: Column(children: [
Divider(),
Text(
t("Exercise") + ": " + exerciseName,
style: (TextStyle(color: Colors.blue)),
),
Text(
exercise.quantity!.toStringAsFixed(0) + unitQuantity + " ",
//+
//exerciseType.unitQuantityUnit == null
// ? ""
// : exerciseType.unitQuantityUnit,
style: (TextStyle(color: Colors.deepOrange)),
),
Text(
strDate,
style: (TextStyle(color: Colors.deepOrange)),
),
]),
actions: [
TextButton(
child: Text(t("No")),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(t("Yes")),
onPressed: () {
Navigator.pop(context);
if (!Cache().hasPurchased) {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogPremium(
unlocked: Cache().hasPurchased,
unlockRound: 1,
unlockedText: t("Enjoy also this premium fetaure to delete mistyped old exercises."),
function: "Delete Exercise",
onTap: () => {Navigator.of(context).pop()},
onCancel: () => {Navigator.of(context).pop()},
);
});
} else {
bloc.add(ExerciseLogDelete(exercise: exercise));
}
},
)
],
));
}
}

View File

@ -78,7 +78,6 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
return MenuSearchBar( return MenuSearchBar(
listItems: menuBloc.menuTreeRepository.menuAsExercise, listItems: menuBloc.menuTreeRepository.menuAsExercise,
onFind: (value) { onFind: (value) {
print("Found exercise $value");
if (value != null) { if (value != null) {
bloc.add(TrainingLogSearch(exerciseTypeId: value.exerciseTypeId)); bloc.add(TrainingLogSearch(exerciseTypeId: value.exerciseTypeId));
} }
@ -101,6 +100,7 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
showAgenda: true, showAgenda: true,
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator, appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
showTrailingAndLeadingDates: true, showTrailingAndLeadingDates: true,
appointmentDisplayCount: 12,
), ),
appointmentTimeTextFormat: 'HH:mm', appointmentTimeTextFormat: 'HH:mm',
headerDateFormat: "y MMMM", headerDateFormat: "y MMMM",
@ -146,7 +146,7 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
flex: 30, flex: 30,
child: Text(result.eventName, child: Text(result.eventName,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: result.isExercise ? 14 : 16, color: Colors.white, fontWeight: FontWeight.bold)), fontSize: result.isExercise ? 14 : 16, color: result.color, fontWeight: FontWeight.bold)),
), ),
Visibility( Visibility(
visible: result.isExercise, visible: result.isExercise,
@ -155,14 +155,13 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
flex: 25, flex: 25,
child: Text( child: Text(
result.summary == null ? "" : result.summary!, result.summary == null ? "" : result.summary!,
style: TextStyle(fontSize: 12, color: Colors.white), style: TextStyle(fontSize: 12, color: result.color),
))), ))),
IconButton( IconButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
icon: Icon(Icons.info_outline, color: Color(0xffb4f500)), icon: Icon(Icons.info_outline, color: result.color),
onPressed: () => result.isExercise ? evaluation(bloc.exerciseRepository, result.exercise!) : trainingEvaluation(), onPressed: () => result.isExercise ? evaluation(bloc.exerciseRepository, result.exercise!) : trainingEvaluation(),
), ),
/* */
])), ])),
)); ));
}), }),

View File

@ -5,7 +5,6 @@ import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/customer_training_plan_details.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/exercise_plan_detail.dart';
import 'package:aitrainer_app/util/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/dialog_common.dart'; import 'package:aitrainer_app/widgets/dialog_common.dart';
@ -515,55 +514,62 @@ class ExerciseTile extends StatelessWidget with Trans {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
setContext(context); setContext(context);
//bloc.setTileKey(tileKey); //print("Display Exercise: ${detail.exerciseTypeId}");
return CarouselSlider( return CarouselSlider(
options: CarouselOptions( options: CarouselOptions(
viewportFraction: 1, viewportFraction: 1,
reverse: false, reverse: false,
enableInfiniteScroll: false, enableInfiniteScroll: false,
autoPlay: false, autoPlay: false,
aspectRatio: 1.3, aspectRatio: 1.28,
enlargeCenterPage: true, enlargeCenterPage: false,
onPageChanged: (index, reason) => {print("index changed $index")}, onPageChanged: (index, reason) {
enlargeStrategy: CenterPageEnlargeStrategy.scale), if (detail.exercises.length == 0) {
int alternateIndex = index;
if (alternateIndex >= bloc.alternatives[detail.customerTrainingPlanDetailsId].length) {
alternateIndex = 0;
}
CustomerTrainingPlanDetails? alternate = bloc.alternatives[detail.customerTrainingPlanDetailsId][alternateIndex];
if (alternate != null) {
bloc.add(TrainingPlanAlternateChange(detail: alternate, index: alternateIndex));
}
} else {
bloc.add(TrainingPlanCreateException(message: t("This exericise has already been begun")));
}
},
),
items: getExerciseTiles(detail), items: getExerciseTiles(detail),
); );
} }
List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) { List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) {
final List<Widget> list = []; final List<Widget> list = [];
list.add(getTile(detail)); if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null &&
bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
/* if (detail.alternatives.length == 0) { int index = 0;
detail.alternatives = Common.getExerciseTypeAlternatives(detail.exerciseTypeId); for (CustomerTrainingPlanDetails alternative in bloc.alternatives[detail.customerTrainingPlanDetailsId]) {
final Widget widget = getTile(alternative, index);
list.add(widget);
index++;
}
} }
if (detail.alternatives.length > 0) {
detail.alternatives.forEach((element) {
CustomerTrainingPlanDetails? alternative = bloc.createDetailFromExerciseType(element, detail);
if (alternative != null) {
final Widget widget = getTile(alternative);
print("Alternatives for ${detail.exerciseTypeId}: $alternative");
list.add(widget);
}
});
} */
return list; return list;
} }
Widget getTile(CustomerTrainingPlanDetails detail) { Widget getTile(CustomerTrainingPlanDetails detail, int index) {
final CustomerTrainingPlanDetails? next = bloc.getNext(); final CustomerTrainingPlanDetails? next = bloc.getNext();
final bool noFilter = next != null && next.exerciseTypeId == detail.exerciseTypeId; final bool noFilter = next != null && next.exerciseTypeId == detail.exerciseTypeId;
final bool done = bloc.isAllDetailsSameExerciseFinished(detail); final bool done = bloc.isAllDetailsSameExerciseFinished(detail);
final bool buddyWarning = detail.exerciseType == null ? false : detail.exerciseType!.buddyWarning; final bool buddyWarning = detail.exerciseType == null ? false : detail.exerciseType!.buddyWarning;
final int step = bloc.getStep(detail); final int step = bloc.getStep(detail);
final int highlightStep = bloc.getHighlightStep(detail); final int highlightStep = bloc.getHighlightStep(detail);
final bool hasAlternative = detail.alternatives.length > 0; final bool hasLeftAlternative = detail.alternatives.length > 0 && index > 0;
final bool hasRightAlternative =
detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
return Container( return Container(
//key: this.tileKey, child: Stack(alignment: Alignment.centerRight, children: [
child: ClipRect(
child: Stack(alignment: Alignment.centerRight, children: [
Stack(alignment: Alignment.centerLeft, children: [ Stack(alignment: Alignment.centerLeft, children: [
Stack(alignment: Alignment.bottomLeft, children: [ Stack(alignment: Alignment.bottomLeft, children: [
Badge( Badge(
@ -684,7 +690,7 @@ class ExerciseTile extends StatelessWidget with Trans {
), ),
), ),
]), ]),
hasAlternative hasLeftAlternative
? Positioned( ? Positioned(
top: 50, top: 50,
child: Image.asset( child: Image.asset(
@ -695,7 +701,7 @@ class ExerciseTile extends StatelessWidget with Trans {
)) ))
: Offstage(), : Offstage(),
]), ]),
hasAlternative hasRightAlternative
? Positioned( ? Positioned(
top: 50, top: 50,
child: Transform.rotate( child: Transform.rotate(
@ -709,7 +715,7 @@ class ExerciseTile extends StatelessWidget with Trans {
)), )),
) )
: Offstage(), : Offstage(),
]))); ]));
} }
void skip() { void skip() {

View File

@ -112,8 +112,6 @@ class TrainingPlanExercise extends StatelessWidget with Trans {
set: detail.set, set: detail.set,
exerciseNr: detail.exercises.length + 1, exerciseNr: detail.exercises.length + 1,
onUnitQuantityChanged: (value) => bloc.add(TrainingPlanWeightChangeRecalculate(weight: value, detail: detail)), onUnitQuantityChanged: (value) => bloc.add(TrainingPlanWeightChangeRecalculate(weight: value, detail: detail)),
//onUnitQuantityChangeUp: () => bloc.add(TrainingPlanWeightChangeUp(detail: detail)),
//onUnitQuantityChangeDown: () => bloc.add(TrainingPlanWeightChangeDown(detail: detail)),
onQuantityChanged: (value) => bloc.add(TrainingPlanRepeatsChange(repeats: value.toInt(), detail: detail)), onQuantityChanged: (value) => bloc.add(TrainingPlanRepeatsChange(repeats: value.toInt(), detail: detail)),
exerciseTypeId: detail.exerciseType!.exerciseTypeId, exerciseTypeId: detail.exerciseType!.exerciseTypeId,
originalQuantity: originalQuantity, originalQuantity: originalQuantity,