Merge ssh://git.aitrainer.app:6622/bossanyit/aitrainer_app
This commit is contained in:
commit
4ee16c9fa6
BIN
asset/image/lock.png
Normal file
BIN
asset/image/lock.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
19
i18n/en.json
19
i18n/en.json
@ -52,6 +52,7 @@
|
||||
"Sizes": "Sizes",
|
||||
"Save Exercise": "Save Exercise of:",
|
||||
"Save": "Save",
|
||||
"Delete": "Delete",
|
||||
|
||||
"Name": "Name",
|
||||
"Exercise": "Exercise",
|
||||
@ -117,5 +118,21 @@
|
||||
"3rd Control Exercise:": "3rd Control Exercise:",
|
||||
|
||||
"My Development":"My Development",
|
||||
"My Training Plan":"My Training Plan"
|
||||
"My Training Plan":"My Training Plan",
|
||||
|
||||
"Please add an exercise plan": "Please add an exercise plan",
|
||||
"Serie": "Serie",
|
||||
"Repeats": "Repeats",
|
||||
"Save The Exercise To The Exercise Plan": "Save The Exercise To The Exercise Plan",
|
||||
"The number of the serie done with":"The number of the serie done with",
|
||||
"The number of the repeats of one serie":"The number of the repeats of one serie",
|
||||
|
||||
"1. Chest": "1. Chest",
|
||||
"2. Biceps": "2. Biceps",
|
||||
"3. Triceps": "3. Triceps",
|
||||
"4. Back": "4. Back",
|
||||
"5. Shoulders": "5. Shoulders",
|
||||
"6. Core": "6. Core",
|
||||
"7. Thigh": "7. Thigh",
|
||||
"8. Calf": "8. Calf"
|
||||
}
|
20
i18n/hu.json
20
i18n/hu.json
@ -52,6 +52,7 @@
|
||||
"Sizes": "Méretek",
|
||||
"Save Exercise": "Gyakorlat mentése:",
|
||||
"Save": "Mentés",
|
||||
"Delete": "Törlés",
|
||||
"The number of the exercise": "Írd be a gyakorlat számát",
|
||||
"The number of the exercise done with": "Írd be, mennyivel csináltad a gyakorlatot",
|
||||
|
||||
@ -116,5 +117,22 @@
|
||||
"3rd Control Exercise:": "3. kontrollgyakorlat:",
|
||||
|
||||
"My Development":"Fejlődésem",
|
||||
"My Training Plan":"Edzéstervem"
|
||||
"My Training Plan":"Edzéstervem",
|
||||
|
||||
"Please add an exercise plan": "Kérlek add meg az edzéstervet a gyakorlathoz",
|
||||
|
||||
"Serie": "Széria",
|
||||
"Repeats": "Ismétlés",
|
||||
"Save The Exercise To The Exercise Plan": "Gyakorlat mentése az edzéstervhez",
|
||||
"The number of the serie done with":"Mennyi szériát csinálsz",
|
||||
"The number of the repeats of one serie":"Hány ismétlést csinálsz egy gyakorlaton belül",
|
||||
|
||||
"1. Chest": "1. Mell",
|
||||
"2. Biceps": "2. Bicepsz",
|
||||
"3. Triceps": "3. Tricepsz",
|
||||
"4. Back": "4. Hát",
|
||||
"5. Shoulders": "5. Váll",
|
||||
"6. Core": "6. Has",
|
||||
"7. Thigh": "7. Comb",
|
||||
"8. Calf": "8. Vádli"
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
@ -16,10 +16,10 @@
|
||||
<viewControllerLayoutGuide type="bottom" id="wCe-IQ-FAo"/>
|
||||
</layoutGuides>
|
||||
<view key="view" autoresizesSubviews="NO" contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="878"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="825"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleAspectFit" ambiguous="YES" image="LaunchImage" adjustsImageSizeForAccessibilityContentSizeCategory="YES" id="YRO-k0-Ey4">
|
||||
<rect key="frame" x="-1" y="0.0" width="414" height="878"/>
|
||||
<rect key="frame" x="-26" y="-92" width="505" height="1009"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="default"/>
|
||||
</imageView>
|
||||
|
@ -3,6 +3,7 @@ import 'dart:async';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
@ -13,6 +14,7 @@ part 'account_state.dart';
|
||||
class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
final CustomerRepository customerRepository;
|
||||
bool loggedIn = false;
|
||||
int traineeId = 0;
|
||||
AccountBloc({this.customerRepository}) : super(AccountInitial()) {
|
||||
if ( Cache().userLoggedIn != null ) {
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
@ -36,8 +38,21 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
} else if (event is AccountLogout) {
|
||||
await Cache().logout();
|
||||
customerRepository.customer = null;
|
||||
customerRepository.emptyTrainees();
|
||||
loggedIn = false;
|
||||
yield AccountLoggedOut();
|
||||
} else if ( event is AccountGetTrainees) {
|
||||
yield AccountLoading();
|
||||
await customerRepository.getTrainees();
|
||||
yield AccountReady();
|
||||
} else if ( event is AccountSelectTrainee ) {
|
||||
yield AccountLoading();
|
||||
customerRepository.setTrainee(event.traineeId);
|
||||
Cache().setTrainee(customerRepository.getTraineeById(event.traineeId));
|
||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
await exerciseRepository.getExercisesByCustomer(event.traineeId);
|
||||
this.traineeId = event.traineeId;
|
||||
yield AccountReady();
|
||||
}
|
||||
} on Exception catch(e) {
|
||||
yield AccountError(message: e.toString());
|
||||
|
@ -44,3 +44,15 @@ class AccountLogInFinished extends AccountEvent {
|
||||
@override
|
||||
List<Object> get props => [customer];
|
||||
}
|
||||
|
||||
class AccountGetTrainees extends AccountEvent {
|
||||
const AccountGetTrainees();
|
||||
}
|
||||
|
||||
class AccountSelectTrainee extends AccountEvent {
|
||||
final int traineeId;
|
||||
const AccountSelectTrainee({this.traineeId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [traineeId];
|
||||
}
|
81
lib/bloc/exercise_add_by_plan_bloc.dart
Normal file
81
lib/bloc/exercise_add_by_plan_bloc.dart
Normal file
@ -0,0 +1,81 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class ExerciseAddByPlanFormBloc extends FormBloc<String, String> {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository;
|
||||
final WorkoutTree workoutTree;
|
||||
final customerId;
|
||||
Customer customer;
|
||||
int step = 1;
|
||||
int countSteps = 1;
|
||||
|
||||
final quantity1Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final unitQuantity1Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
ExerciseAddByPlanFormBloc({this.exerciseRepository, this.exercisePlanRepository, this.customerId, this.workoutTree}) {
|
||||
addFieldBlocs(fieldBlocs: [
|
||||
quantity1Field,
|
||||
unitQuantity1Field,
|
||||
]);
|
||||
|
||||
quantity1Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setQuantity(current.valueToDouble);
|
||||
});
|
||||
|
||||
unitQuantity1Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
|
||||
});
|
||||
|
||||
exerciseRepository.exerciseType = workoutTree.exerciseType;
|
||||
if ( Cache().userLoggedIn.customerId == customerId) {
|
||||
customer = Cache().userLoggedIn;
|
||||
} else if ( Cache().getTrainee().customerId == customerId) {
|
||||
customer = Cache().getTrainee();
|
||||
}
|
||||
exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
exerciseRepository.customer = customer;
|
||||
countSteps = exercisePlanRepository.actualPlanDetail.serie;
|
||||
|
||||
unitQuantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.weightEquation);
|
||||
quantity1Field.updateInitialValue(exercisePlanRepository.actualPlanDetail.repeats.toString());
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
void onSubmitting() async {
|
||||
|
||||
try {
|
||||
emitLoading(progress: 30);
|
||||
step++;
|
||||
|
||||
exerciseRepository.setUnitQuantity(unitQuantity1Field.valueToDouble);
|
||||
exerciseRepository.setQuantity(quantity1Field.valueToDouble);
|
||||
exerciseRepository.exercise.exercisePlanDetailId =
|
||||
exercisePlanRepository.actualPlanDetail.exercisePlanDetailId;
|
||||
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
|
||||
workoutTree.executed = true;
|
||||
print("On Submitting Add Exercise By Plan " + exerciseRepository.exercise.toJson().toString());
|
||||
await exerciseRepository.addExercise();
|
||||
|
||||
emitSuccess(canSubmitAgain: true);
|
||||
} on Exception catch (ex) {
|
||||
emitFailure(failureResponse: ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//@override
|
||||
Future<void> close() {
|
||||
quantity1Field.close();
|
||||
unitQuantity1Field.close();
|
||||
|
||||
return super.close();
|
||||
}
|
||||
}
|
58
lib/bloc/exercise_by_plan/exercise_by_plan_bloc.dart
Normal file
58
lib/bloc/exercise_by_plan/exercise_by_plan_bloc.dart
Normal file
@ -0,0 +1,58 @@
|
||||
import 'dart:async';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'exercise_by_plan_event.dart';
|
||||
|
||||
part 'exercise_by_plan_state.dart';
|
||||
|
||||
class ExerciseByPlanBloc extends Bloc<ExerciseByPlanEvent, ExerciseByPlanState> {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final MenuTreeRepository menuTreeRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||
int customerId;
|
||||
@override
|
||||
ExerciseByPlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
|
||||
|
||||
Future<void> getData() async {
|
||||
exercisePlanRepository.setCustomerId(customerId);
|
||||
await exercisePlanRepository.getLastExercisePlan();
|
||||
await exercisePlanRepository.getExercisePlanDetails();
|
||||
menuTreeRepository.sortedTree = null;
|
||||
menuTreeRepository.sortByMuscleType();
|
||||
|
||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listWorkoutTree = value;
|
||||
listWorkoutTree.forEach((workoutTree) {
|
||||
workoutTree.selected = false;
|
||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<ExerciseByPlanState> mapEventToState(ExerciseByPlanEvent event) async* {
|
||||
try {
|
||||
if (event is ExerciseByPlanLoad) {
|
||||
yield ExerciseByPlanLoading();
|
||||
await this.getData();
|
||||
yield ExerciseByPlanReady();
|
||||
} else if (event is AddExerciseByPlanEvent) {
|
||||
yield ExerciseByPlanLoading();
|
||||
yield ExerciseByPlanReady();
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield ExerciseByPlanError(message: e.toString());
|
||||
}
|
||||
}
|
||||
}
|
21
lib/bloc/exercise_by_plan/exercise_by_plan_event.dart
Normal file
21
lib/bloc/exercise_by_plan/exercise_by_plan_event.dart
Normal file
@ -0,0 +1,21 @@
|
||||
part of 'exercise_by_plan_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ExerciseByPlanEvent extends Equatable {
|
||||
const ExerciseByPlanEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class AddExerciseByPlanEvent extends ExerciseByPlanEvent {
|
||||
final ExerciseType exerciseType;
|
||||
const AddExerciseByPlanEvent({this.exerciseType});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exerciseType];
|
||||
}
|
||||
|
||||
class ExerciseByPlanLoad extends ExerciseByPlanEvent {
|
||||
const ExerciseByPlanLoad();
|
||||
}
|
31
lib/bloc/exercise_by_plan/exercise_by_plan_state.dart
Normal file
31
lib/bloc/exercise_by_plan/exercise_by_plan_state.dart
Normal file
@ -0,0 +1,31 @@
|
||||
part of 'exercise_by_plan_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ExerciseByPlanState extends Equatable {
|
||||
const ExerciseByPlanState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class ExerciseByPlanStateInitial extends ExerciseByPlanState {
|
||||
const ExerciseByPlanStateInitial();
|
||||
}
|
||||
|
||||
class ExerciseByPlanLoading extends ExerciseByPlanState {
|
||||
const ExerciseByPlanLoading();
|
||||
}
|
||||
|
||||
// updated screen
|
||||
class ExerciseByPlanReady extends ExerciseByPlanState {
|
||||
const ExerciseByPlanReady();
|
||||
}
|
||||
|
||||
// error splash screen
|
||||
class ExerciseByPlanError extends ExerciseByPlanState {
|
||||
final String message;
|
||||
const ExerciseByPlanError({this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
89
lib/bloc/exercise_plan/exercise_plan_bloc.dart
Normal file
89
lib/bloc/exercise_plan/exercise_plan_bloc.dart
Normal file
@ -0,0 +1,89 @@
|
||||
import 'dart:async';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'exercise_plan_event.dart';
|
||||
|
||||
part 'exercise_plan_state.dart';
|
||||
|
||||
class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
|
||||
final MenuTreeRepository menuTreeRepository;
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
|
||||
int customerId;
|
||||
|
||||
ExercisePlanBloc({this.exerciseRepository, this.menuTreeRepository}) : super(ExercisePlanInitial());
|
||||
|
||||
Future<void> getData() async {
|
||||
exercisePlanRepository.setCustomerId(customerId);
|
||||
await exercisePlanRepository.getLastExercisePlan();
|
||||
await exercisePlanRepository.getExercisePlanDetails();
|
||||
menuTreeRepository.sortedTree = null;
|
||||
menuTreeRepository.sortByMuscleType();
|
||||
|
||||
menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listWorkoutTree = value;
|
||||
listWorkoutTree.forEach((workoutTree) {
|
||||
workoutTree.selected = false;
|
||||
if (exercisePlanRepository.exercisePlanDetails.length > 0) {
|
||||
if (exercisePlanRepository.exercisePlanDetails[workoutTree.exerciseTypeId] != null) {
|
||||
//print("bingo");
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
|
||||
try {
|
||||
if (event is ExercisePlanLoad) {
|
||||
yield ExercisePlanLoading();
|
||||
await this.getData();
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
if (event is ExercisePlanUpdate) {
|
||||
yield ExercisePlanLoading();
|
||||
WorkoutTree workoutTree = event.workoutTree;
|
||||
if (workoutTree != null) {
|
||||
exercisePlanRepository.addExerciseTypeToPlan(workoutTree.exerciseType);
|
||||
workoutTree.selected = true;
|
||||
}
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanRemoveExercise) {
|
||||
yield ExercisePlanLoading();
|
||||
ExercisePlanDetail planDetail = event.exercisePlanDetail;
|
||||
exercisePlanRepository.removeExerciseTypeFromPlan(planDetail.exerciseType);
|
||||
this.menuTreeRepository.sortedTree.forEach((key, value) {
|
||||
List<WorkoutTree> listTreeItem = value;
|
||||
listTreeItem.forEach((element) {
|
||||
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
|
||||
element.selected = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanUpdateExercise) {
|
||||
yield ExercisePlanReady();
|
||||
} else if (event is ExercisePlanSave) {
|
||||
if (exercisePlanRepository.getExercisePlanDetailSize() == 0) {
|
||||
throw Exception("Please select an exercise");
|
||||
} else {
|
||||
yield ExercisePlanLoading();
|
||||
exercisePlanRepository.saveExercisePlan();
|
||||
yield ExercisePlanReady();
|
||||
}
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield ExercisePlanError(message: e.toString());
|
||||
}
|
||||
}
|
||||
}
|
49
lib/bloc/exercise_plan/exercise_plan_event.dart
Normal file
49
lib/bloc/exercise_plan/exercise_plan_event.dart
Normal file
@ -0,0 +1,49 @@
|
||||
part of 'exercise_plan_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ExercisePlanEvent extends Equatable {
|
||||
const ExercisePlanEvent();
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class ExercisePlanLoad extends ExercisePlanEvent {
|
||||
const ExercisePlanLoad();
|
||||
}
|
||||
|
||||
class ExercisePlanUpdate extends ExercisePlanEvent {
|
||||
final WorkoutTree workoutTree;
|
||||
const ExercisePlanUpdate({this.workoutTree});
|
||||
|
||||
@override
|
||||
List<Object> get props => [workoutTree];
|
||||
}
|
||||
|
||||
class ExercisePlanAddExercise extends ExercisePlanEvent {
|
||||
final ExerciseType exerciseType;
|
||||
const ExercisePlanAddExercise({this.exerciseType});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exerciseType];
|
||||
}
|
||||
|
||||
class ExercisePlanRemoveExercise extends ExercisePlanEvent {
|
||||
final ExercisePlanDetail exercisePlanDetail;
|
||||
const ExercisePlanRemoveExercise({this.exercisePlanDetail});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exercisePlanDetail];
|
||||
}
|
||||
|
||||
class ExercisePlanUpdateExercise extends ExercisePlanEvent {
|
||||
final ExercisePlanDetail exercisePlanDetail;
|
||||
const ExercisePlanUpdateExercise({this.exercisePlanDetail});
|
||||
|
||||
@override
|
||||
List<Object> get props => [exercisePlanDetail];
|
||||
}
|
||||
|
||||
class ExercisePlanSave extends ExercisePlanEvent {
|
||||
const ExercisePlanSave();
|
||||
}
|
||||
|
37
lib/bloc/exercise_plan/exercise_plan_state.dart
Normal file
37
lib/bloc/exercise_plan/exercise_plan_state.dart
Normal file
@ -0,0 +1,37 @@
|
||||
part of 'exercise_plan_bloc.dart';
|
||||
|
||||
@immutable
|
||||
abstract class ExercisePlanState extends Equatable{
|
||||
const ExercisePlanState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
// Display the last saved exercise plan
|
||||
class ExercisePlanInitial extends ExercisePlanState {
|
||||
const ExercisePlanInitial();
|
||||
}
|
||||
|
||||
// Loading screen
|
||||
class ExercisePlanLoading extends ExercisePlanState {
|
||||
const ExercisePlanLoading();
|
||||
}
|
||||
|
||||
// updated screen
|
||||
class ExercisePlanReady extends ExercisePlanState {
|
||||
const ExercisePlanReady();
|
||||
}
|
||||
|
||||
// error splash screen
|
||||
class ExercisePlanError extends ExercisePlanState {
|
||||
final String message;
|
||||
const ExercisePlanError({this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
94
lib/bloc/exercise_plan_custom_form.dart
Normal file
94
lib/bloc/exercise_plan_custom_form.dart
Normal file
@ -0,0 +1,94 @@
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class ExercisePlanCustomerFormBloc extends FormBloc<String, String> {
|
||||
final ExercisePlanRepository exercisePlanRepository;
|
||||
final ExercisePlanBloc planBloc;
|
||||
final serieField = TextFieldBloc(
|
||||
validators: [
|
||||
FieldBlocValidators.required,
|
||||
],
|
||||
);
|
||||
|
||||
final quantityField = TextFieldBloc(
|
||||
validators: [
|
||||
FieldBlocValidators.required,
|
||||
],
|
||||
);
|
||||
|
||||
final weightField = TextFieldBloc(
|
||||
validators: [
|
||||
FieldBlocValidators.required,
|
||||
],
|
||||
);
|
||||
|
||||
final exerciseTypeField = TextFieldBloc(
|
||||
validators: [
|
||||
FieldBlocValidators.required,
|
||||
],
|
||||
);
|
||||
|
||||
ExercisePlanCustomerFormBloc({this.exercisePlanRepository, this.planBloc}) {
|
||||
addFieldBlocs(fieldBlocs: [
|
||||
quantityField,
|
||||
serieField,
|
||||
weightField
|
||||
]);
|
||||
|
||||
String repeatsInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.repeats != null ?
|
||||
exercisePlanRepository.actualPlanDetail.repeats.toString() : "12";
|
||||
quantityField.updateInitialValue(repeatsInitial);
|
||||
|
||||
String serieInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.serie != null ?
|
||||
exercisePlanRepository.actualPlanDetail.serie.toString() : "3";
|
||||
serieField.updateInitialValue(serieInitial);
|
||||
|
||||
String weightInitial = exercisePlanRepository.actualPlanDetail != null &&
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation != null ?
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation : "30";
|
||||
weightField.updateInitialValue(weightInitial);
|
||||
|
||||
quantityField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.repeats = current.valueToInt;
|
||||
});
|
||||
serieField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.serie = current.valueToInt;
|
||||
});
|
||||
weightField.onValueChanges(onData: (previous, current) async* {
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation = current.value;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onSubmitting() async {
|
||||
print("On Submitting Custom Plan form");
|
||||
try {
|
||||
emitLoading(progress: 30);
|
||||
// Emit either Loaded or Error
|
||||
|
||||
exercisePlanRepository.actualPlanDetail.repeats = quantityField.valueToInt;
|
||||
exercisePlanRepository.actualPlanDetail.serie = serieField.valueToInt;
|
||||
exercisePlanRepository.actualPlanDetail.weightEquation = weightField.value;
|
||||
|
||||
exercisePlanRepository.addToPlan();
|
||||
planBloc.add(ExercisePlanUpdate());
|
||||
|
||||
emitSuccess(canSubmitAgain: false);
|
||||
} on Exception catch (ex) {
|
||||
emitFailure(failureResponse: ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//@override
|
||||
Future<void> close() {
|
||||
quantityField.close();
|
||||
serieField.close();
|
||||
weightField.close();
|
||||
exerciseTypeField.close();
|
||||
return super.close();
|
||||
}
|
||||
}
|
@ -34,6 +34,10 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
||||
yield SettingsLoading();
|
||||
await _changeLang( event.language);
|
||||
yield SettingsReady(_locale);
|
||||
} else if ( event is SettingsGetLanguage) {
|
||||
await AppLanguage().fetchLocale();
|
||||
_locale = AppLanguage().appLocal;
|
||||
yield SettingsReady(_locale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,12 +54,13 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
|
||||
break;
|
||||
}
|
||||
this.language = lang;
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
appLanguage.changeLanguage(_locale);
|
||||
await loadLang();
|
||||
}
|
||||
|
||||
Future<void> loadLang() async{
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
appLanguage.changeLanguage(_locale);
|
||||
print (" -- Loading lang $_locale");
|
||||
if ( context != null ) {
|
||||
AppLocalizations.of(context).setLocale(_locale);
|
||||
await AppLocalizations.of(context).load();
|
||||
|
@ -11,3 +11,7 @@ class SettingsChangeLanguage extends SettingsEvent {
|
||||
final String language;
|
||||
const SettingsChangeLanguage({this.language});
|
||||
}
|
||||
|
||||
class SettingsGetLanguage extends SettingsEvent {
|
||||
const SettingsGetLanguage();
|
||||
}
|
||||
|
@ -20,19 +20,24 @@ class AppLanguage{
|
||||
|
||||
Future<void> fetchLocale() async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
if (prefs.getString('language_code') == null) {
|
||||
String langCode = prefs.getString('language_code');
|
||||
print(" ---- lang code $langCode");
|
||||
if ( langCode == null) {
|
||||
_appLocale = Locale('en');
|
||||
} else {
|
||||
_appLocale = Locale(prefs.getString('language_code'));
|
||||
_appLocale = Locale(langCode);
|
||||
}
|
||||
print(" ---- Fetched lang: " + _appLocale.toString());
|
||||
}
|
||||
|
||||
getLocale(SharedPreferences prefs) {
|
||||
if (prefs.getString('language_code') == null) {
|
||||
String langCode = prefs.getString('language_code');
|
||||
if ( langCode == null) {
|
||||
_appLocale = Locale('en');
|
||||
}
|
||||
_appLocale = Locale(prefs.getString('language_code'));
|
||||
_appLocale = Locale(langCode);
|
||||
print(" ---- Get lang: " + _appLocale.toString() + " lang code $langCode");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@ class AppLocalizations {
|
||||
|
||||
Future<bool> load() async {
|
||||
// Load the language JSON file from the "lang" folder
|
||||
print(" -- load language pieces " + locale.languageCode);
|
||||
String jsonString =
|
||||
await rootBundle.loadString('i18n/${locale.languageCode}.json');
|
||||
Map<String, dynamic> jsonMap = json.decode(jsonString);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
||||
import 'package:aitrainer_app/util/session.dart';
|
||||
import 'package:aitrainer_app/view/account.dart';
|
||||
@ -9,13 +10,19 @@ import 'package:aitrainer_app/view/customer_fitness_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_goal_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_modify_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_welcome_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_add_by_plan_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_control_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_execute_by_plan_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_log_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_plan_custom_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_plan_detail_add_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_type_description.dart';
|
||||
import 'package:aitrainer_app/view/gdpr.dart';
|
||||
import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/view/mydevelopment_page.dart';
|
||||
import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
|
||||
import 'package:aitrainer_app/view/registration.dart';
|
||||
import 'package:aitrainer_app/view/settings.dart';
|
||||
import 'package:aitrainer_app/widgets/home.dart';
|
||||
@ -27,6 +34,8 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:sentry/sentry.dart';
|
||||
import 'bloc/account/account_bloc.dart';
|
||||
import 'bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'bloc/menu/menu_bloc.dart';
|
||||
import 'bloc/session/session_bloc.dart';
|
||||
import 'bloc/settings/settings_bloc.dart';
|
||||
@ -96,14 +105,15 @@ Future<Null> main() async {
|
||||
// - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
|
||||
// - https://www.dartlang.org/articles/libraries/zones
|
||||
runZonedGuarded<Future<Null>>(() async {
|
||||
final MenuTreeRepository menuTreeRepository = MenuTreeRepository();
|
||||
runApp(
|
||||
MultiBlocProvider(
|
||||
providers: [
|
||||
providers: [
|
||||
BlocProvider<SessionBloc>(
|
||||
create: (BuildContext context) => SessionBloc(session: Session()),
|
||||
),
|
||||
BlocProvider<MenuBloc>(
|
||||
create: (BuildContext context) => MenuBloc( menuTreeRepository: MenuTreeRepository()),
|
||||
create: (BuildContext context) => MenuBloc( menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<SettingsBloc>(
|
||||
create: (BuildContext context) => SettingsBloc(),
|
||||
@ -111,6 +121,12 @@ Future<Null> main() async {
|
||||
BlocProvider<AccountBloc>(
|
||||
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
|
||||
),
|
||||
BlocProvider<ExercisePlanBloc>(
|
||||
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<ExerciseByPlanBloc>(
|
||||
create: (BuildContext context) => ExerciseByPlanBloc(menuTreeRepository: menuTreeRepository, exerciseRepository: ExerciseRepository()),
|
||||
),
|
||||
],
|
||||
|
||||
child: AitrainerApp(),
|
||||
@ -172,10 +188,16 @@ class AitrainerApp extends StatelessWidget {
|
||||
'account': (context) => AccountPage(),
|
||||
'settings': (context) => SettingsPage(),
|
||||
'exerciseTypeDescription': (context) => ExerciseTypeDescription(),
|
||||
'mydevelopment': (context) => MyDevelopmentPage(),
|
||||
'myDevelopment': (context) => MyDevelopmentPage(),
|
||||
'myExercisePlan': (context) => MyExercisePlanPage(),
|
||||
'exerciseLogPage': (context) => ExerciseLogPage(),
|
||||
'exercisePlanCustomPage': (context) => ExercisePlanCustomPage(),
|
||||
'exercisePlanDetailAdd': (context) => ExercisePlanDetailAddPage(),
|
||||
'exerciseByPlanPage': (context) => ExerciseByPlanPage(),
|
||||
'exerciseAddByPlanPage': (context) => ExerciseAddByPlanPage(),
|
||||
},
|
||||
initialRoute: 'home',
|
||||
title: 'Aitrainer',
|
||||
title: 'WorkoutTest',
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.light,
|
||||
//primarySwatch: Colors.transparent,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
@ -55,10 +56,19 @@ class Cache {
|
||||
|
||||
List<ExerciseType> _exerciseTypes;
|
||||
List<ExerciseTree> _exerciseTree;
|
||||
|
||||
List<Exercise> _exercises;
|
||||
ExercisePlan _myExercisePlan;
|
||||
List<ExercisePlanDetail> _myExercisesPlanDetail;
|
||||
|
||||
LinkedHashMap _tree = LinkedHashMap<String, WorkoutTree>();
|
||||
double _percentExercises = -1;
|
||||
|
||||
Customer _trainee;
|
||||
List<Exercise> _exercisesTrainee;
|
||||
ExercisePlan _traineeExercisePlan;
|
||||
List<ExercisePlanDetail> _traineeExercisesPlanDetail;
|
||||
|
||||
List deviceLanguages;
|
||||
String startPage;
|
||||
|
||||
@ -73,6 +83,10 @@ class Cache {
|
||||
}
|
||||
}
|
||||
|
||||
void setTestBaseUrl() {
|
||||
baseUrl = 'http://aitrainer.app:8899/api/';
|
||||
}
|
||||
|
||||
String getAuthToken() {
|
||||
return this.authToken;
|
||||
}
|
||||
@ -106,6 +120,12 @@ class Cache {
|
||||
logout() async {
|
||||
userLoggedIn = null;
|
||||
authToken = "";
|
||||
_trainee = null;
|
||||
_percentExercises = -1;
|
||||
_exercisesTrainee = null;
|
||||
_traineeExercisePlan = null;
|
||||
_exercises = List();
|
||||
print("Trainees is null? " + (_trainee == null).toString() );
|
||||
//firstLoad = true;
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
await setPreferences(prefs, SharePrefsChange.logout, 0);
|
||||
@ -154,6 +174,10 @@ class Cache {
|
||||
this._exercises = exercises;
|
||||
}
|
||||
|
||||
void setExercisesTrainee( List<Exercise> exercises ) {
|
||||
this._exercisesTrainee = exercises;
|
||||
}
|
||||
|
||||
void setWorkoutTree( LinkedHashMap<String, WorkoutTree> tree) {
|
||||
this._tree = tree;
|
||||
}
|
||||
@ -170,6 +194,10 @@ class Cache {
|
||||
return this._exercises;
|
||||
}
|
||||
|
||||
List<Exercise> getExercisesTrainee() {
|
||||
return this._exercisesTrainee;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, WorkoutTree> getWorkoutTree() {
|
||||
return this._tree;
|
||||
}
|
||||
@ -186,4 +214,20 @@ class Cache {
|
||||
_exercises.add(exercise);
|
||||
}
|
||||
|
||||
void addExerciseTrainee(Exercise exercise) {
|
||||
_exercisesTrainee.add(exercise);
|
||||
}
|
||||
|
||||
Customer getTrainee() {
|
||||
return this._trainee;
|
||||
}
|
||||
|
||||
void setTrainee(Customer trainee) {
|
||||
this._trainee = trainee;
|
||||
}
|
||||
|
||||
void setTraineeExercisePlan(ExercisePlan exercisePlan) {
|
||||
this._traineeExercisePlan = exercisePlan;
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@ class Customer {
|
||||
String fitnessLevel;
|
||||
String bodyType;
|
||||
int admin;
|
||||
int trainer;
|
||||
int dataPolicyAllowed;
|
||||
|
||||
|
||||
@ -30,6 +31,7 @@ class Customer {
|
||||
this.goal,
|
||||
this.weight,
|
||||
this.admin,
|
||||
this.trainer,
|
||||
this.dataPolicyAllowed
|
||||
});
|
||||
|
||||
@ -47,6 +49,7 @@ class Customer {
|
||||
this.goal = json['goal'];
|
||||
this.weight = json['weight'];
|
||||
this.admin = json['admin'];
|
||||
this.trainer = json['trainer'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
@ -64,6 +67,7 @@ class Customer {
|
||||
"goal": goal,
|
||||
"weight": weight,
|
||||
"admin": admin,
|
||||
"trainer": trainer,
|
||||
"dataPolicyAllowed": dataPolicyAllowed,
|
||||
};
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ class Exercise {
|
||||
String unit;
|
||||
double unitQuantity;
|
||||
DateTime dateAdd;
|
||||
int exercisePlanDetailId;
|
||||
|
||||
|
||||
|
||||
@ -30,5 +31,6 @@ class Exercise {
|
||||
"unit": unit,
|
||||
"unitQuantity": unitQuantity,
|
||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
|
||||
"exercisePlanDetailId": exercisePlanDetailId,
|
||||
};
|
||||
}
|
58
lib/model/exercise_plan.dart
Normal file
58
lib/model/exercise_plan.dart
Normal file
@ -0,0 +1,58 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class ExercisePlan {
|
||||
int exercisePlanId;
|
||||
int customerId;
|
||||
String name;
|
||||
String description;
|
||||
bool private;
|
||||
DateTime dateAdd;
|
||||
DateTime dateUpd;
|
||||
|
||||
ExercisePlan(String name, int customerId) {
|
||||
this.customerId = customerId;
|
||||
this.name = name;
|
||||
this.dateUpd = DateTime.now();
|
||||
}
|
||||
|
||||
ExercisePlan.fromJson(Map json) {
|
||||
this.exercisePlanId = json['exercisePlanId'];
|
||||
this.customerId = json['customerId'];
|
||||
this.name = json['name'];
|
||||
this.private = json['private'];
|
||||
this.description = json['description'];
|
||||
this.dateAdd = json['dateAdd'] == null ? null : DateTime.parse( json['dateAdd'] );
|
||||
this.dateUpd = json['dateUpd'] == null ? null : DateTime.parse( json['dateUpd'] );
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
String formattedDateAdd;
|
||||
if ( dateAdd != null) {
|
||||
formattedDateAdd = DateFormat('yyyy-MM-dd HH:mm').format(dateAdd);
|
||||
}
|
||||
String formattedDateUpd = DateFormat('yyyy-MM-dd HH:mm').format(dateUpd);
|
||||
|
||||
print("DateAdd $formattedDateAdd");
|
||||
if ( exercisePlanId == null ) {
|
||||
return {
|
||||
"customerId": customerId,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"private": private,
|
||||
"dateAdd": formattedDateAdd,
|
||||
"dateUpd": formattedDateUpd,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
"exercisePlanId": exercisePlanId,
|
||||
"customerId": customerId,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"private": private,
|
||||
"dateAdd": formattedDateAdd,
|
||||
"dateUpd": formattedDateUpd,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
lib/model/exercise_plan_detail.dart
Normal file
36
lib/model/exercise_plan_detail.dart
Normal file
@ -0,0 +1,36 @@
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
|
||||
import 'exercise_type.dart';
|
||||
|
||||
class ExercisePlanDetail {
|
||||
int exercisePlanDetailId;
|
||||
int exercisePlanId;
|
||||
int exerciseTypeId;
|
||||
int serie;
|
||||
int repeats;
|
||||
String weightEquation;
|
||||
|
||||
ExerciseType exerciseType;
|
||||
|
||||
ExercisePlanDetail(int exerciseTypeId) {
|
||||
this.exerciseTypeId = exerciseTypeId;
|
||||
}
|
||||
|
||||
ExercisePlanDetail.fromJson(Map json) {
|
||||
this.exercisePlanDetailId = json['exercisePlanDetailId'];
|
||||
this.exercisePlanId = json['exercisePlanId'];
|
||||
this.exerciseTypeId = json['exerciseTypeId'];
|
||||
this.serie = json['serie'];
|
||||
this.repeats = json['repeats'];
|
||||
this.weightEquation = json['weightEquation'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
"exercisePlanId": exercisePlanId,
|
||||
"exerciseTypeId": exerciseTypeId,
|
||||
"serie": serie,
|
||||
"repeats": repeats,
|
||||
"weightEquation": weightEquation
|
||||
};
|
||||
}
|
@ -5,7 +5,7 @@ import 'exercise_type.dart';
|
||||
class WorkoutTree {
|
||||
int id;
|
||||
int parent;
|
||||
String name; // is also the key
|
||||
String name;
|
||||
String imageName;
|
||||
Color color;
|
||||
double fontSize;
|
||||
@ -15,7 +15,26 @@ class WorkoutTree {
|
||||
bool base;
|
||||
|
||||
bool is1RM;
|
||||
bool selected = false;
|
||||
bool executed = false;
|
||||
String exerciseDetail;
|
||||
String nameEnglish;
|
||||
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, this.exerciseType, this.base, this.is1RM);
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child,
|
||||
this.exerciseTypeId, this.exerciseType, this.base, this.is1RM, this.nameEnglish);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"id": id,
|
||||
"parent": parent,
|
||||
"name": name,
|
||||
"imageName": imageName,
|
||||
"color": color.toString(),
|
||||
"fontSize": fontSize.toString(),
|
||||
"child": child.toString(),
|
||||
"exerciseTypeId": exerciseTypeId.toString(),
|
||||
"base": base.toString(),
|
||||
"is1RM": is1RM.toString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
|
||||
@ -9,6 +10,9 @@ class GenderItem {
|
||||
|
||||
class CustomerRepository {
|
||||
Customer customer;
|
||||
Customer _trainee;
|
||||
List<Customer> _trainees;
|
||||
|
||||
//List<CustomerRepository> customerList = List<CustomerRepository>();
|
||||
bool visibleDetails = false;
|
||||
List<GenderItem> genders;
|
||||
@ -131,13 +135,53 @@ class CustomerRepository {
|
||||
await CustomerApi().saveCustomer(modelCustomer);
|
||||
}
|
||||
|
||||
/* Future<List<CustomerRepository>> getCustomers() async {
|
||||
final results = await CustomerApi().getRealCustomers("");
|
||||
this.customerList = results.map((item) => CustomerRepository(customer: item)).toList();
|
||||
return this.customerList;
|
||||
Future<Customer> getTraineeAsCustomer() async {
|
||||
this._trainee = await CustomerApi().getTrainee(
|
||||
Cache().userLoggedIn.customerId
|
||||
);
|
||||
return _trainee;
|
||||
}
|
||||
|
||||
addNewCustomerToList(CustomerRepository customerViewModel) {
|
||||
customerList.add(customerViewModel);
|
||||
}*/
|
||||
Future<List<Customer>> getTrainees() async {
|
||||
int trainerId = Cache().userLoggedIn.customerId;
|
||||
final results = await CustomerApi().getTrainees(trainerId);
|
||||
this._trainees = results;
|
||||
return results;
|
||||
}
|
||||
|
||||
List<Customer> getTraineesList() {
|
||||
return _trainees;
|
||||
}
|
||||
|
||||
void setTrainee(int traineeId ) {
|
||||
if ( _trainees == null ) {
|
||||
return;
|
||||
}
|
||||
_trainees.forEach((element) {
|
||||
if ( traineeId == element.customerId) {
|
||||
this._trainee = element;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void emptyTrainees() {
|
||||
_trainees = null;
|
||||
_trainee = null;
|
||||
}
|
||||
|
||||
Customer getTrainee() {
|
||||
return this._trainee;
|
||||
}
|
||||
|
||||
Customer getTraineeById(int customerId) {
|
||||
if (_trainees == null) {
|
||||
return null;
|
||||
}
|
||||
_trainees.forEach((element) {
|
||||
if ( customerId == element.customerId) {
|
||||
this._trainee = element;
|
||||
}
|
||||
});
|
||||
return _trainee;
|
||||
}
|
||||
}
|
||||
|
167
lib/repository/exercise_plan_repository.dart
Normal file
167
lib/repository/exercise_plan_repository.dart
Normal file
@ -0,0 +1,167 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
||||
|
||||
class ExercisePlanRepository {
|
||||
bool newPlan = true;
|
||||
ExercisePlan _exercisePlan;
|
||||
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails =
|
||||
LinkedHashMap<int, ExercisePlanDetail>();
|
||||
LinkedHashMap<int, ExercisePlanDetail> _origExercisePlanDetails =
|
||||
LinkedHashMap<int, ExercisePlanDetail>();
|
||||
int _customerId = 0;
|
||||
ExercisePlanDetail actualPlanDetail;
|
||||
|
||||
void setCustomerId( int customerId ) {
|
||||
this._customerId = customerId;
|
||||
}
|
||||
|
||||
int getCustomerId() {
|
||||
return this._customerId;
|
||||
}
|
||||
|
||||
void addExerciseTypeToPlan(ExerciseType exerciseType) {
|
||||
setActualPlanDetail(exerciseType);
|
||||
}
|
||||
|
||||
void addToPlan() {
|
||||
exercisePlanDetails[actualPlanDetail.exerciseTypeId] = actualPlanDetail;
|
||||
}
|
||||
|
||||
void setActualPlanDetail(ExerciseType exerciseType) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseType.exerciseTypeId];
|
||||
if ( detail != null ) {
|
||||
actualPlanDetail = detail;
|
||||
} else {
|
||||
actualPlanDetail = ExercisePlanDetail(exerciseType.exerciseTypeId);
|
||||
}
|
||||
actualPlanDetail.exerciseType = exerciseType;
|
||||
}
|
||||
|
||||
int getPlanDetailId(int exerciseTypeId) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
||||
return detail.exercisePlanDetailId;
|
||||
}
|
||||
|
||||
String getPlanDetail(int exerciseTypeId) {
|
||||
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
|
||||
String detailString = "";
|
||||
if ( detail != null) {
|
||||
detailString =
|
||||
detail.serie.toString() + "x" + detail.repeats.toString() + " " +
|
||||
detail.weightEquation + "kg";
|
||||
}
|
||||
return detailString;
|
||||
}
|
||||
|
||||
int getExercisePlanDetailSize() {
|
||||
return exercisePlanDetails.length;
|
||||
}
|
||||
|
||||
void updateExercisePlanDetail(ExerciseType exerciseType, int serie, int repeat, String weight) {
|
||||
if ( exercisePlanDetails[exerciseType.exerciseTypeId] == null) {
|
||||
return;
|
||||
}
|
||||
ExercisePlanDetail exercisePlanDetail = exercisePlanDetails[exerciseType.exerciseTypeId];
|
||||
exercisePlanDetail.serie = serie;
|
||||
exercisePlanDetail.repeats = repeat;
|
||||
exercisePlanDetail.weightEquation = weight;
|
||||
|
||||
exercisePlanDetails[exerciseType.exerciseTypeId] = exercisePlanDetail;
|
||||
}
|
||||
|
||||
void removeExerciseTypeFromPlan(ExerciseType exerciseType) {
|
||||
exercisePlanDetails.remove(exerciseType.exerciseTypeId);
|
||||
}
|
||||
|
||||
Future<void> saveExercisePlan() async {
|
||||
|
||||
if ( _exercisePlan == null ) {
|
||||
if ( Cache().userLoggedIn == null ) {
|
||||
throw Exception("please log in");
|
||||
}
|
||||
|
||||
String exercisePlanName;
|
||||
if ( this._customerId == Cache().userLoggedIn.customerId) {
|
||||
exercisePlanName = Cache().userLoggedIn.name + " private";
|
||||
} else {
|
||||
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
|
||||
}
|
||||
|
||||
_exercisePlan = ExercisePlan(exercisePlanName, this._customerId);
|
||||
}
|
||||
if ( newPlan ) {
|
||||
_exercisePlan.dateAdd = DateTime.now();
|
||||
_exercisePlan.private = true;
|
||||
ExercisePlan savedExercisePlan =
|
||||
await ExercisePlanApi().saveExercisePlan(_exercisePlan);
|
||||
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId;
|
||||
await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
|
||||
});
|
||||
} else {
|
||||
|
||||
await ExercisePlanApi().updateExercisePlan(_exercisePlan, _exercisePlan.exercisePlanId);
|
||||
|
||||
_origExercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
|
||||
if (exercisePlanDetails[exercisePlanDetail.exercisePlanDetailId] == null) {
|
||||
await ExercisePlanApi()
|
||||
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
|
||||
} else {
|
||||
await ExercisePlanApi()
|
||||
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
|
||||
}
|
||||
});
|
||||
|
||||
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async{
|
||||
exercisePlanDetail.exercisePlanId = _exercisePlan.exercisePlanId;
|
||||
if ( _origExercisePlanDetails[exercisePlanDetail.exercisePlanDetailId] == null) {
|
||||
await ExercisePlanApi()
|
||||
.saveExercisePlanDetail(exercisePlanDetail);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<ExercisePlan> getLastExercisePlan() async {
|
||||
if ( _customerId == 0) {
|
||||
return null;
|
||||
}
|
||||
_exercisePlan = await ExercisePlanApi().getLastExercisePlan(_customerId);
|
||||
newPlan = (_exercisePlan == null);
|
||||
print("New plan: " + newPlan.toString());
|
||||
|
||||
return _exercisePlan;
|
||||
}
|
||||
|
||||
Future<void> getExercisePlanDetails() async {
|
||||
if (_exercisePlan == null) {
|
||||
ExercisePlan exercisePlan = await this.getLastExercisePlan();
|
||||
if ( exercisePlan == null ) {
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
return;
|
||||
}
|
||||
}
|
||||
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
_origExercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
|
||||
|
||||
List<ExercisePlanDetail> list =
|
||||
await ExercisePlanApi().getExercisePlanDetail(_exercisePlan.exercisePlanId);
|
||||
|
||||
list.forEach((element) {
|
||||
newPlan = false;
|
||||
ExercisePlanDetail detail = element;
|
||||
_origExercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||
exercisePlanDetails[detail.exerciseTypeId] = detail;
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
@ -72,8 +72,12 @@ class ExerciseRepository {
|
||||
final Exercise modelExercise = this.exercise;
|
||||
modelExercise.customerId = this.customer.customerId;
|
||||
modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId;
|
||||
await ExerciseApi().addExercise(modelExercise);
|
||||
Cache().addExercise(exercise);
|
||||
Exercise savedExercise = await ExerciseApi().addExercise(modelExercise);
|
||||
if ( customer.customerId == Cache().userLoggedIn.customerId) {
|
||||
Cache().addExercise(savedExercise);
|
||||
} else if ( Cache().getTrainee() != null && customer.customerId == Cache().getTrainee().customerId ) {
|
||||
Cache().addExerciseTrainee(savedExercise);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -89,15 +93,26 @@ class ExerciseRepository {
|
||||
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
|
||||
final results = await ExerciseApi().getExercisesByCustomer(customerId);
|
||||
this.exerciseList = results;
|
||||
Cache().setExercises(exerciseList);
|
||||
if ( customerId == Cache().userLoggedIn.customerId) {
|
||||
Cache().setExercises(exerciseList);
|
||||
} else if ( Cache().getTrainee() != null && customerId == Cache().getTrainee().customerId ) {
|
||||
Cache().setExercisesTrainee(exerciseList);
|
||||
}
|
||||
return this.exerciseList;
|
||||
}
|
||||
|
||||
List<Exercise> getExerciseList() {
|
||||
if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
||||
this.exerciseList = Cache().getExercises();
|
||||
}
|
||||
return this.exerciseList;
|
||||
//if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
||||
return this.exerciseList = Cache().getExercises();
|
||||
//}
|
||||
//return this.exerciseList;
|
||||
}
|
||||
|
||||
List<Exercise> getExerciseListTrainee() {
|
||||
//if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
||||
return this.exerciseList = Cache().getExercisesTrainee();
|
||||
//}
|
||||
//return this.exerciseList;
|
||||
}
|
||||
|
||||
void getBaseExerciseFinishedPercent() {
|
||||
|
@ -9,12 +9,44 @@ import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Antagonist {
|
||||
static String chest = "Chest";
|
||||
static int chestNr = 1;
|
||||
static String biceps = "Biceps";
|
||||
static int bicepsNr = 2;
|
||||
static String triceps = "Triceps";
|
||||
static int tricepsNr =3;
|
||||
static String back = "Back";
|
||||
static int backNr = 4;
|
||||
static String shoulder = "Shoulders";
|
||||
static int shoulderNr = 5;
|
||||
static String core = "Core";
|
||||
static int coreNr = 6;
|
||||
static String thigh = "Thigh";
|
||||
static int thighNr = 7;
|
||||
static String calf = "Calf";
|
||||
static int calfNr = 8;
|
||||
}
|
||||
|
||||
class MenuTreeRepository {
|
||||
final LinkedHashMap tree = LinkedHashMap<String, WorkoutTree>();
|
||||
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
||||
bool isEnglish;
|
||||
|
||||
final Map<String, int> _antagonist = {
|
||||
Antagonist.chest: Antagonist.chestNr,
|
||||
Antagonist.biceps: Antagonist.bicepsNr,
|
||||
Antagonist.triceps: Antagonist.tricepsNr,
|
||||
Antagonist.back: Antagonist.backNr,
|
||||
Antagonist.shoulder: Antagonist.shoulderNr,
|
||||
Antagonist.core: Antagonist.coreNr,
|
||||
Antagonist.thigh: Antagonist.thighNr,
|
||||
Antagonist.calf: Antagonist.calfNr
|
||||
};
|
||||
|
||||
Future<void> createTree() async {
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
bool isEnglish = appLanguage.appLocal == Locale('en');
|
||||
isEnglish = appLanguage.appLocal == Locale('en');
|
||||
print("** Start creating tree on lang: " + appLanguage.appLocal.toString());
|
||||
|
||||
List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
|
||||
@ -25,7 +57,7 @@ class MenuTreeRepository {
|
||||
exerciseTree.forEach( (treeItem) async {
|
||||
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
|
||||
String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7);
|
||||
bool is1RM = treeItem.name == '1RM' ? true : false;
|
||||
bool is1RM = treeItem.name == 'One Rep Max' ? true : false;
|
||||
if ( is1RM == false && treeItem.parentId != 0) {
|
||||
is1RM = isParent1RM(treeItem.parentId);
|
||||
}
|
||||
@ -34,12 +66,13 @@ class MenuTreeRepository {
|
||||
treeItem.parentId,
|
||||
treeName,
|
||||
assetImage, Colors.white,
|
||||
32,
|
||||
24,
|
||||
false,
|
||||
0,
|
||||
null,
|
||||
false,
|
||||
is1RM
|
||||
is1RM,
|
||||
treeItem.name,
|
||||
);
|
||||
});
|
||||
|
||||
@ -65,7 +98,8 @@ class MenuTreeRepository {
|
||||
exerciseType.exerciseTypeId,
|
||||
exerciseType,
|
||||
exerciseType.base,
|
||||
is1RM
|
||||
is1RM,
|
||||
exerciseType.name
|
||||
);
|
||||
});
|
||||
|
||||
@ -81,7 +115,7 @@ class MenuTreeRepository {
|
||||
WorkoutTree treeItem = value as WorkoutTree;
|
||||
if ( treeItem.id == treeId ) {
|
||||
isTreeItem1RM = treeItem.is1RM;
|
||||
//print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
|
||||
print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
|
||||
}
|
||||
|
||||
});
|
||||
@ -99,4 +133,34 @@ class MenuTreeRepository {
|
||||
});
|
||||
return branch;
|
||||
}
|
||||
|
||||
List<WorkoutTree> getBranchList(int parent) {
|
||||
List branch = List<WorkoutTree>();
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
if ( parent == workoutTree.parent) {
|
||||
branch.add(workoutTree);
|
||||
}
|
||||
});
|
||||
return branch;
|
||||
}
|
||||
|
||||
void sortByMuscleType() {
|
||||
sortedTree = SplayTreeMap<String, List<WorkoutTree>>();
|
||||
tree.forEach((key, value) {
|
||||
WorkoutTree workoutTree = value as WorkoutTree;
|
||||
//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) {
|
||||
String treeName = _antagonist[workoutTree.nameEnglish].toString() + ". " + workoutTree.name;
|
||||
sortedTree[treeName] = this.getBranchList(workoutTree.id);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
|
||||
@ -22,6 +23,8 @@ class APIClient with Common {
|
||||
);
|
||||
if(response.statusCode == 200) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else if(response.statusCode == 404 ) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
throw Exception("Unable to perform HTTP request!");
|
||||
}
|
||||
|
@ -5,64 +5,65 @@ import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
|
||||
class CustomerApi {
|
||||
final APIClient _client=new APIClient();
|
||||
final APIClient _client = new APIClient();
|
||||
|
||||
Future<List<Customer>> getRealCustomers(String param) async {
|
||||
final body = await _client.get("customers/", param);
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<Customer> customers = json.map( (customer) => Customer.fromJson(customer) ).toList();
|
||||
final List<Customer> customers = json.map((customer) =>
|
||||
Customer.fromJson(customer)).toList();
|
||||
|
||||
return customers;
|
||||
}
|
||||
|
||||
Future<void> saveCustomer(Customer customer) async {
|
||||
String body = JsonEncoder().convert(customer.toJson());
|
||||
print(" ===== saving customer id: " + customer.customerId.toString() + ":" + body );
|
||||
print(" ===== saving customer id: " + customer.customerId.toString() + ":" +
|
||||
body);
|
||||
await _client.post(
|
||||
"customers/"+customer.customerId.toString(),
|
||||
body);
|
||||
"customers/" + customer.customerId.toString(),
|
||||
body);
|
||||
}
|
||||
|
||||
Future<void> addCustomer(Customer customer) async {
|
||||
String body = JsonEncoder().convert(customer.toJson());
|
||||
print(" ===== add new customer: " + body );
|
||||
print(" ===== add new customer: " + body);
|
||||
await _client.post(
|
||||
"customers",
|
||||
body);
|
||||
"customers",
|
||||
body);
|
||||
}
|
||||
|
||||
Future<void> addUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
print(" ===== register new user: " + body );
|
||||
print(" ===== register new user: " + body);
|
||||
final String responseBody = await _client.post(
|
||||
"registration",
|
||||
body);
|
||||
"registration",
|
||||
body);
|
||||
Customer customer;
|
||||
try {
|
||||
int status = jsonDecode(responseBody)['status'];
|
||||
if ( status != null ) {
|
||||
if (status != null) {
|
||||
throw new Exception(jsonDecode(responseBody)['error']);
|
||||
} else {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
Cache().afterRegistration(customer);
|
||||
}
|
||||
} on FormatException catch(exception) {
|
||||
} on FormatException catch (exception) {
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Future<void> getUser(User user) async {
|
||||
String body = JsonEncoder().convert(user.toJson());
|
||||
print(" ===== login the user: " + body );
|
||||
print(" ===== login the user: " + body);
|
||||
final String responseBody = await _client.post(
|
||||
"login",
|
||||
body);
|
||||
"login",
|
||||
body);
|
||||
Customer customer;
|
||||
try {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
await Cache().afterLogin(customer);
|
||||
} on FormatException catch(exception) {
|
||||
} on FormatException catch (exception) {
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
}
|
||||
@ -70,18 +71,54 @@ class CustomerApi {
|
||||
|
||||
Future<void> getCustomer(int customerId) async {
|
||||
String body = "";
|
||||
print(" ===== get the customer by id: " + customerId.toString() );
|
||||
print(" ===== get the customer by id: " + customerId.toString());
|
||||
try {
|
||||
final String responseBody = await _client.get(
|
||||
"customers/"+customerId.toString(),
|
||||
body);
|
||||
"customers/" + customerId.toString(),
|
||||
body);
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
print(" --- Customer: " + customer.toJson().toString());
|
||||
Cache().afterRegistration(customer);
|
||||
} catch (exception) {
|
||||
print ("Exception: " + exception.toString());
|
||||
print (" === go to registration ");
|
||||
print("Exception: " + exception.toString());
|
||||
print(" === go to registration ");
|
||||
Cache().logout();
|
||||
Cache().startPage = "registration";
|
||||
}
|
||||
}
|
||||
|
||||
Future<Customer> getTrainee(int customerId) async {
|
||||
String body = "";
|
||||
Customer customer;
|
||||
print(" ===== get Trainee customer by id: " + customerId.toString());
|
||||
try {
|
||||
final String responseBody = await _client.get(
|
||||
"customers/" + customerId.toString(),
|
||||
body);
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
print(" --- Trainee: " + customer.toJson().toString());
|
||||
} catch (exception) {
|
||||
print("Exception: " + exception.toString());
|
||||
throw Exception(exception);
|
||||
}
|
||||
return customer;
|
||||
}
|
||||
|
||||
Future<List<Customer>> getTrainees(int trainerId) async {
|
||||
List<Customer> trainees = List<Customer>();
|
||||
print("Get trainees list");
|
||||
try {
|
||||
String body = "";
|
||||
final String responseBody = await _client.get(
|
||||
"customers/trainees/" + trainerId.toString(),
|
||||
body
|
||||
);
|
||||
final Iterable json = jsonDecode(responseBody);
|
||||
trainees = json.map((customer) => Customer.fromJson(customer)).toList();
|
||||
} catch (exception) {
|
||||
print("Exception: " + exception.toString());
|
||||
throw Exception(exception);
|
||||
}
|
||||
return trainees;
|
||||
}
|
||||
}
|
145
lib/service/exercise_plan_service.dart
Normal file
145
lib/service/exercise_plan_service.dart
Normal file
@ -0,0 +1,145 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||
import 'dart:convert';
|
||||
import 'api.dart';
|
||||
|
||||
class ExercisePlanApi {
|
||||
final APIClient _client = new APIClient();
|
||||
|
||||
Future<ExercisePlan> saveExercisePlan(ExercisePlan exercisePlan) async {
|
||||
String body = JsonEncoder().convert(exercisePlan.toJson());
|
||||
print(" ===== saving exercisePlan $exercisePlan");
|
||||
ExercisePlan savedExercisePlan;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
"exercise_plan",
|
||||
body);
|
||||
savedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||
Cache().setTraineeExercisePlan(savedExercisePlan);
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return savedExercisePlan;
|
||||
}
|
||||
|
||||
Future<ExercisePlan> updateExercisePlan(
|
||||
ExercisePlan exercisePlan,
|
||||
int exercisePlanId) async {
|
||||
String body = JsonEncoder().convert(exercisePlan.toJson());
|
||||
print(" ===== saving exercisePlan $exercisePlan");
|
||||
ExercisePlan updatedExercisePlan;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
"exercise_plan/" + exercisePlanId.toString(),
|
||||
body);
|
||||
updatedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||
Cache().setTraineeExercisePlan(updatedExercisePlan);
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return updatedExercisePlan;
|
||||
}
|
||||
|
||||
Future<ExercisePlanDetail> saveExercisePlanDetail(ExercisePlanDetail exercisePlanDetail) async {
|
||||
String body = JsonEncoder().convert(exercisePlanDetail.toJson());
|
||||
print(" ===== update exercisePlanDetail $exercisePlanDetail");
|
||||
ExercisePlanDetail savedExercisePlanDetail;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
"exercise_plan_detail",
|
||||
body);
|
||||
savedExercisePlanDetail = ExercisePlanDetail.fromJson(jsonDecode(responseBody));
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return savedExercisePlanDetail;
|
||||
}
|
||||
|
||||
Future<ExercisePlanDetail> updateExercisePlanDetail(ExercisePlanDetail exercisePlanDetail,
|
||||
int exercisePlanDetailId) async {
|
||||
String body = JsonEncoder().convert(exercisePlanDetail.toJson());
|
||||
print(" ===== update exercisePlanDetail $exercisePlanDetail");
|
||||
ExercisePlanDetail savedExercisePlanDetail;
|
||||
try {
|
||||
final String responseBody = await _client.post(
|
||||
"exercise_plan_detail/" + exercisePlanDetailId.toString(),
|
||||
body);
|
||||
savedExercisePlanDetail = ExercisePlanDetail.fromJson(jsonDecode(responseBody));
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return savedExercisePlanDetail;
|
||||
}
|
||||
|
||||
Future<void> deleteExercisePlanDetail(int exercisePlanDetailId) async {
|
||||
print(" ===== delete exercisePlanDetail $exercisePlanDetailId");
|
||||
String body = "";
|
||||
try {
|
||||
await _client.post(
|
||||
"exercise_plan_detail/delete/" + exercisePlanDetailId.toString(),
|
||||
body);
|
||||
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void> deleteExercisePlan(int exercisePlanId) async {
|
||||
String body = "";
|
||||
print(" ===== delete exercisePlan $exercisePlanId");
|
||||
|
||||
try {
|
||||
await _client.post(
|
||||
"exercise_plan/delete/" + exercisePlanId.toString(),
|
||||
body);
|
||||
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<ExercisePlan> getLastExercisePlan(int customerId) async {
|
||||
String body = "";
|
||||
print(" ===== get last exercisePlan $customerId");
|
||||
ExercisePlan exercisePlan;
|
||||
try {
|
||||
final String responseBody = await _client.get(
|
||||
"exercise_plan/last/" + customerId.toString(),
|
||||
body);
|
||||
exercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody));
|
||||
} on Exception catch(e) {
|
||||
if ( e is NotFoundException) {
|
||||
print("ExercisePlan not found for " + customerId.toString());
|
||||
return exercisePlan;
|
||||
} else {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
}
|
||||
return exercisePlan;
|
||||
}
|
||||
|
||||
Future<List<ExercisePlanDetail>> getExercisePlanDetail(int exercisePlanId) async {
|
||||
String body = "";
|
||||
print(" ===== get exercisePlanDetail $exercisePlanId");
|
||||
List<ExercisePlanDetail> listExercisePlanDetail;
|
||||
try {
|
||||
final String responseBody = await _client.get(
|
||||
"exercise_plan_detail/" + exercisePlanId.toString(),
|
||||
body);
|
||||
print("response body:" + responseBody);
|
||||
final Iterable json = jsonDecode(responseBody);
|
||||
listExercisePlanDetail = json.map( (planDetail) => ExercisePlanDetail.fromJson(planDetail) ) .toList();
|
||||
} on Exception catch(e) {
|
||||
throw new Exception(e.toString());
|
||||
}
|
||||
return listExercisePlanDetail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -22,12 +22,14 @@ class ExerciseApi {
|
||||
body);
|
||||
}
|
||||
|
||||
Future<void> addExercise(Exercise exercise) async {
|
||||
Future<Exercise> addExercise(Exercise exercise) async {
|
||||
String body = JsonEncoder().convert(exercise.toJson());
|
||||
print(" ===== add new exercise: " + body );
|
||||
await _client.post(
|
||||
final String response = await _client.post(
|
||||
"exercises",
|
||||
body);
|
||||
final Exercise savedExercise = Exercise.fromJson(jsonDecode(response));
|
||||
return savedExercise;
|
||||
}
|
||||
|
||||
Future<List<Exercise>> getExercisesByCustomer(int customerId ) async {
|
||||
|
4
lib/util/not_found_exception.dart
Normal file
4
lib/util/not_found_exception.dart
Normal file
@ -0,0 +1,4 @@
|
||||
class NotFoundException implements Exception {
|
||||
final String message;
|
||||
const NotFoundException({this.message});
|
||||
}
|
@ -27,7 +27,7 @@ class Session {
|
||||
if ( Cache().firstLoad ) {
|
||||
|
||||
print (" -- Session: fetch locale..");
|
||||
await appLanguage.fetchLocale();
|
||||
await appLanguage.getLocale(_sharedPreferences);
|
||||
await AppLocalizations.delegate.load(appLanguage.appLocal);
|
||||
print (" -- Session: fetch token..");
|
||||
await _fetchToken(_sharedPreferences);
|
||||
@ -95,7 +95,6 @@ class Session {
|
||||
//Navigator.of(context).pushNamed('login');
|
||||
Cache().startPage = "login";
|
||||
} else {
|
||||
print("************** Store SharedPreferences");
|
||||
// get API customer
|
||||
customerId = prefs.getInt(Cache.customerIdKey);
|
||||
await CustomerApi().getCustomer(customerId);
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -7,6 +9,7 @@ import 'package:flutter/cupertino.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AccountPage extends StatelessWidget {
|
||||
// ignore: close_sinks
|
||||
AccountBloc accountBloc;
|
||||
|
||||
@override
|
||||
@ -93,7 +96,7 @@ class AccountPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
loginOut( context, accountBloc ),
|
||||
//exercises(exerciseChangingViewModel),
|
||||
getMyTrainees(context, accountBloc),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -137,93 +140,72 @@ class AccountPage extends StatelessWidget {
|
||||
return element;
|
||||
}
|
||||
|
||||
/* ListTile exercises( ExerciseChangingViewModel model ) {
|
||||
ListTile element = ListTile();
|
||||
if ( Auth().userLoggedIn == null ) {
|
||||
return element;
|
||||
Widget getMyTrainees( BuildContext context, AccountBloc accountBloc ) {
|
||||
if ( accountBloc.customerRepository.customer == null ) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
element = ListTile(
|
||||
title: Text(AppLocalizations.of(context).translate("Exercises")),
|
||||
subtitle: Column(
|
||||
children: [
|
||||
FutureBuilder<List<ExerciseViewModel>>(
|
||||
future: _exercises,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
return getExercises( model );//CustomerListWidget(customers: _exerciseViewModel.exerciseList);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text("${snapshot.error}");
|
||||
}
|
||||
|
||||
// By default, show a loading spinner.
|
||||
return CircularProgressIndicator();
|
||||
}
|
||||
),]
|
||||
));
|
||||
|
||||
return element;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
Widget getExercises( ExerciseChangingViewModel model ) {
|
||||
List<ExerciseViewModel> exercises = model.exerciseList;
|
||||
|
||||
Column element = Column();
|
||||
if (exercises.length > 0) {
|
||||
List<Column> rows = List();
|
||||
|
||||
exercises.forEach((exercise) {
|
||||
String exerciseName = AppLocalizations.of(context).translate(
|
||||
Common.getExerciseType(exercise.getExercise().exerciseTypeId).name);
|
||||
|
||||
String quantity = exercise.getExercise().quantity.toString() + " " +
|
||||
AppLocalizations.of(context).translate(exercise.getExercise().unit);
|
||||
|
||||
String unitQuantity = "";
|
||||
String unitQuantityUnit = "";
|
||||
String date = Common.getDateLocale(exercise.getExercise().dateAdd, false);
|
||||
if (exercise.getExercise().unitQuantity != null) {
|
||||
unitQuantity = exercise.getExercise().unitQuantity.toString();
|
||||
unitQuantityUnit = AppLocalizations.of(context).translate(
|
||||
Common.getExerciseType(exercise.getExercise().exerciseTypeId).unitQuantityUnit);
|
||||
}
|
||||
|
||||
TableRow row = TableRow(
|
||||
children: [
|
||||
Text(date),
|
||||
Text(exerciseName),
|
||||
Text(quantity),
|
||||
|
||||
Text(unitQuantity + " " + unitQuantityUnit),
|
||||
]
|
||||
);
|
||||
|
||||
Table table = Table(
|
||||
defaultColumnWidth: FractionColumnWidth(0.28),
|
||||
children: [row],
|
||||
);
|
||||
|
||||
Column col = Column(
|
||||
children: [
|
||||
table,
|
||||
Row(
|
||||
children: [
|
||||
Text(" "),
|
||||
]
|
||||
)
|
||||
],
|
||||
);
|
||||
rows.add(col);
|
||||
});
|
||||
|
||||
|
||||
element = Column(
|
||||
children: rows,
|
||||
if ( accountBloc.customerRepository.customer.trainer == 0 ) {
|
||||
return ListTile(
|
||||
title: Container(),
|
||||
);
|
||||
}
|
||||
|
||||
return element;
|
||||
if (accountBloc.customerRepository.getTraineesList() == null ) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.people),
|
||||
title: RaisedButton(
|
||||
color: Colors.white70,
|
||||
onPressed: () => accountBloc.add(AccountGetTrainees()),
|
||||
child: Text("See my trainees"),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
List<Widget> elements = List<Widget>();
|
||||
accountBloc.customerRepository.getTraineesList().forEach((element) {
|
||||
Customer trainee = element;
|
||||
String name = trainee.name;
|
||||
String firstName = trainee.firstname;
|
||||
String nodeName = AppLanguage().appLocal == Locale("en") ?
|
||||
firstName + " " + name : name + " " + firstName;
|
||||
|
||||
bool selected = accountBloc.traineeId == trainee.customerId;
|
||||
|
||||
Widget widget = FlatButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
shape:RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
side: BorderSide(width: 2, color: selected ? Colors.blue : Colors.black26 ),
|
||||
),
|
||||
onPressed: () {
|
||||
accountBloc.add(AccountSelectTrainee(traineeId: trainee.customerId));
|
||||
//Navigator.of(context).pushNamed('login');
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(nodeName, style:
|
||||
TextStyle(
|
||||
color: selected ? Colors.blue : Colors.black54,
|
||||
fontWeight: selected ? FontWeight.bold : FontWeight.normal
|
||||
),
|
||||
),
|
||||
Icon(Icons.arrow_forward_ios),
|
||||
]),
|
||||
);
|
||||
elements.add(widget);
|
||||
});
|
||||
|
||||
return ListTile(
|
||||
leading: Icon(Icons.people),
|
||||
subtitle: Text("My Trainees"),
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: elements,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
} */
|
||||
}
|
||||
|
241
lib/view/exercise_add_by_plan_page.dart
Normal file
241
lib/view/exercise_add_by_plan_page.dart
Normal file
@ -0,0 +1,241 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_add_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class ExerciseAddByPlanPage extends StatefulWidget{
|
||||
_ExerciseAddByPlanPage createState() => _ExerciseAddByPlanPage();
|
||||
}
|
||||
|
||||
class _ExerciseAddByPlanPage extends State<ExerciseAddByPlanPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
// ignore: close_sinks
|
||||
final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan'];
|
||||
final int customerId = arguments['customerId'];
|
||||
final WorkoutTree workoutTree = arguments['workoutTree'];
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
ExerciseAddByPlanFormBloc(
|
||||
exerciseRepository: exerciseRepository,
|
||||
exercisePlanRepository: bloc.exercisePlanRepository,
|
||||
customerId: customerId,
|
||||
workoutTree: workoutTree),
|
||||
child: BlocBuilder<ExerciseAddByPlanFormBloc, FormBlocState>(
|
||||
builder: (context, state) {
|
||||
// ignore: close_sinks
|
||||
final exerciseBloc = BlocProvider.of<ExerciseAddByPlanFormBloc>(context);
|
||||
if ( state is FormBlocLoading ) {
|
||||
return LoadingDialog();
|
||||
} else if ( state is FormBlocSuccess) {
|
||||
return getControlForm(exerciseBloc);
|
||||
} else {
|
||||
return getControlForm(exerciseBloc);
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
Form getControlForm( ExerciseAddByPlanFormBloc exerciseBloc) {
|
||||
String exerciseName = AppLanguage().appLocal == Locale("en") ?
|
||||
exerciseBloc.exerciseRepository.exerciseType.name :
|
||||
exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
|
||||
|
||||
return Form(
|
||||
autovalidate: true,
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.black,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text("Add Exercise"),
|
||||
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(
|
||||
width: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width,
|
||||
height: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.height,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only (top: 25, left: 25, right: 25),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text(exerciseName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold,
|
||||
fontSize: 18,
|
||||
color: Colors.deepOrange),
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
softWrap: true,
|
||||
),
|
||||
Divider(color: Colors.transparent,),
|
||||
|
||||
Divider(),
|
||||
Column(
|
||||
children: repeatExercises(exerciseBloc),
|
||||
|
||||
),
|
||||
Divider(),
|
||||
|
||||
|
||||
|
||||
]),
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Column> repeatExercises(ExerciseAddByPlanFormBloc exerciseBloc) {
|
||||
List<Column> listColumns = List<Column>();
|
||||
for ( int i = 0; i < exerciseBloc.countSteps; i++) {
|
||||
Column col = Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Divider(color: Colors.transparent,),
|
||||
Text("Execute the " + (i+1).toString() + ". set!",
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: AppLocalizations.of(context)
|
||||
.translate("The number of the exercise"),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: "Please repeat with " + exerciseBloc.unitQuantity1Field.value + " " +
|
||||
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
|
||||
exerciseBloc.exercisePlanRepository.actualPlanDetail.repeats.toString() + " times!",
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != i+1,
|
||||
textFieldBloc: exerciseBloc.unitQuantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.black54,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter(RegExp(r"[\d.]"))
|
||||
],
|
||||
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange, fontWeight: FontWeight.normal),
|
||||
labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: exerciseBloc.step == i+1 ? Colors.blue : Colors.black26,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
print ("Submit step " + exerciseBloc.step.toString() + " (i) " + i.toString()),
|
||||
if ( exerciseBloc.step == i+1 ) {
|
||||
exerciseBloc.submit()
|
||||
},
|
||||
if ( i+1 == exerciseBloc.countSteps) {
|
||||
Navigator.of(context).pop()
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate("Check"),
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
Divider(color: Colors.transparent,),
|
||||
],
|
||||
);
|
||||
listColumns.add(col);
|
||||
}
|
||||
return listColumns;
|
||||
}
|
||||
|
||||
String validateNumberInput(input) {
|
||||
String error = AppLocalizations.of(context).translate(
|
||||
"Please type the right quantity 0-10000");
|
||||
dynamic rc = (input != null && input.length > 0);
|
||||
if (!rc) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Pattern pattern = r'^\d+(?:\.\d+)?$';
|
||||
RegExp regex = new RegExp(pattern);
|
||||
if (!regex.hasMatch(input)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
rc = double.tryParse(input);
|
||||
if (rc == null) {
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
if (!(double.parse(input) < 10000 && double.parse(input) > 0)) {
|
||||
return error;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
187
lib/view/exercise_execute_by_plan_page.dart
Normal file
187
lib/view/exercise_execute_by_plan_page.dart
Normal file
@ -0,0 +1,187 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExerciseByPlanPage extends StatefulWidget {
|
||||
@override
|
||||
_ExerciseByPlanPage createState() => _ExerciseByPlanPage();
|
||||
}
|
||||
|
||||
class _ExerciseByPlanPage extends State<ExerciseByPlanPage> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExerciseByPlanBloc bloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
BlocProvider.of<ExerciseByPlanBloc>(context).add(ExerciseByPlanLoad());
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExerciseByPlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||
AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<ExerciseByPlanBloc, ExerciseByPlanState>(listener: (context, state) {
|
||||
if (state is ExerciseByPlanError) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExerciseByPlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
if (state is ExerciseByPlanStateInitial || state is ExerciseByPlanLoading) {
|
||||
return Container();
|
||||
} else if (state is ExerciseByPlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExerciseByPlanError) {
|
||||
return exerciseWidget(bloc);
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExerciseByPlanBloc bloc) {
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: false,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
/* Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc); */
|
||||
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
args['blocExerciseByPlan'] = bloc;
|
||||
args['customerId'] = bloc.customerId;
|
||||
args['workoutTree'] = workoutTree;
|
||||
Navigator.of(context).pushNamed("exerciseAddByPlanPage", arguments: args);
|
||||
},
|
||||
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExerciseByPlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
|
||||
WorkoutTree treeItem = element;
|
||||
if ( treeItem.selected ) {
|
||||
icon =
|
||||
treeItem.executed == false ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") :
|
||||
NodeIcon(codePoint: Icons.check_box.codePoint, color: "green");
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail + ")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
}
|
||||
});
|
||||
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name,
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
});
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
148
lib/view/exercise_log_page.dart
Normal file
148
lib/view/exercise_log_page.dart
Normal file
@ -0,0 +1,148 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExerciseLogPage extends StatefulWidget {
|
||||
@override
|
||||
_ExerciseLogPage createState() => _ExerciseLogPage();
|
||||
}
|
||||
|
||||
class _ExerciseLogPage extends State<ExerciseLogPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final CustomerRepository customerRepository = arguments['customerRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||
AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: exerciseWidget(exerciseRepository, customerId),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExerciseRepository exerciseRepository, int customerId) {
|
||||
TreeViewController _treeViewController =
|
||||
TreeViewController(children: nodeExercises(exerciseRepository, customerId));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.caret,
|
||||
modifier: ExpanderModifier.none,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.red.shade800,
|
||||
size: 20,
|
||||
),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
letterSpacing: 0.1,
|
||||
),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
letterSpacing: 0.1,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 18,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
colorScheme: ColorScheme.light(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: false,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
setState(() {
|
||||
_treeViewController = _treeViewController.copyWith(selectedKey: key);
|
||||
});
|
||||
},
|
||||
theme: _treeViewTheme,
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercises(ExerciseRepository exerciseRepository, int customerId) {
|
||||
List<Node> nodes = List<Node>();
|
||||
List<Exercise> exercises;
|
||||
if ( customerId == Cache().userLoggedIn.customerId ) {
|
||||
exercises = exerciseRepository.getExerciseList();
|
||||
} else if ( Cache().getTrainee() != null && customerId == Cache().getTrainee().customerId ) {
|
||||
exercises = exerciseRepository.getExerciseListTrainee();
|
||||
}
|
||||
|
||||
|
||||
String prevDay = "";
|
||||
Node actualNode;
|
||||
List<Node> listExercisesPerDay;
|
||||
exercises.forEach((element) {
|
||||
Exercise exercise = element;
|
||||
ExerciseType exerciseType =
|
||||
exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId);
|
||||
String actualDay = exercise.dateAdd.year.toString() +
|
||||
"-" +
|
||||
exercise.dateAdd.month.toString() +
|
||||
"-" +
|
||||
exercise.dateAdd.day.toString();
|
||||
|
||||
if (prevDay.compareTo(actualDay) != 0) {
|
||||
listExercisesPerDay = List<Node>();
|
||||
actualNode = Node(
|
||||
label: actualDay,
|
||||
key: exercise.dateAdd.toString(),
|
||||
expanded: true,
|
||||
children: listExercisesPerDay,
|
||||
icon:
|
||||
NodeIcon(codePoint: Icons.date_range.codePoint, color: "blue"));
|
||||
nodes.add(actualNode);
|
||||
prevDay = actualDay;
|
||||
}
|
||||
|
||||
String exerciseName = AppLanguage().appLocal == Locale("en")
|
||||
? exerciseType.name
|
||||
: exerciseType.nameTranslation;
|
||||
String unitQuantity = exerciseType.unitQuantity == "1"
|
||||
? exercise.unitQuantity.toStringAsFixed(0) +
|
||||
" " +
|
||||
AppLocalizations.of(context)
|
||||
.translate(exerciseType.unitQuantityUnit) +
|
||||
" "
|
||||
: "";
|
||||
|
||||
String labelExercise = exerciseName +
|
||||
" " +
|
||||
unitQuantity +
|
||||
exercise.quantity.toStringAsFixed(0) +
|
||||
" " +
|
||||
AppLocalizations.of(context).translate(exercise.unit);
|
||||
listExercisesPerDay.add(Node(
|
||||
label: labelExercise,
|
||||
key: exercise.exerciseId.toString(),
|
||||
expanded: false,
|
||||
icon: NodeIcon(codePoint: Icons.repeat.codePoint, color: "blue")));
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
}
|
190
lib/view/exercise_plan_custom_page.dart
Normal file
190
lib/view/exercise_plan_custom_page.dart
Normal file
@ -0,0 +1,190 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class ExercisePlanCustomPage extends StatefulWidget {
|
||||
@override
|
||||
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
|
||||
}
|
||||
|
||||
class _ExercisePlanCustomPage extends State<ExercisePlanCustomPage> {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
// ignore: close_sinks
|
||||
ExercisePlanBloc bloc;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
BlocProvider.of<ExercisePlanBloc>(context).add(ExercisePlanLoad());
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final int customerId = arguments['customerId'];
|
||||
bloc = BlocProvider.of<ExercisePlanBloc>(context);
|
||||
bloc.customerId = customerId;
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'):
|
||||
AssetImage('asset/image/WT_menu_dark.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<ExercisePlanBloc, ExercisePlanState>(listener: (context, state) {
|
||||
if (state is ExercisePlanError) {
|
||||
//showInSnackBar(state.message);
|
||||
//return exerciseWidget(bloc);
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
content: Text(
|
||||
state.message,
|
||||
),
|
||||
backgroundColor: Colors.orange,
|
||||
));
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
LoadingDialog();
|
||||
}
|
||||
},
|
||||
// ignore: missing_return
|
||||
builder: (context, state) {
|
||||
if (state is ExercisePlanInitial) {
|
||||
return Container();
|
||||
} else if (state is ExercisePlanReady) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanError) {
|
||||
return exerciseWidget(bloc);
|
||||
} else if (state is ExercisePlanLoading) {
|
||||
return Container();
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExercisePlanBloc bloc) {
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercisePlan(bloc));
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.plusMinus,
|
||||
modifier: ExpanderModifier.circleOutlined,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.black26,
|
||||
size: 10,
|
||||
),
|
||||
labelStyle: TextStyle(fontSize: 14, letterSpacing: 0, color: Colors.blue.shade800),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
letterSpacing: 0.3,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 20,
|
||||
color: Colors.blue.shade800,
|
||||
),
|
||||
colorScheme: bloc.customerId == Cache().userLoggedIn.customerId ? ColorScheme.light(background: Colors.transparent) : ColorScheme.dark(background: Colors.transparent),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: true,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
Node<dynamic> node = _treeViewController.getNode(key);
|
||||
WorkoutTree workoutTree = node.data as WorkoutTree;
|
||||
bloc.exercisePlanRepository.setActualPlanDetail(workoutTree.exerciseType);
|
||||
print("change node " + node.label + " key " + key);
|
||||
bloc.add(ExercisePlanUpdate(workoutTree: workoutTree));
|
||||
Navigator.of(context).pushNamed("exercisePlanDetailAdd", arguments: bloc);
|
||||
},
|
||||
theme: _treeViewTheme,
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
backgroundColor: Colors.blueAccent,
|
||||
child: Icon(Icons.save_alt),
|
||||
onPressed: () => {
|
||||
bloc.add(ExercisePlanSave()),
|
||||
if (bloc.exercisePlanRepository.getExercisePlanDetailSize() > 0) {
|
||||
Navigator.of(context).pop()
|
||||
}
|
||||
}
|
||||
),
|
||||
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercisePlan(ExercisePlanBloc bloc) {
|
||||
List<Node> nodes = List<Node>();
|
||||
Node actualNode;
|
||||
bool isEnglish = AppLanguage().appLocal == Locale("en");
|
||||
|
||||
bloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
List<WorkoutTree> listWorkoutItem = list;
|
||||
List<Node> listExerciseTypePerMuscle = List<Node>();
|
||||
NodeIcon icon;
|
||||
listWorkoutItem.forEach((element) {
|
||||
WorkoutTree treeItem = element;
|
||||
icon =
|
||||
treeItem.selected == true ? NodeIcon(codePoint: Icons.bubble_chart.codePoint, color: "blueAccent") : null;
|
||||
|
||||
String exerciseLabel = isEnglish
|
||||
? treeItem.name
|
||||
: treeItem.exerciseType == null ? treeItem.name : treeItem.exerciseType.nameTranslation;
|
||||
|
||||
List<Node<dynamic>> planDetailList = List<Node<dynamic>>();
|
||||
String planDetail = bloc.exercisePlanRepository.getPlanDetail(treeItem.exerciseTypeId);
|
||||
|
||||
if (planDetail.length > 0) {
|
||||
exerciseLabel += " (" + planDetail +")";
|
||||
}
|
||||
|
||||
actualNode = Node(
|
||||
label: exerciseLabel,
|
||||
key: treeItem.id.toString(),
|
||||
data: treeItem,
|
||||
expanded: planDetailList.length > 0 ? true : false,
|
||||
children: [],
|
||||
icon: icon);
|
||||
listExerciseTypePerMuscle.add(actualNode);
|
||||
});
|
||||
//print ("Node name " + name);
|
||||
if (name != null) {
|
||||
actualNode = Node(
|
||||
label: name, // AppLocalizations.of(context).translate(name),
|
||||
key: name,
|
||||
expanded: true,
|
||||
children: listExerciseTypePerMuscle,
|
||||
icon: NodeIcon(codePoint: Icons.perm_identity.codePoint, color: "orange"));
|
||||
nodes.add(actualNode);
|
||||
}
|
||||
});
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
144
lib/view/exercise_plan_detail_add_page.dart
Normal file
144
lib/view/exercise_plan_detail_add_page.dart
Normal file
@ -0,0 +1,144 @@
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/exercise_plan_custom_form.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class ExercisePlanDetailAddPage extends StatefulWidget {
|
||||
@override
|
||||
_ExercisePlanDetailAddPage createState() => _ExercisePlanDetailAddPage();
|
||||
}
|
||||
|
||||
class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// ignore: close_sinks
|
||||
final ExercisePlanBloc planBloc = ModalRoute.of(context).settings.arguments;
|
||||
final ExercisePlanRepository exercisePlanRepository = planBloc.exercisePlanRepository;
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) => ExercisePlanCustomerFormBloc(exercisePlanRepository: exercisePlanRepository, planBloc: planBloc),
|
||||
child: Builder(builder: (context) {
|
||||
// ignore: close_sinks
|
||||
final bloc = BlocProvider.of<ExercisePlanCustomerFormBloc>(context);
|
||||
|
||||
String exerciseName = "";
|
||||
if (bloc != null) {
|
||||
exerciseName = AppLanguage().appLocal == Locale("en")
|
||||
? bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name
|
||||
: bloc.exercisePlanRepository.actualPlanDetail.exerciseType.nameTranslation;
|
||||
}
|
||||
|
||||
return Form(
|
||||
autovalidate: true,
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top: 25, left: 25, right: 25),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
|
||||
Text(AppLocalizations.of(context).translate('Save The Exercise To The Exercise Plan'),
|
||||
style: TextStyle(fontSize: 14, color: Colors.blueAccent)),
|
||||
Text(
|
||||
exerciseName,
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange),
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
softWrap: true,
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
textFieldBloc: bloc.serieField,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: AppLocalizations.of(context).translate("The number of the serie done with"),
|
||||
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
|
||||
labelText: AppLocalizations.of(context).translate("Serie"),
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
textFieldBloc: bloc.quantityField,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: AppLocalizations.of(context).translate("The number of the repeats of one serie"),
|
||||
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
|
||||
labelText: AppLocalizations.of(context).translate("Repeats"),
|
||||
),
|
||||
),
|
||||
TextFieldBlocBuilder(
|
||||
textFieldBloc: bloc.weightField,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(fontSize: 30, color: Colors.lightBlue, fontWeight: FontWeight.bold),
|
||||
inputFormatters: [WhitelistingTextInputFormatter(RegExp(r"[\d.]"))],
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
hintStyle: TextStyle(fontSize: 16, color: Colors.black54, fontWeight: FontWeight.w100),
|
||||
hintText: AppLocalizations.of(context).translate("The weight"),
|
||||
labelStyle: TextStyle(fontSize: 16, color: Colors.lightBlue),
|
||||
labelText: AppLocalizations.of(context).translate("Weight"),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
RaisedButton(
|
||||
textColor: Colors.white,
|
||||
color: Colors.red.shade300,
|
||||
focusColor: Colors.white,
|
||||
onPressed: () => {
|
||||
print("Remove " + bloc.exercisePlanRepository.actualPlanDetail.exerciseType.name),
|
||||
planBloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: bloc.exercisePlanRepository.actualPlanDetail)),
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
child: Text("Delete"), //Text(AppLocalizations.of(context).translate("Delete"), style: TextStyle(fontSize: 16),)
|
||||
),
|
||||
RaisedButton(
|
||||
textColor: Colors.white,
|
||||
color: Colors.blueAccent,
|
||||
focusColor: Colors.white,
|
||||
onPressed: () => {
|
||||
bloc.submit(),
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate("Save"),
|
||||
style: TextStyle(fontSize: 16),
|
||||
)),
|
||||
],
|
||||
),
|
||||
]),
|
||||
))),
|
||||
),
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_treeview/tree_view.dart';
|
||||
|
||||
class MyDevelopmentPage extends StatefulWidget {
|
||||
@override
|
||||
_MyDevelopmentPage createState() => _MyDevelopmentPage();
|
||||
}
|
||||
|
||||
class _MyDevelopmentPage extends State<MyDevelopmentPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBarNav(),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child:
|
||||
exerciseWidget(exerciseRepository),
|
||||
|
||||
)
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1));
|
||||
}
|
||||
|
||||
Widget exerciseWidget(ExerciseRepository exerciseRepository) {
|
||||
TreeViewController _treeViewController = TreeViewController(children: nodeExercises(exerciseRepository) );
|
||||
|
||||
TreeViewTheme _treeViewTheme = TreeViewTheme(
|
||||
expanderTheme: ExpanderThemeData(
|
||||
type: ExpanderType.caret,
|
||||
modifier: ExpanderModifier.none,
|
||||
position: ExpanderPosition.start,
|
||||
color: Colors.red.shade800,
|
||||
size: 20,
|
||||
),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 12,
|
||||
letterSpacing: 0.1,
|
||||
),
|
||||
parentLabelStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
letterSpacing: 0.1,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.orange.shade600,
|
||||
),
|
||||
iconTheme: IconThemeData(
|
||||
size: 18,
|
||||
color: Colors.grey.shade800,
|
||||
),
|
||||
colorScheme: ColorScheme.light(
|
||||
background: Colors.transparent
|
||||
),
|
||||
);
|
||||
|
||||
return TreeView(
|
||||
controller: _treeViewController,
|
||||
allowParentSelect: false,
|
||||
supportParentDoubleTap: false,
|
||||
//onExpansionChanged: _expandNodeHandler,
|
||||
onNodeTap: (key) {
|
||||
setState(() {
|
||||
_treeViewController = _treeViewController.copyWith(selectedKey: key);
|
||||
});
|
||||
},
|
||||
theme: _treeViewTheme,
|
||||
);
|
||||
}
|
||||
|
||||
List<Node> nodeExercises(ExerciseRepository exerciseRepository) {
|
||||
List<Node> nodes = List<Node>();
|
||||
List<Exercise> exercises = exerciseRepository.getExerciseList();
|
||||
|
||||
String prevDay = "";
|
||||
Node actualNode;
|
||||
List<Node> listExercisesPerDay;
|
||||
exercises.forEach((element) {
|
||||
Exercise exercise = element;
|
||||
ExerciseType exerciseType =
|
||||
exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId);
|
||||
String actualDay = exercise.dateAdd.year.toString()+"-"+
|
||||
exercise.dateAdd.month.toString()+"-"+
|
||||
exercise.dateAdd.day.toString();
|
||||
|
||||
if ( prevDay.compareTo(actualDay) != 0) {
|
||||
listExercisesPerDay = List<Node>();
|
||||
actualNode =
|
||||
Node(
|
||||
label: actualDay,
|
||||
key: exercise.dateAdd.toString(),
|
||||
expanded: true,
|
||||
children: listExercisesPerDay,
|
||||
icon: NodeIcon(
|
||||
codePoint: Icons.date_range.codePoint,
|
||||
color: "blue"
|
||||
)
|
||||
);
|
||||
nodes.add(actualNode);
|
||||
prevDay = actualDay;
|
||||
}
|
||||
|
||||
String exerciseName = AppLanguage().appLocal == Locale("en") ?
|
||||
exerciseType.name :
|
||||
exerciseType.nameTranslation;
|
||||
String unitQuantity = exerciseType.unitQuantity == "1" ?
|
||||
exercise.unitQuantity.toStringAsFixed(0)
|
||||
+ " " + AppLocalizations.of(context).translate(exerciseType.unitQuantityUnit) + " "
|
||||
: "";
|
||||
|
||||
String labelExercise =
|
||||
exerciseName + " " + unitQuantity
|
||||
+ exercise.quantity.toStringAsFixed(0) + " "
|
||||
+ AppLocalizations.of(context).translate(exercise.unit);
|
||||
listExercisesPerDay.add(
|
||||
Node(
|
||||
label: labelExercise,
|
||||
key: exercise.exerciseId.toString(),
|
||||
expanded: false,
|
||||
icon: NodeIcon(
|
||||
codePoint: Icons.repeat.codePoint,
|
||||
color: "blue"
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
|
196
lib/view/myexcercise_plan_page.dart
Normal file
196
lib/view/myexcercise_plan_page.dart
Normal file
@ -0,0 +1,196 @@
|
||||
import 'dart:collection';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_common.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MyExercisePlanPage extends StatefulWidget {
|
||||
@override
|
||||
_MyExercisePlanPage createState() => _MyExercisePlanPage();
|
||||
}
|
||||
|
||||
class _MyExercisePlanPage extends State<MyExercisePlanPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBarCommonNav(),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.png'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: CustomScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers:
|
||||
[
|
||||
SliverGrid(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['customerId'] = Cache().userLoggedIn.customerId,
|
||||
Navigator.of(context).pushNamed('exerciseByPlanPage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text("Execute My Selected Training Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
),
|
||||
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['exerciseRepository'] = exerciseRepository,
|
||||
args['customerId'] = Cache().userLoggedIn.customerId,
|
||||
Navigator.of(context).pushNamed('exercisePlanCustomPage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text("Edit My Custom Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
),
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
|
||||
},
|
||||
child: Text("Suggested Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
),
|
||||
Stack(
|
||||
fit: StackFit.passthrough,
|
||||
overflow: Overflow.clip,
|
||||
alignment: Alignment.topLeft,
|
||||
children: [
|
||||
Image.asset('asset/image/lock.png',
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
|
||||
},
|
||||
child: Text("My Special Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
|
||||
Stack(
|
||||
fit: StackFit.passthrough,
|
||||
overflow: Overflow.clip,
|
||||
children: [
|
||||
Image.asset('asset/image/lock.png',
|
||||
height: 40,
|
||||
width: 40,
|
||||
),
|
||||
FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
|
||||
},
|
||||
child: Text("My Arnold's Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
),
|
||||
|
||||
]
|
||||
),
|
||||
|
||||
hiddenPlanWidget(exerciseRepository),
|
||||
hiddenTrainingWidget(),
|
||||
|
||||
|
||||
]
|
||||
),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 20.0,
|
||||
crossAxisSpacing: 20.0,
|
||||
childAspectRatio: 1.2,
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
),
|
||||
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2));
|
||||
}
|
||||
|
||||
Widget hiddenPlanWidget(ExerciseRepository exerciseRepository) {
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
if ( Cache().getTrainee() != null ) {
|
||||
return FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['exerciseRepository'] = exerciseRepository,
|
||||
args['customerId'] = Cache().getTrainee().customerId,
|
||||
Navigator.of(context).pushNamed('exercisePlanCustomPage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text("My Trainee's Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
Widget hiddenTrainingWidget() {
|
||||
final LinkedHashMap args = LinkedHashMap();
|
||||
if ( Cache().getTrainee() != null ) {
|
||||
print ("!!Trainee: " + Cache().getTrainee().firstname + " " + Cache().getTrainee().name);
|
||||
return FlatButton(
|
||||
padding: EdgeInsets.all(20),
|
||||
textColor: Colors.white,
|
||||
color: Colors.black12,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['customerId'] = Cache().getTrainee().customerId,
|
||||
Navigator.of(context).pushNamed('exerciseByPlanPage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text("Execute My Trainee's Training Plan",
|
||||
style: TextStyle(fontSize: 18),)
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,13 @@ class SettingsPage extends StatelessWidget{
|
||||
)
|
||||
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(Icons.get_app),
|
||||
title: RaisedButton(
|
||||
child: Text("Check lang", style: TextStyle(fontSize: 12),),
|
||||
onPressed: () => settingsBloc.add(SettingsGetLanguage()),
|
||||
)
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -56,14 +56,15 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
||||
}
|
||||
}); */
|
||||
colorAnim = RainbowColorTween([Colors.white70,
|
||||
Colors.greenAccent,
|
||||
Colors.lightGreen,
|
||||
Colors.lightGreenAccent,
|
||||
Colors.yellow,
|
||||
Colors.blueGrey,
|
||||
Colors.blueAccent,
|
||||
Colors.lightBlue,
|
||||
Colors.lightBlueAccent,
|
||||
Colors.yellowAccent,
|
||||
Colors.orange,
|
||||
Colors.orangeAccent,
|
||||
Colors.white70])
|
||||
Colors.yellowAccent,
|
||||
Color(0xffcce6ff)])
|
||||
.animate(colorController)
|
||||
..addListener(() { setState(() {}); })
|
||||
..addStatusListener((status) {
|
||||
@ -103,7 +104,9 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
||||
onPressed: () =>
|
||||
{
|
||||
menuBloc.add(MenuTreeUp(parent: 0))
|
||||
if ( menuBloc != null ) {
|
||||
menuBloc.add(MenuTreeUp(parent: 0)),
|
||||
}
|
||||
},
|
||||
)
|
||||
);
|
||||
@ -151,7 +154,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
||||
trailing: Icon(percent > 0.6 ? Icons.mood : Icons.mood_bad, color: colorAnim.value,),
|
||||
linearStrokeCap: LinearStrokeCap.roundAll,
|
||||
backgroundColor: colorAnim.value,
|
||||
progressColor: Colors.blue,
|
||||
progressColor: Color(0xff73e600),
|
||||
animation: true,
|
||||
),
|
||||
],
|
||||
|
133
lib/widgets/app_bar_common.dart
Normal file
133
lib/widgets/app_bar_common.dart
Normal file
@ -0,0 +1,133 @@
|
||||
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).pop()
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@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 ) {
|
||||
return Stack(
|
||||
alignment: Alignment.topLeft,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate("Make your first test"),
|
||||
style: TextStyle(fontSize: 16, 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) + "% 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,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -91,12 +91,13 @@ class _NawDrawerWidget extends State<BottomNavigator> {
|
||||
|
||||
break;
|
||||
case 1:
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('mydevelopment');
|
||||
//Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('myDevelopment');
|
||||
break;
|
||||
case 2:
|
||||
|
||||
//throw new StateError('This is a Dart exception on event.');
|
||||
//Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed('myExercisePlan');
|
||||
|
||||
break;
|
||||
case 3:
|
||||
|
@ -24,7 +24,6 @@ class AitrainerHome extends StatefulWidget {
|
||||
|
||||
class _HomePageState extends State<AitrainerHome> {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -45,7 +44,9 @@ class _HomePageState extends State<AitrainerHome> {
|
||||
sessionBloc.add(SessionStart());
|
||||
// ignore: close_sinks
|
||||
SettingsBloc settingsBloc = BlocProvider.of<SettingsBloc>(context);
|
||||
settingsBloc.loadLang();
|
||||
String lang = AppLanguage().appLocal.languageCode;
|
||||
print (" -- Loading delayed lang $lang");
|
||||
settingsBloc.add(SettingsChangeLanguage(language: lang));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -6,8 +6,8 @@ class LoadingScreenMain extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
Image _backgroundImage = Image.asset('asset/image/WT01_loading_layers.png',
|
||||
fit: BoxFit.cover,
|
||||
//height: double.infinity,
|
||||
//width: double.infinity,
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
);
|
||||
return Scaffold(
|
||||
|
@ -37,7 +37,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
child: Center(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
fit: StackFit.loose,
|
||||
clipBehavior: Clip.antiAliasWithSaveLayer,
|
||||
children: [
|
||||
FlatButton(
|
||||
child: _getButtonImage(workoutTree),
|
||||
@ -45,21 +45,35 @@ class MenuPageWidget extends StatelessWidget {
|
||||
shape: getShape(workoutTree),
|
||||
onPressed: () => menuClick(workoutTree, menuBloc, context),
|
||||
),
|
||||
InkWell(
|
||||
onTap:() => menuClick(workoutTree, menuBloc, context),
|
||||
child: Text(
|
||||
" " + workoutTree.name,
|
||||
maxLines: 2,
|
||||
style: TextStyle(
|
||||
color: workoutTree.color,
|
||||
fontSize: workoutTree.fontSize,
|
||||
fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900),
|
||||
Positioned(
|
||||
top: workoutTree.name.length > 30 ? 140 : 150,
|
||||
left: 5,
|
||||
child: Container(
|
||||
height: 300,
|
||||
width: 280,
|
||||
child: InkWell(
|
||||
onTap:() => menuClick(workoutTree, menuBloc, context),
|
||||
child: Text(
|
||||
" " + workoutTree.name,
|
||||
maxLines: 2,
|
||||
style: TextStyle(
|
||||
color: workoutTree.color,
|
||||
fontSize: workoutTree.fontSize,
|
||||
fontFamily: 'Arial',
|
||||
fontWeight: FontWeight.w900),
|
||||
),
|
||||
|
||||
highlightColor: workoutTree.color,
|
||||
),
|
||||
color: Colors.transparent,
|
||||
),
|
||||
highlightColor: workoutTree.color,
|
||||
),
|
||||
|
||||
]))));
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
SliverList sliverList =
|
||||
|
888
pubspec.lock
888
pubspec.lock
@ -1,888 +0,0 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.39.17"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
bloc_test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: bloc_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.0.3"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.11"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.12"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.11"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.16.2"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.6"
|
||||
devicelocale:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: devicelocale
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
equatable:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: equatable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.4"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.4"
|
||||
flutter_driver:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_facebook_login:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_facebook_login
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
flutter_form_bloc:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_form_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.19.0"
|
||||
flutter_keyboard_visibility:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_keyboard_visibility
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.5"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_local_notifications
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter_local_notifications_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
flutter_localizations:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_test:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_treeview:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_treeview
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.0+1"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
form_bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: form_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.19.1"
|
||||
freezed:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: freezed
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.6"
|
||||
freezed_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: freezed_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.0+1"
|
||||
fuchsia_remote_debug_protocol:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
gradient_bottom_navigation_bar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: gradient_bottom_navigation_bar
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0+4"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.14.0+3"
|
||||
http:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.1"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.12"
|
||||
intl:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.2"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
json_rpc_2:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_rpc_2
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.6"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.8"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7"
|
||||
mockito:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: mockito
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.1"
|
||||
multi_server_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: multi_server_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.12"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
percent_indicator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: percent_indicator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.12"
|
||||
provider:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2+1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
rainbow_color:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: rainbow_color
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
rainbow_vis:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rainbow_vis
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.24.1"
|
||||
sentry:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sentry
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
shared_preferences:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.10"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.2+2"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+10"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2+7"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_gen:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.6"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.9"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
spider_chart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: spider_chart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
sync_http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sync_http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.14.4"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.15"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
usage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: usage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.2"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.2"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
vm_service_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.6+2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
webdriver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webdriver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.3"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
sdks:
|
||||
dart: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.16.0 <2.0.0"
|
16
pubspec.yaml
16
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.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.0+12
|
||||
version: 1.1.0+20
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
@ -26,19 +26,19 @@ dependencies:
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.3
|
||||
devicelocale: ^0.3.1
|
||||
cupertino_icons: ^1.0.0
|
||||
devicelocale: ^0.3.2
|
||||
sentry: ^3.0.1
|
||||
# firebase_messaging: ^6.0.16
|
||||
flutter_local_notifications: 1.1.1
|
||||
flutter_facebook_login: ^3.0.0
|
||||
flutter_bloc: ^6.0.4
|
||||
flutter_bloc: ^6.0.5
|
||||
equatable: ^1.2.4
|
||||
freezed: ^0.11.6
|
||||
flutter_form_bloc: ^0.19.0
|
||||
spider_chart: ^0.1.5
|
||||
rainbow_color: ^0.1.1
|
||||
percent_indicator: ^2.1.5
|
||||
percent_indicator: ^2.1.6
|
||||
gradient_bottom_navigation_bar: ^1.0.0+4
|
||||
flutter_treeview: ^0.6.0+1
|
||||
|
||||
@ -51,17 +51,16 @@ dev_dependencies:
|
||||
flutter_driver:
|
||||
sdk: flutter
|
||||
test: any
|
||||
bloc_test: ^7.0.1
|
||||
bloc_test: ^7.0.3
|
||||
|
||||
build_runner:
|
||||
|
||||
|
||||
http: 0.12.1
|
||||
provider: ^4.3.2+1
|
||||
intl: 0.16.1
|
||||
shared_preferences: ^0.5.10
|
||||
|
||||
flutter_launcher_icons: ^0.7.5
|
||||
flutter_launcher_icons: ^0.8.0
|
||||
|
||||
flutter_icons:
|
||||
android: "launcher_icon"
|
||||
@ -94,6 +93,7 @@ flutter:
|
||||
- asset/image/WT_weight_loss.png
|
||||
- asset/image/WT_welcome.png
|
||||
- asset/image/login_fb.png
|
||||
- asset/image/lock.png
|
||||
- asset/menu/1.cardio.png
|
||||
- asset/menu/1.1.aerob.png
|
||||
- asset/menu/1.2.anaerob.png
|
||||
|
79
test/account_bloc_test.dart
Normal file
79
test/account_bloc_test.dart
Normal file
@ -0,0 +1,79 @@
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart' as test;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class MockCustomerRepository extends Mock implements CustomerRepository {
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
MockCustomerRepository customerRepository;
|
||||
AccountBloc accountBloc;
|
||||
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
test.setUp(() {
|
||||
customerRepository = MockCustomerRepository();
|
||||
accountBloc = AccountBloc(customerRepository: customerRepository);
|
||||
});
|
||||
|
||||
test.tearDown(() {
|
||||
accountBloc?.close();
|
||||
});
|
||||
|
||||
test.test('initial state is correct', () {
|
||||
expect(accountBloc.state, AccountInitial());
|
||||
});
|
||||
|
||||
group('Account', () {
|
||||
test.test(
|
||||
'emits [loading, logged in] when the customer clicked login',
|
||||
() {
|
||||
final expectedResponse = [
|
||||
AccountLoading(),
|
||||
AccountLoggedIn(),
|
||||
];
|
||||
|
||||
//verify(accountBloc.customerRepository.customer == null);
|
||||
|
||||
expectLater(
|
||||
accountBloc, emitsInOrder(expectedResponse),
|
||||
);
|
||||
|
||||
accountBloc.add(AccountLogin());
|
||||
});
|
||||
});
|
||||
|
||||
test.test(
|
||||
'emits [loading, logged out] when the customer clicked logout',
|
||||
() {
|
||||
final expectedResponse = [
|
||||
AccountLoading(),
|
||||
AccountLoggedOut(),
|
||||
];
|
||||
|
||||
expectLater(
|
||||
accountBloc, emitsInOrder(expectedResponse),
|
||||
);
|
||||
|
||||
accountBloc.add(AccountLogout());
|
||||
});
|
||||
|
||||
test.test(
|
||||
'emits [loading, logged out] when the customer data changed',
|
||||
() {
|
||||
final expectedResponse = [
|
||||
AccountLoading(),
|
||||
AccountReady(),
|
||||
];
|
||||
|
||||
expectLater(
|
||||
accountBloc, emitsInOrder(expectedResponse),
|
||||
);
|
||||
|
||||
accountBloc.add(AccountChangeCustomer());
|
||||
});
|
||||
|
||||
}
|
52
test/customer_service_test.dart
Normal file
52
test/customer_service_test.dart
Normal file
@ -0,0 +1,52 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.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:mockito/mockito.dart';
|
||||
//import 'package:mockito/mockito.dart';
|
||||
|
||||
// Create a MockClient using the Mock class provided by the Mockito package.
|
||||
// Create new instances of this class in each test.
|
||||
/* class MockClient extends Mock implements CustomerApi {
|
||||
Future<List<Customer>> getTrainees(int trainerId) async {
|
||||
if (trainerId == 62) {
|
||||
List<Customer> list = List<Customer>();
|
||||
Customer customer1 = Customer(firstname: "Zalán", name: "Boss");
|
||||
Customer customer2 = Customer(firstname: "Zétény", name: "Boss");
|
||||
list.add(customer1);
|
||||
list.add(customer2);
|
||||
return list;
|
||||
} else {
|
||||
throw Exception("No trainees found");
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
main() {
|
||||
|
||||
|
||||
setUp(() {
|
||||
Cache().setTestBaseUrl();
|
||||
});
|
||||
|
||||
group('fetchPost', () {
|
||||
test('returns a List<Customer> if the http call completes successfully', () async {
|
||||
final client = CustomerApi();
|
||||
|
||||
// Use Mockito to return a successful response when it calls the
|
||||
// provided http.Client.
|
||||
List<Customer> trainees = List<Customer>();
|
||||
trainees = await client.getTrainees(62);
|
||||
|
||||
expect(trainees.length, 2);
|
||||
expect(trainees[0].firstname, "Zalán");
|
||||
});
|
||||
|
||||
test('throws an exception if the http call completes with an error', () async {
|
||||
final client = CustomerApi();
|
||||
|
||||
expect(client.getTrainees(22), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
72
test/exercise_plan_test.dart
Normal file
72
test/exercise_plan_test.dart
Normal file
@ -0,0 +1,72 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/service/exercise_plan_service.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() {
|
||||
|
||||
setUp(() {
|
||||
Cache().setTestBaseUrl();
|
||||
});
|
||||
|
||||
group('new Plan', () {
|
||||
test('add new plan and plan details', () async {
|
||||
final client = ExercisePlanApi();
|
||||
|
||||
ExercisePlan exercisePlan = ExercisePlan(
|
||||
"Test plan " + DateTime.now().toIso8601String(),
|
||||
62
|
||||
);
|
||||
exercisePlan.dateAdd = DateTime.now();
|
||||
|
||||
ExercisePlan savedPlan = await client.saveExercisePlan(exercisePlan);
|
||||
expect(savedPlan.name.substring(0, 9), "Test plan");
|
||||
expect(savedPlan.customerId, 62);
|
||||
|
||||
|
||||
|
||||
int newPlanId = savedPlan.exercisePlanId;
|
||||
//savedPlan.exercisePlanId = newPlanId;
|
||||
|
||||
ExercisePlanDetail detail = ExercisePlanDetail(
|
||||
39 //exerciseTypeId
|
||||
);
|
||||
detail.serie = 3;
|
||||
detail.repeats = 12;
|
||||
detail.weightEquation = "90";
|
||||
detail.exercisePlanId = newPlanId;
|
||||
|
||||
ExercisePlanDetail savedDetail = await client.saveExercisePlanDetail(detail);
|
||||
|
||||
expect(savedDetail.weightEquation, "90");
|
||||
expect(savedDetail.repeats, 12);
|
||||
expect(savedDetail.exercisePlanId, newPlanId);
|
||||
|
||||
await client.deleteExercisePlanDetail(savedDetail.exercisePlanDetailId);
|
||||
await client.deleteExercisePlan(savedPlan.exercisePlanId);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test('get the last plan and change plan details', () async {
|
||||
final client = ExercisePlanApi();
|
||||
|
||||
ExercisePlan exercisePlan = await client.getLastExercisePlan(61);
|
||||
List<ExercisePlanDetail> list = await client.getExercisePlanDetail(exercisePlan.exercisePlanId);
|
||||
|
||||
expect(list.length, 2);
|
||||
ExercisePlanDetail detail = ExercisePlanDetail(3);
|
||||
detail.serie = 4;
|
||||
detail.repeats = 12;
|
||||
detail.weightEquation = "10";
|
||||
detail.exercisePlanId = exercisePlan.exercisePlanId;
|
||||
//list.add(detail);
|
||||
ExercisePlanDetail newObjectToSave = await client.saveExercisePlanDetail(detail);
|
||||
List<ExercisePlanDetail> list2 = await client.getExercisePlanDetail(exercisePlan.exercisePlanId);
|
||||
expect(list2.length, 3);
|
||||
expect(list2.last.weightEquation, "10");
|
||||
await client.deleteExercisePlanDetail(newObjectToSave.exercisePlanDetailId);
|
||||
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user