wt1.1.2 new treeview, bar chart for muscle development
This commit is contained in:
parent
4a193e085f
commit
89c06123d2
26
i18n/en.json
26
i18n/en.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"Customers And Exercises": "Customers And Exercises",
|
||||
"Network Error, please try again later": "Network Error, please try again later",
|
||||
"Home": "Home",
|
||||
"Customers": "Customers",
|
||||
"Exercises": "Exercises",
|
||||
@ -66,7 +66,9 @@
|
||||
"Do you save this exercise with these parameters?":"Do you save this exercise with these parameters?",
|
||||
"The number of the exercise": "The number of the exercise",
|
||||
"The number of the exercise done with": "The number of the exercise done with",
|
||||
"Please repeat with ": "Please repeat with ",
|
||||
"Please repeat with": "Please repeat with",
|
||||
"Execute the": "Execute the",
|
||||
". set!":". set!",
|
||||
|
||||
|
||||
"repeat": "repeat",
|
||||
@ -109,6 +111,7 @@
|
||||
|
||||
"Description": "Description",
|
||||
"Make your first test": "Make your first test",
|
||||
"finished": "finished",
|
||||
"Why do you need Exercise Control?" : "Why do you need Exercise Control?",
|
||||
|
||||
"Your 1RM:":"Your 1RM:",
|
||||
@ -149,5 +152,22 @@
|
||||
"My Whole Body Development": "My Whole Body Development",
|
||||
"Development Of Muscles": "Development Of Muscles",
|
||||
"Predictions": "Predictions",
|
||||
"My Trainee's Exercise Logs": "My Trainee's Exercise Logs"
|
||||
"My Trainee's Exercise Logs": "My Trainee's Exercise Logs",
|
||||
|
||||
"My Development By Muscle": "My Development By Muscle",
|
||||
"Here you see you development in the last period." : "Here you see your development in the last period.",
|
||||
"Sum Of Mass":"Sum Of Mass",
|
||||
"Percent": "Percent",
|
||||
"One Max Rep": "One Max Rep",
|
||||
"Detailed": "Detailed",
|
||||
"Weekly": "Weekly",
|
||||
"Monthly": "Monthly",
|
||||
"Yearly": "Yearly",
|
||||
"times!": "times!",
|
||||
|
||||
"Execute your active Exercise Plan!": "Execute your active Exercise Plan!",
|
||||
"Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.": "Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.",
|
||||
|
||||
"Custom Exercise Plan": "Custom Exercise Plan",
|
||||
"Select manually the exercises what you would like to have in your plan. At the end don't forget to save.": "Select manually the exercises what you would like to have in your plan. At the end don't forget to save."
|
||||
}
|
28
i18n/hu.json
28
i18n/hu.json
@ -1,5 +1,5 @@
|
||||
{
|
||||
"Customers And Exercises": "Ügyfelek és gyakorlatok",
|
||||
"Network Error, please try again later": "Hálózati hiba, kérlek próbáld meg később",
|
||||
"Home": "Főoldal",
|
||||
"Customers": "Ügyfelek",
|
||||
"Exercises": "Gyakorlatok",
|
||||
@ -55,8 +55,9 @@
|
||||
"Delete": "Törlés",
|
||||
"The number of the exercise": "Írd be a gyakorlat számát",
|
||||
"The number of the exercise done with": "Írd be, mennyivel csináltad a gyakorlatot",
|
||||
"Please repeat with ": "Kérlek ismételd",
|
||||
|
||||
"Please repeat with": "Kérlek ismételd",
|
||||
"Execute the": "Hajtsd végre a(z)",
|
||||
". set!":". sorozatot!",
|
||||
|
||||
"Name": "Név",
|
||||
"Exercise": "Gyakorlat",
|
||||
@ -69,6 +70,7 @@
|
||||
"with": "",
|
||||
"Do you save this exercise with these parameters?":"Elmented a gyakorlatot ezekkel az adatokkal?",
|
||||
|
||||
|
||||
"repeat": "ismétlés",
|
||||
"meter": "meter",
|
||||
"percent": "százalék",
|
||||
@ -109,6 +111,7 @@
|
||||
|
||||
"Description": "Leírás",
|
||||
"Make your first test": "Végezd el az első tesztet",
|
||||
"finished": "végrehajtva",
|
||||
"Why do you need Exercise Control?": "Miért szükséges a kontrollgyakorlat?",
|
||||
"Your 1RM:":"Maxerőd:",
|
||||
"Your Real 1RM:":"Ellenőrzött maxerő:",
|
||||
@ -149,5 +152,22 @@
|
||||
"My Whole Body Development": "Testem fejlődése",
|
||||
"Development Of Muscles": "Izomcsoportok fejlődése",
|
||||
"Predictions": "Előrejelzések",
|
||||
"My Trainee's Exercise Logs": "Kliensem edzésnaplőja"
|
||||
"My Trainee's Exercise Logs": "Kliensem edzésnaplőja",
|
||||
|
||||
"My Development By Muscle": "Izomcsoportok fejlődése",
|
||||
"Here you see you development in the last period." : "Itt az izomcsoportok fejlődését látod az elmúlt időszakban. A pontos képhez három diagram közül választhatsz: 'Gyakorlat össztömeg', 'Maxerő' és 'Százalékos fejlődés', illetv választhatsz 4 különböző időszaki bontásból is: 'Részletes', 'Heti', 'Havi', 'Éves",
|
||||
"Sum Of Mass":"Össztömeg",
|
||||
"Percent": "Százalék",
|
||||
"One Max Rep": "Maxerő",
|
||||
"Detailed": "Részletes",
|
||||
"Weekly": "Heti",
|
||||
"Monthly": "Havi",
|
||||
"Yearly": "Éves",
|
||||
"times!": "ismétléssel!",
|
||||
|
||||
"Execute your active Exercise Plan!": "Hajtsd végre az aktív edzéstervedet",
|
||||
"Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.": "Válaszd ki az izomcsoporton belül a gyakorlatot, és a következő oldalon add meg a súlyt és az ismétlés számot.",
|
||||
"Custom Exercise Plan": "Egyedi edzésterv",
|
||||
"Select manually the exercises what you would like to have in your plan. At the end don't forget to save.": "Válaszd ki a gyakorlatokat, amelyeket szeretnél végrehajtani a tervedben. Utána ne felejtsd el elmenteni."
|
||||
|
||||
}
|
292
lib/bloc/development_by_muscle/development_by_muscle_bloc.dart
Normal file
292
lib/bloc/development_by_muscle/development_by_muscle_bloc.dart
Normal file
@ -0,0 +1,292 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:aitrainer_app/util/calculate.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
|
||||
part 'development_by_muscle_event.dart';
|
||||
|
||||
part 'development_by_muscle_state.dart';
|
||||
|
||||
class DateRate {
|
||||
static String daily = "daily";
|
||||
static String weekly = "weekly";
|
||||
static String monthly = "monthly";
|
||||
static String yearly = "yearly";
|
||||
}
|
||||
|
||||
class DiagramType {
|
||||
static String sumMass = "sumMass";
|
||||
static String oneRepMax = "oneRepMax";
|
||||
static String percent = "percent";
|
||||
}
|
||||
|
||||
class ChartDataExtended {
|
||||
final List<BarChartGroupData> data;
|
||||
final double interval;
|
||||
final int gridInterval;
|
||||
|
||||
const ChartDataExtended({this.data, this.interval, this.gridInterval});
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
"data": data.toString(),
|
||||
"interval" : interval.toString(),
|
||||
"gridInterval" : gridInterval,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate, Common {
|
||||
final WorkoutTreeRepository workoutTreeRepository;
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap();
|
||||
List<BarChartGroupData> chartData;
|
||||
String diagramType = DiagramType.sumMass;
|
||||
String dateRate = DateRate.daily;
|
||||
double basePercent = 0;
|
||||
|
||||
@override
|
||||
DevelopmentByMuscleBloc({
|
||||
this.workoutTreeRepository}) :
|
||||
super(DevelopmentByMuscleStateInitial());
|
||||
|
||||
Future<void> getData() async {
|
||||
|
||||
workoutTreeRepository.sortedTree = null;
|
||||
workoutTreeRepository.sortByMuscleType();
|
||||
|
||||
workoutTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutMenuTree> listWorkoutTree = value;
|
||||
listWorkoutTree.forEach((workoutTree) {
|
||||
workoutTree.selected = false;
|
||||
});
|
||||
});
|
||||
|
||||
this.getChartData();
|
||||
|
||||
}
|
||||
|
||||
void getChartData() {
|
||||
List<Exercise> exercises = exerciseRepository.getExerciseList();
|
||||
exercises.sort( (a, b) => a.exerciseTypeId.compareTo(b.exerciseTypeId));
|
||||
exercises = this.groupByDate(exercises);
|
||||
|
||||
int origExerciseTypeId = 0;
|
||||
int x = 0;
|
||||
chartData = List();
|
||||
double maxData = 0;
|
||||
double minData = 9999999999999;
|
||||
exercises.forEach((exercise) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
if (origExerciseTypeId != exercise.exerciseTypeId && diagramType == DiagramType.percent) {
|
||||
this.basePercent = getBasePercent(exercise);
|
||||
}
|
||||
double diagramValue = this.getDiagramValue(exercise);
|
||||
|
||||
if (maxData < diagramValue) {
|
||||
maxData = diagramValue;
|
||||
}
|
||||
if (minData > diagramValue) {
|
||||
minData = diagramValue;
|
||||
}
|
||||
//print("exercise " + exercise.exerciseTypeId.toString() + " d " + getDateFormat(exercise.dateAdd) + " mass " + sumMass.toString());
|
||||
//print("date " + exercise.dateAdd.toIso8601String() + " epoch " + exercise.dateAdd.millisecondsSinceEpoch.toString() );
|
||||
BarChartGroupData data = BarChartGroupData(
|
||||
x: exercise.dateAdd.millisecondsSinceEpoch,
|
||||
barRods: [
|
||||
BarChartRodData(y: diagramValue, width: 12, color: Colors.lightBlue)
|
||||
]
|
||||
);
|
||||
if (origExerciseTypeId != exercise.exerciseTypeId) {
|
||||
if (origExerciseTypeId == 0) {
|
||||
origExerciseTypeId = exercise.exerciseTypeId;
|
||||
chartData.add(data);
|
||||
} else {
|
||||
double dInterval = ((maxData + minData) / 8).roundToDouble();
|
||||
int gridInterval = (dInterval / 3).floor();
|
||||
ChartDataExtended extended = ChartDataExtended(
|
||||
data: chartData, interval: dInterval, gridInterval: gridInterval);
|
||||
listChartData[origExerciseTypeId] = extended;
|
||||
maxData = 0;
|
||||
minData = 9999999999999;
|
||||
chartData = List();
|
||||
chartData.add(data);
|
||||
origExerciseTypeId = exercise.exerciseTypeId;
|
||||
}
|
||||
} else {
|
||||
origExerciseTypeId = exercise.exerciseTypeId;
|
||||
chartData.add(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
listChartData.forEach((key, value) {
|
||||
print ("typeid " + key.toString() + " chardata " + value.toJson().toString());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
String getDatePart(DateTime date) {
|
||||
String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);;
|
||||
if ( this.dateRate == DateRate.weekly ) {
|
||||
datePart = weekNumber(date).toString();
|
||||
} else if ( this.dateRate == DateRate.monthly ) {
|
||||
datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if ( this.dateRate == DateRate.yearly ) {
|
||||
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if ( this.dateRate == DateRate.daily ) {
|
||||
datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
}
|
||||
return datePart;
|
||||
}
|
||||
|
||||
List<Exercise> groupByDate(List<Exercise> exercises) {
|
||||
List<Exercise> groupedExercises = List();
|
||||
|
||||
String origDatePart;
|
||||
|
||||
int countExercises = 0;
|
||||
double sumQuantity = 0;
|
||||
double maxQuantity = 0;
|
||||
Exercise origExercise;
|
||||
exercises.forEach((exercise) {
|
||||
String exerciseDatePart = getDatePart(exercise.dateAdd);
|
||||
if ( origExercise != null ) {
|
||||
if ( origExercise.exerciseTypeId != exercise.exerciseTypeId || origDatePart != exerciseDatePart ) {
|
||||
Exercise newExercise = origExercise.copy();
|
||||
newExercise.datePart = origDatePart;
|
||||
if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
|
||||
newExercise.quantity = maxQuantity;
|
||||
} else {
|
||||
newExercise.quantity = sumQuantity / countExercises;
|
||||
}
|
||||
groupedExercises.add(newExercise);
|
||||
countExercises = 0;
|
||||
sumQuantity = 0;
|
||||
maxQuantity = 0;
|
||||
}
|
||||
}
|
||||
origExercise = exercise;
|
||||
origDatePart = exerciseDatePart;
|
||||
|
||||
double newQuantity = getQuantityByDate(exercise);
|
||||
sumQuantity += newQuantity;
|
||||
if (maxQuantity < newQuantity) {
|
||||
maxQuantity = newQuantity;
|
||||
}
|
||||
countExercises++;
|
||||
|
||||
});
|
||||
|
||||
groupedExercises.forEach((element) {
|
||||
print("grouped " + element.toJson().toString());
|
||||
});
|
||||
|
||||
|
||||
return groupedExercises;
|
||||
}
|
||||
|
||||
double getQuantityByDate(Exercise exercise) {
|
||||
double sum = 0;
|
||||
if ( this.diagramType == DiagramType.sumMass ) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
sum = exercise.quantity * exercise.unitQuantity;
|
||||
} else {
|
||||
sum = exercise.quantity;
|
||||
}
|
||||
} else if ( this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent ) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
sum = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||
} else {
|
||||
sum = exercise.quantity;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double getBasePercent(Exercise exercise) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
this.basePercent = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||
} else {
|
||||
this.basePercent = exercise.quantity;
|
||||
}
|
||||
//print("Base percent of " + exercise.exerciseTypeId.toString() + ": " + basePercent.toString());
|
||||
return this.basePercent;
|
||||
}
|
||||
|
||||
double getDiagramValue(Exercise exercise) {
|
||||
double value = 0;
|
||||
/*if ( diagramType == DiagramType.sumMass) {
|
||||
value = exercise.quantity;
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
value *= exercise.unitQuantity;
|
||||
}
|
||||
} else if ( diagramType == DiagramType.oneRepMax) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
value = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||
}
|
||||
} else if ( diagramType == DiagramType.percent) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
double oneRepMax = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||
value = (oneRepMax / this.basePercent) * 100;
|
||||
//print("Percent of " + exercise.exerciseTypeId.toString() + ": " + value.toString() + " date " + exercise.dateAdd.toIso8601String() + " 1RM " + oneRepMax.toString());
|
||||
} else {
|
||||
value = (exercise.quantity / this.basePercent ) * 100;
|
||||
}*/
|
||||
|
||||
if ( diagramType == DiagramType.percent) {
|
||||
if ( exercise.unitQuantity != null ) {
|
||||
double oneRepMax = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||
value = (oneRepMax / this.basePercent) * 100;
|
||||
//print("Percent of " + exercise.exerciseTypeId.toString() + ": " + value.toString() + " date " + exercise.dateAdd.toIso8601String() + " 1RM " + oneRepMax.toString());
|
||||
} else {
|
||||
value = (exercise.quantity / this.basePercent ) * 100;
|
||||
}
|
||||
} else {
|
||||
return exercise.quantity;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
String getDateFormat(DateTime datetime) {
|
||||
return DateFormat('yMd', AppLanguage().appLocal.toString()).format(datetime);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<DevelopmentByMuscleState> mapEventToState(DevelopmentByMuscleEvent event) async* {
|
||||
try {
|
||||
if (event is DevelopmentByMuscleLoad) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
await getData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
} else if ( event is DevelopmentByMuscleDiagramTypeChange ) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
String type = event.diagramType;
|
||||
this.diagramType = type;
|
||||
getChartData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
} else if ( event is DevelopmentByMuscleDateRateChange ) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
String dateRate = event.dateRate;
|
||||
this.dateRate = dateRate;
|
||||
getChartData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield DevelopmentByMuscleErrorState(message: e.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
part of 'development_by_muscle_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class DevelopmentByMuscleEvent extends Equatable {
|
||||
const DevelopmentByMuscleEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleLoad extends DevelopmentByMuscleEvent {
|
||||
const DevelopmentByMuscleLoad();
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
|
||||
final String dateRate;
|
||||
const DevelopmentByMuscleDateRateChange({this.dateRate});
|
||||
|
||||
@override
|
||||
List<Object> get props => [dateRate];
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleDiagramTypeChange extends DevelopmentByMuscleEvent {
|
||||
final String diagramType;
|
||||
const DevelopmentByMuscleDiagramTypeChange({this.diagramType});
|
||||
|
||||
@override
|
||||
List<Object> get props => [diagramType];
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
part of 'development_by_muscle_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class DevelopmentByMuscleState extends Equatable{
|
||||
const DevelopmentByMuscleState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleStateInitial extends DevelopmentByMuscleState {
|
||||
const DevelopmentByMuscleStateInitial();
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleLoadingState extends DevelopmentByMuscleState {
|
||||
const DevelopmentByMuscleLoadingState();
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleReadyState extends DevelopmentByMuscleState {
|
||||
const DevelopmentByMuscleReadyState();
|
||||
}
|
||||
|
||||
|
||||
class DevelopmentByMuscleErrorState extends DevelopmentByMuscleState {
|
||||
final String message;
|
||||
const DevelopmentByMuscleErrorState({this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
@ -8,7 +8,7 @@ import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository;
|
||||
final WorkoutTree workoutTree;
|
||||
final WorkoutMenuTree workoutTree;
|
||||
final customerId;
|
||||
Customer customer;
|
||||
int step = 1;
|
||||
@ -40,12 +40,12 @@ class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
||||
} else if ( Cache().getTrainee().customerId == customerId) {
|
||||
customer = Cache().getTrainee();
|
||||
}
|
||||
exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
|
||||
exerciseRepository.customer = customer;
|
||||
countSteps = exercisePlanRepository.actualPlanDetail.serie;
|
||||
countSteps = exercisePlanRepository.getActualPlanDetail().serie;
|
||||
|
||||
unitQuantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.weightEquation);
|
||||
quantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.repeats.toString());
|
||||
unitQuantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().weightEquation);
|
||||
quantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().repeats.toString());
|
||||
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
||||
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
|
||||
exerciseRepository.setQuantity(quantity1Field.valueToDouble);
|
||||
exerciseRepository.exercise.exercisePlanDetailId =
|
||||
exercisePlanRepository.actualPlanDetail.exercisePlanDetailId;
|
||||
exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId;
|
||||
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
|
||||
workoutTree.executed = true;
|
||||
print("On Submitting Add Exercise By Plan " + exerciseRepository.exercise.toJson().toString());
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
@ -13,12 +12,11 @@ part 'exercise_by_plan_event.dart';
|
||||
part 'exercise_by_plan_state.dart';
|
||||
|
||||
class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState> {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final WorkoutTreeRepository menuTreeRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||
int customerId;
|
||||
@override
|
||||
ExerciseByPlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
|
||||
ExerciseByPlanBloc({this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
|
||||
|
||||
Future<void> getData() async {
|
||||
exercisePlanRepository.setCustomerId(customerId);
|
||||
@ -28,11 +26,11 @@ class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState>
|
||||
menuTreeRepository.sortByMuscleType();
|
||||
|
||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listWorkoutTree = value;
|
||||
List<WorkoutMenuTree> listWorkoutTree = value;
|
||||
listWorkoutTree.forEach((workoutTree) {
|
||||
workoutTree.selected = false;
|
||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||
if (exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId) != null) {
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
@ -15,11 +13,10 @@ part 'exercise_plan_state.dart';
|
||||
|
||||
class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||
final WorkoutTreeRepository menuTreeRepository;
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||
ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||
int customerId;
|
||||
|
||||
ExercisePlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExercisePlanInitial());
|
||||
ExercisePlanBloc({this.menuTreeRepository}) : super(ExercisePlanInitial());
|
||||
|
||||
Future<void> getData() async {
|
||||
exercisePlanRepository.setCustomerId(customerId);
|
||||
@ -29,12 +26,11 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||
menuTreeRepository.sortByMuscleType();
|
||||
|
||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listWorkoutTree = value;
|
||||
List<WorkoutMenuTree> listWorkoutTree = value;
|
||||
listWorkoutTree.forEach((workoutTree) {
|
||||
workoutTree.selected = false;
|
||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
||||
//print("bingo");
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||
if (exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId) != null) {
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
}
|
||||
@ -42,6 +38,8 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||
});
|
||||
}
|
||||
|
||||
void setExercisePlanRepository(ExercisePlanRepository repo ) => exercisePlanRepository = repo;
|
||||
|
||||
@override
|
||||
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
|
||||
try {
|
||||
@ -50,38 +48,62 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||
await this.getData();
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
if (event is ExercisePlanUpdate) {
|
||||
|
||||
if (event is ExercisePlanUpdateUI) {
|
||||
yield ExercisePlanLoading();
|
||||
WorkoutTree workoutTree = event.workoutTree;
|
||||
|
||||
WorkoutMenuTree workoutTree = event.workoutTree;
|
||||
if (workoutTree != null) {
|
||||
exercisePlanRepository.addExerciseTypeToPlan(workoutTree.exerciseType);
|
||||
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanRemoveExercise) {
|
||||
}
|
||||
|
||||
else if (event is ExercisePlanAddExercise) {
|
||||
yield ExercisePlanLoading();
|
||||
ExercisePlanDetail planDetail = event.exercisePlanDetail;
|
||||
exercisePlanRepository.removeExerciseTypeFromPlan(planDetail.exerciseType);
|
||||
exercisePlanRepository.actualPlanDetail = planDetail;
|
||||
|
||||
/*if ( exercisePlanRepository.exercisePlanDetails[planDetail.exerciseTypeId] == null ) {
|
||||
print("Add plan detail " + planDetail.toJson().toString());
|
||||
exercisePlanRepository.actualPlanDetail.change = ExercisePlanDetailChange.add;
|
||||
} else {
|
||||
print("Update plan detail " + planDetail.toJson().toString());
|
||||
exercisePlanRepository.actualPlanDetail.change = ExercisePlanDetailChange.update;
|
||||
}
|
||||
exercisePlanRepository.addDetailToPlan();*/
|
||||
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
|
||||
await exercisePlanRepository.saveExercisePlan();
|
||||
}
|
||||
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
|
||||
|
||||
else if (event is ExercisePlanRemoveExercise) {
|
||||
yield ExercisePlanLoading();
|
||||
ExercisePlanDetail planDetail = event.exercisePlanDetail;
|
||||
exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(planDetail.exerciseTypeId);
|
||||
|
||||
this.menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listTreeItem = value;
|
||||
List<WorkoutMenuTree> listTreeItem = value;
|
||||
listTreeItem.forEach((element) {
|
||||
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
|
||||
element.selected = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanUpdateExercise) {
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanSave) {
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() == 0) {
|
||||
throw Exception("Please select an exercise");
|
||||
} else {
|
||||
yield ExercisePlanLoading();
|
||||
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
|
||||
exercisePlanRepository.saveExercisePlan();
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
|
||||
} on Exception catch (e) {
|
||||
yield ExercisePlanError(message: e.toString());
|
||||
}
|
||||
|
@ -11,21 +11,16 @@ class ExercisePlanLoad extends ExercisePlanEvent {
|
||||
const ExercisePlanLoad();
|
||||
}
|
||||
|
||||
class ExercisePlanUpdate extends ExercisePlanEvent {
|
||||
final WorkoutTree workoutTree;
|
||||
const ExercisePlanUpdate({this.workoutTree});
|
||||
|
||||
// update UI
|
||||
class ExercisePlanUpdateUI extends ExercisePlanEvent {
|
||||
final WorkoutMenuTree workoutTree;
|
||||
const ExercisePlanUpdateUI({this.workoutTree});
|
||||
|
||||
@override
|
||||
List<Object> get props => [workoutTree];
|
||||
}
|
||||
|
||||
class ExercisePlanAddExercise extends ExercisePlanEvent {
|
||||
final ExerciseType exerciseType;
|
||||
const ExercisePlanAddExercise({this.exerciseType});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exerciseType];
|
||||
}
|
||||
|
||||
class ExercisePlanRemoveExercise extends ExercisePlanEvent {
|
||||
final ExercisePlanDetail exercisePlanDetail;
|
||||
@ -35,15 +30,10 @@ class ExercisePlanRemoveExercise extends ExercisePlanEvent {
|
||||
List<Object> get props => [exercisePlanDetail];
|
||||
}
|
||||
|
||||
class ExercisePlanUpdateExercise extends ExercisePlanEvent {
|
||||
class ExercisePlanAddExercise extends ExercisePlanEvent {
|
||||
final ExercisePlanDetail exercisePlanDetail;
|
||||
const ExercisePlanUpdateExercise({this.exercisePlanDetail});
|
||||
const ExercisePlanAddExercise({this.exercisePlanDetail});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exercisePlanDetail];
|
||||
}
|
||||
|
||||
class ExercisePlanSave extends ExercisePlanEvent {
|
||||
const ExercisePlanSave();
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
@ -36,29 +37,29 @@ class ExercisePlanCustomerFormBloc extends FormBloc<String, String> {
|
||||
weightField
|
||||
]);
|
||||
|
||||
String repeatsInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.repeats != null ?
|
||||
exercisePlanRepository.actualPlanDetail.repeats.toString() : "12";
|
||||
String repeatsInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||
exercisePlanRepository.getActualPlanDetail().repeats != null ?
|
||||
exercisePlanRepository.getActualPlanDetail().repeats.toString() : "12";
|
||||
quantityField.updateInitialValue(repeatsInitial);
|
||||
|
||||
String serieInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.serie != null ?
|
||||
exercisePlanRepository.actualPlanDetail.serie.toString() : "3";
|
||||
String serieInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||
exercisePlanRepository.getActualPlanDetail().serie != null ?
|
||||
exercisePlanRepository.getActualPlanDetail().serie.toString() : "3";
|
||||
serieField.updateInitialValue(serieInitial);
|
||||
|
||||
String weightInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation != null ?
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation : "30";
|
||||
String weightInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||
exercisePlanRepository.getActualPlanDetail().weightEquation != null ?
|
||||
exercisePlanRepository.getActualPlanDetail().weightEquation : "30";
|
||||
weightField.updateInitialValue(weightInitial);
|
||||
|
||||
quantityField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.repeats = current.valueToInt;
|
||||
exercisePlanRepository.getActualPlanDetail().repeats = current.valueToInt;
|
||||
});
|
||||
serieField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.serie = current.valueToInt;
|
||||
exercisePlanRepository.getActualPlanDetail().serie = current.valueToInt;
|
||||
});
|
||||
weightField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation = current.value;
|
||||
exercisePlanRepository.getActualPlanDetail().weightEquation = current.value;
|
||||
});
|
||||
}
|
||||
|
||||
@ -69,12 +70,16 @@ class ExercisePlanCustomerFormBloc extends FormBloc<String, String> {
|
||||
emitLoading(progress: 30);
|
||||
// Emit either Loaded or Error
|
||||
|
||||
exercisePlanRepository.actualPlanDetail.repeats = quantityField.valueToInt;
|
||||
exercisePlanRepository.actualPlanDetail.serie = serieField.valueToInt;
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation = weightField.value;
|
||||
|
||||
exercisePlanRepository.addToPlan();
|
||||
planBloc.add(ExercisePlanUpdate());
|
||||
exercisePlanRepository.getActualPlanDetail().repeats = quantityField.valueToInt;
|
||||
exercisePlanRepository.getActualPlanDetail().serie = serieField.valueToInt;
|
||||
exercisePlanRepository.getActualPlanDetail().weightEquation = weightField.value;
|
||||
if ( exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null ) {
|
||||
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.add;
|
||||
} else {
|
||||
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.update;
|
||||
}
|
||||
exercisePlanRepository.addDetailToPlan();
|
||||
planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()));
|
||||
|
||||
emitSuccess(canSubmitAgain: false);
|
||||
} on Exception catch (ex) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
@ -17,7 +17,7 @@ class MenuLoading extends MenuState {
|
||||
}
|
||||
|
||||
class MenuReady extends MenuState {
|
||||
final WorkoutTree workoutTree;
|
||||
final WorkoutMenuTree workoutTree;
|
||||
|
||||
const MenuReady({this.workoutTree});
|
||||
|
||||
|
@ -15,12 +15,13 @@ import 'package:aitrainer_app/view/exercise_control_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_execute_by_plan_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_log_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_plan_custom_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_plan_detail_add_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_plan_custom_detail_add_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_type_description.dart';
|
||||
import 'package:aitrainer_app/view/gdpr.dart';
|
||||
import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
|
||||
import 'package:aitrainer_app/view/mydevelopment_page.dart';
|
||||
import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
|
||||
import 'package:aitrainer_app/view/registration.dart';
|
||||
@ -34,6 +35,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:sentry/sentry.dart';
|
||||
import 'bloc/account/account_bloc.dart';
|
||||
import 'bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
||||
import 'bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'bloc/menu/menu_bloc.dart';
|
||||
@ -108,7 +110,7 @@ Future<Null> main() async {
|
||||
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
||||
runApp(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
providers: [
|
||||
BlocProvider<SessionBloc>(
|
||||
create: (BuildContext context) => SessionBloc(session: Session()),
|
||||
),
|
||||
@ -125,7 +127,12 @@ Future<Null> main() async {
|
||||
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<ExerciseByPlanBloc>(
|
||||
create: (BuildContext context) => ExerciseByPlanBloc(menuTreeRepository: menuTreeRepository, exerciseRepository: ExerciseRepository()),
|
||||
create: (BuildContext context) => ExerciseByPlanBloc(
|
||||
menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<DevelopmentByMuscleBloc>(
|
||||
create: (BuildContext context) => DevelopmentByMuscleBloc(
|
||||
workoutTreeRepository: menuTreeRepository),
|
||||
),
|
||||
],
|
||||
|
||||
@ -195,6 +202,7 @@ class AitrainerApp extends StatelessWidget {
|
||||
'exercisePlanDetailAdd': (context) => ExercisePlanDetailAddPage(),
|
||||
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
||||
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
||||
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
||||
},
|
||||
initialRoute: 'home',
|
||||
title: 'WorkoutTest',
|
||||
|
@ -4,7 +4,7 @@ import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
@ -59,9 +59,10 @@ class Cache {
|
||||
|
||||
List<Exercise> _exercises;
|
||||
ExercisePlan _myExercisePlan;
|
||||
List<ExercisePlanDetail> _myExercisesPlanDetail;
|
||||
|
||||
LinkedHashMap _tree = LinkedHashMap<String, WorkoutTree>();
|
||||
LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
LinkedHashMap _tree = LinkedHashMap<String, WorkoutMenuTree>();
|
||||
double _percentExercises = -1;
|
||||
|
||||
Customer _trainee;
|
||||
@ -178,56 +179,63 @@ class Cache {
|
||||
this._exercisesTrainee = exercises;
|
||||
}
|
||||
|
||||
void setWorkoutTree( LinkedHashMap<String, WorkoutTree> tree) {
|
||||
void setWorkoutMenuTree( LinkedHashMap<String, WorkoutMenuTree> tree) {
|
||||
this._tree = tree;
|
||||
}
|
||||
|
||||
List<ExerciseType> getExerciseTypes() {
|
||||
return this._exerciseTypes;
|
||||
List<ExerciseType> getExerciseTypes() => this._exerciseTypes;
|
||||
|
||||
List<ExerciseTree> getExerciseTree() => this._exerciseTree;
|
||||
|
||||
List<Exercise> getExercises() => this._exercises;
|
||||
|
||||
List<Exercise> getExercisesTrainee() => this._exercisesTrainee;
|
||||
|
||||
LinkedHashMap<String, WorkoutMenuTree> getWorkoutMenuTree() => this._tree;
|
||||
|
||||
void setPercentExercises(double percent) => this._percentExercises = percent;
|
||||
|
||||
double getPercentExercises() => this._percentExercises;
|
||||
|
||||
void addExercise(Exercise exercise) => _exercises.add(exercise);
|
||||
|
||||
void addExerciseTrainee(Exercise exercise) => _exercisesTrainee.add(exercise);
|
||||
|
||||
Customer getTrainee() => this._trainee;
|
||||
|
||||
void setTrainee(Customer trainee) => _trainee = trainee;
|
||||
|
||||
void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan;
|
||||
|
||||
ExercisePlan getTraineesExercisePlan() => this._traineeExercisePlan;
|
||||
|
||||
void setMyExercisePlan(ExercisePlan exercisePlan) => _myExercisePlan = exercisePlan;
|
||||
|
||||
ExercisePlan getMyExercisePlan() => _myExercisePlan;
|
||||
|
||||
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail)
|
||||
=> _myExercisesPlanDetails = listExercisePlanDetail;
|
||||
|
||||
void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail;
|
||||
|
||||
LinkedHashMap<int, ExercisePlanDetail> getMyExercisePlanDetails() => _myExercisesPlanDetails;
|
||||
|
||||
void resetMyExercisePlanDetails() => _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
void updateMyExercisePlanDetail(ExercisePlanDetail detail) {
|
||||
this.addToMyExercisePlanDetails(detail);
|
||||
}
|
||||
|
||||
List<ExerciseTree> getExerciseTree() {
|
||||
return this._exerciseTree;
|
||||
void deleteMyExercisePlanDetail(ExercisePlanDetail detail)
|
||||
=> this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
|
||||
|
||||
void deletedMyExercisePlanDetail(ExercisePlanDetail detail)
|
||||
=> this._myExercisesPlanDetails[detail.exerciseTypeId].change = ExercisePlanDetailChange.deleted;
|
||||
|
||||
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
|
||||
this._myExercisesPlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete;
|
||||
}
|
||||
|
||||
List<Exercise> getExercises() {
|
||||
return this._exercises;
|
||||
}
|
||||
|
||||
List<Exercise> getExercisesTrainee() {
|
||||
return this._exercisesTrainee;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, WorkoutTree> getWorkoutTree() {
|
||||
return this._tree;
|
||||
}
|
||||
|
||||
void setPercentExercises(double percent) {
|
||||
this._percentExercises = percent;
|
||||
}
|
||||
|
||||
double getPercentExercises() {
|
||||
return this._percentExercises;
|
||||
}
|
||||
|
||||
void addExercise(Exercise exercise) {
|
||||
_exercises.add(exercise);
|
||||
}
|
||||
|
||||
void addExerciseTrainee(Exercise exercise) {
|
||||
_exercisesTrainee.add(exercise);
|
||||
}
|
||||
|
||||
Customer getTrainee() {
|
||||
return this._trainee;
|
||||
}
|
||||
|
||||
void setTrainee(Customer trainee) {
|
||||
this._trainee = trainee;
|
||||
}
|
||||
|
||||
void setTraineeExercisePlan(ExercisePlan exercisePlan) {
|
||||
this._traineeExercisePlan = exercisePlan;
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class Exercise {
|
||||
@ -10,6 +11,8 @@ class Exercise {
|
||||
DateTime dateAdd;
|
||||
int exercisePlanDetailId;
|
||||
|
||||
String datePart;
|
||||
|
||||
|
||||
|
||||
Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.dateAdd});
|
||||
@ -21,6 +24,7 @@ class Exercise {
|
||||
this.unit = json['unit'];
|
||||
this.unitQuantity = json['unitQuantity'];
|
||||
this.dateAdd = DateTime.parse( json['dateAdd'] );
|
||||
this.datePart = DateFormat('yyyy-MM-dd').format(this.dateAdd);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
@ -33,4 +37,16 @@ class Exercise {
|
||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
|
||||
"exercisePlanDetailId": exercisePlanDetailId,
|
||||
};
|
||||
|
||||
Exercise copy() {
|
||||
Exercise newExercise = Exercise();
|
||||
newExercise.exerciseTypeId = this.exerciseTypeId;
|
||||
newExercise.customerId = this.customerId;
|
||||
newExercise.quantity = this.quantity;
|
||||
newExercise.unit = this.unit;
|
||||
newExercise.unitQuantity = this.unitQuantity;
|
||||
newExercise.dateAdd = this.dateAdd;
|
||||
newExercise.exercisePlanDetailId = this.exercisePlanDetailId;
|
||||
return newExercise;
|
||||
}
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
|
||||
import 'exercise_type.dart';
|
||||
|
||||
class ExercisePlanDetailChange {
|
||||
static const String add = "add";
|
||||
static const String delete = "delete";
|
||||
static const String update = "update";
|
||||
static const String deleted = "deleted";
|
||||
}
|
||||
|
||||
class ExercisePlanDetail {
|
||||
int exercisePlanDetailId;
|
||||
int exercisePlanId;
|
||||
@ -11,6 +16,7 @@ class ExercisePlanDetail {
|
||||
String weightEquation;
|
||||
|
||||
ExerciseType exerciseType;
|
||||
String change; // 1: update -1:delete 0: new
|
||||
|
||||
ExercisePlanDetail(int exerciseTypeId) {
|
||||
this.exerciseTypeId = exerciseTypeId;
|
||||
|
@ -2,7 +2,7 @@ import 'dart:ui';
|
||||
|
||||
import 'exercise_type.dart';
|
||||
|
||||
class WorkoutTree {
|
||||
class WorkoutMenuTree {
|
||||
int id;
|
||||
int parent;
|
||||
String name;
|
||||
@ -20,7 +20,7 @@ class WorkoutTree {
|
||||
String exerciseDetail;
|
||||
String nameEnglish;
|
||||
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child,
|
||||
WorkoutMenuTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child,
|
||||
this.exerciseTypeId, this.exerciseType, this.base, this.is1RM, this.nameEnglish);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
@ -8,31 +8,34 @@ import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
||||
|
||||
class ExercisePlanRepository {
|
||||
bool newPlan = true;
|
||||
ExercisePlan _exercisePlan;
|
||||
ExercisePlan exercisePlan;
|
||||
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails =
|
||||
LinkedHashMap<int, ExercisePlanDetail>();
|
||||
LinkedHashMap<int, ExercisePlanDetail> _origExercisePlanDetails =
|
||||
LinkedHashMap<int, ExercisePlanDetail>();
|
||||
int _customerId = 0;
|
||||
int customerId = 0;
|
||||
ExercisePlanDetail actualPlanDetail;
|
||||
|
||||
void setCustomerId( int customerId ) {
|
||||
this._customerId = customerId;
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
int getCustomerId() {
|
||||
return this._customerId;
|
||||
int getCustomerId() => customerId;
|
||||
|
||||
void setExercisePlan(ExercisePlan plan) {
|
||||
this.exercisePlan = plan;
|
||||
}
|
||||
|
||||
void addExerciseTypeToPlan(ExerciseType exerciseType) {
|
||||
setActualPlanDetail(exerciseType);
|
||||
}
|
||||
|
||||
void addToPlan() {
|
||||
ExercisePlan getExercisePlan() => exercisePlan;
|
||||
|
||||
void addDetailToPlan() {
|
||||
actualPlanDetail.exercisePlanId = exercisePlan.exercisePlanId;
|
||||
exercisePlanDetails[actualPlanDetail.exerciseTypeId] = actualPlanDetail;
|
||||
Cache().addToMyExercisePlanDetails(actualPlanDetail);
|
||||
}
|
||||
|
||||
void setActualPlanDetail(ExerciseType exerciseType) {
|
||||
ExercisePlanDetail getExercisePlanDetailByExerciseId(int exerciseTypeId) => exercisePlanDetails[exerciseTypeId];
|
||||
|
||||
void setActualPlanDetailByExerciseType(ExerciseType exerciseType) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseType.exerciseTypeId];
|
||||
if ( detail != null ) {
|
||||
actualPlanDetail = detail;
|
||||
@ -42,11 +45,14 @@ class ExercisePlanRepository {
|
||||
actualPlanDetail.exerciseType = exerciseType;
|
||||
}
|
||||
|
||||
int getPlanDetailId(int exerciseTypeId) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
||||
return detail.exercisePlanDetailId;
|
||||
ExercisePlanDetail getActualPlanDetail() => actualPlanDetail;
|
||||
|
||||
void setActualPlanDetail( ExercisePlanDetail detail ) {
|
||||
this.actualPlanDetail = detail;
|
||||
}
|
||||
|
||||
int getPlanDetailId(int exerciseTypeId) => exercisePlanDetails[exerciseTypeId].exercisePlanDetailId;
|
||||
|
||||
String getPlanDetail(int exerciseTypeId) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
||||
String detailString = "";
|
||||
@ -70,96 +76,121 @@ class ExercisePlanRepository {
|
||||
exercisePlanDetail.serie = serie;
|
||||
exercisePlanDetail.repeats = repeat;
|
||||
exercisePlanDetail.weightEquation = weight;
|
||||
exercisePlanDetail.change = ExercisePlanDetailChange.update;
|
||||
|
||||
exercisePlanDetails[exerciseType.exerciseTypeId] = exercisePlanDetail;
|
||||
}
|
||||
|
||||
void removeExerciseTypeFromPlan(ExerciseType exerciseType) {
|
||||
exercisePlanDetails.remove(exerciseType.exerciseTypeId);
|
||||
removeExerciseTypeFromPlanByExerciseTypeId(exerciseType.exerciseTypeId);
|
||||
}
|
||||
|
||||
void removeExerciseTypeFromPlanByExerciseTypeId(int exerciseTypeId) {
|
||||
exercisePlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete;
|
||||
Cache().deleteMyExercisePlanDetailByExerciseTypeId(exerciseTypeId);
|
||||
}
|
||||
|
||||
Future<void> saveExercisePlan() async {
|
||||
|
||||
if ( _exercisePlan == null ) {
|
||||
if ( exercisePlan == null ) {
|
||||
if ( Cache().userLoggedIn == null ) {
|
||||
throw Exception("please log in");
|
||||
}
|
||||
|
||||
String exercisePlanName;
|
||||
if ( this._customerId == Cache().userLoggedIn.customerId) {
|
||||
if ( this.customerId == Cache().userLoggedIn.customerId) {
|
||||
exercisePlanName = Cache().userLoggedIn.name + " private";
|
||||
} else {
|
||||
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
|
||||
}
|
||||
|
||||
_exercisePlan = ExercisePlan(exercisePlanName, this._customerId);
|
||||
exercisePlan = ExercisePlan(exercisePlanName, this.customerId);
|
||||
}
|
||||
if ( newPlan ) {
|
||||
_exercisePlan.dateAdd = DateTime.now();
|
||||
_exercisePlan.private = true;
|
||||
exercisePlan.dateAdd = DateTime.now();
|
||||
exercisePlan.private = true;
|
||||
ExercisePlan savedExercisePlan =
|
||||
await ExercisePlanApi().saveExercisePlan(_exercisePlan);
|
||||
await ExercisePlanApi().saveExercisePlan(exercisePlan);
|
||||
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
LinkedHashMap<int, ExercisePlanDetail> savedExercisePlanDetails = LinkedHashMap();
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId;
|
||||
await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||
});
|
||||
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||
savedExercisePlanDetails[savedDetail.exerciseTypeId] = savedDetail;
|
||||
});
|
||||
|
||||
exercisePlan = savedExercisePlan;
|
||||
exercisePlanDetails = savedExercisePlanDetails;
|
||||
|
||||
} else {
|
||||
|
||||
await ExercisePlanApi().updateExercisePlan(_exercisePlan, _exercisePlan.exercisePlanId);
|
||||
//await ExercisePlanApi().updateExercisePlan(exercisePlan, exercisePlan.exercisePlanId);
|
||||
|
||||
_origExercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
if (exercisePlanDetails[exercisePlanDetail.exercisePlanDetailId] == null) {
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
if ( exercisePlanDetail.change == ExercisePlanDetailChange.delete ) {
|
||||
await ExercisePlanApi()
|
||||
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
|
||||
} else {
|
||||
exercisePlanDetail.change = ExercisePlanDetailChange.deleted;
|
||||
Cache().deletedMyExercisePlanDetail(exercisePlanDetail);
|
||||
|
||||
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.update ) {
|
||||
await ExercisePlanApi()
|
||||
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
|
||||
Cache().updateMyExercisePlanDetail(exercisePlanDetail);
|
||||
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.add ) {
|
||||
await ExercisePlanApi()
|
||||
.saveExercisePlanDetail(exercisePlanDetail);
|
||||
Cache().addToMyExercisePlanDetails(exercisePlanDetail);
|
||||
}
|
||||
});
|
||||
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async{
|
||||
exercisePlanDetail.exercisePlanId = _exercisePlan.exercisePlanId;
|
||||
if ( _origExercisePlanDetails[exercisePlanDetail.exercisePlanDetailId] == null) {
|
||||
await ExercisePlanApi()
|
||||
.saveExercisePlanDetail(exercisePlanDetail);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Future<ExercisePlan> getLastExercisePlan() async {
|
||||
if ( _customerId == 0) {
|
||||
if ( customerId == 0) {
|
||||
return null;
|
||||
}
|
||||
_exercisePlan = await ExercisePlanApi().getLastExercisePlan(_customerId);
|
||||
newPlan = (_exercisePlan == null);
|
||||
print("New plan: " + newPlan.toString());
|
||||
ExercisePlan myExercisePlan = Cache().getMyExercisePlan();
|
||||
if ( myExercisePlan != null ) {
|
||||
exercisePlan = myExercisePlan;
|
||||
return myExercisePlan;
|
||||
}
|
||||
|
||||
return _exercisePlan;
|
||||
exercisePlan = await ExercisePlanApi().getLastExercisePlan(customerId);
|
||||
newPlan = (exercisePlan == null);
|
||||
print("New plan: " + newPlan.toString());
|
||||
Cache().setMyExercisePlan(exercisePlan);
|
||||
return exercisePlan;
|
||||
}
|
||||
|
||||
Future<void> getExercisePlanDetails() async {
|
||||
if (_exercisePlan == null) {
|
||||
if (exercisePlan == null) {
|
||||
ExercisePlan exercisePlan = await this.getLastExercisePlan();
|
||||
if ( exercisePlan == null ) {
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
return;
|
||||
}
|
||||
}
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
List<ExercisePlanDetail> list =
|
||||
await ExercisePlanApi().getExercisePlanDetail(_exercisePlan.exercisePlanId);
|
||||
List<ExercisePlanDetail> list = List();
|
||||
LinkedHashMap<int, ExercisePlanDetail> listCache = Cache().getMyExercisePlanDetails();
|
||||
if ( listCache.length > 0) {
|
||||
exercisePlanDetails = listCache;
|
||||
return;
|
||||
} else {
|
||||
list = await ExercisePlanApi().getExercisePlanDetail(exercisePlan.exercisePlanId);
|
||||
}
|
||||
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
list.forEach((element) {
|
||||
newPlan = false;
|
||||
ExercisePlanDetail detail = element;
|
||||
_origExercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||
exercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||
});
|
||||
Cache().setMyExercisePlanDetails(exercisePlanDetails);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/service/exercise_service.dart';
|
||||
|
||||
class ExerciseRepository {
|
||||
@ -120,14 +120,14 @@ class ExerciseRepository {
|
||||
List<int> baseTreeItem = List();
|
||||
List<int> checkedBaseTreeItem = List();
|
||||
int count1RMExercises = 0;
|
||||
LinkedHashMap<String, WorkoutTree> tree = Cache().getWorkoutTree();
|
||||
LinkedHashMap<String, WorkoutMenuTree> tree = Cache().getWorkoutMenuTree();
|
||||
|
||||
if ( tree == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree treeItem = value;
|
||||
WorkoutMenuTree treeItem = value;
|
||||
if (treeItem.exerciseType != null &&
|
||||
treeItem.exerciseType.base == true &&
|
||||
!baseTreeItem.contains(treeItem.parent)) {
|
||||
@ -148,7 +148,7 @@ class ExerciseRepository {
|
||||
if ( !checkedExerciseTypeId.contains(exercise.exerciseTypeId )) {
|
||||
checkedExerciseTypeId.add(exercise.exerciseTypeId);
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree treeItem = value;
|
||||
WorkoutMenuTree treeItem = value;
|
||||
if (treeItem.exerciseType != null
|
||||
&& treeItem.exerciseType.base == true
|
||||
&& exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId
|
||||
|
@ -3,7 +3,7 @@ import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
@ -29,8 +29,8 @@ class Antagonist {
|
||||
}
|
||||
|
||||
class WorkoutTreeRepository {
|
||||
final LinkedHashMap tree = LinkedHashMap<String, WorkoutTree>();
|
||||
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
||||
final LinkedHashMap tree = LinkedHashMap<String, WorkoutMenuTree>();
|
||||
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||
bool isEnglish;
|
||||
|
||||
final Map<String, int> _antagonist = {
|
||||
@ -61,7 +61,7 @@ class WorkoutTreeRepository {
|
||||
if ( is1RM == false && treeItem.parentId != 0) {
|
||||
is1RM = isParent1RM(treeItem.parentId);
|
||||
}
|
||||
this.tree[treeItem.name] = WorkoutTree(
|
||||
this.tree[treeItem.name] = WorkoutMenuTree(
|
||||
treeItem.treeId,
|
||||
treeItem.parentId,
|
||||
treeName,
|
||||
@ -87,7 +87,7 @@ class WorkoutTreeRepository {
|
||||
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
||||
bool is1RM = this.isParent1RM(exerciseType.treeId);
|
||||
exerciseType.is1RM = is1RM;
|
||||
this.tree[exerciseType.name] = WorkoutTree(
|
||||
this.tree[exerciseType.name] = WorkoutMenuTree(
|
||||
exerciseType.exerciseTypeId,
|
||||
exerciseType.treeId,
|
||||
exerciseTypeName,
|
||||
@ -103,7 +103,7 @@ class WorkoutTreeRepository {
|
||||
);
|
||||
});
|
||||
|
||||
Cache().setWorkoutTree(tree);
|
||||
Cache().setWorkoutMenuTree(tree);
|
||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
exerciseRepository.getBaseExerciseFinishedPercent();
|
||||
}
|
||||
@ -112,7 +112,7 @@ class WorkoutTreeRepository {
|
||||
bool isTreeItem1RM = false;
|
||||
|
||||
this.tree.forEach((key, value) {
|
||||
WorkoutTree treeItem = value as WorkoutTree;
|
||||
WorkoutMenuTree treeItem = value as WorkoutMenuTree;
|
||||
if ( treeItem.id == treeId ) {
|
||||
isTreeItem1RM = treeItem.is1RM;
|
||||
//print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
|
||||
@ -124,9 +124,9 @@ class WorkoutTreeRepository {
|
||||
}
|
||||
|
||||
LinkedHashMap getBranch(int parent) {
|
||||
LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
|
||||
LinkedHashMap branch = LinkedHashMap<String, WorkoutMenuTree>();
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||
if ( parent == workoutTree.parent) {
|
||||
branch[key] = value;
|
||||
}
|
||||
@ -134,10 +134,10 @@ class WorkoutTreeRepository {
|
||||
return branch;
|
||||
}
|
||||
|
||||
List<WorkoutTree> getBranchList(int parent) {
|
||||
List branch = List<WorkoutTree>();
|
||||
List<WorkoutMenuTree> getBranchList(int parent) {
|
||||
List branch = List<WorkoutMenuTree>();
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||
if ( parent == workoutTree.parent) {
|
||||
branch.add(workoutTree);
|
||||
}
|
||||
@ -146,9 +146,9 @@ class WorkoutTreeRepository {
|
||||
}
|
||||
|
||||
void sortByMuscleType() {
|
||||
sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
||||
sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||
//print("treeitem: " + workoutTree.toJson().toString());
|
||||
/*if ( workoutTree.exerciseType != null) {
|
||||
print("treeItem exerciseTye " + workoutTree.exerciseType.toJson().toString());
|
||||
|
@ -21,12 +21,13 @@ class APIClient with Common {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + authToken }
|
||||
);
|
||||
print(" ------------get response code: " + response.statusCode.toString());
|
||||
if(response.statusCode == 200) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else if(response.statusCode == 404 ) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
throw Exception("Unable to perform HTTP request!");
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,8 +50,9 @@ class APIClient with Common {
|
||||
},
|
||||
body: body,
|
||||
);
|
||||
String decodedResponse = utf8convert(response.body);
|
||||
print(" ------------ response: " + decodedResponse);
|
||||
print(" ------------post response code: " + response.statusCode.toString());
|
||||
final String decodedResponse = utf8convert(response.body);
|
||||
print(" ------------ response: $decodedResponse");
|
||||
return decodedResponse;
|
||||
}
|
||||
|
||||
@ -59,6 +61,7 @@ class APIClient with Common {
|
||||
|
||||
try {
|
||||
final body = '{"username":"$email", "password":"$password"}';
|
||||
print("authentication with $email");
|
||||
final response = await http.post(
|
||||
uri,
|
||||
headers: {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||
@ -17,7 +16,7 @@ class ExercisePlanApi {
|
||||
"exercise_plan",
|
||||
body);
|
||||
savedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||
Cache().setTraineeExercisePlan(savedExercisePlan);
|
||||
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
@ -28,14 +27,14 @@ class ExercisePlanApi {
|
||||
ExercisePlan exercisePlan,
|
||||
int exercisePlanId) async {
|
||||
String body = JsonEncoder().convert(exercisePlan.toJson());
|
||||
print(" ===== saving exercisePlan $exercisePlan");
|
||||
print(" ===== update exercisePlan $exercisePlan");
|
||||
ExercisePlan updatedExercisePlan;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
"exercise_plan/" + exercisePlanId.toString(),
|
||||
body);
|
||||
updatedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||
Cache().setTraineeExercisePlan(updatedExercisePlan);
|
||||
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
@ -44,7 +43,7 @@ class ExercisePlanApi {
|
||||
|
||||
Future<ExercisePlanDetail> saveExercisePlanDetail(ExercisePlanDetail exercisePlanDetail) async {
|
||||
String body = JsonEncoder().convert(exercisePlanDetail.toJson());
|
||||
print(" ===== update exercisePlanDetail $exercisePlanDetail");
|
||||
print(" ===== save exercisePlanDetail $exercisePlanDetail");
|
||||
ExercisePlanDetail savedExercisePlanDetail;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
|
135
lib/treeview/tree_view.dart
Normal file
135
lib/treeview/tree_view.dart
Normal file
@ -0,0 +1,135 @@
|
||||
/// Tree view widget library
|
||||
library tree_view;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
class TreeView extends InheritedWidget {
|
||||
final List<Widget> children;
|
||||
final bool startExpanded;
|
||||
|
||||
TreeView({
|
||||
Key key,
|
||||
@required List<Widget> children,
|
||||
bool startExpanded = false,
|
||||
}) : this.children = children,
|
||||
this.startExpanded = startExpanded,
|
||||
super(
|
||||
key: key,
|
||||
child: _TreeViewData(
|
||||
children: children,
|
||||
),
|
||||
);
|
||||
|
||||
static TreeView of(BuildContext context) {
|
||||
//return context.inheritFromWidgetOfExactType(TreeView);
|
||||
return context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(TreeView oldWidget) {
|
||||
if (oldWidget.children == this.children &&
|
||||
oldWidget.startExpanded == this.startExpanded) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class _TreeViewData extends StatelessWidget {
|
||||
final List<Widget> children;
|
||||
|
||||
const _TreeViewData({
|
||||
this.children,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView.builder(
|
||||
itemCount: children.length,
|
||||
itemBuilder: (context, index) {
|
||||
return children.elementAt(index);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TreeViewChild extends StatefulWidget {
|
||||
final bool startExpanded;
|
||||
final Widget parent;
|
||||
final List<Widget> children;
|
||||
final VoidCallback onTap;
|
||||
|
||||
TreeViewChild({
|
||||
@required this.parent,
|
||||
@required this.children,
|
||||
this.startExpanded,
|
||||
this.onTap,
|
||||
Key key,
|
||||
}) : super(key: key) {
|
||||
assert(parent != null);
|
||||
assert(children != null);
|
||||
}
|
||||
|
||||
@override
|
||||
TreeViewChildState createState() => TreeViewChildState();
|
||||
|
||||
TreeViewChild copyWith(
|
||||
TreeViewChild source, {
|
||||
bool startExpanded,
|
||||
Widget parent,
|
||||
List<Widget> children,
|
||||
VoidCallback onTap,
|
||||
}) {
|
||||
return TreeViewChild(
|
||||
parent: parent ?? source.parent,
|
||||
children: children ?? source.children,
|
||||
startExpanded: startExpanded ?? source.startExpanded,
|
||||
onTap: onTap ?? source.onTap,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TreeViewChildState extends State<TreeViewChild> {
|
||||
bool isExpanded;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
isExpanded = widget.startExpanded;
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
isExpanded = widget.startExpanded ?? TreeView.of(context).startExpanded;
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
GestureDetector(
|
||||
child: widget.parent,
|
||||
onTap: widget.onTap ?? () => toggleExpanded(),
|
||||
),
|
||||
AnimatedContainer(
|
||||
duration: Duration(milliseconds: 400),
|
||||
child: isExpanded
|
||||
? Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: widget.children,
|
||||
)
|
||||
: Offstage(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void toggleExpanded() {
|
||||
setState(() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
});
|
||||
}
|
||||
}
|
15
lib/util/calculate.dart
Normal file
15
lib/util/calculate.dart
Normal file
@ -0,0 +1,15 @@
|
||||
mixin Calculate {
|
||||
|
||||
double calculate1RM(double quantity, double unitQuantity) {
|
||||
double weight = unitQuantity;
|
||||
double repeat = quantity;
|
||||
if ( weight == 0 || repeat == 0) {
|
||||
return 0;
|
||||
}
|
||||
double rmWendler = weight * repeat * 0.0333 + weight;
|
||||
double rmOconner = weight * (1 + repeat / 40);
|
||||
double average = (rmWendler + rmOconner)/2;
|
||||
|
||||
return average;
|
||||
}
|
||||
}
|
@ -73,4 +73,10 @@ mixin Common {
|
||||
return _passwordRegExp.hasMatch(password);
|
||||
}
|
||||
|
||||
/// Calculates week number from a date as per https://en.wikipedia.org/wiki/ISO_week_date#Calculation
|
||||
int weekNumber(DateTime date) {
|
||||
int dayOfYear = int.parse(DateFormat("D").format(date));
|
||||
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ import 'dart:collection';
|
||||
import 'package:aitrainer_app/bloc/exercise_add_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
@ -25,7 +25,7 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
// ignore: close_sinks
|
||||
final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan'];
|
||||
final int customerId = arguments['customerId'];
|
||||
final WorkoutTree workoutTree = arguments['workoutTree'];
|
||||
final WorkoutMenuTree workoutTree = arguments['workoutTree'];
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
setContext(context);
|
||||
|
||||
@ -136,38 +136,15 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Divider(color: Colors.transparent,),
|
||||
Text("Execute the " + (i+1).toString() + ". set!",
|
||||
Text(t("Execute the") + " " + (i+1).toString() + t(". set!"),
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: t("The number of the exercise"),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: t("Please repeat with ") + exerciseBloc.unitQuantity1Field.value + " " +
|
||||
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
|
||||
exerciseBloc.exercisePlanRepository.actualPlanDetail.repeats.toString() + " times!",
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.unitQuantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontSize: 18,
|
||||
color: Colors.black54,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
@ -178,11 +155,35 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: t("The number of the exercise"),
|
||||
labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: t("Please repeat with") + " "+ exerciseBloc.unitQuantity1Field.value + " " +
|
||||
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
|
||||
exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() + " " + t("times!"),
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
|
@ -1,23 +1,25 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExerciseByPlanPage extends StatefulWidget {
|
||||
@override
|
||||
_ExerciseByPlanPage createState() => _ExerciseByPlanPage();
|
||||
}
|
||||
|
||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> with Trans {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExerciseByPlanBloc bloc;
|
||||
@ -38,21 +40,24 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExerciseByPlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||
AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId
|
||||
? AssetImage('asset/image/WT_light_background.png')
|
||||
: AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(listener: (context, state) {
|
||||
),
|
||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(
|
||||
listener: (context, state) {
|
||||
if (state is ExerciseByPlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
@ -64,124 +69,147 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
|
||||
builder: (context, state) {
|
||||
if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) {
|
||||
return Container();
|
||||
} else if (state is ExerciseByPlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExerciseByPlanError) {
|
||||
} else {
|
||||
return exerciseWidget(bloc);
|
||||
}
|
||||
})));
|
||||
})),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
);
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExerciseByPlanBloc bloc) {
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: false,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
/* Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc); */
|
||||
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
args['blocExerciseByPlan'] = bloc;
|
||||
args['customerId'] = bloc.customerId;
|
||||
args['workoutTree'] = workoutTree;
|
||||
Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args);
|
||||
},
|
||||
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: nodeExercisePlan(bloc),
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
List<Widget> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
|
||||
Card explanation = Card(
|
||||
color: Colors.white38,
|
||||
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(" "),
|
||||
Flexible(
|
||||
child:
|
||||
Text(
|
||||
t("Execute your active Exercise Plan!"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Select the muscle type and tap on the exercise. One the next page enter the weight and repeat."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
],
|
||||
)));
|
||||
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
|
||||
WorkoutTree treeItem = element;
|
||||
if ( treeItem.selected ) {
|
||||
icon =
|
||||
treeItem.executed == false ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") :
|
||||
NodeIcon(codePoint: Icons.check_box.codePoint, color: "green");
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail + ")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
}
|
||||
});
|
||||
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name,
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
exerciseTypes.add(
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: ExerciseTypeWidget(exerciseTypeName: name), //_getExerciseWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return nodes;
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, ExerciseByPlanBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
|
||||
if ( element.selected) {
|
||||
list.add(
|
||||
TreeViewChild(
|
||||
startExpanded: false,
|
||||
parent:
|
||||
Card(
|
||||
margin: EdgeInsets.only(left: 10, top: 5),
|
||||
color: Colors.white54,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, top: 0, right: 5, bottom: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: element.executed ? Icon(Icons.check_box, color: Colors.green):
|
||||
Icon(Icons.indeterminate_check_box, color: Colors.blue.shade800,),
|
||||
onPressed: () => {
|
||||
addExerciseByPlanEvent(bloc, element)
|
||||
},
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Flexible(
|
||||
child:
|
||||
InkWell(
|
||||
child:
|
||||
Text(
|
||||
element.name,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
onTap: () => {
|
||||
addExerciseByPlanEvent(bloc, element)
|
||||
},
|
||||
),
|
||||
|
||||
),
|
||||
IconButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
icon: Icon(Icons.description, color: Colors.black12,),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
),
|
||||
children: [
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
void addExerciseByPlanEvent(ExerciseByPlanBloc bloc, WorkoutMenuTree workoutTree) {
|
||||
LinkedHashMap args = LinkedHashMap();
|
||||
args['blocExerciseByPlan'] = bloc;
|
||||
args['customerId'] = bloc.customerId;
|
||||
args['workoutTree'] = workoutTree;
|
||||
Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import 'package:aitrainer_app/localization/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/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
@ -21,7 +20,6 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans {
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final CustomerRepository customerRepository = arguments['customerRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
setContext(context);
|
||||
|
||||
|
@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_plan_custom_form.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
@ -34,8 +35,8 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
||||
String exerciseName = "";
|
||||
if (bloc != null) {
|
||||
exerciseName = AppLanguage().appLocal == Locale("en")
|
||||
? bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name
|
||||
: bloc.exercisePlanRepository.actualPlanDetail.exerciseType.nameTranslation;
|
||||
? bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name
|
||||
: bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation;
|
||||
}
|
||||
|
||||
return Form(
|
||||
@ -118,9 +119,10 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
||||
color: Colors.red.shade300,
|
||||
focusColor: Colors.white,
|
||||
onPressed: () => {
|
||||
print("Remove " + bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name),
|
||||
print("Remove " + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name),
|
||||
bloc.exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.delete,
|
||||
planBloc.add(ExercisePlanRemoveExercise(
|
||||
exercisePlanDetail: bloc.exercisePlanRepository.actualPlanDetail)),
|
||||
exercisePlanDetail: bloc.exercisePlanRepository.getActualPlanDetail() )),
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
child: Text(t(
|
@ -1,24 +1,26 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExercisePlanCustomPage extends StatefulWidget {
|
||||
@override
|
||||
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
|
||||
}
|
||||
|
||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExercisePlanBloc bloc;
|
||||
@ -36,10 +38,10 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExercisePlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
@ -54,135 +56,158 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(listener: (context, state) {
|
||||
if (state is ExercisePlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(
|
||||
listener: (context, state) {
|
||||
if (state is ExercisePlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
if (state is ExercisePlanInitial) {
|
||||
builder: (context, state) {
|
||||
if (state is ExercisePlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
}
|
||||
return Container();
|
||||
} else if (state is ExercisePlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanError) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
return Container();
|
||||
}
|
||||
})));
|
||||
|
||||
}
|
||||
)
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
);
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExercisePlanBloc bloc) {
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: true,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc);
|
||||
},
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
backgroundColor: Colors.blueAccent,
|
||||
child: Icon(Icons.save_alt),
|
||||
onPressed: () => {
|
||||
bloc.add(ExercisePlanSave()),
|
||||
if (bloc.exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||
Navigator.of(context).pop()
|
||||
}
|
||||
}
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: _getTreeChildren(bloc),
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExercisePlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
List<Widget> _getTreeChildren(ExercisePlanBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
WorkoutTree treeItem = element;
|
||||
icon =
|
||||
treeItem.selected == true ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") : null;
|
||||
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("Custom Exercise Plan"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail +")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
});
|
||||
//print ("Node name " + name);
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name, // AppLocalizations.of(context).translate(name),
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
exerciseTypes.add(Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: ExerciseTypeWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return nodes;
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, ExercisePlanBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
|
||||
list.add(
|
||||
TreeViewChild(
|
||||
startExpanded: false,
|
||||
parent:
|
||||
Card(
|
||||
margin: EdgeInsets.only(left: 10, top: 5),
|
||||
color: Colors.white54,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, top: 0, right: 5, bottom: 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: element.selected ? Icon(Icons.check, color: Colors.greenAccent.shade700,) : Icon(Icons.add, color: Colors.blue.shade400,),
|
||||
onPressed: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
Flexible(
|
||||
child:
|
||||
InkWell(
|
||||
child:
|
||||
Text(
|
||||
element.name,
|
||||
textAlign: TextAlign.start,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
onTap: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
child:
|
||||
element.selected && bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].change != null ?
|
||||
Text(bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].repeats.toString() +
|
||||
" x " + bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].weightEquation +
|
||||
" " + element.exerciseType.unitQuantityUnit, style: TextStyle(fontSize: 9, color: Colors.green),) : Text(""),
|
||||
onTap: () => {
|
||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
icon: Icon(Icons.description, color: Colors.black12,),
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
),
|
||||
children: [
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
322
lib/view/mydevelopment_muscle_page.dart
Normal file
322
lib/view/mydevelopment_muscle_page.dart
Normal file
@ -0,0 +1,322 @@
|
||||
import 'dart:collection';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/exercise_type_widget.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class MyDevelopmentMusclePage extends StatefulWidget {
|
||||
@override
|
||||
_MyDevelopmentMuscleState createState() => _MyDevelopmentMuscleState();
|
||||
}
|
||||
|
||||
class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Common, Trans {
|
||||
// ignore: close_sinks
|
||||
DevelopmentByMuscleBloc bloc;
|
||||
double cWidth;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
BlocProvider.of<DevelopmentByMuscleBloc>(context).add(DevelopmentByMuscleLoad());
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bloc = BlocProvider.of<DevelopmentByMuscleBloc>(context);
|
||||
cWidth = mediaSizeWidth(context);
|
||||
setContext(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<DevelopmentByMuscleBloc, DevelopmentByMuscleState>(
|
||||
listener: (context, state) {
|
||||
if (state is DevelopmentByMuscleErrorState) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is DevelopmentByMuscleLoadingState) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is DevelopmentByMuscleStateInitial) {
|
||||
return Container();
|
||||
} else {
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),
|
||||
);
|
||||
}
|
||||
;
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _getTreeChildren(SplayTreeMap tree, DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> exerciseTypes = List();
|
||||
|
||||
Card explanation = Card(
|
||||
color: Colors.white60,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 5, top: 12),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Text(
|
||||
t("My Development By Muscle"),
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Text(
|
||||
t("Here you see you development in the last period."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.bubble_chart,),
|
||||
label: Text(t('Sum Of Mass')),
|
||||
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.sumMass,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.sumMass))
|
||||
},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.accessibility_new),
|
||||
label: Text(t('One Max Rep')),
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.oneRepMax,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.oneRepMax))
|
||||
},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.perm_device_information),
|
||||
label: Text(t('Percent')),
|
||||
labelStyle: TextStyle(fontSize: 9,color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.percent,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.percent))
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Detailed')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
disabledColor: Colors.black26,
|
||||
selectedColor: Colors.greenAccent,
|
||||
selected: bloc.dateRate == DateRate.daily,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.daily))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Weekly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white12,
|
||||
tooltip: "Heti bontás",
|
||||
selected: bloc.dateRate == DateRate.weekly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.weekly))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Monthly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.black26,
|
||||
selected: bloc.dateRate == DateRate.monthly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.monthly))
|
||||
},
|
||||
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Yearly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white70,
|
||||
selected: bloc.dateRate == DateRate.yearly,
|
||||
onSelected: (value) => {
|
||||
bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.yearly))
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
tree.forEach((name, list) {
|
||||
List<WorkoutMenuTree> listWorkoutMenuTree = list;
|
||||
exerciseTypes.add(Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: true,
|
||||
parent: _getExerciseWidget(exerciseTypeName: name),
|
||||
children: _getChildList(list, bloc),
|
||||
)));
|
||||
});
|
||||
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
Widget _getExerciseWidget({@required String exerciseTypeName, List<WorkoutMenuTree> list}) {
|
||||
return ExerciseTypeWidget(exerciseTypeName: exerciseTypeName);
|
||||
}
|
||||
|
||||
List<Widget> _getChildList(List<WorkoutMenuTree> listWorkoutTree, DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> list = List();
|
||||
listWorkoutTree.forEach((element) {
|
||||
bool hasNoData = (bloc.listChartData[element.exerciseTypeId] == null);
|
||||
String unit = " kg";
|
||||
if ( bloc.diagramType == DiagramType.percent) {
|
||||
unit = " %";
|
||||
}
|
||||
list.add(SizedBox(
|
||||
width: cWidth * 0.85,
|
||||
height: hasNoData ? 0 : 200,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left:5, top:5, right:5, bottom: 5),
|
||||
color: Colors.white70,
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
hasNoData
|
||||
? Container()
|
||||
: Text(
|
||||
element.exerciseType.nameTranslation,
|
||||
style: TextStyle(color: Colors.deepOrange),
|
||||
),
|
||||
hasNoData
|
||||
? Container(
|
||||
//child: Text("no data for " + element.exerciseType.nameTranslation),
|
||||
)
|
||||
: Expanded(
|
||||
//fit: FlexFit.loose,
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
tooltipBgColor: Colors.white70,
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
return BarTooltipItem(
|
||||
rod.y.toStringAsFixed(0) + unit,
|
||||
TextStyle(color: Colors.black54, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
);
|
||||
}),
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
show: true,
|
||||
bottomTitles: SideTitles(
|
||||
showTitles: true,
|
||||
textStyle: TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
getTitles: (double value) {
|
||||
var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt());
|
||||
//String strDate = DateFormat('MM.dd.', AppLanguage().appLocal.toString()).format(date);
|
||||
String strDate = bloc.getDatePart(date);
|
||||
return strDate;
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
textStyle: TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
interval: bloc.listChartData[element.exerciseTypeId] == null
|
||||
? 100
|
||||
: bloc.listChartData[element.exerciseTypeId].interval,
|
||||
margin: 10,
|
||||
getTitles: (double value) {
|
||||
return value.toStringAsFixed(0) + unit;
|
||||
})),
|
||||
borderData: FlBorderData(
|
||||
show: false,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
checkToShowHorizontalLine: (value) =>
|
||||
value % bloc.listChartData[element.exerciseTypeId].gridInterval == 0,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.black26,
|
||||
strokeWidth: 0.5,
|
||||
);
|
||||
},
|
||||
),
|
||||
groupsSpace: 2,
|
||||
barGroups: bloc.listChartData[element.exerciseTypeId] == null
|
||||
? []
|
||||
: bloc.listChartData[element.exerciseTypeId].data,
|
||||
),
|
||||
swapAnimationDuration: Duration(milliseconds: 1200),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
));
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class MyDevelopmentPage extends StatefulWidget {
|
||||
@override
|
||||
@ -84,10 +85,10 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
fit: StackFit.passthrough,
|
||||
overflow: Overflow.clip,
|
||||
children: [
|
||||
Image.asset('asset/image/lock.png',
|
||||
/*Image.asset('asset/image/lock.png',
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
),*/
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
@ -95,6 +96,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
Navigator.of(context).pushNamed('mydevelopmentMusclePage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text(t("Development Of Muscles"),
|
||||
style: TextStyle(fontSize: 18),)
|
||||
|
@ -151,7 +151,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
||||
lineHeight: 14.0,
|
||||
percent: percent,
|
||||
center: Text(
|
||||
(percent * 100).toStringAsFixed(0) + "% finished",
|
||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||
style: new TextStyle(fontSize: 12.0),
|
||||
),
|
||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
||||
|
@ -75,7 +75,7 @@ class _AppBarCommonNav extends State<AppBarCommonNav> with SingleTickerProvider
|
||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
||||
onPressed: () =>
|
||||
{
|
||||
Navigator.of(context).pop()
|
||||
Navigator.of(context).pushNamed('home')
|
||||
},
|
||||
)
|
||||
);
|
||||
@ -119,7 +119,7 @@ class _AppBarCommonNav extends State<AppBarCommonNav> with SingleTickerProvider
|
||||
lineHeight: 14.0,
|
||||
percent: percent,
|
||||
center: Text(
|
||||
(percent * 100).toStringAsFixed(0) + "% finished",
|
||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||
style: new TextStyle(fontSize: 12.0),
|
||||
),
|
||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
||||
|
@ -91,12 +91,12 @@ class _NawDrawerWidget extends State<BottomNavigator> {
|
||||
|
||||
break;
|
||||
case 1:
|
||||
//Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('myDevelopment');
|
||||
break;
|
||||
case 2:
|
||||
|
||||
//Navigator.of(context).pop();
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('myExercisePlan');
|
||||
|
||||
break;
|
||||
|
30
lib/widgets/exercise_type_widget.dart
Normal file
30
lib/widgets/exercise_type_widget.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ExerciseTypeWidget extends StatelessWidget {
|
||||
final String exerciseTypeName;
|
||||
//final DateTime lastModified;
|
||||
|
||||
ExerciseTypeWidget({@required this.exerciseTypeName});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget exerciseTypeNameWidget = Text(
|
||||
this.exerciseTypeName,
|
||||
style: TextStyle(fontWeight: FontWeight.w800, color: Colors.blueAccent, backgroundColor: Colors.transparent),
|
||||
);
|
||||
|
||||
Icon icon = Icon(Icons.person);
|
||||
|
||||
return Card(
|
||||
color: Colors.white38,
|
||||
shadowColor: Colors.black54,
|
||||
elevation: 0.0,
|
||||
child: ListTile(
|
||||
leading: icon,
|
||||
title: exerciseTypeNameWidget,
|
||||
//subtitle: lastModifiedWidget,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -45,9 +45,6 @@ class _HomePageState extends State<AitrainerHome> {
|
||||
SettingsBloc settingsBloc = BlocProvider.of<SettingsBloc>(context);
|
||||
settingsBloc.context = context;
|
||||
sessionBloc.add(SessionStart(settingsBloc: settingsBloc));
|
||||
//String lang = AppLanguage().appLocal.languageCode;
|
||||
//print (" -- Loading delayed lang $lang");
|
||||
//settingsBloc.add(SettingsChangeLanguage(language: lang));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ import 'dart:ui';
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
@ -31,7 +31,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
menuBloc.menuTreeRepository
|
||||
.getBranch(menuBloc.parent)
|
||||
.forEach((treeName, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||
_columnChildren.add(Container(
|
||||
padding: EdgeInsets.only(top: 16.0),
|
||||
child: Center(
|
||||
@ -83,7 +83,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
void menuClick(
|
||||
WorkoutTree workoutTree, MenuBloc menuBloc, BuildContext context) {
|
||||
WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {
|
||||
print("Hi!, Menu clicked " + workoutTree.id.toString());
|
||||
if (workoutTree.child == false) {
|
||||
menuBloc.add(MenuTreeDown(parent: workoutTree.id));
|
||||
@ -107,7 +107,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
dynamic getShape(WorkoutTree workoutTree) {
|
||||
dynamic getShape(WorkoutMenuTree workoutTree) {
|
||||
bool base = workoutTree.base;
|
||||
dynamic returnCode = (base == true)
|
||||
? RoundedRectangleBorder(
|
||||
@ -117,7 +117,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
dynamic _getButtonImage(WorkoutTree workoutTree) {
|
||||
dynamic _getButtonImage(WorkoutMenuTree workoutTree) {
|
||||
dynamic image;
|
||||
try {
|
||||
image = Image.asset(
|
||||
|
65
pubspec.lock
65
pubspec.lock
@ -225,6 +225,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -239,6 +246,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
fl_chart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fl_chart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -333,14 +347,14 @@ packages:
|
||||
name: freezed
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.6"
|
||||
version: "0.12.1"
|
||||
freezed_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: freezed_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.0+1"
|
||||
version: "0.12.0"
|
||||
fuchsia_remote_debug_protocol:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -401,7 +415,7 @@ packages:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.14"
|
||||
version: "2.1.18"
|
||||
intl:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -429,7 +443,7 @@ packages:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.1.0"
|
||||
json_rpc_2:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -514,6 +528,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
path_drawing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_drawing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.1+1"
|
||||
path_parsing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_parsing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.4"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -528,6 +556,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+1"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -541,7 +576,7 @@ packages:
|
||||
name: percent_indicator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.6"
|
||||
version: "2.1.7+3"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -639,7 +674,7 @@ packages:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.10"
|
||||
version: "0.5.12"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -668,6 +703,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+7"
|
||||
shared_preferences_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -707,7 +749,7 @@ packages:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.6"
|
||||
version: "0.9.7+1"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -876,6 +918,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.3"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.3"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -889,7 +938,7 @@ packages:
|
||||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
version: "4.5.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.0+21
|
||||
version: 1.1.0+22
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
@ -34,13 +34,14 @@ dependencies:
|
||||
flutter_facebook_login: ^3.0.0
|
||||
flutter_bloc: ^6.0.5
|
||||
equatable: ^1.2.5
|
||||
freezed: ^0.11.6
|
||||
freezed: ^0.12.1
|
||||
flutter_form_bloc: ^0.19.0
|
||||
spider_chart: ^0.1.5
|
||||
rainbow_color: ^0.1.1
|
||||
percent_indicator: ^2.1.6
|
||||
percent_indicator: ^2.1.7+3
|
||||
gradient_bottom_navigation_bar: ^1.0.0+4
|
||||
flutter_treeview: ^0.6.0+1
|
||||
fl_chart: ^0.11.1
|
||||
|
||||
mockito: ^4.1.1
|
||||
|
||||
@ -58,7 +59,7 @@ dev_dependencies:
|
||||
|
||||
http: 0.12.1
|
||||
intl: 0.16.1
|
||||
shared_preferences: ^0.5.10
|
||||
shared_preferences: ^0.5.12
|
||||
|
||||
flutter_launcher_icons: ^0.8.0
|
||||
|
||||
|
193
test/exercise_plan_bloc.dart
Normal file
193
test/exercise_plan_bloc.dart
Normal file
@ -0,0 +1,193 @@
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'mocks.dart';
|
||||
|
||||
main() {
|
||||
SimExercisePlanRepository _exercisePlanRepository;
|
||||
ExercisePlanBloc bloc;
|
||||
|
||||
int _customerId;
|
||||
|
||||
Future<void> setUpPlan() async {
|
||||
final String planName2 = "Test Plan2";
|
||||
ExercisePlan plan2 = ExercisePlan(planName2, 101);
|
||||
_exercisePlanRepository.setCustomerId(101);
|
||||
_exercisePlanRepository.setExercisePlan(plan2);
|
||||
|
||||
ExercisePlanDetail detail3 = ExercisePlanDetail(3);
|
||||
detail3.repeats = 23;
|
||||
detail3.weightEquation = "60";
|
||||
detail3.serie = 4;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail3);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
ExercisePlanDetail detail4 = ExercisePlanDetail(4);
|
||||
detail4.repeats = 12;
|
||||
detail4.weightEquation = "95";
|
||||
detail4.serie = 3;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail4);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
await _exercisePlanRepository.saveExercisePlan();
|
||||
}
|
||||
|
||||
setUp(() async {
|
||||
_exercisePlanRepository = SimExercisePlanRepository();
|
||||
WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
||||
bloc = ExercisePlanBloc(menuTreeRepository: menuTreeRepository);
|
||||
bloc.setExercisePlanRepository(_exercisePlanRepository);
|
||||
_customerId = 62;
|
||||
await setUpPlan();
|
||||
});
|
||||
|
||||
/*
|
||||
group('New Plan', () {
|
||||
test('Get Data', () async {
|
||||
});
|
||||
|
||||
test('Add bloc', () async {
|
||||
|
||||
});
|
||||
test('Update bloc', () async {
|
||||
|
||||
});
|
||||
test('Delete bloc', () async {
|
||||
|
||||
});
|
||||
|
||||
});*/
|
||||
|
||||
group('Existing Plan', () {
|
||||
test('Get Data', () async {
|
||||
bloc.customerId = 101;
|
||||
bloc.add(ExercisePlanLoad());
|
||||
|
||||
final expectedResponse = [
|
||||
ExercisePlanLoading(),
|
||||
ExercisePlanReady()
|
||||
];
|
||||
|
||||
expectLater(
|
||||
bloc,
|
||||
emitsInOrder(expectedResponse),
|
||||
).then((_) {
|
||||
expect(bloc.exercisePlanRepository.newPlan, false);
|
||||
expect(bloc.exercisePlanRepository.exercisePlan.name, "Test Plan2" );
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails[4].weightEquation, "95");
|
||||
expect(Cache().getMyExercisePlan().name, "Test Plan2");
|
||||
expect(Cache().getMyExercisePlanDetails()[4].weightEquation, "95");
|
||||
});
|
||||
});
|
||||
|
||||
test('Add bloc', () async {
|
||||
bloc.customerId = 101;
|
||||
|
||||
bloc.exercisePlanRepository.getLastExercisePlan();
|
||||
bloc.exercisePlanRepository.getExercisePlanDetails();
|
||||
|
||||
ExercisePlanDetail detail4 = ExercisePlanDetail(5);
|
||||
detail4.repeats = 20;
|
||||
detail4.weightEquation = "55";
|
||||
detail4.serie = 3;
|
||||
|
||||
|
||||
|
||||
bloc.add(ExercisePlanAddExercise(exercisePlanDetail: detail4));
|
||||
|
||||
final expectedResponse2 = [
|
||||
ExercisePlanLoading(),
|
||||
ExercisePlanReady()
|
||||
];
|
||||
|
||||
expectLater(
|
||||
bloc,
|
||||
emitsInOrder(expectedResponse2),
|
||||
).then((_) {
|
||||
expect(bloc.exercisePlanRepository.newPlan, false);
|
||||
expect(bloc.exercisePlanRepository.exercisePlan.customerId, 101);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 3);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails[5].repeats, 20);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails[5].change, ExercisePlanDetailChange.add);
|
||||
expect(Cache()
|
||||
.getMyExercisePlan()
|
||||
.name, "Test Plan2");
|
||||
expect(Cache().getMyExercisePlanDetails()[5].weightEquation, "55");
|
||||
expect(Cache().getMyExercisePlanDetails()[5].repeats, 20);
|
||||
});
|
||||
});
|
||||
test('Update bloc', () async {
|
||||
bloc.customerId = 101;
|
||||
|
||||
bloc.exercisePlanRepository.getLastExercisePlan();
|
||||
bloc.exercisePlanRepository.getExercisePlanDetails();
|
||||
bloc.exercisePlanRepository.exercisePlanDetails[3].repeats = 25;
|
||||
|
||||
bloc.add(ExercisePlanAddExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));
|
||||
|
||||
final expectedResponse2 = [
|
||||
ExercisePlanLoading(),
|
||||
ExercisePlanReady()
|
||||
];
|
||||
|
||||
expectLater(
|
||||
bloc,
|
||||
emitsInOrder(expectedResponse2),
|
||||
).then((_) {
|
||||
expect(bloc.exercisePlanRepository.newPlan, false);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails[3].repeats, 25);
|
||||
expect(Cache().getMyExercisePlanDetails()[3].repeats, 25);
|
||||
});
|
||||
|
||||
});
|
||||
test('Delete bloc', () async {
|
||||
bloc.customerId = 101;
|
||||
bloc.exercisePlanRepository.getLastExercisePlan();
|
||||
bloc.exercisePlanRepository.getExercisePlanDetails();
|
||||
bloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));
|
||||
|
||||
final expectedResponse2 = [
|
||||
ExercisePlanLoading(),
|
||||
ExercisePlanReady()
|
||||
];
|
||||
|
||||
expectLater(
|
||||
bloc,
|
||||
emitsInOrder(expectedResponse2),
|
||||
).then((_) {
|
||||
expect(bloc.exercisePlanRepository.newPlan, false);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 2);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails[3], isNull);
|
||||
expect(Cache().getMyExercisePlanDetails()[3], isNull);
|
||||
});
|
||||
});
|
||||
|
||||
test('Test Trainee', () async {
|
||||
/*bloc.customerId = 102;
|
||||
bloc.exercisePlanRepository.customerId = 102;
|
||||
|
||||
bloc.add(ExercisePlanLoad());
|
||||
|
||||
final expectedResponse = [
|
||||
ExercisePlanLoading(),
|
||||
ExercisePlanReady()
|
||||
];
|
||||
|
||||
|
||||
expectLater(
|
||||
bloc,
|
||||
emitsInOrder(expectedResponse),
|
||||
).then((_) {
|
||||
expect(bloc.exercisePlanRepository.newPlan, true);
|
||||
expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 0);
|
||||
});*/
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
158
test/exercise_plan_repository_test.dart
Normal file
158
test/exercise_plan_repository_test.dart
Normal file
@ -0,0 +1,158 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'mocks.dart';
|
||||
|
||||
|
||||
main() {
|
||||
SimExercisePlanRepository _exercisePlanRepository;
|
||||
int _customerId;
|
||||
|
||||
Future<void> setUpPlan() async {
|
||||
|
||||
final String planName2 = "Test Plan2";
|
||||
ExercisePlan plan2 = ExercisePlan(planName2, 101);
|
||||
_exercisePlanRepository.setCustomerId(101);
|
||||
_exercisePlanRepository.setExercisePlan(plan2);
|
||||
|
||||
ExercisePlanDetail detail3 = ExercisePlanDetail(3);
|
||||
detail3.repeats = 23;
|
||||
detail3.weightEquation = "60";
|
||||
detail3.serie = 4;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail3);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
ExercisePlanDetail detail4 = ExercisePlanDetail(4);
|
||||
detail4.repeats = 12;
|
||||
detail4.weightEquation = "95";
|
||||
detail4.serie = 3;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail4);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
await _exercisePlanRepository.saveExercisePlan();
|
||||
}
|
||||
|
||||
setUp(() async {
|
||||
_exercisePlanRepository = SimExercisePlanRepository();
|
||||
_customerId = 62;
|
||||
await setUpPlan();
|
||||
});
|
||||
|
||||
|
||||
|
||||
group('New Plan', () {
|
||||
test('add new plan and plan details and save', () async {
|
||||
final String planName = "Boss Test Plan";
|
||||
ExercisePlan plan = ExercisePlan(planName, _customerId);
|
||||
_exercisePlanRepository.setExercisePlan(plan);
|
||||
|
||||
ExercisePlanDetail detail1 = ExercisePlanDetail(37);
|
||||
detail1.repeats = 12;
|
||||
detail1.weightEquation = "80";
|
||||
detail1.serie = 4;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail1);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
ExercisePlanDetail detail2 = ExercisePlanDetail(55);
|
||||
detail2.repeats = 13;
|
||||
detail2.weightEquation = "55";
|
||||
detail2.serie = 3;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail2);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
await _exercisePlanRepository.saveExercisePlan();
|
||||
|
||||
expect(_exercisePlanRepository.getExercisePlan().name, planName);
|
||||
expect(_exercisePlanRepository.getExercisePlan().exercisePlanId > 0, true);
|
||||
|
||||
ExercisePlanDetail detail =
|
||||
_exercisePlanRepository.getExercisePlanDetailByExerciseId(55);
|
||||
expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan().exercisePlanId);
|
||||
|
||||
|
||||
});
|
||||
test('save new plan and plan details second', () async {
|
||||
int customerId = 100;
|
||||
final String planName = "Boss2 Test Plan";
|
||||
ExercisePlan plan = ExercisePlan(planName, customerId);
|
||||
_exercisePlanRepository.setExercisePlan(plan);
|
||||
|
||||
ExercisePlanDetail detail1 = ExercisePlanDetail(12);
|
||||
detail1.repeats = 10;
|
||||
detail1.weightEquation = "40";
|
||||
detail1.serie = 5;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail1);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
ExercisePlanDetail detail2 = ExercisePlanDetail(13);
|
||||
detail2.repeats = 33;
|
||||
detail2.weightEquation = "15";
|
||||
detail2.serie = 3;
|
||||
_exercisePlanRepository.setActualPlanDetail(detail2);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
await _exercisePlanRepository.saveExercisePlan();
|
||||
|
||||
expect(_exercisePlanRepository.getExercisePlan().name, planName);
|
||||
expectLater(_exercisePlanRepository.getExercisePlan().exercisePlanId > 0, true);
|
||||
|
||||
ExercisePlanDetail detail = _exercisePlanRepository.getExercisePlanDetailByExerciseId(13);
|
||||
expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan().exercisePlanId);
|
||||
expect(detail.repeats, 33);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
group('Existing Plan', () {
|
||||
test('Get Last Plan and Details from DB', () async {
|
||||
ExercisePlan exercisePlan = await _exercisePlanRepository.getLastExercisePlan();
|
||||
expect(exercisePlan.customerId,101);
|
||||
|
||||
await _exercisePlanRepository.getExercisePlanDetails();
|
||||
expect(_exercisePlanRepository.exercisePlanDetails[3].repeats,23 );
|
||||
expect(_exercisePlanRepository.exercisePlanDetails[4].weightEquation,"95" );
|
||||
|
||||
//Test Cache
|
||||
expect(Cache().getMyExercisePlan().name,"Test Plan2");
|
||||
expect(Cache().getMyExercisePlanDetails()[3].weightEquation,"60");
|
||||
});
|
||||
|
||||
test('Add new PlanDetail', () async {
|
||||
_exercisePlanRepository.newPlan = false;
|
||||
ExercisePlanDetail detail4 = ExercisePlanDetail(5);
|
||||
detail4.repeats = 6;
|
||||
detail4.weightEquation = "105";
|
||||
detail4.serie = 3;
|
||||
|
||||
_exercisePlanRepository.setActualPlanDetail(detail4);
|
||||
_exercisePlanRepository.addDetailToPlan();
|
||||
|
||||
await _exercisePlanRepository.saveExercisePlan();
|
||||
|
||||
expect(_exercisePlanRepository.getExercisePlan().name, "Test Plan2");
|
||||
expect(Cache().getMyExercisePlanDetails()[5].weightEquation, "105");
|
||||
expect(Cache().getMyExercisePlanDetails()[5].repeats, 6);
|
||||
|
||||
});
|
||||
|
||||
test('Delete from PlanDetails', () async {
|
||||
_exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(4);
|
||||
_exercisePlanRepository.saveExercisePlan();
|
||||
|
||||
expect(_exercisePlanRepository.exercisePlanDetails[4].change, ExercisePlanDetailChange.delete);
|
||||
expect(Cache().getMyExercisePlanDetails()[4], isNull);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
181
test/mocks.dart
Normal file
181
test/mocks.dart
Normal file
@ -0,0 +1,181 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
class MockExercisePlanApi extends Mock implements ExercisePlanApi {
|
||||
static final MockExercisePlanApi _singleton = MockExercisePlanApi._internal();
|
||||
factory MockExercisePlanApi() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
MockExercisePlanApi._internal() {}
|
||||
|
||||
final List<ExercisePlan> memoryExercisePlan = List();
|
||||
final List<ExercisePlanDetail> memoryExercisePlanDetail = List();
|
||||
|
||||
Future<ExercisePlan> saveExercisePlan(ExercisePlan plan) async {
|
||||
memoryExercisePlan.add(plan);
|
||||
plan.exercisePlanId = memoryExercisePlan.length;
|
||||
return plan;
|
||||
}
|
||||
|
||||
Future<ExercisePlanDetail> saveExercisePlanDetail(ExercisePlanDetail detail) async {
|
||||
memoryExercisePlanDetail.add(detail);
|
||||
detail.exercisePlanDetailId = memoryExercisePlanDetail.length;
|
||||
return detail;
|
||||
}
|
||||
|
||||
Future<ExercisePlanDetail> updateExercisePlanDetail(ExercisePlanDetail detail, int planDetailId) async {
|
||||
ExercisePlanDetail updated;
|
||||
memoryExercisePlanDetail.forEach((element) {
|
||||
if ( element.exercisePlanDetailId == planDetailId ) {
|
||||
element = detail;
|
||||
}
|
||||
});
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
Future<void> deleteExercisePlanDetail(int exercisePlanId) async {
|
||||
int index = -1;
|
||||
int countIndex = 0;
|
||||
memoryExercisePlanDetail.forEach((element) {
|
||||
if ( element.exercisePlanId == exercisePlanId ) {
|
||||
index = countIndex;
|
||||
}
|
||||
countIndex++;
|
||||
});
|
||||
if ( index > -1) {
|
||||
memoryExercisePlanDetail.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ExercisePlanDetail>> getExercisePlanDetail(int exercisePlanId) async {
|
||||
List<ExercisePlanDetail> foundList = List();
|
||||
memoryExercisePlanDetail.forEach((element) {
|
||||
if ( element.exercisePlanId == exercisePlanId ) {
|
||||
foundList.add(element);
|
||||
}
|
||||
});
|
||||
return foundList;
|
||||
}
|
||||
|
||||
Future<ExercisePlan> getLastExercisePlan(int customerId) async {
|
||||
ExercisePlan found;
|
||||
memoryExercisePlan.forEach((element) {
|
||||
if ( element.customerId == customerId ) {
|
||||
found = element;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
class SimExercisePlanRepository with ExercisePlanRepository {
|
||||
|
||||
Future<void> getExercisePlanDetails() async {
|
||||
if (exercisePlan == null) {
|
||||
ExercisePlan exercisePlan = await this.getLastExercisePlan();
|
||||
if ( exercisePlan == null ) {
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
List<ExercisePlanDetail> list = List();
|
||||
LinkedHashMap<int, ExercisePlanDetail> listCache = Cache().getMyExercisePlanDetails();
|
||||
if ( listCache.length > 0) {
|
||||
exercisePlanDetails = listCache;
|
||||
return;
|
||||
} else {
|
||||
list = await MockExercisePlanApi().getExercisePlanDetail(exercisePlan.exercisePlanId);
|
||||
}
|
||||
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
list.forEach((element) {
|
||||
newPlan = false;
|
||||
ExercisePlanDetail detail = element;
|
||||
exercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||
});
|
||||
Cache().setMyExercisePlanDetails(exercisePlanDetails);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Future<ExercisePlan> getLastExercisePlan() async {
|
||||
if ( customerId == 0) {
|
||||
return null;
|
||||
}
|
||||
ExercisePlan myExercisePlan = Cache().getMyExercisePlan();
|
||||
if ( myExercisePlan != null ) {
|
||||
newPlan = false;
|
||||
return myExercisePlan;
|
||||
}
|
||||
|
||||
exercisePlan = await MockExercisePlanApi().getLastExercisePlan(customerId);
|
||||
newPlan = (exercisePlan == null);
|
||||
Cache().setMyExercisePlan(exercisePlan);
|
||||
return exercisePlan;
|
||||
}
|
||||
|
||||
Future<void> saveExercisePlan() async {
|
||||
if ( exercisePlan == null ) {
|
||||
if ( Cache().userLoggedIn == null ) {
|
||||
throw Exception("please log in");
|
||||
}
|
||||
|
||||
String exercisePlanName;
|
||||
if ( this.customerId == Cache().userLoggedIn.customerId) {
|
||||
exercisePlanName = Cache().userLoggedIn.name + " private";
|
||||
} else {
|
||||
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
|
||||
}
|
||||
|
||||
exercisePlan = ExercisePlan(exercisePlanName, this.customerId);
|
||||
}
|
||||
if ( newPlan ) {
|
||||
exercisePlan.dateAdd = DateTime.now();
|
||||
exercisePlan.private = true;
|
||||
|
||||
ExercisePlan savedExercisePlan
|
||||
= await MockExercisePlanApi().saveExercisePlan(exercisePlan);
|
||||
|
||||
|
||||
LinkedHashMap<int, ExercisePlanDetail> savedExercisePlanDetails = LinkedHashMap();
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId;
|
||||
|
||||
ExercisePlanDetail savedDetail = await MockExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||
|
||||
savedExercisePlanDetails[savedDetail.exerciseTypeId] = savedDetail;
|
||||
});
|
||||
|
||||
exercisePlan = savedExercisePlan;
|
||||
} else {
|
||||
|
||||
await MockExercisePlanApi().updateExercisePlan(exercisePlan, exercisePlan.exercisePlanId);
|
||||
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
if ( exercisePlanDetail.change == ExercisePlanDetailChange.delete ) {
|
||||
await MockExercisePlanApi()
|
||||
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
|
||||
Cache().deleteMyExercisePlanDetail(exercisePlanDetail);
|
||||
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.update ) {
|
||||
await MockExercisePlanApi()
|
||||
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
|
||||
Cache().updateMyExercisePlanDetail(exercisePlanDetail);
|
||||
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.add ) {
|
||||
await MockExercisePlanApi()
|
||||
.saveExercisePlanDetail(exercisePlanDetail);
|
||||
Cache().addToMyExercisePlanDetails(exercisePlanDetail);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user