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",
|
"Home": "Home",
|
||||||
"Customers": "Customers",
|
"Customers": "Customers",
|
||||||
"Exercises": "Exercises",
|
"Exercises": "Exercises",
|
||||||
@ -66,7 +66,9 @@
|
|||||||
"Do you save this exercise with these parameters?":"Do you save this exercise with these parameters?",
|
"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": "The number of the exercise",
|
||||||
"The number of the exercise done with": "The number of the exercise done with",
|
"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",
|
"repeat": "repeat",
|
||||||
@ -109,6 +111,7 @@
|
|||||||
|
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Make your first test": "Make your first test",
|
"Make your first test": "Make your first test",
|
||||||
|
"finished": "finished",
|
||||||
"Why do you need Exercise Control?" : "Why do you need Exercise Control?",
|
"Why do you need Exercise Control?" : "Why do you need Exercise Control?",
|
||||||
|
|
||||||
"Your 1RM:":"Your 1RM:",
|
"Your 1RM:":"Your 1RM:",
|
||||||
@ -149,5 +152,22 @@
|
|||||||
"My Whole Body Development": "My Whole Body Development",
|
"My Whole Body Development": "My Whole Body Development",
|
||||||
"Development Of Muscles": "Development Of Muscles",
|
"Development Of Muscles": "Development Of Muscles",
|
||||||
"Predictions": "Predictions",
|
"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",
|
"Home": "Főoldal",
|
||||||
"Customers": "Ügyfelek",
|
"Customers": "Ügyfelek",
|
||||||
"Exercises": "Gyakorlatok",
|
"Exercises": "Gyakorlatok",
|
||||||
@ -55,8 +55,9 @@
|
|||||||
"Delete": "Törlés",
|
"Delete": "Törlés",
|
||||||
"The number of the exercise": "Írd be a gyakorlat számát",
|
"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",
|
"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",
|
"Name": "Név",
|
||||||
"Exercise": "Gyakorlat",
|
"Exercise": "Gyakorlat",
|
||||||
@ -69,6 +70,7 @@
|
|||||||
"with": "",
|
"with": "",
|
||||||
"Do you save this exercise with these parameters?":"Elmented a gyakorlatot ezekkel az adatokkal?",
|
"Do you save this exercise with these parameters?":"Elmented a gyakorlatot ezekkel az adatokkal?",
|
||||||
|
|
||||||
|
|
||||||
"repeat": "ismétlés",
|
"repeat": "ismétlés",
|
||||||
"meter": "meter",
|
"meter": "meter",
|
||||||
"percent": "százalék",
|
"percent": "százalék",
|
||||||
@ -109,6 +111,7 @@
|
|||||||
|
|
||||||
"Description": "Leírás",
|
"Description": "Leírás",
|
||||||
"Make your first test": "Végezd el az első tesztet",
|
"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?",
|
"Why do you need Exercise Control?": "Miért szükséges a kontrollgyakorlat?",
|
||||||
"Your 1RM:":"Maxerőd:",
|
"Your 1RM:":"Maxerőd:",
|
||||||
"Your Real 1RM:":"Ellenőrzött maxerő:",
|
"Your Real 1RM:":"Ellenőrzött maxerő:",
|
||||||
@ -149,5 +152,22 @@
|
|||||||
"My Whole Body Development": "Testem fejlődése",
|
"My Whole Body Development": "Testem fejlődése",
|
||||||
"Development Of Muscles": "Izomcsoportok fejlődése",
|
"Development Of Muscles": "Izomcsoportok fejlődése",
|
||||||
"Predictions": "Előrejelzések",
|
"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/cache.dart';
|
||||||
import 'package:aitrainer_app/model/customer.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_plan_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:flutter_form_bloc/flutter_form_bloc.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> {
|
class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
||||||
final ExerciseRepository exerciseRepository;
|
final ExerciseRepository exerciseRepository;
|
||||||
final ExercisePlanRepository exercisePlanRepository;
|
final ExercisePlanRepository exercisePlanRepository;
|
||||||
final WorkoutTree workoutTree;
|
final WorkoutMenuTree workoutTree;
|
||||||
final customerId;
|
final customerId;
|
||||||
Customer customer;
|
Customer customer;
|
||||||
int step = 1;
|
int step = 1;
|
||||||
@ -40,12 +40,12 @@ class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
|||||||
} else if ( Cache().getTrainee().customerId == customerId) {
|
} else if ( Cache().getTrainee().customerId == customerId) {
|
||||||
customer = Cache().getTrainee();
|
customer = Cache().getTrainee();
|
||||||
}
|
}
|
||||||
exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
|
||||||
exerciseRepository.customer = customer;
|
exerciseRepository.customer = customer;
|
||||||
countSteps = exercisePlanRepository.actualPlanDetail.serie;
|
countSteps = exercisePlanRepository.getActualPlanDetail().serie;
|
||||||
|
|
||||||
unitQuantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.weightEquation);
|
unitQuantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().weightEquation);
|
||||||
quantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.repeats.toString());
|
quantity1Field.updateInitialValue(exercisePlanRepository.getActualPlanDetail().repeats.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
|||||||
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
|
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
|
||||||
exerciseRepository.setQuantity(quantity1Field.valueToDouble);
|
exerciseRepository.setQuantity(quantity1Field.valueToDouble);
|
||||||
exerciseRepository.exercise.exercisePlanDetailId =
|
exerciseRepository.exercise.exercisePlanDetailId =
|
||||||
exercisePlanRepository.actualPlanDetail.exercisePlanDetailId;
|
exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId;
|
||||||
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
|
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
|
||||||
workoutTree.executed = true;
|
workoutTree.executed = true;
|
||||||
print("On Submitting Add Exercise By Plan " + exerciseRepository.exercise.toJson().toString());
|
print("On Submitting Add Exercise By Plan " + exerciseRepository.exercise.toJson().toString());
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:aitrainer_app/model/exercise_type.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_plan_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
|
||||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
@ -13,12 +12,11 @@ part 'exercise_by_plan_event.dart';
|
|||||||
part 'exercise_by_plan_state.dart';
|
part 'exercise_by_plan_state.dart';
|
||||||
|
|
||||||
class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState> {
|
class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState> {
|
||||||
final ExerciseRepository exerciseRepository;
|
|
||||||
final WorkoutTreeRepository menuTreeRepository;
|
final WorkoutTreeRepository menuTreeRepository;
|
||||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||||
int customerId;
|
int customerId;
|
||||||
@override
|
@override
|
||||||
ExerciseByPlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
|
ExerciseByPlanBloc({this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
|
||||||
|
|
||||||
Future<void> getData() async {
|
Future<void> getData() async {
|
||||||
exercisePlanRepository.setCustomerId(customerId);
|
exercisePlanRepository.setCustomerId(customerId);
|
||||||
@ -28,11 +26,11 @@ class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState>
|
|||||||
menuTreeRepository.sortByMuscleType();
|
menuTreeRepository.sortByMuscleType();
|
||||||
|
|
||||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||||
List<WorkoutTree> listWorkoutTree = value;
|
List<WorkoutMenuTree> listWorkoutTree = value;
|
||||||
listWorkoutTree.forEach((workoutTree) {
|
listWorkoutTree.forEach((workoutTree) {
|
||||||
workoutTree.selected = false;
|
workoutTree.selected = false;
|
||||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
if (exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId) != null) {
|
||||||
workoutTree.selected = true;
|
workoutTree.selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
|
||||||
import 'package:aitrainer_app/repository/exercise_plan_repository.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:aitrainer_app/repository/workout_tree_repository.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
@ -15,11 +13,10 @@ part 'exercise_plan_state.dart';
|
|||||||
|
|
||||||
class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||||
final WorkoutTreeRepository menuTreeRepository;
|
final WorkoutTreeRepository menuTreeRepository;
|
||||||
final ExerciseRepository exerciseRepository;
|
ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
|
||||||
int customerId;
|
int customerId;
|
||||||
|
|
||||||
ExercisePlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExercisePlanInitial());
|
ExercisePlanBloc({this.menuTreeRepository}) : super(ExercisePlanInitial());
|
||||||
|
|
||||||
Future<void> getData() async {
|
Future<void> getData() async {
|
||||||
exercisePlanRepository.setCustomerId(customerId);
|
exercisePlanRepository.setCustomerId(customerId);
|
||||||
@ -29,12 +26,11 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
|||||||
menuTreeRepository.sortByMuscleType();
|
menuTreeRepository.sortByMuscleType();
|
||||||
|
|
||||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||||
List<WorkoutTree> listWorkoutTree = value;
|
List<WorkoutMenuTree> listWorkoutTree = value;
|
||||||
listWorkoutTree.forEach((workoutTree) {
|
listWorkoutTree.forEach((workoutTree) {
|
||||||
workoutTree.selected = false;
|
workoutTree.selected = false;
|
||||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
if (exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId) != null) {
|
||||||
//print("bingo");
|
|
||||||
workoutTree.selected = true;
|
workoutTree.selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,6 +38,8 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setExercisePlanRepository(ExercisePlanRepository repo ) => exercisePlanRepository = repo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
|
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
|
||||||
try {
|
try {
|
||||||
@ -50,38 +48,62 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
|||||||
await this.getData();
|
await this.getData();
|
||||||
yield ExercisePlanReady();
|
yield ExercisePlanReady();
|
||||||
}
|
}
|
||||||
if (event is ExercisePlanUpdate) {
|
|
||||||
|
if (event is ExercisePlanUpdateUI) {
|
||||||
yield ExercisePlanLoading();
|
yield ExercisePlanLoading();
|
||||||
WorkoutTree workoutTree = event.workoutTree;
|
|
||||||
|
WorkoutMenuTree workoutTree = event.workoutTree;
|
||||||
if (workoutTree != null) {
|
if (workoutTree != null) {
|
||||||
exercisePlanRepository.addExerciseTypeToPlan(workoutTree.exerciseType);
|
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
|
||||||
workoutTree.selected = true;
|
workoutTree.selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ExercisePlanReady();
|
yield ExercisePlanReady();
|
||||||
} else if (event is ExercisePlanRemoveExercise) {
|
}
|
||||||
|
|
||||||
|
else if (event is ExercisePlanAddExercise) {
|
||||||
yield ExercisePlanLoading();
|
yield ExercisePlanLoading();
|
||||||
ExercisePlanDetail planDetail = event.exercisePlanDetail;
|
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) {
|
this.menuTreeRepository.sortedTree.forEach((key, value) {
|
||||||
List<WorkoutTree> listTreeItem = value;
|
List<WorkoutMenuTree> listTreeItem = value;
|
||||||
listTreeItem.forEach((element) {
|
listTreeItem.forEach((element) {
|
||||||
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
|
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
|
||||||
element.selected = false;
|
element.selected = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
yield ExercisePlanReady();
|
|
||||||
} else if (event is ExercisePlanUpdateExercise) {
|
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
|
||||||
yield ExercisePlanReady();
|
|
||||||
} else if (event is ExercisePlanSave) {
|
|
||||||
if (exercisePlanRepository.getExercisePlanDetailSize() == 0) {
|
|
||||||
throw Exception("Please select an exercise");
|
|
||||||
} else {
|
|
||||||
yield ExercisePlanLoading();
|
|
||||||
exercisePlanRepository.saveExercisePlan();
|
exercisePlanRepository.saveExercisePlan();
|
||||||
yield ExercisePlanReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
yield ExercisePlanReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
yield ExercisePlanError(message: e.toString());
|
yield ExercisePlanError(message: e.toString());
|
||||||
}
|
}
|
||||||
|
@ -11,21 +11,16 @@ class ExercisePlanLoad extends ExercisePlanEvent {
|
|||||||
const ExercisePlanLoad();
|
const ExercisePlanLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExercisePlanUpdate extends ExercisePlanEvent {
|
|
||||||
final WorkoutTree workoutTree;
|
// update UI
|
||||||
const ExercisePlanUpdate({this.workoutTree});
|
class ExercisePlanUpdateUI extends ExercisePlanEvent {
|
||||||
|
final WorkoutMenuTree workoutTree;
|
||||||
|
const ExercisePlanUpdateUI({this.workoutTree});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [workoutTree];
|
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 {
|
class ExercisePlanRemoveExercise extends ExercisePlanEvent {
|
||||||
final ExercisePlanDetail exercisePlanDetail;
|
final ExercisePlanDetail exercisePlanDetail;
|
||||||
@ -35,15 +30,10 @@ class ExercisePlanRemoveExercise extends ExercisePlanEvent {
|
|||||||
List<Object> get props => [exercisePlanDetail];
|
List<Object> get props => [exercisePlanDetail];
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExercisePlanUpdateExercise extends ExercisePlanEvent {
|
class ExercisePlanAddExercise extends ExercisePlanEvent {
|
||||||
final ExercisePlanDetail exercisePlanDetail;
|
final ExercisePlanDetail exercisePlanDetail;
|
||||||
const ExercisePlanUpdateExercise({this.exercisePlanDetail});
|
const ExercisePlanAddExercise({this.exercisePlanDetail});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [exercisePlanDetail];
|
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/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:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||||
|
|
||||||
@ -36,29 +37,29 @@ class ExercisePlanCustomerFormBloc extends FormBloc<String, String> {
|
|||||||
weightField
|
weightField
|
||||||
]);
|
]);
|
||||||
|
|
||||||
String repeatsInitial = exercisePlanRepository.actualPlanDetail != null &&
|
String repeatsInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||||
exercisePlanRepository.actualPlanDetail.repeats != null ?
|
exercisePlanRepository.getActualPlanDetail().repeats != null ?
|
||||||
exercisePlanRepository.actualPlanDetail.repeats.toString() : "12";
|
exercisePlanRepository.getActualPlanDetail().repeats.toString() : "12";
|
||||||
quantityField.updateInitialValue(repeatsInitial);
|
quantityField.updateInitialValue(repeatsInitial);
|
||||||
|
|
||||||
String serieInitial = exercisePlanRepository.actualPlanDetail != null &&
|
String serieInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||||
exercisePlanRepository.actualPlanDetail.serie != null ?
|
exercisePlanRepository.getActualPlanDetail().serie != null ?
|
||||||
exercisePlanRepository.actualPlanDetail.serie.toString() : "3";
|
exercisePlanRepository.getActualPlanDetail().serie.toString() : "3";
|
||||||
serieField.updateInitialValue(serieInitial);
|
serieField.updateInitialValue(serieInitial);
|
||||||
|
|
||||||
String weightInitial = exercisePlanRepository.actualPlanDetail != null &&
|
String weightInitial = exercisePlanRepository.getActualPlanDetail() != null &&
|
||||||
exercisePlanRepository.actualPlanDetail.weightEquation != null ?
|
exercisePlanRepository.getActualPlanDetail().weightEquation != null ?
|
||||||
exercisePlanRepository.actualPlanDetail.weightEquation : "30";
|
exercisePlanRepository.getActualPlanDetail().weightEquation : "30";
|
||||||
weightField.updateInitialValue(weightInitial);
|
weightField.updateInitialValue(weightInitial);
|
||||||
|
|
||||||
quantityField.onValueChanges(onData: (previous, current) async* {
|
quantityField.onValueChanges(onData: (previous, current) async* {
|
||||||
exercisePlanRepository.actualPlanDetail.repeats = current.valueToInt;
|
exercisePlanRepository.getActualPlanDetail().repeats = current.valueToInt;
|
||||||
});
|
});
|
||||||
serieField.onValueChanges(onData: (previous, current) async* {
|
serieField.onValueChanges(onData: (previous, current) async* {
|
||||||
exercisePlanRepository.actualPlanDetail.serie = current.valueToInt;
|
exercisePlanRepository.getActualPlanDetail().serie = current.valueToInt;
|
||||||
});
|
});
|
||||||
weightField.onValueChanges(onData: (previous, current) async* {
|
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);
|
emitLoading(progress: 30);
|
||||||
// Emit either Loaded or Error
|
// Emit either Loaded or Error
|
||||||
|
|
||||||
exercisePlanRepository.actualPlanDetail.repeats = quantityField.valueToInt;
|
exercisePlanRepository.getActualPlanDetail().repeats = quantityField.valueToInt;
|
||||||
exercisePlanRepository.actualPlanDetail.serie = serieField.valueToInt;
|
exercisePlanRepository.getActualPlanDetail().serie = serieField.valueToInt;
|
||||||
exercisePlanRepository.actualPlanDetail.weightEquation = weightField.value;
|
exercisePlanRepository.getActualPlanDetail().weightEquation = weightField.value;
|
||||||
|
if ( exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null ) {
|
||||||
exercisePlanRepository.addToPlan();
|
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.add;
|
||||||
planBloc.add(ExercisePlanUpdate());
|
} else {
|
||||||
|
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.update;
|
||||||
|
}
|
||||||
|
exercisePlanRepository.addDetailToPlan();
|
||||||
|
planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()));
|
||||||
|
|
||||||
emitSuccess(canSubmitAgain: false);
|
emitSuccess(canSubmitAgain: false);
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
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:aitrainer_app/repository/workout_tree_repository.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
@ -17,7 +17,7 @@ class MenuLoading extends MenuState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MenuReady extends MenuState {
|
class MenuReady extends MenuState {
|
||||||
final WorkoutTree workoutTree;
|
final WorkoutMenuTree workoutTree;
|
||||||
|
|
||||||
const MenuReady({this.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_execute_by_plan_page.dart';
|
||||||
import 'package:aitrainer_app/view/exercise_log_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_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/exercise_type_description.dart';
|
||||||
import 'package:aitrainer_app/view/gdpr.dart';
|
import 'package:aitrainer_app/view/gdpr.dart';
|
||||||
import 'package:aitrainer_app/view/login.dart';
|
import 'package:aitrainer_app/view/login.dart';
|
||||||
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
||||||
import 'package:aitrainer_app/view/menu_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/mydevelopment_page.dart';
|
||||||
import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
|
import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
|
||||||
import 'package:aitrainer_app/view/registration.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:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:sentry/sentry.dart';
|
import 'package:sentry/sentry.dart';
|
||||||
import 'bloc/account/account_bloc.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_by_plan/exercise_by_plan_bloc.dart';
|
||||||
import 'bloc/exercise_plan/exercise_plan_bloc.dart';
|
import 'bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||||
import 'bloc/menu/menu_bloc.dart';
|
import 'bloc/menu/menu_bloc.dart';
|
||||||
@ -108,7 +110,7 @@ Future<Null> main() async {
|
|||||||
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
||||||
runApp(
|
runApp(
|
||||||
MultiBlocProvider(
|
MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider<SessionBloc>(
|
BlocProvider<SessionBloc>(
|
||||||
create: (BuildContext context) => SessionBloc(session: Session()),
|
create: (BuildContext context) => SessionBloc(session: Session()),
|
||||||
),
|
),
|
||||||
@ -125,7 +127,12 @@ Future<Null> main() async {
|
|||||||
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
||||||
),
|
),
|
||||||
BlocProvider<ExerciseByPlanBloc>(
|
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(),
|
'exercisePlanDetailAdd': (context) => ExercisePlanDetailAddPage(),
|
||||||
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
||||||
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
||||||
|
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
||||||
},
|
},
|
||||||
initialRoute: 'home',
|
initialRoute: 'home',
|
||||||
title: 'WorkoutTest',
|
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_plan_detail.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'package:aitrainer_app/model/exercise.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/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||||
@ -59,9 +59,10 @@ class Cache {
|
|||||||
|
|
||||||
List<Exercise> _exercises;
|
List<Exercise> _exercises;
|
||||||
ExercisePlan _myExercisePlan;
|
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;
|
double _percentExercises = -1;
|
||||||
|
|
||||||
Customer _trainee;
|
Customer _trainee;
|
||||||
@ -178,56 +179,63 @@ class Cache {
|
|||||||
this._exercisesTrainee = exercises;
|
this._exercisesTrainee = exercises;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setWorkoutTree( LinkedHashMap<String, WorkoutTree> tree) {
|
void setWorkoutMenuTree( LinkedHashMap<String, WorkoutMenuTree> tree) {
|
||||||
this._tree = tree;
|
this._tree = tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ExerciseType> getExerciseTypes() {
|
List<ExerciseType> getExerciseTypes() => this._exerciseTypes;
|
||||||
return 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() {
|
void deleteMyExercisePlanDetail(ExercisePlanDetail detail)
|
||||||
return this._exerciseTree;
|
=> 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';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class Exercise {
|
class Exercise {
|
||||||
@ -10,6 +11,8 @@ class Exercise {
|
|||||||
DateTime dateAdd;
|
DateTime dateAdd;
|
||||||
int exercisePlanDetailId;
|
int exercisePlanDetailId;
|
||||||
|
|
||||||
|
String datePart;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.dateAdd});
|
Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.dateAdd});
|
||||||
@ -21,6 +24,7 @@ class Exercise {
|
|||||||
this.unit = json['unit'];
|
this.unit = json['unit'];
|
||||||
this.unitQuantity = json['unitQuantity'];
|
this.unitQuantity = json['unitQuantity'];
|
||||||
this.dateAdd = DateTime.parse( json['dateAdd'] );
|
this.dateAdd = DateTime.parse( json['dateAdd'] );
|
||||||
|
this.datePart = DateFormat('yyyy-MM-dd').format(this.dateAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() =>
|
||||||
@ -33,4 +37,16 @@ class Exercise {
|
|||||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
|
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
|
||||||
"exercisePlanDetailId": exercisePlanDetailId,
|
"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';
|
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 {
|
class ExercisePlanDetail {
|
||||||
int exercisePlanDetailId;
|
int exercisePlanDetailId;
|
||||||
int exercisePlanId;
|
int exercisePlanId;
|
||||||
@ -11,6 +16,7 @@ class ExercisePlanDetail {
|
|||||||
String weightEquation;
|
String weightEquation;
|
||||||
|
|
||||||
ExerciseType exerciseType;
|
ExerciseType exerciseType;
|
||||||
|
String change; // 1: update -1:delete 0: new
|
||||||
|
|
||||||
ExercisePlanDetail(int exerciseTypeId) {
|
ExercisePlanDetail(int exerciseTypeId) {
|
||||||
this.exerciseTypeId = exerciseTypeId;
|
this.exerciseTypeId = exerciseTypeId;
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:ui';
|
|||||||
|
|
||||||
import 'exercise_type.dart';
|
import 'exercise_type.dart';
|
||||||
|
|
||||||
class WorkoutTree {
|
class WorkoutMenuTree {
|
||||||
int id;
|
int id;
|
||||||
int parent;
|
int parent;
|
||||||
String name;
|
String name;
|
||||||
@ -20,7 +20,7 @@ class WorkoutTree {
|
|||||||
String exerciseDetail;
|
String exerciseDetail;
|
||||||
String nameEnglish;
|
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);
|
this.exerciseTypeId, this.exerciseType, this.base, this.is1RM, this.nameEnglish);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
@ -8,31 +8,34 @@ import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
|||||||
|
|
||||||
class ExercisePlanRepository {
|
class ExercisePlanRepository {
|
||||||
bool newPlan = true;
|
bool newPlan = true;
|
||||||
ExercisePlan _exercisePlan;
|
ExercisePlan exercisePlan;
|
||||||
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails =
|
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails =
|
||||||
LinkedHashMap<int, ExercisePlanDetail>();
|
LinkedHashMap<int, ExercisePlanDetail>();
|
||||||
LinkedHashMap<int, ExercisePlanDetail> _origExercisePlanDetails =
|
int customerId = 0;
|
||||||
LinkedHashMap<int, ExercisePlanDetail>();
|
|
||||||
int _customerId = 0;
|
|
||||||
ExercisePlanDetail actualPlanDetail;
|
ExercisePlanDetail actualPlanDetail;
|
||||||
|
|
||||||
void setCustomerId( int customerId ) {
|
void setCustomerId( int customerId ) {
|
||||||
this._customerId = customerId;
|
this.customerId = customerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCustomerId() {
|
int getCustomerId() => customerId;
|
||||||
return this._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;
|
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];
|
ExercisePlanDetail detail = exercisePlanDetails[exerciseType.exerciseTypeId];
|
||||||
if ( detail != null ) {
|
if ( detail != null ) {
|
||||||
actualPlanDetail = detail;
|
actualPlanDetail = detail;
|
||||||
@ -42,11 +45,14 @@ class ExercisePlanRepository {
|
|||||||
actualPlanDetail.exerciseType = exerciseType;
|
actualPlanDetail.exerciseType = exerciseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getPlanDetailId(int exerciseTypeId) {
|
ExercisePlanDetail getActualPlanDetail() => actualPlanDetail;
|
||||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
|
||||||
return detail.exercisePlanDetailId;
|
void setActualPlanDetail( ExercisePlanDetail detail ) {
|
||||||
|
this.actualPlanDetail = detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getPlanDetailId(int exerciseTypeId) => exercisePlanDetails[exerciseTypeId].exercisePlanDetailId;
|
||||||
|
|
||||||
String getPlanDetail(int exerciseTypeId) {
|
String getPlanDetail(int exerciseTypeId) {
|
||||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
||||||
String detailString = "";
|
String detailString = "";
|
||||||
@ -70,96 +76,121 @@ class ExercisePlanRepository {
|
|||||||
exercisePlanDetail.serie = serie;
|
exercisePlanDetail.serie = serie;
|
||||||
exercisePlanDetail.repeats = repeat;
|
exercisePlanDetail.repeats = repeat;
|
||||||
exercisePlanDetail.weightEquation = weight;
|
exercisePlanDetail.weightEquation = weight;
|
||||||
|
exercisePlanDetail.change = ExercisePlanDetailChange.update;
|
||||||
|
|
||||||
exercisePlanDetails[exerciseType.exerciseTypeId] = exercisePlanDetail;
|
exercisePlanDetails[exerciseType.exerciseTypeId] = exercisePlanDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeExerciseTypeFromPlan(ExerciseType exerciseType) {
|
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 {
|
Future<void> saveExercisePlan() async {
|
||||||
|
|
||||||
if ( _exercisePlan == null ) {
|
if ( exercisePlan == null ) {
|
||||||
if ( Cache().userLoggedIn == null ) {
|
if ( Cache().userLoggedIn == null ) {
|
||||||
throw Exception("please log in");
|
throw Exception("please log in");
|
||||||
}
|
}
|
||||||
|
|
||||||
String exercisePlanName;
|
String exercisePlanName;
|
||||||
if ( this._customerId == Cache().userLoggedIn.customerId) {
|
if ( this.customerId == Cache().userLoggedIn.customerId) {
|
||||||
exercisePlanName = Cache().userLoggedIn.name + " private";
|
exercisePlanName = Cache().userLoggedIn.name + " private";
|
||||||
} else {
|
} else {
|
||||||
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
|
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
|
||||||
}
|
}
|
||||||
|
|
||||||
_exercisePlan = ExercisePlan(exercisePlanName, this._customerId);
|
exercisePlan = ExercisePlan(exercisePlanName, this.customerId);
|
||||||
}
|
}
|
||||||
if ( newPlan ) {
|
if ( newPlan ) {
|
||||||
_exercisePlan.dateAdd = DateTime.now();
|
exercisePlan.dateAdd = DateTime.now();
|
||||||
_exercisePlan.private = true;
|
exercisePlan.private = true;
|
||||||
ExercisePlan savedExercisePlan =
|
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;
|
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId;
|
||||||
await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||||
});
|
savedExercisePlanDetails[savedDetail.exerciseTypeId] = savedDetail;
|
||||||
|
});
|
||||||
|
|
||||||
|
exercisePlan = savedExercisePlan;
|
||||||
|
exercisePlanDetails = savedExercisePlanDetails;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
await ExercisePlanApi().updateExercisePlan(_exercisePlan, _exercisePlan.exercisePlanId);
|
//await ExercisePlanApi().updateExercisePlan(exercisePlan, exercisePlan.exercisePlanId);
|
||||||
|
|
||||||
_origExercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||||
if (exercisePlanDetails[exercisePlanDetail.exercisePlanDetailId] == null) {
|
if ( exercisePlanDetail.change == ExercisePlanDetailChange.delete ) {
|
||||||
await ExercisePlanApi()
|
await ExercisePlanApi()
|
||||||
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
|
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
|
||||||
} else {
|
exercisePlanDetail.change = ExercisePlanDetailChange.deleted;
|
||||||
|
Cache().deletedMyExercisePlanDetail(exercisePlanDetail);
|
||||||
|
|
||||||
|
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.update ) {
|
||||||
await ExercisePlanApi()
|
await ExercisePlanApi()
|
||||||
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
|
.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 {
|
Future<ExercisePlan> getLastExercisePlan() async {
|
||||||
if ( _customerId == 0) {
|
if ( customerId == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
_exercisePlan = await ExercisePlanApi().getLastExercisePlan(_customerId);
|
ExercisePlan myExercisePlan = Cache().getMyExercisePlan();
|
||||||
newPlan = (_exercisePlan == null);
|
if ( myExercisePlan != null ) {
|
||||||
print("New plan: " + newPlan.toString());
|
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 {
|
Future<void> getExercisePlanDetails() async {
|
||||||
if (_exercisePlan == null) {
|
if (exercisePlan == null) {
|
||||||
ExercisePlan exercisePlan = await this.getLastExercisePlan();
|
ExercisePlan exercisePlan = await this.getLastExercisePlan();
|
||||||
if ( exercisePlan == null ) {
|
if ( exercisePlan == null ) {
|
||||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
|
||||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
|
||||||
|
|
||||||
List<ExercisePlanDetail> list =
|
List<ExercisePlanDetail> list = List();
|
||||||
await ExercisePlanApi().getExercisePlanDetail(_exercisePlan.exercisePlanId);
|
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) {
|
list.forEach((element) {
|
||||||
newPlan = false;
|
newPlan = false;
|
||||||
ExercisePlanDetail detail = element;
|
ExercisePlanDetail detail = element;
|
||||||
_origExercisePlanDetails[detail.exerciseTypeId] = detail;
|
|
||||||
exercisePlanDetails[detail.exerciseTypeId] = detail;
|
exercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||||
});
|
});
|
||||||
|
Cache().setMyExercisePlanDetails(exercisePlanDetails);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import 'package:aitrainer_app/model/cache.dart';
|
|||||||
import 'package:aitrainer_app/model/customer.dart';
|
import 'package:aitrainer_app/model/customer.dart';
|
||||||
import 'package:aitrainer_app/model/exercise.dart';
|
import 'package:aitrainer_app/model/exercise.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.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';
|
import 'package:aitrainer_app/service/exercise_service.dart';
|
||||||
|
|
||||||
class ExerciseRepository {
|
class ExerciseRepository {
|
||||||
@ -120,14 +120,14 @@ class ExerciseRepository {
|
|||||||
List<int> baseTreeItem = List();
|
List<int> baseTreeItem = List();
|
||||||
List<int> checkedBaseTreeItem = List();
|
List<int> checkedBaseTreeItem = List();
|
||||||
int count1RMExercises = 0;
|
int count1RMExercises = 0;
|
||||||
LinkedHashMap<String, WorkoutTree> tree = Cache().getWorkoutTree();
|
LinkedHashMap<String, WorkoutMenuTree> tree = Cache().getWorkoutMenuTree();
|
||||||
|
|
||||||
if ( tree == null ) {
|
if ( tree == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutTree treeItem = value;
|
WorkoutMenuTree treeItem = value;
|
||||||
if (treeItem.exerciseType != null &&
|
if (treeItem.exerciseType != null &&
|
||||||
treeItem.exerciseType.base == true &&
|
treeItem.exerciseType.base == true &&
|
||||||
!baseTreeItem.contains(treeItem.parent)) {
|
!baseTreeItem.contains(treeItem.parent)) {
|
||||||
@ -148,7 +148,7 @@ class ExerciseRepository {
|
|||||||
if ( !checkedExerciseTypeId.contains(exercise.exerciseTypeId )) {
|
if ( !checkedExerciseTypeId.contains(exercise.exerciseTypeId )) {
|
||||||
checkedExerciseTypeId.add(exercise.exerciseTypeId);
|
checkedExerciseTypeId.add(exercise.exerciseTypeId);
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutTree treeItem = value;
|
WorkoutMenuTree treeItem = value;
|
||||||
if (treeItem.exerciseType != null
|
if (treeItem.exerciseType != null
|
||||||
&& treeItem.exerciseType.base == true
|
&& treeItem.exerciseType.base == true
|
||||||
&& exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId
|
&& 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/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.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/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||||
@ -29,8 +29,8 @@ class Antagonist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WorkoutTreeRepository {
|
class WorkoutTreeRepository {
|
||||||
final LinkedHashMap tree = LinkedHashMap<String, WorkoutTree>();
|
final LinkedHashMap tree = LinkedHashMap<String, WorkoutMenuTree>();
|
||||||
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||||
bool isEnglish;
|
bool isEnglish;
|
||||||
|
|
||||||
final Map<String, int> _antagonist = {
|
final Map<String, int> _antagonist = {
|
||||||
@ -61,7 +61,7 @@ class WorkoutTreeRepository {
|
|||||||
if ( is1RM == false && treeItem.parentId != 0) {
|
if ( is1RM == false && treeItem.parentId != 0) {
|
||||||
is1RM = isParent1RM(treeItem.parentId);
|
is1RM = isParent1RM(treeItem.parentId);
|
||||||
}
|
}
|
||||||
this.tree[treeItem.name] = WorkoutTree(
|
this.tree[treeItem.name] = WorkoutMenuTree(
|
||||||
treeItem.treeId,
|
treeItem.treeId,
|
||||||
treeItem.parentId,
|
treeItem.parentId,
|
||||||
treeName,
|
treeName,
|
||||||
@ -87,7 +87,7 @@ class WorkoutTreeRepository {
|
|||||||
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
||||||
bool is1RM = this.isParent1RM(exerciseType.treeId);
|
bool is1RM = this.isParent1RM(exerciseType.treeId);
|
||||||
exerciseType.is1RM = is1RM;
|
exerciseType.is1RM = is1RM;
|
||||||
this.tree[exerciseType.name] = WorkoutTree(
|
this.tree[exerciseType.name] = WorkoutMenuTree(
|
||||||
exerciseType.exerciseTypeId,
|
exerciseType.exerciseTypeId,
|
||||||
exerciseType.treeId,
|
exerciseType.treeId,
|
||||||
exerciseTypeName,
|
exerciseTypeName,
|
||||||
@ -103,7 +103,7 @@ class WorkoutTreeRepository {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Cache().setWorkoutTree(tree);
|
Cache().setWorkoutMenuTree(tree);
|
||||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
exerciseRepository.getBaseExerciseFinishedPercent();
|
exerciseRepository.getBaseExerciseFinishedPercent();
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ class WorkoutTreeRepository {
|
|||||||
bool isTreeItem1RM = false;
|
bool isTreeItem1RM = false;
|
||||||
|
|
||||||
this.tree.forEach((key, value) {
|
this.tree.forEach((key, value) {
|
||||||
WorkoutTree treeItem = value as WorkoutTree;
|
WorkoutMenuTree treeItem = value as WorkoutMenuTree;
|
||||||
if ( treeItem.id == treeId ) {
|
if ( treeItem.id == treeId ) {
|
||||||
isTreeItem1RM = treeItem.is1RM;
|
isTreeItem1RM = treeItem.is1RM;
|
||||||
//print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
|
//print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
|
||||||
@ -124,9 +124,9 @@ class WorkoutTreeRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LinkedHashMap getBranch(int parent) {
|
LinkedHashMap getBranch(int parent) {
|
||||||
LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
|
LinkedHashMap branch = LinkedHashMap<String, WorkoutMenuTree>();
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutTree workoutTree = value as WorkoutTree;
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
if ( parent == workoutTree.parent) {
|
if ( parent == workoutTree.parent) {
|
||||||
branch[key] = value;
|
branch[key] = value;
|
||||||
}
|
}
|
||||||
@ -134,10 +134,10 @@ class WorkoutTreeRepository {
|
|||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WorkoutTree> getBranchList(int parent) {
|
List<WorkoutMenuTree> getBranchList(int parent) {
|
||||||
List branch = List<WorkoutTree>();
|
List branch = List<WorkoutMenuTree>();
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutTree workoutTree = value as WorkoutTree;
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
if ( parent == workoutTree.parent) {
|
if ( parent == workoutTree.parent) {
|
||||||
branch.add(workoutTree);
|
branch.add(workoutTree);
|
||||||
}
|
}
|
||||||
@ -146,9 +146,9 @@ class WorkoutTreeRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sortByMuscleType() {
|
void sortByMuscleType() {
|
||||||
sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutTree workoutTree = value as WorkoutTree;
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
//print("treeitem: " + workoutTree.toJson().toString());
|
//print("treeitem: " + workoutTree.toJson().toString());
|
||||||
/*if ( workoutTree.exerciseType != null) {
|
/*if ( workoutTree.exerciseType != null) {
|
||||||
print("treeItem exerciseTye " + workoutTree.exerciseType.toJson().toString());
|
print("treeItem exerciseTye " + workoutTree.exerciseType.toJson().toString());
|
||||||
|
@ -21,12 +21,13 @@ class APIClient with Common {
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization' : "Bearer " + authToken }
|
'Authorization' : "Bearer " + authToken }
|
||||||
);
|
);
|
||||||
|
print(" ------------get response code: " + response.statusCode.toString());
|
||||||
if(response.statusCode == 200) {
|
if(response.statusCode == 200) {
|
||||||
return utf8.decode(response.bodyBytes);
|
return utf8.decode(response.bodyBytes);
|
||||||
} else if(response.statusCode == 404 ) {
|
} else if(response.statusCode == 404 ) {
|
||||||
throw NotFoundException(message: "Not Found");
|
throw NotFoundException(message: "Not Found");
|
||||||
} else {
|
} 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,
|
body: body,
|
||||||
);
|
);
|
||||||
String decodedResponse = utf8convert(response.body);
|
print(" ------------post response code: " + response.statusCode.toString());
|
||||||
print(" ------------ response: " + decodedResponse);
|
final String decodedResponse = utf8convert(response.body);
|
||||||
|
print(" ------------ response: $decodedResponse");
|
||||||
return decodedResponse;
|
return decodedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ class APIClient with Common {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final body = '{"username":"$email", "password":"$password"}';
|
final body = '{"username":"$email", "password":"$password"}';
|
||||||
|
print("authentication with $email");
|
||||||
final response = await http.post(
|
final response = await http.post(
|
||||||
uri,
|
uri,
|
||||||
headers: {
|
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.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||||
import 'package:aitrainer_app/util/not_found_exception.dart';
|
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||||
@ -17,7 +16,7 @@ class ExercisePlanApi {
|
|||||||
"exercise_plan",
|
"exercise_plan",
|
||||||
body);
|
body);
|
||||||
savedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
savedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||||
Cache().setTraineeExercisePlan(savedExercisePlan);
|
|
||||||
} on Exception catch(e) {
|
} on Exception catch(e) {
|
||||||
throw new Exception(e.toString());
|
throw new Exception(e.toString());
|
||||||
}
|
}
|
||||||
@ -28,14 +27,14 @@ class ExercisePlanApi {
|
|||||||
ExercisePlan exercisePlan,
|
ExercisePlan exercisePlan,
|
||||||
int exercisePlanId) async {
|
int exercisePlanId) async {
|
||||||
String body = JsonEncoder().convert(exercisePlan.toJson());
|
String body = JsonEncoder().convert(exercisePlan.toJson());
|
||||||
print(" ===== saving exercisePlan $exercisePlan");
|
print(" ===== update exercisePlan $exercisePlan");
|
||||||
ExercisePlan updatedExercisePlan;
|
ExercisePlan updatedExercisePlan;
|
||||||
try {
|
try {
|
||||||
final String responseBody = await _client.post(
|
final String responseBody = await _client.post(
|
||||||
"exercise_plan/" + exercisePlanId.toString(),
|
"exercise_plan/" + exercisePlanId.toString(),
|
||||||
body);
|
body);
|
||||||
updatedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
updatedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||||
Cache().setTraineeExercisePlan(updatedExercisePlan);
|
|
||||||
} on Exception catch(e) {
|
} on Exception catch(e) {
|
||||||
throw new Exception(e.toString());
|
throw new Exception(e.toString());
|
||||||
}
|
}
|
||||||
@ -44,7 +43,7 @@ class ExercisePlanApi {
|
|||||||
|
|
||||||
Future<ExercisePlanDetail> saveExercisePlanDetail(ExercisePlanDetail exercisePlanDetail) async {
|
Future<ExercisePlanDetail> saveExercisePlanDetail(ExercisePlanDetail exercisePlanDetail) async {
|
||||||
String body = JsonEncoder().convert(exercisePlanDetail.toJson());
|
String body = JsonEncoder().convert(exercisePlanDetail.toJson());
|
||||||
print(" ===== update exercisePlanDetail $exercisePlanDetail");
|
print(" ===== save exercisePlanDetail $exercisePlanDetail");
|
||||||
ExercisePlanDetail savedExercisePlanDetail;
|
ExercisePlanDetail savedExercisePlanDetail;
|
||||||
try {
|
try {
|
||||||
final String responseBody = await _client.post(
|
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);
|
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_add_by_plan_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_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/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/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
@ -25,7 +25,7 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
|||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan'];
|
final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan'];
|
||||||
final int customerId = arguments['customerId'];
|
final int customerId = arguments['customerId'];
|
||||||
final WorkoutTree workoutTree = arguments['workoutTree'];
|
final WorkoutMenuTree workoutTree = arguments['workoutTree'];
|
||||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
setContext(context);
|
setContext(context);
|
||||||
|
|
||||||
@ -136,38 +136,15 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Divider(color: Colors.transparent,),
|
Divider(color: Colors.transparent,),
|
||||||
Text("Execute the " + (i+1).toString() + ". set!",
|
Text(t("Execute the") + " " + (i+1).toString() + t(". set!"),
|
||||||
style: TextStyle(),),
|
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(
|
TextFieldBlocBuilder(
|
||||||
readOnly: exerciseBloc.step != i+1,
|
readOnly: exerciseBloc.step != i+1,
|
||||||
textFieldBloc: exerciseBloc.unitQuantity1Field,
|
textFieldBloc: exerciseBloc.unitQuantity1Field,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 18,
|
||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
@ -178,11 +155,35 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
|||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||||
labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
|
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(
|
RaisedButton(
|
||||||
|
|
||||||
padding: EdgeInsets.all(0),
|
padding: EdgeInsets.all(0),
|
||||||
|
@ -1,23 +1,25 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_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/localization/app_language.dart';
|
||||||
import 'package:aitrainer_app/model/cache.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/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:aitrainer_app/widgets/splash.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_treeview/tree_view.dart';
|
|
||||||
|
|
||||||
class ExerciseByPlanPage extends StatefulWidget {
|
class ExerciseByPlanPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_ExerciseByPlanPage createState() => _ExerciseByPlanPage();
|
_ExerciseByPlanPage createState() => _ExerciseByPlanPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> with Trans {
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
ExerciseByPlanBloc bloc;
|
ExerciseByPlanBloc bloc;
|
||||||
@ -38,21 +40,24 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
|||||||
final int customerId = arguments['customerId'];
|
final int customerId = arguments['customerId'];
|
||||||
bloc = BlocProvider.of<ExerciseByPlanBloc>(context);
|
bloc = BlocProvider.of<ExerciseByPlanBloc>(context);
|
||||||
bloc.customerId = customerId;
|
bloc.customerId = customerId;
|
||||||
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarCommonNav(),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
image: customerId == Cache().userLoggedIn.customerId
|
||||||
AssetImage('asset/image/WT_menu_dark.png'),
|
? AssetImage('asset/image/WT_light_background.png')
|
||||||
fit: BoxFit.cover,
|
: AssetImage('asset/image/WT_menu_dark.png'),
|
||||||
alignment: Alignment.center,
|
fit: BoxFit.cover,
|
||||||
),
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(listener: (context, state) {
|
),
|
||||||
|
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(
|
||||||
|
listener: (context, state) {
|
||||||
if (state is ExerciseByPlanError) {
|
if (state is ExerciseByPlanError) {
|
||||||
Scaffold.of(context).showSnackBar(SnackBar(
|
Scaffold.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(
|
content: Text(
|
||||||
@ -64,124 +69,147 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
|||||||
LoadingDialog();
|
LoadingDialog();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// ignore: missing_return
|
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) {
|
if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) {
|
||||||
return Container();
|
return Container();
|
||||||
} else if (state is ExerciseByPlanReady) {
|
} else if (state is ExerciseByPlanReady) {
|
||||||
return exerciseWidget(bloc);
|
return exerciseWidget(bloc);
|
||||||
} else if (state is ExerciseByPlanError) {
|
} else {
|
||||||
return exerciseWidget(bloc);
|
return exerciseWidget(bloc);
|
||||||
}
|
}
|
||||||
})));
|
})),
|
||||||
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget exerciseWidget(ExerciseByPlanBloc bloc) {
|
Widget exerciseWidget(ExerciseByPlanBloc bloc) {
|
||||||
final LinkedHashMap args = LinkedHashMap();
|
return TreeView(
|
||||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
startExpanded: false,
|
||||||
|
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,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Node> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
List<Widget> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||||
List<Node> nodes = List<Node>();
|
List<Widget> exerciseTypes = List();
|
||||||
Node actualNode;
|
|
||||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
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) {
|
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||||
List<WorkoutTree> listWorkoutItem = list;
|
exerciseTypes.add(
|
||||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
Container(
|
||||||
NodeIcon icon;
|
margin: const EdgeInsets.only(left: 4.0),
|
||||||
listWorkoutItem.forEach((element) {
|
child: TreeViewChild(
|
||||||
|
startExpanded: true,
|
||||||
WorkoutTree treeItem = element;
|
parent: ExerciseTypeWidget(exerciseTypeName: name), //_getExerciseWidget(exerciseTypeName: name),
|
||||||
if ( treeItem.selected ) {
|
children: _getChildList(list, bloc),
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise.dart';
|
import 'package:aitrainer_app/model/exercise.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.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/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/app_bar_common.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) {
|
Widget build(BuildContext context) {
|
||||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||||
final CustomerRepository customerRepository = arguments['customerRepository'];
|
|
||||||
final int customerId = arguments['customerId'];
|
final int customerId = arguments['customerId'];
|
||||||
setContext(context);
|
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/bloc/exercise_plan_custom_form.dart';
|
||||||
import 'package:aitrainer_app/localization/app_language.dart';
|
import 'package:aitrainer_app/localization/app_language.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.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/repository/exercise_plan_repository.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||||
@ -34,8 +35,8 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
String exerciseName = "";
|
String exerciseName = "";
|
||||||
if (bloc != null) {
|
if (bloc != null) {
|
||||||
exerciseName = AppLanguage().appLocal == Locale("en")
|
exerciseName = AppLanguage().appLocal == Locale("en")
|
||||||
? bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name
|
? bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name
|
||||||
: bloc.exercisePlanRepository.actualPlanDetail.exerciseType.nameTranslation;
|
: bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.nameTranslation;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Form(
|
return Form(
|
||||||
@ -118,9 +119,10 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
color: Colors.red.shade300,
|
color: Colors.red.shade300,
|
||||||
focusColor: Colors.white,
|
focusColor: Colors.white,
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
print("Remove " + bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name),
|
print("Remove " + bloc.exercisePlanRepository.getActualPlanDetail().exerciseType.name),
|
||||||
|
bloc.exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.delete,
|
||||||
planBloc.add(ExercisePlanRemoveExercise(
|
planBloc.add(ExercisePlanRemoveExercise(
|
||||||
exercisePlanDetail: bloc.exercisePlanRepository.actualPlanDetail)),
|
exercisePlanDetail: bloc.exercisePlanRepository.getActualPlanDetail() )),
|
||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
},
|
},
|
||||||
child: Text(t(
|
child: Text(t(
|
@ -1,24 +1,26 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
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/cache.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/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/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:aitrainer_app/widgets/splash.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_treeview/tree_view.dart';
|
|
||||||
|
|
||||||
class ExercisePlanCustomPage extends StatefulWidget {
|
class ExercisePlanCustomPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
|
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
ExercisePlanBloc bloc;
|
ExercisePlanBloc bloc;
|
||||||
@ -36,10 +38,10 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
|
||||||
final int customerId = arguments['customerId'];
|
final int customerId = arguments['customerId'];
|
||||||
bloc = BlocProvider.of<ExercisePlanBloc>(context);
|
bloc = BlocProvider.of<ExercisePlanBloc>(context);
|
||||||
bloc.customerId = customerId;
|
bloc.customerId = customerId;
|
||||||
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
@ -54,135 +56,158 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(listener: (context, state) {
|
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(
|
||||||
if (state is ExercisePlanError) {
|
listener: (context, state) {
|
||||||
Scaffold.of(context).showSnackBar(SnackBar(
|
if (state is ExercisePlanError) {
|
||||||
content: Text(
|
Scaffold.of(context).showSnackBar(SnackBar(
|
||||||
state.message,
|
content: Text(
|
||||||
),
|
state.message,
|
||||||
backgroundColor: Colors.orange,
|
),
|
||||||
));
|
backgroundColor: Colors.orange,
|
||||||
} else if (state is ExercisePlanLoading) {
|
));
|
||||||
LoadingDialog();
|
} else if (state is ExercisePlanLoading) {
|
||||||
}
|
LoadingDialog();
|
||||||
},
|
}
|
||||||
|
},
|
||||||
// ignore: missing_return
|
// ignore: missing_return
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is ExercisePlanInitial) {
|
if (state is ExercisePlanReady) {
|
||||||
|
return exerciseWidget(bloc);
|
||||||
|
}
|
||||||
return Container();
|
return Container();
|
||||||
} else if (state is ExercisePlanReady) {
|
|
||||||
return exerciseWidget(bloc);
|
}
|
||||||
} else if (state is ExercisePlanError) {
|
)
|
||||||
return exerciseWidget(bloc);
|
),
|
||||||
} else if (state is ExercisePlanLoading) {
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||||
return Container();
|
);
|
||||||
}
|
|
||||||
})));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget exerciseWidget(ExercisePlanBloc bloc) {
|
Widget exerciseWidget(ExercisePlanBloc bloc) {
|
||||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
return TreeView(
|
||||||
|
startExpanded: false,
|
||||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
children: _getTreeChildren(bloc),
|
||||||
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,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Node> nodeExercisePlan(ExercisePlanBloc bloc) {
|
List<Widget> _getTreeChildren(ExercisePlanBloc bloc) {
|
||||||
List<Node> nodes = List<Node>();
|
List<Widget> exerciseTypes = List();
|
||||||
Node actualNode;
|
|
||||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
|
||||||
|
|
||||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
Card explanation = Card(
|
||||||
List<WorkoutTree> listWorkoutItem = list;
|
color: Colors.white60,
|
||||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
child: Container(
|
||||||
NodeIcon icon;
|
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
|
||||||
listWorkoutItem.forEach((element) {
|
child: Column(
|
||||||
WorkoutTree treeItem = element;
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
icon =
|
children: [
|
||||||
treeItem.selected == true ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") : null;
|
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>>();
|
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
exerciseTypes.add(Container(
|
||||||
|
margin: const EdgeInsets.only(left: 4.0),
|
||||||
if (planDetail.length > 0) {
|
child: TreeViewChild(
|
||||||
exerciseLabel += " (" + planDetail +")";
|
startExpanded: true,
|
||||||
}
|
parent: ExerciseTypeWidget(exerciseTypeName: name),
|
||||||
|
children: _getChildList(list, bloc),
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
class MyDevelopmentPage extends StatefulWidget {
|
class MyDevelopmentPage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@ -84,10 +85,10 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
fit: StackFit.passthrough,
|
fit: StackFit.passthrough,
|
||||||
overflow: Overflow.clip,
|
overflow: Overflow.clip,
|
||||||
children: [
|
children: [
|
||||||
Image.asset('asset/image/lock.png',
|
/*Image.asset('asset/image/lock.png',
|
||||||
height: 40,
|
height: 40,
|
||||||
width: 40,
|
width: 40,
|
||||||
),
|
),*/
|
||||||
FlatButton(
|
FlatButton(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
@ -95,6 +96,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
focusColor: Colors.blueAccent,
|
focusColor: Colors.blueAccent,
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
{
|
{
|
||||||
|
Navigator.of(context).pushNamed('mydevelopmentMusclePage',
|
||||||
|
arguments: args)
|
||||||
},
|
},
|
||||||
child: Text(t("Development Of Muscles"),
|
child: Text(t("Development Of Muscles"),
|
||||||
style: TextStyle(fontSize: 18),)
|
style: TextStyle(fontSize: 18),)
|
||||||
|
@ -151,7 +151,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
lineHeight: 14.0,
|
lineHeight: 14.0,
|
||||||
percent: percent,
|
percent: percent,
|
||||||
center: Text(
|
center: Text(
|
||||||
(percent * 100).toStringAsFixed(0) + "% finished",
|
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||||
style: new TextStyle(fontSize: 12.0),
|
style: new TextStyle(fontSize: 12.0),
|
||||||
),
|
),
|
||||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
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),
|
icon: Icon(Icons.arrow_back, color: Colors.white),
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
{
|
{
|
||||||
Navigator.of(context).pop()
|
Navigator.of(context).pushNamed('home')
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -119,7 +119,7 @@ class _AppBarCommonNav extends State<AppBarCommonNav> with SingleTickerProvider
|
|||||||
lineHeight: 14.0,
|
lineHeight: 14.0,
|
||||||
percent: percent,
|
percent: percent,
|
||||||
center: Text(
|
center: Text(
|
||||||
(percent * 100).toStringAsFixed(0) + "% finished",
|
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||||
style: new TextStyle(fontSize: 12.0),
|
style: new TextStyle(fontSize: 12.0),
|
||||||
),
|
),
|
||||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
||||||
|
@ -91,12 +91,12 @@ class _NawDrawerWidget extends State<BottomNavigator> {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
//Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pushNamed('myDevelopment');
|
Navigator.of(context).pushNamed('myDevelopment');
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
|
||||||
//Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Navigator.of(context).pushNamed('myExercisePlan');
|
Navigator.of(context).pushNamed('myExercisePlan');
|
||||||
|
|
||||||
break;
|
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 settingsBloc = BlocProvider.of<SettingsBloc>(context);
|
||||||
settingsBloc.context = context;
|
settingsBloc.context = context;
|
||||||
sessionBloc.add(SessionStart(settingsBloc: settingsBloc));
|
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/bloc/menu/menu_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:aitrainer_app/model/cache.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/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
@ -31,7 +31,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
menuBloc.menuTreeRepository
|
menuBloc.menuTreeRepository
|
||||||
.getBranch(menuBloc.parent)
|
.getBranch(menuBloc.parent)
|
||||||
.forEach((treeName, value) {
|
.forEach((treeName, value) {
|
||||||
WorkoutTree workoutTree = value as WorkoutTree;
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
_columnChildren.add(Container(
|
_columnChildren.add(Container(
|
||||||
padding: EdgeInsets.only(top: 16.0),
|
padding: EdgeInsets.only(top: 16.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
@ -83,7 +83,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void menuClick(
|
void menuClick(
|
||||||
WorkoutTree workoutTree, MenuBloc menuBloc, BuildContext context) {
|
WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {
|
||||||
print("Hi!, Menu clicked " + workoutTree.id.toString());
|
print("Hi!, Menu clicked " + workoutTree.id.toString());
|
||||||
if (workoutTree.child == false) {
|
if (workoutTree.child == false) {
|
||||||
menuBloc.add(MenuTreeDown(parent: workoutTree.id));
|
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;
|
bool base = workoutTree.base;
|
||||||
dynamic returnCode = (base == true)
|
dynamic returnCode = (base == true)
|
||||||
? RoundedRectangleBorder(
|
? RoundedRectangleBorder(
|
||||||
@ -117,7 +117,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic _getButtonImage(WorkoutTree workoutTree) {
|
dynamic _getButtonImage(WorkoutMenuTree workoutTree) {
|
||||||
dynamic image;
|
dynamic image;
|
||||||
try {
|
try {
|
||||||
image = Image.asset(
|
image = Image.asset(
|
||||||
|
65
pubspec.lock
65
pubspec.lock
@ -225,6 +225,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
ffi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: ffi
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -239,6 +246,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.11"
|
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:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -333,14 +347,14 @@ packages:
|
|||||||
name: freezed
|
name: freezed
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.6"
|
version: "0.12.1"
|
||||||
freezed_annotation:
|
freezed_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: freezed_annotation
|
name: freezed_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.0+1"
|
version: "0.12.0"
|
||||||
fuchsia_remote_debug_protocol:
|
fuchsia_remote_debug_protocol:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -401,7 +415,7 @@ packages:
|
|||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.14"
|
version: "2.1.18"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -429,7 +443,7 @@ packages:
|
|||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
version: "3.1.0"
|
||||||
json_rpc_2:
|
json_rpc_2:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -514,6 +528,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.0"
|
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:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -528,6 +556,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
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:
|
pedantic:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -541,7 +576,7 @@ packages:
|
|||||||
name: percent_indicator
|
name: percent_indicator
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.6"
|
version: "2.1.7+3"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -639,7 +674,7 @@ packages:
|
|||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.10"
|
version: "0.5.12"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -668,6 +703,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2+7"
|
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:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -707,7 +749,7 @@ packages:
|
|||||||
name: source_gen
|
name: source_gen
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.6"
|
version: "0.9.7+1"
|
||||||
source_map_stack_trace:
|
source_map_stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -876,6 +918,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3"
|
version: "0.7.3"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.7.3"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -889,7 +938,7 @@ packages:
|
|||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.0"
|
version: "4.5.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.1.0+21
|
version: 1.1.0+22
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
@ -34,13 +34,14 @@ dependencies:
|
|||||||
flutter_facebook_login: ^3.0.0
|
flutter_facebook_login: ^3.0.0
|
||||||
flutter_bloc: ^6.0.5
|
flutter_bloc: ^6.0.5
|
||||||
equatable: ^1.2.5
|
equatable: ^1.2.5
|
||||||
freezed: ^0.11.6
|
freezed: ^0.12.1
|
||||||
flutter_form_bloc: ^0.19.0
|
flutter_form_bloc: ^0.19.0
|
||||||
spider_chart: ^0.1.5
|
spider_chart: ^0.1.5
|
||||||
rainbow_color: ^0.1.1
|
rainbow_color: ^0.1.1
|
||||||
percent_indicator: ^2.1.6
|
percent_indicator: ^2.1.7+3
|
||||||
gradient_bottom_navigation_bar: ^1.0.0+4
|
gradient_bottom_navigation_bar: ^1.0.0+4
|
||||||
flutter_treeview: ^0.6.0+1
|
flutter_treeview: ^0.6.0+1
|
||||||
|
fl_chart: ^0.11.1
|
||||||
|
|
||||||
mockito: ^4.1.1
|
mockito: ^4.1.1
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ dev_dependencies:
|
|||||||
|
|
||||||
http: 0.12.1
|
http: 0.12.1
|
||||||
intl: 0.16.1
|
intl: 0.16.1
|
||||||
shared_preferences: ^0.5.10
|
shared_preferences: ^0.5.12
|
||||||
|
|
||||||
flutter_launcher_icons: ^0.8.0
|
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