wt1.1.2d ProgressInfo+
BIN
asset/image/Congrats_N1.jpg
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
asset/image/development_muscles.jpg
Normal file
After Width: | Height: | Size: 4.2 MiB |
BIN
asset/image/exercise_log.jpg
Normal file
After Width: | Height: | Size: 3.9 MiB |
BIN
asset/menu/Back_pullup.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/biceps.jpg
Normal file
After Width: | Height: | Size: 217 KiB |
BIN
asset/menu/cable triceps.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
asset/menu/calf.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
asset/menu/legpress.jpg
Normal file
After Width: | Height: | Size: 162 KiB |
BIN
asset/menu/shoulder press.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/squat.jpg
Normal file
After Width: | Height: | Size: 331 KiB |
BIN
asset/menu/tricdip.jpg
Normal file
After Width: | Height: | Size: 177 KiB |
26
i18n/en.json
@ -170,5 +170,29 @@
|
|||||||
|
|
||||||
"Custom Exercise Plan": "Custom Exercise Plan",
|
"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.",
|
"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.",
|
||||||
"In this list you will find all your executed exercises grouped by the date.": "In this list you will find all your executed exercises grouped by the date."
|
"In this list you will find all your executed exercises grouped by the date.": "In this list you will find all your executed exercises grouped by the date.",
|
||||||
|
|
||||||
|
"Persistence!": "Persistence!",
|
||||||
|
"Greetings!": "Greetings!",
|
||||||
|
"The purpose is to measure you physical condition": "The purpose is to measure you physical condition.",
|
||||||
|
"The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.": "The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.",
|
||||||
|
"Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.": "Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.",
|
||||||
|
"Please continue your tests with a": "Please continue your tests with a",
|
||||||
|
"I suggest begin your tests with a": "I suggest begin your tests with a 'chest' exercise",
|
||||||
|
"Nice! This is a good start": "Nice! This is a good start",
|
||||||
|
"Go on!":"Go on!",
|
||||||
|
"You are on track": "You are on track",
|
||||||
|
"Not so much left": "Not so much left",
|
||||||
|
"Almost!": "Almost done!",
|
||||||
|
"You have only 1-2 exercise left to finish!": "You have only 1-2 exercise left to finish!",
|
||||||
|
"exercise!": "exercise!",
|
||||||
|
"Chest": "Chest",
|
||||||
|
"Back": "Back",
|
||||||
|
"Thigh": "Thigh",
|
||||||
|
"Calf": "Calf",
|
||||||
|
|
||||||
|
"Bring me there": "Bring me there",
|
||||||
|
|
||||||
|
"My Body Development": "My Body Development",
|
||||||
|
"You see here your whole body development by muscle groups.": "You see here your whole body development by muscle groups."
|
||||||
}
|
}
|
26
i18n/hu.json
@ -169,5 +169,29 @@
|
|||||||
"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.",
|
"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",
|
"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.",
|
"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.",
|
||||||
"In this list you will find all your executed exercises grouped by the date.": "Ebben a listában találod az eddig végrehajtott gyakorlataid dátum szerint csoportosítva."
|
"In this list you will find all your executed exercises grouped by the date.": "Ebben a listában találod az eddig végrehajtott gyakorlataid dátum szerint csoportosítva.",
|
||||||
|
|
||||||
|
"Persistence!": "Kitartás!",
|
||||||
|
"Greetings!": "Üdvözöllek!",
|
||||||
|
"The purpose is to measure you physical condition": "A cél a jelenlegi fizikai kondíciód felmérése.",
|
||||||
|
"The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.": "A gyakorlatok javasolt végrehajtási sorrendje: mell - bicepsz - tricepsz - hát - váll - has - comb - vádli.",
|
||||||
|
"Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.": "Menj a menüben az Erő - Max Erő - Mell menüpontba, és válaszd ki a kedvenc gyakorlatod.",
|
||||||
|
"Please continue your tests with a": "Kérlek folytasd a gyakorlatokat egy",
|
||||||
|
"I suggest begin your tests with a": "Azt javaslom, kezdd a teszteket egy 'mell' gyakorlattal",
|
||||||
|
"Nice! This is a good start": "Nagyon jó! Ez egy kitűnő start a teszthez",
|
||||||
|
"Go on!":"Gyerünk tovább!",
|
||||||
|
"You are on track": "Jó úton haladsz",
|
||||||
|
"Not so much left": "Már nincs sok hátra",
|
||||||
|
"Almost!": "Majdnem a végén vagy!",
|
||||||
|
"You have only 1-2 exercise left to finish!": "Már csak 1-2 gyakorlat van a végéig!",
|
||||||
|
"exercise!": "gyakorlattal!",
|
||||||
|
"Chest": "mell",
|
||||||
|
"Back": "hát",
|
||||||
|
"Thigh": "comb",
|
||||||
|
"Calf": "vádli",
|
||||||
|
|
||||||
|
"Bring me there": "Vigyél oda",
|
||||||
|
|
||||||
|
"My Body Development": "Testem fejlődése",
|
||||||
|
"You see here your whole body development by muscle groups.": "Itt láthatod a tested fejlődését izomcsoportonként"
|
||||||
}
|
}
|
43
lib/bloc/body_development/body_development_bloc.dart
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
|
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
|
part 'body_development_event.dart';
|
||||||
|
|
||||||
|
part 'body_development_state.dart';
|
||||||
|
|
||||||
|
class BodyDevelopmentBloc extends Bloc<BodyDevelopmentEvent, BodyDevelopmentState> {
|
||||||
|
final WorkoutTreeRepository workoutTreeRepository;
|
||||||
|
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
|
|
||||||
|
List<int> radarTicks = List();
|
||||||
|
List<String> radarFeatures = List();
|
||||||
|
List<List<int>> radarData = List();
|
||||||
|
|
||||||
|
@override
|
||||||
|
BodyDevelopmentBloc({this.workoutTreeRepository}): super(BodyDevelopmentInitial());
|
||||||
|
|
||||||
|
Future<void> getData() async{
|
||||||
|
radarTicks = [20, 40, 60, 80, 100];
|
||||||
|
radarFeatures = ["Mell", "Bicepsz", "Tricepsz", "Hát", "Váll"];
|
||||||
|
radarData = [
|
||||||
|
[80, 95, 45, 67, 83]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Stream<BodyDevelopmentState> mapEventToState(BodyDevelopmentEvent event) async* {
|
||||||
|
try {
|
||||||
|
if (event is BodyDevelopmentLoad) {
|
||||||
|
yield BodyDevelopmentLoading();
|
||||||
|
await getData();
|
||||||
|
yield BodyDevelopmentReady();
|
||||||
|
}
|
||||||
|
} on Exception catch (e) {
|
||||||
|
yield BodyDevelopmentError(message: e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
lib/bloc/body_development/body_development_event.dart
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
part of 'body_development_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class BodyDevelopmentEvent extends Equatable{
|
||||||
|
const BodyDevelopmentEvent();
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDevelopmentLoad extends BodyDevelopmentEvent {
|
||||||
|
const BodyDevelopmentLoad();
|
||||||
|
}
|
30
lib/bloc/body_development/body_development_state.dart
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
part of 'body_development_bloc.dart';
|
||||||
|
|
||||||
|
@immutable
|
||||||
|
abstract class BodyDevelopmentState extends Equatable {
|
||||||
|
const BodyDevelopmentState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDevelopmentInitial extends BodyDevelopmentState {
|
||||||
|
const BodyDevelopmentInitial();
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDevelopmentLoading extends BodyDevelopmentState {
|
||||||
|
const BodyDevelopmentLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDevelopmentReady extends BodyDevelopmentState {
|
||||||
|
const BodyDevelopmentReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyDevelopmentError extends BodyDevelopmentState {
|
||||||
|
final String message;
|
||||||
|
const BodyDevelopmentError({this.message});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [message];
|
||||||
|
}
|
||||||
|
|
@ -95,6 +95,7 @@ class CustomerChangeFormBloc extends FormBloc<String, String> {
|
|||||||
birthYearField.close();
|
birthYearField.close();
|
||||||
weightField.close();
|
weightField.close();
|
||||||
genderField.close();
|
genderField.close();
|
||||||
|
goalField.close();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ 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:aitrainer_app/util/calculate.dart';
|
import 'package:aitrainer_app/util/calculate.dart';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
|
import 'package:aitrainer_app/util/group_data.dart';
|
||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
@ -20,19 +21,240 @@ part 'development_by_muscle_event.dart';
|
|||||||
|
|
||||||
part 'development_by_muscle_state.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 {
|
class DiagramType {
|
||||||
static String sumMass = "sumMass";
|
static String sumMass = "sumMass";
|
||||||
static String oneRepMax = "oneRepMax";
|
static String oneRepMax = "oneRepMax";
|
||||||
static String percent = "percent";
|
static String percent = "percent";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=========== GROUPDATE CLASS
|
||||||
|
*/
|
||||||
|
|
||||||
|
class GroupDate extends GroupData with Calculate, Common {
|
||||||
|
final List<dynamic> inputList;
|
||||||
|
final List<dynamic> outputList;
|
||||||
|
|
||||||
|
String _origDatePart;
|
||||||
|
int _origExerciseTypeId;
|
||||||
|
Exercise _origExercise;
|
||||||
|
|
||||||
|
double _sumQuantity;
|
||||||
|
double _maxQuantity;
|
||||||
|
int _countExercises;
|
||||||
|
|
||||||
|
String diagramType;
|
||||||
|
String dateRate;
|
||||||
|
|
||||||
|
GroupDate({this.inputList, this.outputList});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addTempData(Exercise exercise) {
|
||||||
|
double newQuantity = getQuantityByDate(exercise);
|
||||||
|
_sumQuantity += newQuantity;
|
||||||
|
if (_maxQuantity < newQuantity) {
|
||||||
|
_maxQuantity = newQuantity;
|
||||||
|
}
|
||||||
|
_countExercises++;
|
||||||
|
_origDatePart = getDatePart(exercise.dateAdd, dateRate);
|
||||||
|
_origExerciseTypeId = exercise.exerciseTypeId;
|
||||||
|
_origExercise = exercise;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool checkNewType(Exercise exercise) {
|
||||||
|
String exerciseDatePart = getDatePart(exercise.dateAdd, dateRate);
|
||||||
|
return _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void iteration() {
|
||||||
|
this.resetTemp();
|
||||||
|
Exercise tempExercise;
|
||||||
|
inputList.forEach((element) {
|
||||||
|
tempExercise = element;
|
||||||
|
if ( this.checkNewType(element)) {
|
||||||
|
if ( _origDatePart == null ) {
|
||||||
|
this.addTempData(element);
|
||||||
|
} else {
|
||||||
|
this.temp2Output(_origExercise);
|
||||||
|
this.resetTemp();
|
||||||
|
this.addTempData(element);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.addTempData(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if ( tempExercise != null) {
|
||||||
|
this.temp2Output(tempExercise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void temp2Output(Exercise exercise) {
|
||||||
|
Exercise newExercise = exercise.copy();
|
||||||
|
newExercise.datePart = _origDatePart;
|
||||||
|
if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
|
||||||
|
newExercise.calculated = _maxQuantity;
|
||||||
|
} else {
|
||||||
|
newExercise.calculated = _sumQuantity / _countExercises;
|
||||||
|
}
|
||||||
|
outputList.add(newExercise);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void resetTemp() {
|
||||||
|
_countExercises = 0;
|
||||||
|
_sumQuantity = 0;
|
||||||
|
_maxQuantity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=========== CHART DATA CLASS
|
||||||
|
*/
|
||||||
|
class GroupChart extends GroupData with Calculate {
|
||||||
|
|
||||||
|
final List<dynamic> inputList;
|
||||||
|
LinkedHashMap<int, ChartDataExtended> outputList = LinkedHashMap();
|
||||||
|
|
||||||
|
int _origExerciseTypeId;
|
||||||
|
double _minData = 999999999999;
|
||||||
|
double _maxData = 0;
|
||||||
|
List<BarChartGroupData> _chartData;
|
||||||
|
double _basePercent;
|
||||||
|
|
||||||
|
String diagramType = DiagramType.sumMass;
|
||||||
|
|
||||||
|
GroupChart({this.inputList, this.outputList});
|
||||||
|
|
||||||
|
double getBasePercent(Exercise exercise) {
|
||||||
|
if ( exercise.unitQuantity != null ) {
|
||||||
|
this._basePercent = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||||
|
} else {
|
||||||
|
this._basePercent = exercise.quantity;
|
||||||
|
}
|
||||||
|
return this._basePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getDiagramValue(Exercise exercise) {
|
||||||
|
double value = 0;
|
||||||
|
|
||||||
|
if ( diagramType == DiagramType.percent) {
|
||||||
|
if ( exercise.unitQuantity != null ) {
|
||||||
|
double oneRepMax = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
||||||
|
value = (oneRepMax / this._basePercent) * 100;
|
||||||
|
} else {
|
||||||
|
value = (exercise.quantity / this._basePercent ) * 100;
|
||||||
|
}
|
||||||
|
} else if ( diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) {
|
||||||
|
value = exercise.calculated;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addTempData(Exercise exercise) {
|
||||||
|
|
||||||
|
double diagramValue = this.getDiagramValue(exercise);
|
||||||
|
|
||||||
|
if (_maxData < diagramValue) {
|
||||||
|
_maxData = diagramValue;
|
||||||
|
}
|
||||||
|
if (_minData > diagramValue) {
|
||||||
|
_minData = diagramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BarChartGroupData data = BarChartGroupData(
|
||||||
|
x: exercise.dateAdd.millisecondsSinceEpoch,
|
||||||
|
barRods: [
|
||||||
|
BarChartRodData(y: diagramValue, width: 12, color: Colors.lightBlue)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
_chartData.add(data);
|
||||||
|
_origExerciseTypeId = exercise.exerciseTypeId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool checkNewType(Exercise exercise) {
|
||||||
|
return _origExerciseTypeId != exercise.exerciseTypeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void iteration() {
|
||||||
|
|
||||||
|
this.resetTemp();
|
||||||
|
Exercise tempExercise;
|
||||||
|
inputList.forEach((element) {
|
||||||
|
tempExercise = element;
|
||||||
|
|
||||||
|
if ( this.checkNewType(element)) {
|
||||||
|
if ( _origExerciseTypeId == null ) {
|
||||||
|
_basePercent = getBasePercent(element);
|
||||||
|
this.addTempData(element);
|
||||||
|
} else {
|
||||||
|
this.temp2Output(element);
|
||||||
|
this.resetTemp();
|
||||||
|
_basePercent = getBasePercent(element);
|
||||||
|
this.addTempData(element);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.addTempData(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if ( tempExercise != null) {
|
||||||
|
this.temp2Output(tempExercise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void temp2Output(Exercise exercise) {
|
||||||
|
double dInterval = ((_maxData + _minData) / 8).roundToDouble();
|
||||||
|
int gridInterval = (dInterval / 3).floor();
|
||||||
|
|
||||||
|
ChartDataExtended extended;
|
||||||
|
if ( outputList[_origExerciseTypeId] == null ) {
|
||||||
|
extended = ChartDataExtended(
|
||||||
|
data: _chartData, interval: dInterval, gridInterval: gridInterval);
|
||||||
|
outputList[_origExerciseTypeId] = extended;
|
||||||
|
} else {
|
||||||
|
extended = outputList[_origExerciseTypeId];
|
||||||
|
_chartData.forEach((element) {
|
||||||
|
extended.data.add(element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void resetTemp() {
|
||||||
|
_minData = 999999999999;
|
||||||
|
_maxData = 0;
|
||||||
|
_chartData = List();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
class ChartDataExtended {
|
class ChartDataExtended {
|
||||||
final List<BarChartGroupData> data;
|
final List<BarChartGroupData> data;
|
||||||
final double interval;
|
final double interval;
|
||||||
@ -40,16 +262,29 @@ class ChartDataExtended {
|
|||||||
|
|
||||||
const ChartDataExtended({this.data, this.interval, this.gridInterval});
|
const ChartDataExtended({this.data, this.interval, this.gridInterval});
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() {
|
||||||
{
|
List listBarChartData = List();
|
||||||
"data": data.toString(),
|
data.forEach((element) {
|
||||||
|
element.barRods.forEach((rods) {
|
||||||
|
var barChartData = {
|
||||||
|
'x': element.x,
|
||||||
|
'y': rods.y,
|
||||||
|
};
|
||||||
|
listBarChartData.add(barChartData);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
var chartData = {
|
||||||
|
"data": listBarChartData.toString(),
|
||||||
"interval": interval.toString(),
|
"interval": interval.toString(),
|
||||||
"gridInterval": gridInterval,
|
"gridInterval": gridInterval,
|
||||||
};
|
};
|
||||||
|
return chartData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate, Common {
|
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate {
|
||||||
final WorkoutTreeRepository workoutTreeRepository;
|
final WorkoutTreeRepository workoutTreeRepository;
|
||||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap();
|
LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap();
|
||||||
@ -81,57 +316,21 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
|
|||||||
|
|
||||||
void getChartData() {
|
void getChartData() {
|
||||||
List<Exercise> exercises = exerciseRepository.getExerciseList();
|
List<Exercise> exercises = exerciseRepository.getExerciseList();
|
||||||
exercises.sort( (a, b) => a.exerciseTypeId.compareTo(b.exerciseTypeId));
|
|
||||||
|
//print("-- Start calculate --- ");
|
||||||
exercises = this.groupByDate(exercises);
|
exercises = this.groupByDate(exercises);
|
||||||
|
|
||||||
int origExerciseTypeId = 0;
|
exercises = sort(exercises, true);
|
||||||
int x = 0;
|
/* exercises.forEach((exercise) {
|
||||||
chartData = List();
|
print ("Chart exercise " + exercise.toJsonDatePart().toString());
|
||||||
double maxData = 0;
|
});*/
|
||||||
double minData = 9999999999999;
|
|
||||||
exercises.forEach((exercise) {
|
listChartData = LinkedHashMap();
|
||||||
if ( exercise.unitQuantity != null ) {
|
GroupChart groupChart = GroupChart(inputList: exercises, outputList: listChartData);
|
||||||
if (origExerciseTypeId != exercise.exerciseTypeId && diagramType == DiagramType.percent) {
|
groupChart.diagramType = this.diagramType;
|
||||||
this.basePercent = getBasePercent(exercise);
|
groupChart.iteration();
|
||||||
}
|
listChartData = groupChart.outputList;
|
||||||
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) {
|
listChartData.forEach((key, value) {
|
||||||
print ("typeid " + key.toString() + " chardata " + value.toJson().toString());
|
print ("typeid " + key.toString() + " chardata " + value.toJson().toString());
|
||||||
@ -139,126 +338,38 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
|
|||||||
return;
|
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> groupByDate(List<Exercise> exercises) {
|
||||||
List<Exercise> groupedExercises = List();
|
List<Exercise> groupedExercises = List();
|
||||||
|
|
||||||
String origDatePart;
|
exercises = sort(exercises, false);
|
||||||
|
|
||||||
int countExercises = 0;
|
|
||||||
double sumQuantity = 0;
|
|
||||||
double maxQuantity = 0;
|
|
||||||
Exercise origExercise;
|
|
||||||
exercises.forEach((exercise) {
|
exercises.forEach((exercise) {
|
||||||
String exerciseDatePart = getDatePart(exercise.dateAdd);
|
print ("Date exercise " + exercise.toJsonDatePart().toString());
|
||||||
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) {
|
GroupDate groupDate = GroupDate(inputList: exercises, outputList: groupedExercises);
|
||||||
print("grouped " + element.toJson().toString());
|
groupDate.dateRate = this.dateRate;
|
||||||
});
|
groupDate.diagramType = this.diagramType;
|
||||||
|
groupDate.iteration();
|
||||||
|
groupedExercises = groupDate.outputList;
|
||||||
|
|
||||||
|
/* groupedExercises.forEach((element) {
|
||||||
|
print("Grouped " + element.toJsonDatePart().toString());
|
||||||
|
});*/
|
||||||
|
|
||||||
|
|
||||||
return groupedExercises;
|
return groupedExercises;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getQuantityByDate(Exercise exercise) {
|
List<Exercise> sort(List<Exercise> exercises, bool asc) {
|
||||||
double sum = 0;
|
exercises.sort( (a, b) {
|
||||||
if ( this.diagramType == DiagramType.sumMass ) {
|
var aDateId = a.exerciseTypeId.toString() + "_" + a.datePart.toString();
|
||||||
if ( exercise.unitQuantity != null ) {
|
var bDateId = b.exerciseTypeId.toString() + "_" + b.datePart.toString();
|
||||||
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) {
|
return asc ? aDateId.compareTo(bDateId) : bDateId.compareTo(aDateId);
|
||||||
if ( exercise.unitQuantity != null ) {
|
});
|
||||||
this.basePercent = calculate1RM(exercise.quantity, exercise.unitQuantity);
|
return exercises;
|
||||||
} 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) {
|
String getDateFormat(DateTime datetime) {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||||
|
|
||||||
class ExerciseControlFormBloc extends FormBloc<String, String> {
|
class ExerciseControlFormBloc extends FormBloc<String, String> {
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
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';
|
||||||
|
|
||||||
|
import 'menu/menu_bloc.dart';
|
||||||
|
|
||||||
class ExerciseFormBloc extends FormBloc<String, String> {
|
class ExerciseFormBloc extends FormBloc<String, String> {
|
||||||
final ExerciseRepository exerciseRepository;
|
final ExerciseRepository exerciseRepository;
|
||||||
|
final MenuBloc menuBloc;
|
||||||
|
|
||||||
final quantityField = TextFieldBloc(
|
final quantityField = TextFieldBloc(
|
||||||
validators: [
|
validators: [
|
||||||
@ -19,7 +22,7 @@ class ExerciseFormBloc extends FormBloc<String, String> {
|
|||||||
final unitQuantityField = TextFieldBloc();
|
final unitQuantityField = TextFieldBloc();
|
||||||
final unitQuantityUnitField = TextFieldBloc();
|
final unitQuantityUnitField = TextFieldBloc();
|
||||||
|
|
||||||
ExerciseFormBloc({this.exerciseRepository}) {
|
ExerciseFormBloc({this.exerciseRepository, this.menuBloc}) {
|
||||||
addFieldBlocs(fieldBlocs: [
|
addFieldBlocs(fieldBlocs: [
|
||||||
quantityField,
|
quantityField,
|
||||||
unitField,
|
unitField,
|
||||||
@ -46,6 +49,7 @@ class ExerciseFormBloc extends FormBloc<String, String> {
|
|||||||
emitLoading(progress: 30);
|
emitLoading(progress: 30);
|
||||||
// Emit either Loaded or Error
|
// Emit either Loaded or Error
|
||||||
await exerciseRepository.addExercise();
|
await exerciseRepository.addExercise();
|
||||||
|
menuBloc.add(MenuTreeDown(parent: 0));
|
||||||
emitSuccess(canSubmitAgain: false);
|
emitSuccess(canSubmitAgain: false);
|
||||||
|
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
|
@ -1,22 +1,72 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.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/repository/workout_tree_repository.dart';
|
||||||
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
|
||||||
part 'menu_event.dart';
|
part 'menu_event.dart';
|
||||||
part 'menu_state.dart';
|
part 'menu_state.dart';
|
||||||
|
|
||||||
class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans {
|
||||||
final WorkoutTreeRepository menuTreeRepository;
|
final WorkoutTreeRepository menuTreeRepository;
|
||||||
|
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
int parent;
|
int parent;
|
||||||
|
WorkoutMenuTree workoutItem;
|
||||||
|
|
||||||
|
String infoTitle = "";
|
||||||
|
String infoText = "";
|
||||||
|
String infoText2 = "";
|
||||||
|
String infoText3 = "";
|
||||||
|
String infoLink = "";
|
||||||
|
int missingParent = 0;
|
||||||
|
String missingTreeName = "";
|
||||||
|
|
||||||
|
BuildContext context;
|
||||||
|
|
||||||
MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) {
|
MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) {
|
||||||
parent = 0;
|
parent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMenuInfo() {
|
||||||
|
double percent = Cache().getPercentExercises();
|
||||||
|
if ( context == null ) return;
|
||||||
|
percent = percent * 100;
|
||||||
|
print("Percent " + percent.toString());
|
||||||
|
if ( percent == -1 || percent == 0) {
|
||||||
|
infoTitle = t("Greetings!");
|
||||||
|
infoText = t("The purpose is to measure you physical condition") + " " + t("The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.");
|
||||||
|
infoText2 = t("I suggest begin your tests with a");
|
||||||
|
infoText3 = t("Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.");
|
||||||
|
infoLink = t("Bring me there");
|
||||||
|
} else if ( percent > 0 && percent < 20) {
|
||||||
|
infoTitle = t("Nice! This is a good start");
|
||||||
|
} else if ( percent > 20 && percent < 40) {
|
||||||
|
infoTitle = t("Go on!") + " " + t("You are on track");
|
||||||
|
} else if ( percent > 60 && percent < 80) {
|
||||||
|
infoTitle = t("Persistence!") + " " + t("Not so much left");
|
||||||
|
} else if ( percent > 80 && percent < 100) {
|
||||||
|
infoTitle = t("Almost!") + " " + t("You have only 1-2 exercise left to finish!");
|
||||||
|
}
|
||||||
|
|
||||||
|
menuTreeRepository.sortByMuscleType();
|
||||||
|
missingTreeName = exerciseRepository.nextMissingBaseExercise(menuTreeRepository.sortedTree);
|
||||||
|
print("Missing " + missingTreeName);
|
||||||
|
if ( percent > 0) {
|
||||||
|
infoText = t("Please continue your tests with a") + " '" + missingTreeName + "' " + t("exercise!");
|
||||||
|
infoLink = t("Bring me there");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setContext(BuildContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<MenuState> mapEventToState(
|
Stream<MenuState> mapEventToState(
|
||||||
MenuEvent event,
|
MenuEvent event,
|
||||||
@ -25,6 +75,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||||||
if ( event is MenuCreate ) {
|
if ( event is MenuCreate ) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
await menuTreeRepository.createTree();
|
await menuTreeRepository.createTree();
|
||||||
|
setMenuInfo();
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuRecreateTree) {
|
} else if (event is MenuRecreateTree) {
|
||||||
// ie. at language changes
|
// ie. at language changes
|
||||||
@ -34,14 +85,28 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> {
|
|||||||
// get child menus or exercises
|
// get child menus or exercises
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
parent = event.parent;
|
parent = event.parent;
|
||||||
|
workoutItem = event.item;
|
||||||
|
//print("menuitem " + workoutItem.id.toString() + " parent "+workoutItem.parent.toString());
|
||||||
menuTreeRepository.getBranch(event.parent);
|
menuTreeRepository.getBranch(event.parent);
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuTreeUp) {
|
} else if (event is MenuTreeUp) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
// get parent menus or exercises
|
// get parent menus or exercises
|
||||||
parent = event.parent;
|
parent = event.parent;
|
||||||
menuTreeRepository.getBranch(parent);
|
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||||
|
if ( workoutItem != null) {
|
||||||
|
//print("UP menuitem " + workoutItem.id.toString() + " parent " + workoutItem.parent.toString());
|
||||||
|
menuTreeRepository.getBranch(workoutItem.parent);
|
||||||
|
}
|
||||||
|
yield MenuReady();
|
||||||
|
} else if (event is MenuTreeJump) {
|
||||||
|
yield MenuLoading();
|
||||||
|
parent = event.parent;
|
||||||
|
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||||
|
if ( workoutItem != null) {
|
||||||
|
//print("JUMP menuitem " + workoutItem.id.toString() + " parent " + workoutItem.parent.toString());
|
||||||
|
menuTreeRepository.getBranch(workoutItem.parent);
|
||||||
|
}
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuClickExercise) {
|
} else if (event is MenuClickExercise) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
|
@ -16,16 +16,26 @@ class MenuCreate extends MenuEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MenuTreeDown extends MenuEvent {
|
class MenuTreeDown extends MenuEvent {
|
||||||
|
final WorkoutMenuTree item;
|
||||||
final int parent;
|
final int parent;
|
||||||
const MenuTreeDown({this.parent});
|
const MenuTreeDown({this.parent, this.item});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [parent];
|
List<Object> get props => [parent, item];
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuTreeUp extends MenuEvent {
|
class MenuTreeUp extends MenuEvent {
|
||||||
final int parent;
|
final int parent;
|
||||||
const MenuTreeUp({this.parent});
|
final WorkoutMenuTree item;
|
||||||
|
const MenuTreeUp({this.parent, this.item});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [parent, item];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MenuTreeJump extends MenuEvent {
|
||||||
|
final int parent;
|
||||||
|
const MenuTreeJump({this.parent});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [parent];
|
List<Object> get props => [parent];
|
||||||
|
@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
|
|
||||||
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/cache.dart';
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
325
lib/library/radar_chart.dart
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
library flutter_radar_chart;
|
||||||
|
|
||||||
|
import 'dart:ui';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'dart:math' show pi, cos, sin;
|
||||||
|
|
||||||
|
const defaultGraphColors = [
|
||||||
|
Colors.green,
|
||||||
|
Colors.blue,
|
||||||
|
Colors.red,
|
||||||
|
Colors.orange,
|
||||||
|
];
|
||||||
|
|
||||||
|
class RadarChart extends StatefulWidget {
|
||||||
|
final List<int> ticks;
|
||||||
|
final List<String> features;
|
||||||
|
final List<List<int>> data;
|
||||||
|
final bool reverseAxis;
|
||||||
|
final TextStyle ticksTextStyle;
|
||||||
|
final TextStyle featuresTextStyle;
|
||||||
|
final Color outlineColor;
|
||||||
|
final Color axisColor;
|
||||||
|
final List<Color> graphColors;
|
||||||
|
final int sides;
|
||||||
|
|
||||||
|
const RadarChart({
|
||||||
|
Key key,
|
||||||
|
@required this.ticks,
|
||||||
|
@required this.features,
|
||||||
|
@required this.data,
|
||||||
|
this.reverseAxis = false,
|
||||||
|
this.ticksTextStyle = const TextStyle(color: Colors.grey, fontSize: 12),
|
||||||
|
this.featuresTextStyle = const TextStyle(color: Colors.black, fontSize: 16),
|
||||||
|
this.outlineColor = Colors.black,
|
||||||
|
this.axisColor = Colors.grey,
|
||||||
|
this.graphColors = defaultGraphColors,
|
||||||
|
this.sides = 0,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
factory RadarChart.light({
|
||||||
|
@required List<int> ticks,
|
||||||
|
@required List<String> features,
|
||||||
|
@required List<List<int>> data,
|
||||||
|
bool reverseAxis = false,
|
||||||
|
bool useSides = false,
|
||||||
|
}) {
|
||||||
|
return RadarChart(
|
||||||
|
ticks: ticks,
|
||||||
|
features: features,
|
||||||
|
data: data,
|
||||||
|
reverseAxis: reverseAxis,
|
||||||
|
sides: useSides ? features.length : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RadarChart.dark({
|
||||||
|
@required List<int> ticks,
|
||||||
|
@required List<String> features,
|
||||||
|
@required List<List<int>> data,
|
||||||
|
bool reverseAxis = false,
|
||||||
|
bool useSides = false,
|
||||||
|
}) {
|
||||||
|
return RadarChart(
|
||||||
|
ticks: ticks,
|
||||||
|
features: features,
|
||||||
|
data: data,
|
||||||
|
featuresTextStyle: const TextStyle(color: Colors.white, fontSize: 16),
|
||||||
|
outlineColor: Colors.white,
|
||||||
|
axisColor: Colors.grey,
|
||||||
|
reverseAxis: reverseAxis,
|
||||||
|
sides: useSides ? features.length : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_RadarChartState createState() => _RadarChartState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RadarChartState extends State<RadarChart>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
double fraction = 0;
|
||||||
|
Animation<double> animation;
|
||||||
|
AnimationController animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
animationController = AnimationController(
|
||||||
|
duration: Duration(milliseconds: 1000), vsync: this);
|
||||||
|
|
||||||
|
animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
|
||||||
|
curve: Curves.fastOutSlowIn,
|
||||||
|
parent: animationController,
|
||||||
|
))
|
||||||
|
..addListener(() {
|
||||||
|
setState(() {
|
||||||
|
fraction = animation.value;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
animationController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(RadarChart oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
|
||||||
|
animationController.reset();
|
||||||
|
animationController.forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return CustomPaint(
|
||||||
|
size: Size(double.infinity, double.infinity),
|
||||||
|
painter: RadarChartPainter(
|
||||||
|
widget.ticks,
|
||||||
|
widget.features,
|
||||||
|
widget.data,
|
||||||
|
widget.reverseAxis,
|
||||||
|
widget.ticksTextStyle,
|
||||||
|
widget.featuresTextStyle,
|
||||||
|
widget.outlineColor,
|
||||||
|
widget.axisColor,
|
||||||
|
widget.graphColors,
|
||||||
|
widget.sides,
|
||||||
|
this.fraction),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
animationController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RadarChartPainter extends CustomPainter {
|
||||||
|
final List<int> ticks;
|
||||||
|
final List<String> features;
|
||||||
|
final List<List<int>> data;
|
||||||
|
final bool reverseAxis;
|
||||||
|
final TextStyle ticksTextStyle;
|
||||||
|
final TextStyle featuresTextStyle;
|
||||||
|
final Color outlineColor;
|
||||||
|
final Color axisColor;
|
||||||
|
final List<Color> graphColors;
|
||||||
|
final int sides;
|
||||||
|
final double fraction;
|
||||||
|
|
||||||
|
RadarChartPainter(
|
||||||
|
this.ticks,
|
||||||
|
this.features,
|
||||||
|
this.data,
|
||||||
|
this.reverseAxis,
|
||||||
|
this.ticksTextStyle,
|
||||||
|
this.featuresTextStyle,
|
||||||
|
this.outlineColor,
|
||||||
|
this.axisColor,
|
||||||
|
this.graphColors,
|
||||||
|
this.sides,
|
||||||
|
this.fraction,
|
||||||
|
);
|
||||||
|
|
||||||
|
Path variablePath(Size size, double radius, int sides) {
|
||||||
|
var path = Path();
|
||||||
|
var angle = (math.pi * 2) / sides;
|
||||||
|
|
||||||
|
Offset center = Offset(size.width / 2, size.height / 2);
|
||||||
|
|
||||||
|
if (sides < 3) {
|
||||||
|
// Draw a circle
|
||||||
|
path.addOval(Rect.fromCircle(
|
||||||
|
center: Offset(size.width / 2, size.height / 2),
|
||||||
|
radius: radius,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
// Draw a polygon
|
||||||
|
Offset startPoint = Offset(radius * cos(-pi / 2), radius * sin(-pi / 2));
|
||||||
|
|
||||||
|
path.moveTo(startPoint.dx + center.dx, startPoint.dy + center.dy);
|
||||||
|
|
||||||
|
for (int i = 1; i <= sides; i++) {
|
||||||
|
double x = radius * cos(angle * i - pi / 2) + center.dx;
|
||||||
|
double y = radius * sin(angle * i - pi / 2) + center.dy;
|
||||||
|
path.lineTo(x, y);
|
||||||
|
}
|
||||||
|
path.close();
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final centerX = size.width / 2.0;
|
||||||
|
final centerY = size.height / 2.0;
|
||||||
|
final centerOffset = Offset(centerX, centerY);
|
||||||
|
final radius = math.min(centerX, centerY) * 0.8;
|
||||||
|
final scale = radius / ticks.last;
|
||||||
|
|
||||||
|
// Painting the chart outline
|
||||||
|
var outlinePaint = Paint()
|
||||||
|
..color = outlineColor
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 2.0
|
||||||
|
..isAntiAlias = true;
|
||||||
|
|
||||||
|
var ticksPaint = Paint()
|
||||||
|
..color = axisColor
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 1.0
|
||||||
|
..isAntiAlias = true;
|
||||||
|
|
||||||
|
canvas.drawPath(variablePath(size, radius, this.sides), outlinePaint);
|
||||||
|
// Painting the circles and labels for the given ticks (could be auto-generated)
|
||||||
|
// The last tick is ignored, since it overlaps with the feature label
|
||||||
|
var tickDistance = radius / (ticks.length);
|
||||||
|
var tickLabels = reverseAxis ? ticks.reversed.toList() : ticks;
|
||||||
|
|
||||||
|
if (reverseAxis) {
|
||||||
|
TextPainter(
|
||||||
|
text: TextSpan(text: tickLabels[0].toString(), style: ticksTextStyle),
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
)
|
||||||
|
..layout(minWidth: 0, maxWidth: size.width)
|
||||||
|
..paint(canvas, Offset(centerX, centerY - ticksTextStyle.fontSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
tickLabels
|
||||||
|
.sublist(
|
||||||
|
reverseAxis ? 1 : 0, reverseAxis ? ticks.length : ticks.length - 1)
|
||||||
|
.asMap()
|
||||||
|
.forEach((index, tick) {
|
||||||
|
var tickRadius = tickDistance * (index + 1);
|
||||||
|
|
||||||
|
canvas.drawPath(variablePath(size, tickRadius, this.sides), ticksPaint);
|
||||||
|
|
||||||
|
TextPainter(
|
||||||
|
text: TextSpan(text: tick.toString(), style: ticksTextStyle),
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
)
|
||||||
|
..layout(minWidth: 0, maxWidth: size.width)
|
||||||
|
..paint(canvas,
|
||||||
|
Offset(centerX, centerY - tickRadius - ticksTextStyle.fontSize));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Painting the axis for each given feature
|
||||||
|
var angle = (2 * pi) / features.length;
|
||||||
|
|
||||||
|
features.asMap().forEach((index, feature) {
|
||||||
|
var xAngle = cos(angle * index - pi / 2);
|
||||||
|
var yAngle = sin(angle * index - pi / 2);
|
||||||
|
|
||||||
|
var featureOffset =
|
||||||
|
Offset(centerX + radius * xAngle, centerY + radius * yAngle);
|
||||||
|
|
||||||
|
canvas.drawLine(centerOffset, featureOffset, ticksPaint);
|
||||||
|
|
||||||
|
var featureLabelFontHeight = featuresTextStyle.fontSize;
|
||||||
|
var featureLabelFontWidth = featuresTextStyle.fontSize - 5;
|
||||||
|
var labelYOffset = yAngle < 0 ? -featureLabelFontHeight : 0;
|
||||||
|
var labelXOffset =
|
||||||
|
xAngle < 0 ? -featureLabelFontWidth * feature.length : 0;
|
||||||
|
|
||||||
|
TextPainter(
|
||||||
|
text: TextSpan(text: feature, style: featuresTextStyle),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
)
|
||||||
|
..layout(minWidth: 0, maxWidth: size.width)
|
||||||
|
..paint(
|
||||||
|
canvas,
|
||||||
|
Offset(featureOffset.dx + labelXOffset,
|
||||||
|
featureOffset.dy + labelYOffset));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Painting each graph
|
||||||
|
data.asMap().forEach((index, graph) {
|
||||||
|
var graphPaint = Paint()
|
||||||
|
..color = graphColors[index % graphColors.length].withOpacity(0.3)
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
|
var graphOutlinePaint = Paint()
|
||||||
|
..color = graphColors[index % graphColors.length]
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 2.0
|
||||||
|
..isAntiAlias = true;
|
||||||
|
|
||||||
|
// Start the graph on the initial point
|
||||||
|
var scaledPoint = scale * graph[0] * fraction;
|
||||||
|
var path = Path();
|
||||||
|
|
||||||
|
if (reverseAxis) {
|
||||||
|
path.moveTo(centerX, centerY - (radius * fraction - scaledPoint));
|
||||||
|
} else {
|
||||||
|
path.moveTo(centerX, centerY - scaledPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.asMap().forEach((index, point) {
|
||||||
|
if (index == 0) return;
|
||||||
|
|
||||||
|
var xAngle = cos(angle * index - pi / 2);
|
||||||
|
var yAngle = sin(angle * index - pi / 2);
|
||||||
|
var scaledPoint = scale * point * fraction;
|
||||||
|
|
||||||
|
if (reverseAxis) {
|
||||||
|
path.lineTo(centerX + (radius * fraction - scaledPoint) * xAngle,
|
||||||
|
centerY + (radius * fraction - scaledPoint) * yAngle);
|
||||||
|
} else {
|
||||||
|
path.lineTo(
|
||||||
|
centerX + scaledPoint * xAngle, centerY + scaledPoint * yAngle);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
path.close();
|
||||||
|
canvas.drawPath(path, graphPaint);
|
||||||
|
canvas.drawPath(path, graphOutlinePaint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(RadarChartPainter oldDelegate) {
|
||||||
|
return oldDelegate.fraction != fraction;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ class AppLanguage{
|
|||||||
String langCode = prefs.getString('language_code');
|
String langCode = prefs.getString('language_code');
|
||||||
if ( langCode == null) {
|
if ( langCode == null) {
|
||||||
_appLocale = Locale('en');
|
_appLocale = Locale('en');
|
||||||
|
langCode = "en";
|
||||||
}
|
}
|
||||||
_appLocale = Locale(langCode);
|
_appLocale = Locale(langCode);
|
||||||
print(" ---- Get lang: " + _appLocale.toString() + " lang code $langCode");
|
print(" ---- Get lang: " + _appLocale.toString() + " lang code $langCode");
|
||||||
|
@ -20,6 +20,7 @@ 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_body_page.dart';
|
||||||
import 'package:aitrainer_app/view/mydevelopment_muscle_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';
|
||||||
@ -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/body_development/body_development_bloc.dart';
|
||||||
import 'bloc/development_by_muscle/development_by_muscle_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';
|
||||||
@ -133,6 +135,10 @@ Future<Null> main() async {
|
|||||||
create: (BuildContext context) => DevelopmentByMuscleBloc(
|
create: (BuildContext context) => DevelopmentByMuscleBloc(
|
||||||
workoutTreeRepository: menuTreeRepository),
|
workoutTreeRepository: menuTreeRepository),
|
||||||
),
|
),
|
||||||
|
BlocProvider<BodyDevelopmentBloc>(
|
||||||
|
create: (BuildContext context) => BodyDevelopmentBloc(
|
||||||
|
workoutTreeRepository: menuTreeRepository),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
|
|
||||||
child: AitrainerApp(),
|
child: AitrainerApp(),
|
||||||
@ -173,7 +179,7 @@ class AitrainerApp extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if ( locale != null && realSupportedLocale.countryCode != locale.countryCode ) {
|
if ( locale != null && realSupportedLocale.countryCode != locale.countryCode ) {
|
||||||
print ("Locale " + locale.countryCode + " not supported on this device :(");
|
//print ("Locale " + locale.countryCode + " not supported on this device :(");
|
||||||
}
|
}
|
||||||
return realSupportedLocale;
|
return realSupportedLocale;
|
||||||
},
|
},
|
||||||
@ -202,6 +208,7 @@ class AitrainerApp extends StatelessWidget {
|
|||||||
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
||||||
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
||||||
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
||||||
|
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),
|
||||||
},
|
},
|
||||||
initialRoute: 'home',
|
initialRoute: 'home',
|
||||||
title: 'WorkoutTest',
|
title: 'WorkoutTest',
|
||||||
@ -220,3 +227,4 @@ class AitrainerApp extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ class Cache {
|
|||||||
_exercisesTrainee = null;
|
_exercisesTrainee = null;
|
||||||
_traineeExercisePlan = null;
|
_traineeExercisePlan = null;
|
||||||
_exercises = List();
|
_exercises = List();
|
||||||
|
_myExercisesPlanDetails = LinkedHashMap();
|
||||||
print("Trainees is null? " + (_trainee == null).toString() );
|
print("Trainees is null? " + (_trainee == null).toString() );
|
||||||
//firstLoad = true;
|
|
||||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||||
await setPreferences(prefs, SharePrefsChange.logout, 0);
|
await setPreferences(prefs, SharePrefsChange.logout, 0);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:aitrainer_app/util/common.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class Exercise {
|
class Exercise {
|
||||||
@ -12,6 +11,7 @@ class Exercise {
|
|||||||
int exercisePlanDetailId;
|
int exercisePlanDetailId;
|
||||||
|
|
||||||
String datePart;
|
String datePart;
|
||||||
|
double calculated;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +25,7 @@ class Exercise {
|
|||||||
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);
|
this.datePart = DateFormat('yyyy-MM-dd').format(this.dateAdd);
|
||||||
|
this.calculated = quantity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
Map<String, dynamic> toJson() =>
|
||||||
@ -38,6 +39,18 @@ class Exercise {
|
|||||||
"exercisePlanDetailId": exercisePlanDetailId,
|
"exercisePlanDetailId": exercisePlanDetailId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Map<String, dynamic> toJsonDatePart() =>
|
||||||
|
{
|
||||||
|
"exerciseTypeId": exerciseTypeId,
|
||||||
|
"customerId": customerId,
|
||||||
|
"quantity": quantity,
|
||||||
|
'calculated': calculated,
|
||||||
|
"unit": unit,
|
||||||
|
"unitQuantity": unitQuantity,
|
||||||
|
"datePart": this.datePart,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Exercise copy() {
|
Exercise copy() {
|
||||||
Exercise newExercise = Exercise();
|
Exercise newExercise = Exercise();
|
||||||
newExercise.exerciseTypeId = this.exerciseTypeId;
|
newExercise.exerciseTypeId = this.exerciseTypeId;
|
||||||
|
@ -28,7 +28,9 @@ class ExercisePlanRepository {
|
|||||||
ExercisePlan getExercisePlan() => exercisePlan;
|
ExercisePlan getExercisePlan() => exercisePlan;
|
||||||
|
|
||||||
void addDetailToPlan() {
|
void addDetailToPlan() {
|
||||||
|
if ( exercisePlan != null ) {
|
||||||
actualPlanDetail.exercisePlanId = exercisePlan.exercisePlanId;
|
actualPlanDetail.exercisePlanId = exercisePlan.exercisePlanId;
|
||||||
|
}
|
||||||
exercisePlanDetails[actualPlanDetail.exerciseTypeId] = actualPlanDetail;
|
exercisePlanDetails[actualPlanDetail.exerciseTypeId] = actualPlanDetail;
|
||||||
Cache().addToMyExercisePlanDetails(actualPlanDetail);
|
Cache().addToMyExercisePlanDetails(actualPlanDetail);
|
||||||
}
|
}
|
||||||
|
@ -56,17 +56,11 @@ class ExerciseRepository {
|
|||||||
this.exercise.dateAdd = datetimeExercise;
|
this.exercise.dateAdd = datetimeExercise;
|
||||||
}
|
}
|
||||||
|
|
||||||
double get unitQuantity {
|
double get unitQuantity => this.exercise.unitQuantity;
|
||||||
return this.exercise.unitQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
double get quantity {
|
double get quantity => this.exercise.quantity;
|
||||||
return this.exercise.quantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exercise getExercise() {
|
Exercise getExercise() => this.exercise;
|
||||||
return this.exercise;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> addExercise() async {
|
Future<void> addExercise() async {
|
||||||
final Exercise modelExercise = this.exercise;
|
final Exercise modelExercise = this.exercise;
|
||||||
@ -81,13 +75,9 @@ class ExerciseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setCustomer(Customer customer) {
|
setCustomer(Customer customer) => this.customer = customer;
|
||||||
this.customer = customer;
|
|
||||||
}
|
|
||||||
|
|
||||||
setExerciseType( ExerciseType exerciseType) {
|
setExerciseType( ExerciseType exerciseType) => this.exerciseType = exerciseType;
|
||||||
this.exerciseType = exerciseType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
|
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
|
||||||
@ -102,17 +92,53 @@ class ExerciseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Exercise> getExerciseList() {
|
List<Exercise> getExerciseList() {
|
||||||
//if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
this.exerciseList = Cache().getExercises();
|
||||||
return this.exerciseList = Cache().getExercises();
|
return this.exerciseList;
|
||||||
//}
|
|
||||||
//return this.exerciseList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Exercise> getExerciseListTrainee() {
|
List<Exercise> getExerciseListTrainee() {
|
||||||
//if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
this.exerciseList = Cache().getExercisesTrainee();
|
||||||
return this.exerciseList = Cache().getExercisesTrainee();
|
return this.exerciseList;
|
||||||
//}
|
}
|
||||||
//return this.exerciseList;
|
|
||||||
|
String nextMissingBaseExercise(SplayTreeMap sortedTree) {
|
||||||
|
if ( exerciseList == null ) {
|
||||||
|
exerciseList = Cache().getExercises();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( exerciseList == null ) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String missingTreeName;
|
||||||
|
String foundTreeName;
|
||||||
|
bool isBreak = false;
|
||||||
|
|
||||||
|
sortedTree.forEach((key, list) {
|
||||||
|
List<WorkoutMenuTree> listByMuscle = list as List<WorkoutMenuTree>;
|
||||||
|
String treeName = key as String;
|
||||||
|
treeName = treeName.substring(3);
|
||||||
|
foundTreeName = null;
|
||||||
|
listByMuscle.forEach((exercise) {
|
||||||
|
if ( missingTreeName == null ) {
|
||||||
|
missingTreeName = treeName;
|
||||||
|
}
|
||||||
|
if ( exercise.base ) {
|
||||||
|
exerciseList.forEach((element) {
|
||||||
|
if ( element.exerciseTypeId == exercise.exerciseTypeId ) {
|
||||||
|
foundTreeName = treeName;
|
||||||
|
//print("Found " + foundTreeName + " Missing actual: " + missingTreeName);
|
||||||
|
isBreak = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if ( foundTreeName == null &&! isBreak ) {
|
||||||
|
missingTreeName = treeName;
|
||||||
|
isBreak = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return missingTreeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getBaseExerciseFinishedPercent() {
|
void getBaseExerciseFinishedPercent() {
|
||||||
@ -153,7 +179,7 @@ class ExerciseRepository {
|
|||||||
&& treeItem.exerciseType.base == true
|
&& treeItem.exerciseType.base == true
|
||||||
&& exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId
|
&& exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId
|
||||||
&& !checkedBaseTreeItem.contains(treeItem.parent)) {
|
&& !checkedBaseTreeItem.contains(treeItem.parent)) {
|
||||||
print ("id: " + exercise.exerciseTypeId.toString());
|
//print ("id: " + exercise.exerciseTypeId.toString());
|
||||||
checkedBaseTreeItem.add(treeItem.parent);
|
checkedBaseTreeItem.add(treeItem.parent);
|
||||||
count1RMExercises++;
|
count1RMExercises++;
|
||||||
}
|
}
|
||||||
@ -197,8 +223,6 @@ class ExerciseRepository {
|
|||||||
return actualExerciseType;
|
return actualExerciseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sortByDate() {
|
void sortByDate() => exerciseList.sort( (a, b) => b.dateAdd.compareTo(a.dateAdd) );
|
||||||
exerciseList.sort( (b, a) => a.dateAdd.compareTo(b.dateAdd) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -44,6 +44,7 @@ class WorkoutTreeRepository {
|
|||||||
Antagonist.calf: Antagonist.calfNr
|
Antagonist.calf: Antagonist.calfNr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Future<void> createTree() async {
|
Future<void> createTree() async {
|
||||||
|
|
||||||
isEnglish = AppLanguage().appLocal == Locale('en');
|
isEnglish = AppLanguage().appLocal == Locale('en');
|
||||||
@ -145,16 +146,21 @@ class WorkoutTreeRepository {
|
|||||||
return branch;
|
return branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorkoutMenuTree getParentItem(int parent) {
|
||||||
|
WorkoutMenuTree parentItem;
|
||||||
|
tree.forEach((key, value) {
|
||||||
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
|
if ( parent == workoutTree.id) {
|
||||||
|
parentItem = workoutTree;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return parentItem;
|
||||||
|
}
|
||||||
|
|
||||||
void sortByMuscleType() {
|
void sortByMuscleType() {
|
||||||
sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
|
||||||
tree.forEach((key, value) {
|
tree.forEach((key, value) {
|
||||||
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
|
||||||
//print("treeitem: " + workoutTree.toJson().toString());
|
|
||||||
/*if ( workoutTree.exerciseType != null) {
|
|
||||||
print("treeItem exerciseTye " + workoutTree.exerciseType.toJson().toString());
|
|
||||||
} else {
|
|
||||||
print("treeItem exerciseType null " + workoutTree.toJson().toString());
|
|
||||||
}*/
|
|
||||||
if ( workoutTree.nameEnglish != 'One Rep Max' && workoutTree.is1RM && workoutTree.exerciseTypeId == 0) {
|
if ( workoutTree.nameEnglish != 'One Rep Max' && workoutTree.is1RM && workoutTree.exerciseTypeId == 0) {
|
||||||
String treeName = _antagonist[workoutTree.nameEnglish].toString() + ". " + workoutTree.name;
|
String treeName = _antagonist[workoutTree.nameEnglish].toString() + ". " + workoutTree.name;
|
||||||
sortedTree[treeName] = this.getBranchList(workoutTree.id);
|
sortedTree[treeName] = this.getBranchList(workoutTree.id);
|
||||||
@ -163,4 +169,16 @@ class WorkoutTreeRepository {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getMissingTreeIdByName(String name) {
|
||||||
|
int missingId = 0;
|
||||||
|
tree.forEach((key, value) {
|
||||||
|
WorkoutMenuTree item = value as WorkoutMenuTree;
|
||||||
|
if ( item.name == name || name == item.nameEnglish ) {
|
||||||
|
missingId = item.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return missingId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -48,7 +48,7 @@ class CustomerApi {
|
|||||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||||
Cache().afterRegistration(customer);
|
Cache().afterRegistration(customer);
|
||||||
}
|
}
|
||||||
} on FormatException catch (exception) {
|
} on FormatException {
|
||||||
throw new Exception(responseBody);
|
throw new Exception(responseBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ class CustomerApi {
|
|||||||
try {
|
try {
|
||||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||||
await Cache().afterLogin(customer);
|
await Cache().afterLogin(customer);
|
||||||
} on FormatException catch (exception) {
|
} on FormatException {
|
||||||
throw new Exception(responseBody);
|
throw new Exception(responseBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,18 @@ class ExerciseApi {
|
|||||||
body);
|
body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<Exercise>> getExercisesByCustomer(int customerId ) async {
|
||||||
|
final body = await _client.get("exercises/customer/", customerId.toString() );
|
||||||
|
final Iterable json = jsonDecode(body);
|
||||||
|
final List<Exercise> exercises = json.map( (exercise) {
|
||||||
|
Exercise item = Exercise.fromJson(exercise);
|
||||||
|
return item;
|
||||||
|
}).toList();
|
||||||
|
//exercises.sort( (a, b) => b.dateAdd.compareTo(a.dateAdd) );
|
||||||
|
|
||||||
|
return exercises;
|
||||||
|
}
|
||||||
|
|
||||||
Future<Exercise> addExercise(Exercise exercise) async {
|
Future<Exercise> addExercise(Exercise exercise) async {
|
||||||
String body = JsonEncoder().convert(exercise.toJson());
|
String body = JsonEncoder().convert(exercise.toJson());
|
||||||
print(" ===== add new exercise: " + body );
|
print(" ===== add new exercise: " + body );
|
||||||
@ -32,12 +44,4 @@ class ExerciseApi {
|
|||||||
return savedExercise;
|
return savedExercise;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Exercise>> getExercisesByCustomer(int customerId ) async {
|
|
||||||
final body = await _client.get("exercises/customer/", customerId.toString() );
|
|
||||||
final Iterable json = jsonDecode(body);
|
|
||||||
final List<Exercise> exercises = json.map( (exercise) => Exercise.fromJson(exercise) ).toList();
|
|
||||||
|
|
||||||
return exercises;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -7,6 +7,13 @@ import 'package:aitrainer_app/repository/user_repository.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
class DateRate {
|
||||||
|
static String daily = "daily";
|
||||||
|
static String weekly = "weekly";
|
||||||
|
static String monthly = "monthly";
|
||||||
|
static String yearly = "yearly";
|
||||||
|
}
|
||||||
|
|
||||||
mixin Common {
|
mixin Common {
|
||||||
|
|
||||||
final EMAIL_ERROR = "Please type a right email address here.";
|
final EMAIL_ERROR = "Please type a right email address here.";
|
||||||
@ -24,7 +31,7 @@ mixin Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ExerciseType getExerciseType( int exerciseTypeId ) {
|
ExerciseType getExerciseType( int exerciseTypeId ) {
|
||||||
ExerciseType returnElement = null;
|
ExerciseType returnElement;
|
||||||
List<ExerciseType> listExerciseType = Cache().getExerciseTypes();
|
List<ExerciseType> listExerciseType = Cache().getExerciseTypes();
|
||||||
if ( listExerciseType != null ) {
|
if ( listExerciseType != null ) {
|
||||||
for ( var element in listExerciseType ) {
|
for ( var element in listExerciseType ) {
|
||||||
@ -32,7 +39,7 @@ mixin Common {
|
|||||||
returnElement = element;
|
returnElement = element;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
return returnElement;
|
return returnElement;
|
||||||
}
|
}
|
||||||
@ -79,4 +86,18 @@ mixin Common {
|
|||||||
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getDatePart(DateTime date, String dateRate) {
|
||||||
|
String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||||
|
if ( dateRate == DateRate.weekly ) {
|
||||||
|
datePart = weekNumber(date).toString();
|
||||||
|
} else if ( dateRate == DateRate.monthly ) {
|
||||||
|
datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date);
|
||||||
|
} else if ( dateRate == DateRate.yearly ) {
|
||||||
|
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
|
||||||
|
} else if ( dateRate == DateRate.daily ) {
|
||||||
|
datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||||
|
}
|
||||||
|
return datePart;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
15
lib/util/group_data.dart
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import 'package:aitrainer_app/model/exercise.dart';
|
||||||
|
|
||||||
|
abstract class GroupData {
|
||||||
|
|
||||||
|
void iteration();
|
||||||
|
|
||||||
|
bool checkNewType(Exercise exercise);
|
||||||
|
|
||||||
|
void addTempData(Exercise element);
|
||||||
|
|
||||||
|
void temp2Output(Exercise exercise);
|
||||||
|
|
||||||
|
void resetTemp();
|
||||||
|
|
||||||
|
}
|
@ -122,7 +122,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
color: Colors.lightBlue,
|
color: Colors.lightBlue,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
onChanged: (input) => {
|
onChanged: (input) => {
|
||||||
print("UnitQuantity value $input"),
|
print("UnitQuantity value $input"),
|
||||||
@ -150,7 +150,6 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
;
|
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
color: Colors.deepOrange,
|
color: Colors.deepOrange,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
onChanged: (input) => {
|
onChanged: (input) => {
|
||||||
print("Quantity value $input"),
|
print("Quantity value $input"),
|
||||||
|
@ -23,7 +23,6 @@ class _CustomerGoalPage extends State<CustomerGoalPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final double cWidth = MediaQuery.of(context).size.width * 0.75;
|
|
||||||
final CustomerRepository customerRepository =
|
final CustomerRepository customerRepository =
|
||||||
ModalRoute.of(context).settings.arguments;
|
ModalRoute.of(context).settings.arguments;
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/customer_change_form_bloc.dart';
|
import 'package:aitrainer_app/bloc/customer_change_form_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
@ -169,7 +168,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
|||||||
child: TextFieldBlocBuilder(
|
child: TextFieldBlocBuilder(
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
textFieldBloc: customerBloc.birthYearField,
|
textFieldBloc: customerBloc.birthYearField,
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white24,
|
fillColor: Colors.white24,
|
||||||
filled: true,
|
filled: true,
|
||||||
@ -186,7 +185,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
|||||||
child: TextFieldBlocBuilder(
|
child: TextFieldBlocBuilder(
|
||||||
style: TextStyle(fontSize: 12),
|
style: TextStyle(fontSize: 12),
|
||||||
textFieldBloc: customerBloc.weightField,
|
textFieldBloc: customerBloc.weightField,
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white24,
|
fillColor: Colors.white24,
|
||||||
filled: true,
|
filled: true,
|
||||||
|
@ -148,7 +148,7 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
|||||||
color: Colors.black54,
|
color: Colors.black54,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@ -169,7 +169,7 @@ class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> with Trans {
|
|||||||
color: Colors.deepOrange,
|
color: Colors.deepOrange,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
|
@ -4,6 +4,8 @@ import 'package:aitrainer_app/bloc/exercise_control_form_bloc.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/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -48,24 +50,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> {
|
|||||||
autovalidate: true,
|
autovalidate: true,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
resizeToAvoidBottomInset: true,
|
resizeToAvoidBottomInset: true,
|
||||||
appBar: AppBar(
|
appBar: AppBarNav(depth: 1),
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
title: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: <Widget>[
|
|
||||||
Text("1RM Control"),
|
|
||||||
Image.asset(
|
|
||||||
'asset/image/WT_long_logo.png',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
height: 65.0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
leading: IconButton(
|
|
||||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
body: Container(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
@ -130,7 +115,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> {
|
|||||||
textFieldBloc: exerciseBloc.quantity1Field,
|
textFieldBloc: exerciseBloc.quantity1Field,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
@ -173,7 +158,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> {
|
|||||||
textFieldBloc: exerciseBloc.quantity2Field,
|
textFieldBloc: exerciseBloc.quantity2Field,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
onChanged: (input) => {
|
onChanged: (input) => {
|
||||||
print("Quantity 2 value $input"),
|
print("Quantity 2 value $input"),
|
||||||
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
||||||
@ -220,7 +205,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> {
|
|||||||
textFieldBloc: exerciseBloc.quantity3Field,
|
textFieldBloc: exerciseBloc.quantity3Field,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
onChanged: (input) => {
|
onChanged: (input) => {
|
||||||
print("Quantity 3 value $input"),
|
print("Quantity 3 value $input"),
|
||||||
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
||||||
@ -255,7 +240,9 @@ class _ExerciseControlPage extends State<ExerciseControlPage> {
|
|||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
))),
|
))),
|
||||||
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
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/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
import 'package:aitrainer_app/library/tree_view.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.dart';
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
@ -44,7 +43,7 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> with Trans {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 1),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -92,8 +91,6 @@ class _ExerciseByPlanPage extends State<ExerciseByPlanPage> with Trans {
|
|||||||
|
|
||||||
List<Widget> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
List<Widget> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||||
List<Widget> exerciseTypes = List();
|
List<Widget> exerciseTypes = List();
|
||||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
|
||||||
|
|
||||||
Card explanation = Card(
|
Card explanation = Card(
|
||||||
color: Colors.white38,
|
color: Colors.white38,
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.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/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/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
import 'package:aitrainer_app/library/tree_view.dart';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
|
|||||||
setContext(context);
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 1),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -38,7 +39,8 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: exerciseWidget(exerciseRepository, customerId),
|
child: exerciseWidget(exerciseRepository, customerId),
|
||||||
)
|
),
|
||||||
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +97,6 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
|
|||||||
|
|
||||||
List<Exercise> listExercises = List();
|
List<Exercise> listExercises = List();
|
||||||
String origDate = "";
|
String origDate = "";
|
||||||
print("start exercises");
|
|
||||||
exerciseRepository.exerciseList.forEach((exercise) {
|
exerciseRepository.exerciseList.forEach((exercise) {
|
||||||
String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd);
|
String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd);
|
||||||
|
|
||||||
@ -109,18 +110,35 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
|
|||||||
margin: const EdgeInsets.only(left: 4.0),
|
margin: const EdgeInsets.only(left: 4.0),
|
||||||
child: TreeViewChild(
|
child: TreeViewChild(
|
||||||
startExpanded: true,
|
startExpanded: true,
|
||||||
parent: TreeviewParentWidget(text: exerciseDate),
|
parent: TreeviewParentWidget(text: origDate),
|
||||||
children: _getChildList(listExercises, exerciseRepository),
|
children: _getChildList(listExercises, exerciseRepository),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
listExercises = List();
|
listExercises = List();
|
||||||
}
|
|
||||||
}
|
|
||||||
origDate = exerciseDate;
|
|
||||||
listExercises.add(exercise);
|
listExercises.add(exercise);
|
||||||
|
origDate = exerciseDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
listExercises.add(exercise);
|
||||||
|
origDate = exerciseDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
if ( listExercises.length > 0) {
|
||||||
|
listWidget.add(
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.only(left: 4.0),
|
||||||
|
child: TreeViewChild(
|
||||||
|
startExpanded: true,
|
||||||
|
parent: TreeviewParentWidget(text: origDate),
|
||||||
|
children: _getChildList(listExercises, exerciseRepository),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return listWidget;
|
return listWidget;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/exercise_form_bloc.dart';
|
import 'package:aitrainer_app/bloc/exercise_form_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.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/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
@ -21,13 +23,16 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
|
final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments;
|
||||||
|
// ignore: close_sinks
|
||||||
|
final menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
|
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => ExerciseFormBloc(exerciseRepository: ExerciseRepository()),
|
create: (context) => ExerciseFormBloc(exerciseRepository: ExerciseRepository(), menuBloc: menuBloc),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
final exerciseBloc = BlocProvider.of<ExerciseFormBloc>(context);
|
final exerciseBloc = BlocProvider.of<ExerciseFormBloc>(context);
|
||||||
|
|
||||||
|
|
||||||
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
|
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
|
||||||
String exerciseName = AppLanguage().appLocal == Locale("en") ?
|
String exerciseName = AppLanguage().appLocal == Locale("en") ?
|
||||||
exerciseBloc.exerciseRepository.exerciseType.name :
|
exerciseBloc.exerciseRepository.exerciseType.name :
|
||||||
@ -37,23 +42,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
autovalidate: true,
|
autovalidate: true,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
resizeToAvoidBottomInset: true,
|
resizeToAvoidBottomInset: true,
|
||||||
appBar: AppBar(
|
appBar: AppBarNav(depth: 1),
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
title: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: <Widget>[
|
|
||||||
Image.asset(
|
|
||||||
'asset/image/WT_long_logo.png',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
height: 65.0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
leading: IconButton(
|
|
||||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
body: Container(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
@ -147,9 +136,10 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
color: Colors.lightBlue,
|
color: Colors.lightBlue,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
onChanged: (input) => {
|
onChanged: (input) =>
|
||||||
|
{
|
||||||
print("UnitQuantity value $input"),
|
print("UnitQuantity value $input"),
|
||||||
bloc.exerciseRepository.setUnitQuantity(
|
bloc.exerciseRepository.setUnitQuantity(
|
||||||
double.parse(input))
|
double.parse(input))
|
||||||
@ -171,7 +161,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
]);
|
]);
|
||||||
};
|
}
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +175,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
color: Colors.deepOrange,
|
color: Colors.deepOrange,
|
||||||
fontWeight: FontWeight.bold),
|
fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
FilteringTextInputFormatter.allow (RegExp(r"[\d.]"))
|
||||||
],
|
],
|
||||||
onChanged: (input) =>
|
onChanged: (input) =>
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@ import 'package:aitrainer_app/localization/app_localization.dart';
|
|||||||
import 'package:aitrainer_app/model/exercise_plan_detail.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.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
@ -43,7 +43,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
autovalidate: true,
|
autovalidate: true,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
resizeToAvoidBottomInset: true,
|
resizeToAvoidBottomInset: true,
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 1),
|
||||||
body: Container(
|
body: Container(
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
@ -72,7 +72,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
textFieldBloc: bloc.serieField,
|
textFieldBloc: bloc.serieField,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
@ -86,7 +86,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
textFieldBloc: bloc.quantityField,
|
textFieldBloc: bloc.quantityField,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
@ -101,7 +101,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
|
|||||||
textFieldBloc: bloc.weightField,
|
textFieldBloc: bloc.weightField,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))],
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
|
@ -4,9 +4,9 @@ import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
|||||||
|
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
import 'package:aitrainer_app/library/tree_view.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.dart';
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
@ -45,7 +45,7 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 1),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -181,10 +181,11 @@ class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> with Trans {
|
|||||||
),
|
),
|
||||||
InkWell(
|
InkWell(
|
||||||
child:
|
child:
|
||||||
element.selected && bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].change != null ?
|
!element.selected || bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId] == null ||
|
||||||
|
bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].change == null ? Text("") :
|
||||||
Text(bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].repeats.toString() +
|
Text(bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].repeats.toString() +
|
||||||
" x " + bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].weightEquation +
|
" x " + bloc.exercisePlanRepository.exercisePlanDetails[element.exerciseTypeId].weightEquation +
|
||||||
" " + element.exerciseType.unitQuantityUnit, style: TextStyle(fontSize: 9, color: Colors.green),) : Text(""),
|
" " + element.exerciseType.unitQuantityUnit, style: TextStyle(fontSize: 9, color: Colors.green),),
|
||||||
onTap: () => {
|
onTap: () => {
|
||||||
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
bloc.add(ExercisePlanUpdateUI(workoutTree: element)),
|
||||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc),
|
||||||
|
@ -28,7 +28,7 @@ class _MenuPage extends State<MenuPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarNav(),
|
appBar: AppBarNav(isMenu: true,),
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
|
129
lib/view/mydevelopment_body_page.dart
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
import 'package:aitrainer_app/library/radar_chart.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/bloc/body_development/body_development_bloc.dart';
|
||||||
|
|
||||||
|
class MyDevelopmentBodyPage extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_MyDevelopmentBodyPage createState() => _MyDevelopmentBodyPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Common {
|
||||||
|
// ignore: close_sinks
|
||||||
|
BodyDevelopmentBloc bloc;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
/// We require the initializers to run after the loading screen is rendered
|
||||||
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||||
|
BlocProvider.of<BodyDevelopmentBloc>(context).add(BodyDevelopmentLoad());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
bloc = BlocProvider.of<BodyDevelopmentBloc>(context);
|
||||||
|
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||||
|
final int customerId = arguments['customerId'];
|
||||||
|
setContext(context);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBarNav(depth: 1),
|
||||||
|
body: Container(
|
||||||
|
padding: EdgeInsets.all(20),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||||
|
AssetImage('asset/image/WT_menu_dark.png'),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: BlocConsumer<BodyDevelopmentBloc, BodyDevelopmentState>(
|
||||||
|
listener: (context, state) {
|
||||||
|
if (state is BodyDevelopmentLoading) {
|
||||||
|
LoadingDialog();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
builder: (context, state) {
|
||||||
|
if ( state is BodyDevelopmentInitial) {
|
||||||
|
return Container();
|
||||||
|
} else {
|
||||||
|
return developmentWidget(customerId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
),
|
||||||
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget developmentWidget(int customerId) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
explanationWidget(),
|
||||||
|
Expanded(
|
||||||
|
child: exerciseWidget(customerId),
|
||||||
|
),
|
||||||
|
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget exerciseWidget(int customerId) {
|
||||||
|
return RadarChart.light(
|
||||||
|
ticks: bloc.radarTicks,
|
||||||
|
features: bloc.radarFeatures,
|
||||||
|
data: bloc.radarData,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget explanationWidget() {
|
||||||
|
return Card(
|
||||||
|
color: Colors.white60,
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.info,
|
||||||
|
color: Colors.orangeAccent,
|
||||||
|
),
|
||||||
|
Text(" "),
|
||||||
|
Text(
|
||||||
|
t("My Body Development"),
|
||||||
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Divider(
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
t("You see here your whole body development by muscle groups."),
|
||||||
|
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
||||||
import 'package:fl_chart/fl_chart.dart';
|
import 'package:fl_chart/fl_chart.dart';
|
||||||
import 'package:aitrainer_app/util/common.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/bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
import 'package:aitrainer_app/treeview/tree_view.dart';
|
import 'package:aitrainer_app/library/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/bottom_nav.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';
|
||||||
@ -43,7 +43,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
|||||||
setContext(context);
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 1),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -75,7 +75,6 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
|||||||
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),
|
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
;
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -209,11 +208,10 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
|||||||
exerciseTypes.add(explanation);
|
exerciseTypes.add(explanation);
|
||||||
|
|
||||||
tree.forEach((name, list) {
|
tree.forEach((name, list) {
|
||||||
List<WorkoutMenuTree> listWorkoutMenuTree = list;
|
|
||||||
exerciseTypes.add(Container(
|
exerciseTypes.add(Container(
|
||||||
margin: const EdgeInsets.only(left: 4.0),
|
margin: const EdgeInsets.only(left: 4.0),
|
||||||
child: TreeViewChild(
|
child: TreeViewChild(
|
||||||
startExpanded: true,
|
startExpanded: false,
|
||||||
parent: _getExerciseWidget(exerciseTypeName: name),
|
parent: _getExerciseWidget(exerciseTypeName: name),
|
||||||
children: _getChildList(list, bloc),
|
children: _getChildList(list, bloc),
|
||||||
)));
|
)));
|
||||||
@ -274,7 +272,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
|||||||
getTitles: (double value) {
|
getTitles: (double value) {
|
||||||
var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt());
|
var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt());
|
||||||
//String strDate = DateFormat('MM.dd.', AppLanguage().appLocal.toString()).format(date);
|
//String strDate = DateFormat('MM.dd.', AppLanguage().appLocal.toString()).format(date);
|
||||||
String strDate = bloc.getDatePart(date);
|
String strDate = getDatePart(date, bloc.dateRate);
|
||||||
return strDate;
|
return strDate;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -4,11 +4,11 @@ import 'package:aitrainer_app/model/cache.dart';
|
|||||||
import 'package:aitrainer_app/repository/customer_repository.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.dart';
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
|
import 'package:aitrainer_app/widgets/image_button.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
|
||||||
@ -24,7 +24,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
setContext(context);
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 0),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -41,7 +41,16 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
SliverGrid(
|
SliverGrid(
|
||||||
delegate: SliverChildListDelegate(
|
delegate: SliverChildListDelegate(
|
||||||
[
|
[
|
||||||
FlatButton(
|
ImageButton(
|
||||||
|
textAlignment: Alignment.topCenter,
|
||||||
|
text: t("My Exercise Logs"),
|
||||||
|
style: TextStyle(fontSize: 20, color: Colors.orange, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||||
|
image: "asset/image/exercise_log.jpg",
|
||||||
|
top: 40,
|
||||||
|
onTap:() => this.callBackExerciseLog(exerciseRepository, customerRepository),
|
||||||
|
isLocked: false,
|
||||||
|
),
|
||||||
|
/*FlatButton(
|
||||||
padding: EdgeInsets.all(0),
|
padding: EdgeInsets.all(0),
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
color: Colors.black12,
|
color: Colors.black12,
|
||||||
@ -56,8 +65,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
},
|
},
|
||||||
child: Text(t("My Exercise Logs"),
|
child: Text(t("My Exercise Logs"),
|
||||||
style: TextStyle(fontSize: 18),)
|
style: TextStyle(fontSize: 18),)
|
||||||
),
|
),*/
|
||||||
Stack(
|
/*Stack(
|
||||||
fit: StackFit.passthrough,
|
fit: StackFit.passthrough,
|
||||||
overflow: Overflow.clip,
|
overflow: Overflow.clip,
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
@ -73,22 +82,51 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
focusColor: Colors.blueAccent,
|
focusColor: Colors.blueAccent,
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
{
|
{
|
||||||
|
args['customerId'] = Cache().userLoggedIn.customerId,
|
||||||
|
Navigator.of(context).pushNamed('mydevelopmentBodyPage',
|
||||||
|
arguments: args)
|
||||||
},
|
},
|
||||||
child: Text(t("My Whole Body Development"),
|
child: Text(t("My Whole Body Development"),
|
||||||
style: TextStyle(fontSize: 18),)
|
style: TextStyle(fontSize: 18),)
|
||||||
),
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
|
),*/
|
||||||
|
ImageButton(
|
||||||
|
textAlignment: Alignment.topLeft,
|
||||||
|
text: t("My Whole Body Development"),
|
||||||
|
style: TextStyle(fontSize: 20, color: Colors.orange, fontWeight: FontWeight.bold,
|
||||||
|
backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||||
|
image: "asset/menu/3.1.BMI.png",
|
||||||
|
top: 50,
|
||||||
|
onTap:() => {
|
||||||
|
args['customerId'] = Cache().userLoggedIn.customerId,
|
||||||
|
Navigator.of(context).pushNamed('mydevelopmentBodyPage',
|
||||||
|
arguments: args)
|
||||||
|
},
|
||||||
|
isLocked: true,
|
||||||
),
|
),
|
||||||
|
ImageButton(
|
||||||
Stack(
|
textAlignment: Alignment.topLeft,
|
||||||
|
text: t("Development Of Muscles"),
|
||||||
|
style: TextStyle(fontSize: 20, color: Colors.orange, fontWeight: FontWeight.bold,
|
||||||
|
backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||||
|
image: "asset/image/development_muscles.jpg",
|
||||||
|
top: 50,
|
||||||
|
onTap:() => {
|
||||||
|
Navigator.of(context).pushNamed('mydevelopmentMusclePage',
|
||||||
|
arguments: args)
|
||||||
|
},
|
||||||
|
isLocked: true,
|
||||||
|
),
|
||||||
|
/*Stack(
|
||||||
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,
|
||||||
@ -104,8 +142,20 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
),
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
),*/
|
||||||
|
ImageButton(
|
||||||
|
textAlignment: Alignment.topLeft,
|
||||||
|
text: t("Predictions"),
|
||||||
|
style: TextStyle(fontSize: 20, color: Colors.orange, fontWeight: FontWeight.bold,
|
||||||
|
backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||||
|
image: "asset/menu/2.2.1.1RM.png",
|
||||||
|
top: 50,
|
||||||
|
onTap:() => {
|
||||||
|
|
||||||
|
},
|
||||||
|
isLocked: true,
|
||||||
),
|
),
|
||||||
Stack(
|
/*Stack(
|
||||||
fit: StackFit.passthrough,
|
fit: StackFit.passthrough,
|
||||||
|
|
||||||
overflow: Overflow.clip,
|
overflow: Overflow.clip,
|
||||||
@ -126,7 +176,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
style: TextStyle(fontSize: 18),)
|
style: TextStyle(fontSize: 18),)
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
),
|
),*/
|
||||||
hiddenWidget(customerRepository, exerciseRepository),
|
hiddenWidget(customerRepository, exerciseRepository),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
@ -167,6 +217,15 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void callBackExerciseLog(ExerciseRepository exerciseRepository, CustomerRepository customerRepository) {
|
||||||
|
final LinkedHashMap args = LinkedHashMap();
|
||||||
|
args['exerciseRepository'] = exerciseRepository;
|
||||||
|
args['customerRepository'] = customerRepository;
|
||||||
|
args['customerId'] = Cache().userLoggedIn.customerId;
|
||||||
|
Navigator.of(context).pushNamed('exerciseLogPage',
|
||||||
|
arguments: args);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:collection';
|
|||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.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.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';
|
||||||
@ -20,7 +20,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans {
|
|||||||
setContext(context);
|
setContext(context);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarCommonNav(),
|
appBar: AppBarNav(depth: 0),
|
||||||
body: Container(
|
body: Container(
|
||||||
padding: EdgeInsets.all(20),
|
padding: EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
@ -2,7 +2,6 @@ import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
|||||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
import 'package:aitrainer_app/bloc/settings/settings_bloc.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/cache.dart';
|
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -4,6 +4,7 @@ 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/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
|
import 'package:aitrainer_app/util/common.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';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -13,20 +14,20 @@ import 'package:rainbow_color/rainbow_color.dart';
|
|||||||
|
|
||||||
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
||||||
final MenuBloc menuBloc;
|
final MenuBloc menuBloc;
|
||||||
const AppBarNav({this.menuBloc});
|
final bool isMenu;
|
||||||
|
final int depth;
|
||||||
|
const AppBarNav({this.menuBloc, this.isMenu, this.depth});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AppBarNav createState() => _AppBarNav();
|
_AppBarNav createState() => _AppBarNav();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Size get preferredSize => const Size.fromHeight(60);
|
Size get preferredSize => const Size.fromHeight(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, Common {
|
||||||
Animation<Color> colorAnim;
|
Animation<Color> colorAnim;
|
||||||
//Animation<double> sizeAnim;
|
|
||||||
AnimationController colorController;
|
AnimationController colorController;
|
||||||
//AnimationController sizeController;
|
|
||||||
MenuBloc menuBloc;
|
MenuBloc menuBloc;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -34,26 +35,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
|
|
||||||
colorController =
|
colorController =
|
||||||
AnimationController(duration: Duration(seconds: 4), vsync:this);
|
AnimationController(duration: Duration(seconds: 4), vsync:this);
|
||||||
//sizeController =
|
|
||||||
// AnimationController(duration: Duration(seconds: 3), vsync: this);
|
|
||||||
|
|
||||||
/* final curvedAnimation = CurvedAnimation(
|
|
||||||
parent: sizeController,
|
|
||||||
curve: Curves.easeIn,
|
|
||||||
reverseCurve: Curves.easeInOutBack,
|
|
||||||
);
|
|
||||||
|
|
||||||
sizeAnim =
|
|
||||||
Tween<double>(begin: 0, end: 1.5).animate(curvedAnimation)
|
|
||||||
..addStatusListener((status) {
|
|
||||||
if (status == AnimationStatus.completed) {
|
|
||||||
sizeController.reverse();
|
|
||||||
} else if (status == AnimationStatus.dismissed) {
|
|
||||||
Timer(Duration(seconds: 5), () {
|
|
||||||
sizeController.forward();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}); */
|
|
||||||
colorAnim = RainbowColorTween([Colors.white70,
|
colorAnim = RainbowColorTween([Colors.white70,
|
||||||
Colors.blueGrey,
|
Colors.blueGrey,
|
||||||
Colors.blueAccent,
|
Colors.blueAccent,
|
||||||
@ -69,7 +51,6 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
..addStatusListener((status) {
|
..addStatusListener((status) {
|
||||||
if (status == AnimationStatus.completed) {
|
if (status == AnimationStatus.completed) {
|
||||||
Timer(Duration(seconds: 10), () {
|
Timer(Duration(seconds: 10), () {
|
||||||
//colorController.reset();
|
|
||||||
if ( mounted ) {
|
if ( mounted ) {
|
||||||
colorController.forward();
|
colorController.forward();
|
||||||
}
|
}
|
||||||
@ -85,7 +66,6 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
//setContext(context);
|
|
||||||
|
|
||||||
return AppBar(
|
return AppBar(
|
||||||
backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
@ -96,8 +76,8 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
getAnimatedWidget(),
|
getAnimatedWidget(),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'asset/image/WT_long_logo.png',
|
'asset/image/WT_long_logo.png',
|
||||||
fit: BoxFit.cover,
|
//fit: BoxFit.cover,
|
||||||
height: 65.0,
|
height: 45.0,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -105,8 +85,16 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
icon: Icon(Icons.arrow_back, color: Colors.white),
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
{
|
{
|
||||||
if ( menuBloc != null ) {
|
if ( widget.isMenu != null ) {
|
||||||
menuBloc.add(MenuTreeUp(parent: 0)),
|
if ( menuBloc.workoutItem != null ) {
|
||||||
|
menuBloc.add(MenuTreeUp(parent: menuBloc.workoutItem.parent)),
|
||||||
|
}
|
||||||
|
} else if ( widget.depth != null ) {
|
||||||
|
if ( widget.depth == 0 ) {
|
||||||
|
Navigator.of(context).pushNamed('home')
|
||||||
|
} else {
|
||||||
|
Navigator.of(context).pop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -115,12 +103,12 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
//sizeController.dispose();
|
|
||||||
colorController.dispose();
|
colorController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget getAnimatedWidget() {
|
Widget getAnimatedWidget() {
|
||||||
|
double cWidth = mediaSizeWidth(context);
|
||||||
double percent = Cache().getPercentExercises();
|
double percent = Cache().getPercentExercises();
|
||||||
if ( percent == -1) {
|
if ( percent == -1) {
|
||||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
@ -130,9 +118,10 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
int sizeExerciseList = Cache().getExercises() == null? 0 : Cache().getExercises().length;
|
int sizeExerciseList = Cache().getExercises() == null? 0 : Cache().getExercises().length;
|
||||||
if ( sizeExerciseList == 0 ) {
|
if ( sizeExerciseList == 0 ) {
|
||||||
String text = AppLocalizations.of(context).translate("Make your first test");
|
String text = AppLocalizations.of(context).translate("Make your first test");
|
||||||
double fontSize = text.length > 15 ? 10 : 16;
|
double fontSize = text.length > 24 ? 10 : 16;
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
|
overflow: Overflow.clip,
|
||||||
children: [
|
children: [
|
||||||
Text(text,
|
Text(text,
|
||||||
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple , blurRadius: 15)]),
|
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple , blurRadius: 15)]),
|
||||||
@ -147,12 +136,12 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
|||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
children: [
|
children: [
|
||||||
LinearPercentIndicator(
|
LinearPercentIndicator(
|
||||||
width: 120.0,
|
width: cWidth / 4,
|
||||||
lineHeight: 14.0,
|
lineHeight: 14.0,
|
||||||
percent: percent,
|
percent: percent,
|
||||||
center: Text(
|
center: Text(
|
||||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||||
style: new TextStyle(fontSize: 12.0),
|
style: new TextStyle(fontSize: 10.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,),
|
||||||
linearStrokeCap: LinearStrokeCap.roundAll,
|
linearStrokeCap: LinearStrokeCap.roundAll,
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
|
||||||
import 'package:rainbow_color/rainbow_color.dart';
|
|
||||||
|
|
||||||
|
|
||||||
class AppBarCommonNav extends StatefulWidget implements PreferredSizeWidget {
|
|
||||||
|
|
||||||
@override
|
|
||||||
_AppBarCommonNav createState() => _AppBarCommonNav();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Size get preferredSize => const Size.fromHeight(60);
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AppBarCommonNav extends State<AppBarCommonNav> with SingleTickerProviderStateMixin {
|
|
||||||
Animation<Color> colorAnim;
|
|
||||||
AnimationController colorController;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
|
|
||||||
colorController =
|
|
||||||
AnimationController(duration: Duration(seconds: 4),vsync: this);
|
|
||||||
|
|
||||||
colorAnim = RainbowColorTween([Colors.white70,
|
|
||||||
Colors.blueGrey,
|
|
||||||
Colors.blueAccent,
|
|
||||||
Colors.lightBlue,
|
|
||||||
Colors.lightBlueAccent,
|
|
||||||
Colors.yellowAccent,
|
|
||||||
Colors.orange,
|
|
||||||
Colors.orangeAccent,
|
|
||||||
Colors.yellowAccent,
|
|
||||||
Color(0xffcce6ff)])
|
|
||||||
.animate(colorController)
|
|
||||||
..addListener(() { setState(() {}); })
|
|
||||||
..addStatusListener((status) {
|
|
||||||
if (status == AnimationStatus.completed) {
|
|
||||||
Timer(Duration(seconds: 10), () {
|
|
||||||
//colorController.reset();
|
|
||||||
if ( mounted ) {
|
|
||||||
colorController.forward();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (status == AnimationStatus.dismissed) {
|
|
||||||
colorController.forward();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
colorController.forward();
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return AppBar(
|
|
||||||
backgroundColor: Colors.black,
|
|
||||||
title: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
|
|
||||||
getAnimatedWidget(),
|
|
||||||
Image.asset(
|
|
||||||
'asset/image/WT_long_logo.png',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
height: 65.0,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
leading: IconButton(
|
|
||||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
|
||||||
onPressed: () =>
|
|
||||||
{
|
|
||||||
Navigator.of(context).pushNamed('home')
|
|
||||||
},
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
//sizeController.dispose();
|
|
||||||
colorController.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget getAnimatedWidget() {
|
|
||||||
double percent = Cache().getPercentExercises();
|
|
||||||
if ( percent == -1) {
|
|
||||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
|
||||||
exerciseRepository.getBaseExerciseFinishedPercent();
|
|
||||||
percent = Cache().getPercentExercises();
|
|
||||||
}
|
|
||||||
int sizeExerciseList = Cache().getExercises() == null? 0 : Cache().getExercises().length;
|
|
||||||
if ( sizeExerciseList == 0 ) {
|
|
||||||
String text = AppLocalizations.of(context).translate("Make your first test");
|
|
||||||
double fontSize = text.length > 17 ? 10 : 16;
|
|
||||||
return Stack(
|
|
||||||
alignment: Alignment.topLeft,
|
|
||||||
children: [
|
|
||||||
Text(text,
|
|
||||||
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple , blurRadius: 15)]),
|
|
||||||
|
|
||||||
),
|
|
||||||
//TestProgress(animation: sizeAnim),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return Stack(
|
|
||||||
alignment: Alignment.topLeft,
|
|
||||||
children: [
|
|
||||||
LinearPercentIndicator(
|
|
||||||
width: 120.0,
|
|
||||||
lineHeight: 14.0,
|
|
||||||
percent: percent,
|
|
||||||
center: Text(
|
|
||||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
|
||||||
style: new TextStyle(fontSize: 12.0),
|
|
||||||
),
|
|
||||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
|
||||||
linearStrokeCap: LinearStrokeCap.roundAll,
|
|
||||||
backgroundColor: colorAnim.value,
|
|
||||||
progressColor: Color(0xff73e600),
|
|
||||||
animation: true,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:aitrainer_app/bloc/session/session_bloc.dart';
|
import 'package:aitrainer_app/bloc/session/session_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
import 'package:aitrainer_app/bloc/settings/settings_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/view/login.dart';
|
import 'package:aitrainer_app/view/login.dart';
|
||||||
import 'package:aitrainer_app/view/menu_page.dart';
|
import 'package:aitrainer_app/view/menu_page.dart';
|
||||||
@ -13,6 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'loading.dart';
|
import 'loading.dart';
|
||||||
|
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
class AitrainerHome extends StatefulWidget {
|
class AitrainerHome extends StatefulWidget {
|
||||||
_HomePageState _state;
|
_HomePageState _state;
|
||||||
@override
|
@override
|
||||||
|
119
lib/widgets/image_button.dart
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
|
||||||
|
class ImageButton extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final TextStyle style;
|
||||||
|
final String image;
|
||||||
|
final double top;
|
||||||
|
final double height;
|
||||||
|
final double width;
|
||||||
|
final bool isShape;
|
||||||
|
final Bloc bloc;
|
||||||
|
final Alignment textAlignment;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
bool isLocked;
|
||||||
|
|
||||||
|
ImageButton({
|
||||||
|
this.text,
|
||||||
|
this.style,
|
||||||
|
this.image,
|
||||||
|
this.top,
|
||||||
|
this.height,
|
||||||
|
this.width,
|
||||||
|
this.bloc,
|
||||||
|
this.isShape,
|
||||||
|
this.textAlignment,
|
||||||
|
this.onTap,
|
||||||
|
@required this.isLocked
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
//alignment: textAlignment,
|
||||||
|
fit: StackFit.passthrough,
|
||||||
|
overflow: Overflow.clip,
|
||||||
|
children: [
|
||||||
|
FlatButton(
|
||||||
|
child: image == null ?
|
||||||
|
_getButtonImage("asset/image/WT_menu_dark.png") :
|
||||||
|
_getButtonImage(image),
|
||||||
|
padding: EdgeInsets.only(left: 0.0, bottom: 0),
|
||||||
|
shape: getShape(isShape),
|
||||||
|
onPressed: onTap ?? onTap,
|
||||||
|
),
|
||||||
|
Stack(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
children: [
|
||||||
|
this.isLocked?
|
||||||
|
Image.asset(
|
||||||
|
'asset/image/lock.png',
|
||||||
|
height: 40,
|
||||||
|
width: 40,
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
]),
|
||||||
|
Positioned(
|
||||||
|
top: top,
|
||||||
|
left: 10,
|
||||||
|
child: Container(
|
||||||
|
height: 100,
|
||||||
|
width: 150,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap ?? onTap,
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
maxLines: 2,
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
//)
|
||||||
|
// )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic getShape(bool isShape) {
|
||||||
|
dynamic returnCode = (isShape == true)
|
||||||
|
? RoundedRectangleBorder(
|
||||||
|
side: BorderSide(width: 4, color: Colors.orangeAccent),
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic _getButtonImage(String imageName) {
|
||||||
|
dynamic image;
|
||||||
|
try {
|
||||||
|
image = Image.asset(
|
||||||
|
imageName,
|
||||||
|
fit: BoxFit.fitWidth,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
errorBuilder: (context, error, stackTrace) {
|
||||||
|
String url = Cache.mediaUrl + 'images/' + imageName.substring(11);
|
||||||
|
Widget image = FadeInImage.assetNetwork(
|
||||||
|
placeholder: 'asset/image/dots.gif',
|
||||||
|
image: url,
|
||||||
|
height: 180,
|
||||||
|
);
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} on Exception catch (_) {
|
||||||
|
String url = Cache.mediaUrl + '/images/' + imageName;
|
||||||
|
image = FadeInImage.assetNetwork(
|
||||||
|
placeholder: 'asset/image/dots.gif',
|
||||||
|
image: url,
|
||||||
|
height: 180,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
113
lib/widgets/menu_info_widget.dart
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class MenuInfoWidget extends StatelessWidget with Common {
|
||||||
|
final String title;
|
||||||
|
final double titleSize;
|
||||||
|
final Color titleColor;
|
||||||
|
final FontWeight titleWeight;
|
||||||
|
final String text;
|
||||||
|
final double textSize;
|
||||||
|
final Color textColor;
|
||||||
|
final FontWeight textWeight;
|
||||||
|
final Icon leadingIcon;
|
||||||
|
final Color leadingIconColor;
|
||||||
|
final String text2;
|
||||||
|
final String text3;
|
||||||
|
final String link;
|
||||||
|
final int parentMenu;
|
||||||
|
final MenuBloc bloc;
|
||||||
|
|
||||||
|
MenuInfoWidget(
|
||||||
|
{this.title,
|
||||||
|
this.titleSize,
|
||||||
|
this.titleColor,
|
||||||
|
this.titleWeight,
|
||||||
|
@required this.text,
|
||||||
|
this.textSize,
|
||||||
|
this.textColor,
|
||||||
|
this.textWeight,
|
||||||
|
this.leadingIcon,
|
||||||
|
this.leadingIconColor,
|
||||||
|
this.text2,
|
||||||
|
this.text3,
|
||||||
|
this.link,
|
||||||
|
this.parentMenu,
|
||||||
|
this.bloc});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
int length = title.length + text2.length + text3.length + link.length;
|
||||||
|
return Container(
|
||||||
|
height: length > 100? 350 : 250,
|
||||||
|
width: 180,
|
||||||
|
padding: EdgeInsets.all(25.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(
|
||||||
|
"asset/menu/3.bcs1.png",
|
||||||
|
),
|
||||||
|
fit: BoxFit.contain),
|
||||||
|
),
|
||||||
|
child: BackdropFilter(
|
||||||
|
filter: ImageFilter.blur(sigmaX: 9, sigmaY: 9),
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(top: 10.0, left: 15, right: 10, bottom: 5),
|
||||||
|
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withOpacity(0.5),
|
||||||
|
border: Border.all(color: Colors.white60),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(10.0)),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
maxLines: 1,
|
||||||
|
style:
|
||||||
|
TextStyle(color: titleColor, fontSize: titleSize, fontFamily: 'Arial', fontWeight: titleWeight),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
Text(
|
||||||
|
text,
|
||||||
|
maxLines: 6,
|
||||||
|
style: TextStyle(color: textColor, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
Text(
|
||||||
|
text2,
|
||||||
|
maxLines: 6,
|
||||||
|
style: TextStyle(color: textColor, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight),
|
||||||
|
),
|
||||||
|
Divider(),
|
||||||
|
Text(
|
||||||
|
text3,
|
||||||
|
maxLines: 6,
|
||||||
|
style: TextStyle(color: textColor, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight),
|
||||||
|
),
|
||||||
|
getLink(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getLink() {
|
||||||
|
int missingId;
|
||||||
|
return InkWell(
|
||||||
|
child: new Text(link, style: TextStyle(color: Colors.lightBlueAccent, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight),),
|
||||||
|
onTap: () =>
|
||||||
|
{
|
||||||
|
missingId = bloc.menuTreeRepository.getMissingTreeIdByName(bloc.missingTreeName),
|
||||||
|
print("menu " + missingId.toString()),
|
||||||
|
bloc.add(MenuTreeJump(parent: missingId))
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -4,13 +4,16 @@ 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_menu_tree.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
|
import 'package:aitrainer_app/util/trans.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';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
import 'menu_info_widget.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class MenuPageWidget extends StatelessWidget {
|
class MenuPageWidget extends StatelessWidget with Trans {
|
||||||
int parent;
|
int parent;
|
||||||
|
|
||||||
MenuPageWidget({this.parent});
|
MenuPageWidget({this.parent});
|
||||||
@ -18,16 +21,37 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
|
setContext(context);
|
||||||
|
|
||||||
return CustomScrollView(
|
return CustomScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
slivers: <Widget>[buildMenuColumn(parent, context, menuBloc)]);
|
slivers: <Widget>[buildMenuColumn(parent, context, menuBloc)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SliverList buildMenuColumn(
|
SliverList buildMenuColumn(int parent, BuildContext context, MenuBloc menuBloc) {
|
||||||
int parent, BuildContext context, MenuBloc menuBloc) {
|
|
||||||
final List<Widget> _columnChildren = List();
|
final List<Widget> _columnChildren = List();
|
||||||
|
|
||||||
|
if ( context != null ) {
|
||||||
|
menuBloc.setContext(context);
|
||||||
|
menuBloc.setMenuInfo();
|
||||||
|
|
||||||
|
Widget info = MenuInfoWidget(
|
||||||
|
title: menuBloc.infoTitle,
|
||||||
|
titleSize: 18,
|
||||||
|
titleWeight: FontWeight.bold,
|
||||||
|
titleColor: Colors.orangeAccent,
|
||||||
|
text: menuBloc.infoText,
|
||||||
|
textSize: 13,
|
||||||
|
textColor: Colors.yellowAccent,
|
||||||
|
text2: menuBloc.infoText2,
|
||||||
|
text3: menuBloc.infoText3,
|
||||||
|
link: menuBloc.infoLink,
|
||||||
|
bloc: menuBloc,
|
||||||
|
);
|
||||||
|
_columnChildren.add(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
menuBloc.menuTreeRepository
|
menuBloc.menuTreeRepository
|
||||||
.getBranch(menuBloc.parent)
|
.getBranch(menuBloc.parent)
|
||||||
.forEach((treeName, value) {
|
.forEach((treeName, value) {
|
||||||
@ -86,7 +110,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
WorkoutMenuTree 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(item: workoutTree, parent: workoutTree.id));
|
||||||
} else {
|
} else {
|
||||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||||
if (Cache().userLoggedIn == null) {
|
if (Cache().userLoggedIn == null) {
|
||||||
|
68
pubspec.lock
@ -35,7 +35,7 @@ packages:
|
|||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0-nullsafety"
|
version: "2.4.2"
|
||||||
bloc:
|
bloc:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -56,7 +56,7 @@ packages:
|
|||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety"
|
version: "2.0.0"
|
||||||
build:
|
build:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -91,14 +91,14 @@ packages:
|
|||||||
name: build_runner
|
name: build_runner
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.2"
|
version: "1.10.0"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.1"
|
version: "5.2.0"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -119,14 +119,14 @@ packages:
|
|||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.2"
|
version: "1.0.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety"
|
version: "1.1.3"
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -147,7 +147,7 @@ packages:
|
|||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety"
|
version: "1.0.1"
|
||||||
code_builder:
|
code_builder:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -161,7 +161,7 @@ packages:
|
|||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0-nullsafety.2"
|
version: "1.14.13"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -224,7 +224,7 @@ packages:
|
|||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety"
|
version: "1.1.0"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -238,7 +238,7 @@ packages:
|
|||||||
name: file
|
name: file
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0-nullsafety.1"
|
version: "5.2.1"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -415,7 +415,7 @@ packages:
|
|||||||
name: js
|
name: js
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.3-nullsafety.1"
|
version: "0.6.2"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -443,14 +443,14 @@ packages:
|
|||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.10-nullsafety"
|
version: "0.12.8"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.2"
|
version: "1.1.8"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -506,7 +506,7 @@ packages:
|
|||||||
name: path
|
name: path
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety"
|
version: "1.7.0"
|
||||||
path_drawing:
|
path_drawing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -548,7 +548,7 @@ packages:
|
|||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0-nullsafety.1"
|
version: "1.9.0"
|
||||||
percent_indicator:
|
percent_indicator:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -562,14 +562,14 @@ packages:
|
|||||||
name: petitparser
|
name: petitparser
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0"
|
version: "3.0.4"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0-nullsafety.1"
|
version: "2.2.1"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -583,14 +583,14 @@ packages:
|
|||||||
name: pool
|
name: pool
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0-nullsafety.1"
|
version: "1.4.0"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0-nullsafety.1"
|
version: "3.0.13"
|
||||||
provider:
|
provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -735,21 +735,21 @@ packages:
|
|||||||
name: source_map_stack_trace
|
name: source_map_stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.2"
|
version: "2.0.0"
|
||||||
source_maps:
|
source_maps:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_maps
|
name: source_maps
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.10-nullsafety.1"
|
version: "0.10.9"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety"
|
version: "1.7.0"
|
||||||
spider_chart:
|
spider_chart:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -763,14 +763,14 @@ packages:
|
|||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0-nullsafety"
|
version: "1.9.5"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety"
|
version: "2.0.0"
|
||||||
stream_transform:
|
stream_transform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -784,7 +784,7 @@ packages:
|
|||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety"
|
version: "1.0.5"
|
||||||
sync_http:
|
sync_http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -798,28 +798,28 @@ packages:
|
|||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety"
|
version: "1.1.0"
|
||||||
test:
|
test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: test
|
name: test
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.16.0-nullsafety.4"
|
version: "1.15.2"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.19-nullsafety"
|
version: "0.2.17"
|
||||||
test_core:
|
test_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_core
|
name: test_core
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.12-nullsafety.4"
|
version: "0.3.10"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -833,7 +833,7 @@ packages:
|
|||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.2"
|
version: "1.2.0"
|
||||||
usage:
|
usage:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -854,14 +854,14 @@ packages:
|
|||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.2"
|
version: "2.0.8"
|
||||||
vm_service:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.0"
|
version: "4.2.0"
|
||||||
vm_service_client:
|
vm_service_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -910,7 +910,7 @@ packages:
|
|||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2"
|
version: "0.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -926,5 +926,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.10.0-4.0.dev <2.10.0"
|
dart: ">=2.9.0-14.0.dev <3.0.0"
|
||||||
flutter: ">=1.16.0 <2.0.0"
|
flutter: ">=1.16.0 <2.0.0"
|
||||||
|
15
pubspec.yaml
@ -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+23
|
version: 1.1.2+2
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.1.0"
|
sdk: ">=2.7.0 <3.1.0"
|
||||||
@ -24,8 +24,6 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.0
|
cupertino_icons: ^1.0.0
|
||||||
devicelocale: ^0.3.2
|
devicelocale: ^0.3.2
|
||||||
sentry: ^3.0.1
|
sentry: ^3.0.1
|
||||||
@ -94,6 +92,9 @@ flutter:
|
|||||||
- asset/image/WT_welcome.png
|
- asset/image/WT_welcome.png
|
||||||
- asset/image/login_fb.png
|
- asset/image/login_fb.png
|
||||||
- asset/image/lock.png
|
- asset/image/lock.png
|
||||||
|
- asset/image/Congrats_N1.jpg
|
||||||
|
- asset/image/development_muscles.jpg
|
||||||
|
- asset/image/exercise_log.jpg
|
||||||
- asset/menu/1.cardio.png
|
- asset/menu/1.cardio.png
|
||||||
- asset/menu/1.1.aerob.png
|
- asset/menu/1.1.aerob.png
|
||||||
- asset/menu/1.2.anaerob.png
|
- asset/menu/1.2.anaerob.png
|
||||||
@ -118,6 +119,14 @@ flutter:
|
|||||||
- asset/menu/3.1.BMI.png
|
- asset/menu/3.1.BMI.png
|
||||||
- asset/menu/3.2.BMR.png
|
- asset/menu/3.2.BMR.png
|
||||||
- asset/menu/3.3.sizes.png
|
- asset/menu/3.3.sizes.png
|
||||||
|
- asset/menu/cable triceps.png
|
||||||
|
- asset/menu/Back_pullup.png
|
||||||
|
- asset/menu/biceps.jpg
|
||||||
|
- asset/menu/calf.png
|
||||||
|
- asset/menu/legpress.jpg
|
||||||
|
- asset/menu/shoulder press.png
|
||||||
|
- asset/menu/squat.jpg
|
||||||
|
- asset/menu/tricdip.jpg
|
||||||
- i18n/en.json
|
- i18n/en.json
|
||||||
- i18n/hu.json
|
- i18n/hu.json
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
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/service/customer_service.dart';
|
import 'package:aitrainer_app/service/customer_service.dart';
|
||||||
import 'package:aitrainer_app/util/env.dart';
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
|
||||||
//import 'package:mockito/mockito.dart';
|
//import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
// Create a MockClient using the Mock class provided by the Mockito package.
|
// Create a MockClient using the Mock class provided by the Mockito package.
|
||||||
|
@ -11,8 +11,6 @@ main() {
|
|||||||
SimExercisePlanRepository _exercisePlanRepository;
|
SimExercisePlanRepository _exercisePlanRepository;
|
||||||
ExercisePlanBloc bloc;
|
ExercisePlanBloc bloc;
|
||||||
|
|
||||||
int _customerId;
|
|
||||||
|
|
||||||
Future<void> setUpPlan() async {
|
Future<void> setUpPlan() async {
|
||||||
final String planName2 = "Test Plan2";
|
final String planName2 = "Test Plan2";
|
||||||
ExercisePlan plan2 = ExercisePlan(planName2, 101);
|
ExercisePlan plan2 = ExercisePlan(planName2, 101);
|
||||||
@ -42,7 +40,6 @@ main() {
|
|||||||
WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
||||||
bloc = ExercisePlanBloc(menuTreeRepository: menuTreeRepository);
|
bloc = ExercisePlanBloc(menuTreeRepository: menuTreeRepository);
|
||||||
bloc.setExercisePlanRepository(_exercisePlanRepository);
|
bloc.setExercisePlanRepository(_exercisePlanRepository);
|
||||||
_customerId = 62;
|
|
||||||
await setUpPlan();
|
await setUpPlan();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:aitrainer_app/model/cache.dart';
|
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:mockito/mockito.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'mocks.dart';
|
import 'mocks.dart';
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
|
|||||||
return _singleton;
|
return _singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
MockExercisePlanApi._internal() {}
|
MockExercisePlanApi._internal();
|
||||||
|
|
||||||
final List<ExercisePlan> memoryExercisePlan = List();
|
final List<ExercisePlan> memoryExercisePlan = List();
|
||||||
final List<ExercisePlanDetail> memoryExercisePlanDetail = List();
|
final List<ExercisePlanDetail> memoryExercisePlanDetail = List();
|
||||||
|
@ -52,13 +52,11 @@ class MockCommon with Common {
|
|||||||
void main() {
|
void main() {
|
||||||
group('LoginScreen', () {
|
group('LoginScreen', () {
|
||||||
MockLoginBloc loginBloc;
|
MockLoginBloc loginBloc;
|
||||||
MockUserRepository userRepository;
|
|
||||||
Widget loginWidget;
|
Widget loginWidget;
|
||||||
MockCommon common;
|
MockCommon common;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
loginBloc = MockLoginBloc();
|
loginBloc = MockLoginBloc();
|
||||||
userRepository = MockUserRepository();
|
|
||||||
common = MockCommon();
|
common = MockCommon();
|
||||||
|
|
||||||
loginWidget =
|
loginWidget =
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
// Imports the Flutter Driver API.
|
// Imports the Flutter Driver API.
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|