wt1.1c auth->cache, control page, animation base exercise percent
This commit is contained in:
parent
18d6994068
commit
6b0892ec09
11
i18n/en.json
11
i18n/en.json
@ -105,5 +105,14 @@
|
||||
"Endomorph": "Endomorph",
|
||||
"Mesomorph": "Mesomorph",
|
||||
|
||||
"Description": "Description"
|
||||
"Description": "Description",
|
||||
"Make your first test": "Make your first test",
|
||||
"Why do you need Exercise Control?" : "Why do you need Exercise Control?",
|
||||
|
||||
"Your 1RM:":"Your 1RM:",
|
||||
"Your Real 1RM:":"Your Real 1RM:",
|
||||
"Check":"Check",
|
||||
"1st Control Exercise:": "1st Control Exercise:",
|
||||
"2nd Control Exercise:": "2nd Control Exercise:",
|
||||
"3rd Control Exercise:": "3rd Control Exercise:"
|
||||
}
|
11
i18n/hu.json
11
i18n/hu.json
@ -105,6 +105,13 @@
|
||||
"Endomorph":"Endomorf",
|
||||
"Mesomorph":"Mezomorf",
|
||||
|
||||
"Description": "Leírás"
|
||||
|
||||
"Description": "Leírás",
|
||||
"Make your first test": "Végezd el az első tesztet",
|
||||
"Why do you need Exercise Control?": "Miért szükséges a kontrollgyakorlat?",
|
||||
"Your 1RM:":"Maxerőd:",
|
||||
"Your Real 1RM:":"Ellenőrzött maxerő:",
|
||||
"Check":"Ellenőrzés",
|
||||
"1st Control Exercise:": "1. kontrollgyakorlat:",
|
||||
"2nd Control Exercise:": "2. kontrollgyakorlat:",
|
||||
"3rd Control Exercise:": "3. kontrollgyakorlat:"
|
||||
}
|
29
lib/animations/test_progress_animation.dart
Normal file
29
lib/animations/test_progress_animation.dart
Normal file
@ -0,0 +1,29 @@
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TestProgress extends AnimatedWidget {
|
||||
|
||||
TestProgress({
|
||||
Key key,
|
||||
@required Animation<double> animation,
|
||||
}) : super(key: key, listenable: animation);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final animation = listenable as Animation<double>;
|
||||
|
||||
return Transform.scale(
|
||||
alignment: Alignment.center,
|
||||
scale: animation.value,
|
||||
origin: Offset(-5,0),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.only(left: 0),
|
||||
child: Icon(Icons.star, color: Colors.yellow,)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
@ -14,8 +14,8 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
final CustomerRepository customerRepository;
|
||||
bool loggedIn = false;
|
||||
AccountBloc({this.customerRepository}) : super(AccountInitial()) {
|
||||
if ( Auth().userLoggedIn != null ) {
|
||||
customerRepository.customer = Auth().userLoggedIn;
|
||||
if ( Cache().userLoggedIn != null ) {
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
loggedIn = true;
|
||||
}
|
||||
}
|
||||
@ -34,7 +34,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
customerRepository.customer = event.customer;
|
||||
yield AccountLoggedIn();
|
||||
} else if (event is AccountLogout) {
|
||||
await Auth().logout();
|
||||
await Cache().logout();
|
||||
customerRepository.customer = null;
|
||||
loggedIn = false;
|
||||
yield AccountLoggedOut();
|
||||
|
@ -92,9 +92,7 @@ class CustomExerciseFormBloc extends FormBloc<String, String> {
|
||||
exerciseRepository.rmWathen =
|
||||
100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
|
||||
rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1));
|
||||
double average = (exerciseRepository.rmWendler + exerciseRepository.rmWathen +
|
||||
exerciseRepository.rmMayhew + exerciseRepository.rmOconner +
|
||||
exerciseRepository.rmMcglothlin)/4;
|
||||
double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner)/2;
|
||||
rmAverageField.updateValue(average.toStringAsFixed(1));
|
||||
rm90Field.updateValue((average*0.9).toStringAsFixed(1));
|
||||
rm80Field.updateValue((average*0.8).toStringAsFixed(1));
|
||||
|
133
lib/bloc/exercise_control_form_bloc.dart
Normal file
133
lib/bloc/exercise_control_form_bloc.dart
Normal file
@ -0,0 +1,133 @@
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class ExerciseControlFormBloc extends FormBloc<String, String> {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
int step = 1;
|
||||
final double percentToCalculate;
|
||||
|
||||
final initialRMField = TextFieldBloc(
|
||||
);
|
||||
|
||||
final quantity1Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final unitQuantity1Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final quantity2Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final unitQuantity2Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final quantity3Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
final unitQuantity3Field = TextFieldBloc(
|
||||
);
|
||||
|
||||
|
||||
|
||||
ExerciseControlFormBloc({this.exerciseRepository, this.percentToCalculate}) {
|
||||
addFieldBlocs(fieldBlocs: [
|
||||
initialRMField,
|
||||
quantity1Field,
|
||||
unitQuantity1Field,
|
||||
quantity2Field,
|
||||
unitQuantity2Field,
|
||||
quantity3Field,
|
||||
unitQuantity3Field,
|
||||
|
||||
]);
|
||||
|
||||
initialRMField.updateInitialValue(calculate1RM(percent75: false).toStringAsFixed(0));
|
||||
unitQuantity1Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
unitQuantity2Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
unitQuantity3Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
|
||||
quantity1Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setQuantity(current.valueToDouble);
|
||||
});
|
||||
|
||||
unitQuantity1Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setUnitQuantity(current.valueToDouble);
|
||||
});
|
||||
quantity2Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setQuantity(current.valueToDouble);
|
||||
});
|
||||
|
||||
unitQuantity2Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setUnitQuantity(current.valueToDouble);
|
||||
});
|
||||
quantity3Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setQuantity(current.valueToDouble);
|
||||
});
|
||||
|
||||
unitQuantity3Field.onValueChanges(onData: (previous, current) async* {
|
||||
exerciseRepository.setUnitQuantity(current.valueToDouble);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onLoading() {
|
||||
step = 1;
|
||||
super.onLoading();
|
||||
}
|
||||
|
||||
@override
|
||||
void onSubmitting() async {
|
||||
print("on Submitting Custom form");
|
||||
try {
|
||||
emitLoading(progress: 30);
|
||||
if ( step == 1) {
|
||||
|
||||
//unitQuantity2Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
//unitQuantity3Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
step = 2;
|
||||
} else if ( step == 2) {
|
||||
//unitQuantity3Field.updateInitialValue(calculate1RM(percent75: true).toStringAsFixed(0));
|
||||
step = 3;
|
||||
} else if ( step == 3 ) {
|
||||
//updatedRMField.updateInitialValue(calculate1RM(percent75: false).toStringAsFixed(0));
|
||||
}
|
||||
|
||||
//await exerciseRepository.addExercise();
|
||||
|
||||
emitSuccess(canSubmitAgain: true);
|
||||
} on Exception catch (ex) {
|
||||
emitFailure(failureResponse: ex.toString());
|
||||
}
|
||||
}
|
||||
|
||||
double calculate1RM({bool percent75}) {
|
||||
if (exerciseRepository.exercise == null) {
|
||||
exerciseRepository.getLastExercise();
|
||||
}
|
||||
double weight = exerciseRepository.exercise.unitQuantity;
|
||||
double repeat = exerciseRepository.exercise.quantity;
|
||||
if ( weight == 0 || repeat == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double rmWendler = weight * repeat * 0.0333 + weight;
|
||||
double rmOconner = weight * (1 + repeat / 40);
|
||||
double average = (rmWendler + rmOconner) / 2;
|
||||
|
||||
return percent75 ? average * this.percentToCalculate : average;
|
||||
}
|
||||
|
||||
//@override
|
||||
Future<void> close() {
|
||||
initialRMField.close();
|
||||
quantity1Field.close();
|
||||
unitQuantity1Field.close();
|
||||
quantity2Field.close();
|
||||
unitQuantity2Field.close();
|
||||
quantity3Field.close();
|
||||
unitQuantity3Field.close();
|
||||
|
||||
return super.close();
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
|
||||
class LoginFormBloc extends FormBloc<String, String> {
|
||||
class LoginFormBloc extends FormBloc<String, String> with Common {
|
||||
final AccountBloc accountBloc;
|
||||
final UserRepository userRepository;
|
||||
|
||||
@ -40,18 +40,18 @@ class LoginFormBloc extends FormBloc<String, String> {
|
||||
void onSubmitting() async {
|
||||
try {
|
||||
emitLoading(progress: 30);
|
||||
if ( ! Common.validateEmail(userRepository)) {
|
||||
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
|
||||
if ( ! validateEmail(userRepository)) {
|
||||
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
|
||||
|
||||
emitFailure(failureResponse: Common.EMAIL_ERROR);
|
||||
} else if ( ! Common.validatePassword(userRepository)) {
|
||||
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
|
||||
emitFailure(failureResponse: Common.PASSWORD_ERROR);
|
||||
emitFailure(failureResponse: EMAIL_ERROR);
|
||||
} else if ( ! validatePassword(userRepository)) {
|
||||
passwordField.addFieldError( PASSWORD_ERROR, isPermanent: true);
|
||||
emitFailure(failureResponse: PASSWORD_ERROR);
|
||||
} else {
|
||||
// Emit either Loaded or Error
|
||||
await userRepository.getUser();
|
||||
emitSuccess(canSubmitAgain: false);
|
||||
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
|
||||
}
|
||||
} on Exception catch (ex) {
|
||||
emitFailure(failureResponse: ex.toString());
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
import 'account/account_bloc.dart';
|
||||
|
||||
class RegistrationFormBloc extends FormBloc<String, String> {
|
||||
class RegistrationFormBloc extends FormBloc<String, String> with Common {
|
||||
final AccountBloc accountBloc;
|
||||
final emailField = TextFieldBloc(
|
||||
validators: [
|
||||
@ -38,18 +38,18 @@ class RegistrationFormBloc extends FormBloc<String, String> {
|
||||
void onSubmitting() async {
|
||||
try {
|
||||
emitLoading(progress: 30);
|
||||
if ( ! Common.validateEmail(userRepository)) {
|
||||
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
|
||||
if ( ! validateEmail(userRepository)) {
|
||||
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
|
||||
|
||||
emitFailure(failureResponse: Common.EMAIL_ERROR);
|
||||
} else if ( ! Common.validatePassword(userRepository)) {
|
||||
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
|
||||
emitFailure(failureResponse: Common.PASSWORD_ERROR);
|
||||
emitFailure(failureResponse: EMAIL_ERROR);
|
||||
} else if ( ! validatePassword(userRepository)) {
|
||||
passwordField.addFieldError(PASSWORD_ERROR, isPermanent: true);
|
||||
emitFailure(failureResponse: PASSWORD_ERROR);
|
||||
} else {
|
||||
// Emit either Loaded or Error
|
||||
await userRepository.addUser();
|
||||
emitSuccess(canSubmitAgain: false);
|
||||
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
|
||||
}
|
||||
} on Exception catch (ex) {
|
||||
emitFailure(failureResponse: ex.toString());
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
||||
import 'package:aitrainer_app/util/session.dart';
|
||||
@ -10,6 +9,7 @@ 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_control_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';
|
||||
@ -163,6 +163,7 @@ class AitrainerApp extends StatelessWidget {
|
||||
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
||||
'exerciseNewPage': (context) => ExerciseNewPage(),
|
||||
'exerciseCustomPage': (context) => CustomExercisePage(),
|
||||
'exerciseControlPage': (context) => ExerciseControlPage(),
|
||||
'login': (context) => LoginPage(),
|
||||
'registration': (context) => RegistrationPage(),
|
||||
'gdpr': (context) => Gdpr(),
|
||||
|
@ -1,5 +1,10 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -27,8 +32,8 @@ enum SharePrefsChange {
|
||||
- is_logged_in
|
||||
*/
|
||||
|
||||
class Auth {
|
||||
static final Auth _singleton = Auth._internal();
|
||||
class Cache {
|
||||
static final Cache _singleton = Cache._internal();
|
||||
|
||||
// Keys to store and fetch data from SharedPreferences
|
||||
static final String authTokenKey = 'auth_token';
|
||||
@ -45,16 +50,20 @@ class Auth {
|
||||
String authToken = "";
|
||||
Customer userLoggedIn;
|
||||
bool firstLoad = true;
|
||||
|
||||
List<ExerciseType> _exerciseTypes;
|
||||
List<ExerciseTree> _exerciseTree;
|
||||
List<Exercise> _exercises;
|
||||
LinkedHashMap _tree = LinkedHashMap<String, WorkoutTree>();
|
||||
|
||||
List deviceLanguages;
|
||||
String startPage;
|
||||
|
||||
factory Auth() {
|
||||
factory Cache() {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
Auth._internal();
|
||||
Cache._internal();
|
||||
|
||||
String getAuthToken() {
|
||||
return this.authToken;
|
||||
@ -101,23 +110,26 @@ class Auth {
|
||||
sharedPreferences = await prefs;
|
||||
|
||||
DateTime now = DateTime.now();
|
||||
sharedPreferences.setString(Auth.lastStoreDateKey, now.toString());
|
||||
sharedPreferences.setString(Cache.lastStoreDateKey, now.toString());
|
||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
if ( type == SharePrefsChange.registration ) {
|
||||
Auth().startPage = "home";
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isRegisteredKey, true);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
Cache().startPage = "home";
|
||||
sharedPreferences.setInt(Cache.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Cache.isRegisteredKey, true);
|
||||
sharedPreferences.setBool(Cache.isLoggedInKey, true);
|
||||
await ExerciseTypeApi().getExerciseTypes();
|
||||
await ExerciseTreeApi().getExerciseTree();
|
||||
exerciseRepository.getExercisesByCustomer(customerId);
|
||||
} else if ( type == SharePrefsChange.login ) {
|
||||
Auth().startPage = "home";
|
||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
||||
Cache().startPage = "home";
|
||||
sharedPreferences.setInt(Cache.customerIdKey, customerId);
|
||||
sharedPreferences.setBool(Cache.isLoggedInKey, true);
|
||||
await ExerciseTypeApi().getExerciseTypes();
|
||||
await ExerciseTreeApi().getExerciseTree();
|
||||
exerciseRepository.getExercisesByCustomer(customerId);
|
||||
} else if ( type == SharePrefsChange.logout ) {
|
||||
sharedPreferences.setBool(Auth.isLoggedInKey, false);
|
||||
sharedPreferences.setInt(Auth.customerIdKey, 0);
|
||||
sharedPreferences.setBool(Cache.isLoggedInKey, false);
|
||||
sharedPreferences.setInt(Cache.customerIdKey, 0);
|
||||
sharedPreferences.setString(authTokenKey, "");
|
||||
}
|
||||
}
|
||||
@ -130,6 +142,14 @@ class Auth {
|
||||
this._exerciseTree = exerciseTree;
|
||||
}
|
||||
|
||||
void setExercises( List<Exercise> exercises ) {
|
||||
this._exercises = exercises;
|
||||
}
|
||||
|
||||
void setWorkoutTree( LinkedHashMap<String, WorkoutTree> tree) {
|
||||
this._tree = tree;
|
||||
}
|
||||
|
||||
List<ExerciseType> getExerciseTypes() {
|
||||
return this._exerciseTypes;
|
||||
}
|
||||
@ -137,4 +157,13 @@ class Auth {
|
||||
List<ExerciseTree> getExerciseTree() {
|
||||
return this._exerciseTree;
|
||||
}
|
||||
|
||||
List<Exercise> getExercises() {
|
||||
return this._exercises;
|
||||
}
|
||||
|
||||
LinkedHashMap<String, WorkoutTree> getWorkoutTree() {
|
||||
return this._tree;
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,8 @@ class ExerciseType {
|
||||
String nameTranslation;
|
||||
String descriptionTranslation;
|
||||
|
||||
bool is1RM;
|
||||
|
||||
ExerciseType({this.name, this.description});
|
||||
|
||||
ExerciseType.fromJson(Map json) {
|
||||
@ -41,4 +43,12 @@ class ExerciseType {
|
||||
"unitQuantityUnit": unitQuantityUnit,
|
||||
"active": active
|
||||
};
|
||||
|
||||
void set1RM(bool is1RM) {
|
||||
this.is1RM = is1RM;
|
||||
}
|
||||
|
||||
bool get1RM() {
|
||||
return this.is1RM;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
class User {
|
||||
class User {
|
||||
String email;
|
||||
String password;
|
||||
int customerId;
|
||||
@ -12,4 +12,4 @@ class User {
|
||||
"username": email,
|
||||
"password": password,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ class WorkoutTree {
|
||||
ExerciseType exerciseType;
|
||||
bool base;
|
||||
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, this.exerciseType, this.base);
|
||||
bool is1RM;
|
||||
|
||||
WorkoutTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, this.exerciseType, this.base, this.is1RM);
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
@ -7,6 +8,7 @@ class ExerciseRepository {
|
||||
Exercise exercise;
|
||||
Customer customer;
|
||||
ExerciseType exerciseType;
|
||||
List<Exercise> exerciseList;
|
||||
|
||||
double rmWendler = 0;
|
||||
double rmMcglothlin = 0;
|
||||
@ -79,10 +81,51 @@ class ExerciseRepository {
|
||||
this.exerciseType = exerciseType;
|
||||
}
|
||||
|
||||
/*
|
||||
Future<List<ExerciseRepository>> getExercisesByCustomer( int customerId ) async {
|
||||
|
||||
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
|
||||
final results = await ExerciseApi().getExercisesByCustomer(customerId);
|
||||
this.exerciseList = results.map((item) => ExerciseRepository(exercise: item)).toList();
|
||||
this.exerciseList = results;
|
||||
Cache().setExercises(exerciseList);
|
||||
return this.exerciseList;
|
||||
} */
|
||||
}
|
||||
|
||||
List<Exercise> getExerciseList() {
|
||||
if ( this.exerciseList == null || this.exerciseList.length == 0 ) {
|
||||
this.exerciseList = Cache().getExercises();
|
||||
}
|
||||
return this.exerciseList;
|
||||
}
|
||||
|
||||
double getBaseExerciseFinishedPercent() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void getLastExercise() {
|
||||
List<Exercise> exercises = this.getExerciseList();
|
||||
Exercise lastExercise = exercises[0];
|
||||
exercises.forEach((element) {
|
||||
Exercise actualExercise = element;
|
||||
if ( actualExercise.dateAdd.compareTo(lastExercise.dateAdd) > 0 ) {
|
||||
lastExercise = actualExercise;
|
||||
}
|
||||
});
|
||||
this.exercise = lastExercise;
|
||||
this.customer = Cache().userLoggedIn;
|
||||
this.exerciseType = getExerciseTypeById(exercise.exerciseTypeId);
|
||||
return;
|
||||
}
|
||||
|
||||
ExerciseType getExerciseTypeById(int exerciseTypeId) {
|
||||
ExerciseType actualExerciseType;
|
||||
Cache().getExerciseTypes().forEach((element) {
|
||||
ExerciseType exerciseType = element;
|
||||
if ( exerciseType.exerciseTypeId == exerciseTypeId) {
|
||||
actualExerciseType = exerciseType;
|
||||
}
|
||||
});
|
||||
if ( actualExerciseType == null ) {
|
||||
throw Exception("Data error, no ExerciseType for exerciseTypeId $exerciseTypeId" );
|
||||
}
|
||||
return actualExerciseType;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import 'dart:collection';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
@ -16,7 +16,7 @@ class MenuTreeRepository {
|
||||
final AppLanguage appLanguage = AppLanguage();
|
||||
bool isEnglish = appLanguage.appLocal == Locale('en');
|
||||
|
||||
List<ExerciseTree> exerciseTree = Auth().getExerciseTree();
|
||||
List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
|
||||
if ( exerciseTree == null || exerciseTree.length == 0) {
|
||||
await ExerciseTreeApi().getExerciseTree();
|
||||
}
|
||||
@ -24,6 +24,10 @@ 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;
|
||||
if ( is1RM == false) {
|
||||
is1RM = false; //isParent1RM(treeItem.treeId);
|
||||
}
|
||||
this.tree[treeItem.name] = WorkoutTree(
|
||||
treeItem.treeId,
|
||||
treeItem.parentId,
|
||||
@ -33,11 +37,12 @@ class MenuTreeRepository {
|
||||
false,
|
||||
0,
|
||||
null,
|
||||
false
|
||||
false,
|
||||
is1RM
|
||||
);
|
||||
});
|
||||
|
||||
List<ExerciseType> exerciseTypes = Auth().getExerciseTypes();
|
||||
List<ExerciseType> exerciseTypes = Cache().getExerciseTypes();
|
||||
if ( exerciseTypes == null || exerciseTypes.length == 0) {
|
||||
await ExerciseTypeApi().getExerciseTypes();
|
||||
}
|
||||
@ -46,6 +51,7 @@ class MenuTreeRepository {
|
||||
String exerciseTypeName = isEnglish ?
|
||||
exerciseType.name : exerciseType.nameTranslation;
|
||||
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
||||
bool is1RM = false; //this.isParent1RM(exerciseType.treeId);
|
||||
this.tree[exerciseType.name] = WorkoutTree(
|
||||
exerciseType.exerciseTypeId,
|
||||
exerciseType.treeId,
|
||||
@ -56,11 +62,24 @@ class MenuTreeRepository {
|
||||
true,
|
||||
exerciseType.exerciseTypeId,
|
||||
exerciseType,
|
||||
exerciseType.base
|
||||
exerciseType.base,
|
||||
is1RM
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
bool isParent1RM(int treeId) {
|
||||
bool isTreeItem1RM = false;
|
||||
|
||||
for (int i = 0; i < this.tree.length; i++ ) {
|
||||
WorkoutTree treeItem = this.tree[i];
|
||||
if ( treeItem.id == treeId ) {
|
||||
isTreeItem1RM = treeItem.is1RM;
|
||||
break;
|
||||
}
|
||||
};
|
||||
return isTreeItem1RM;
|
||||
}
|
||||
|
||||
LinkedHashMap getBranch(int parent) {
|
||||
LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
|
||||
|
@ -1,18 +1,17 @@
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
|
||||
class APIClient extends ChangeNotifier {
|
||||
class APIClient with Common {
|
||||
|
||||
Future<String> get(String endPoint, String param) async {
|
||||
final url = Auth.getBaseUrl() + endPoint + param;
|
||||
String authToken = Auth().getAuthToken();
|
||||
final url = Cache.getBaseUrl() + endPoint + param;
|
||||
String authToken = Cache().getAuthToken();
|
||||
if ( authToken.length == 0 ) {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
Cache.username,
|
||||
Cache.password
|
||||
);
|
||||
authToken = responseJson['token'];
|
||||
}
|
||||
@ -21,7 +20,6 @@ class APIClient extends ChangeNotifier {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization' : "Bearer " + authToken }
|
||||
);
|
||||
notifyListeners();
|
||||
if(response.statusCode == 200) {
|
||||
return utf8.decode(response.bodyBytes);
|
||||
} else {
|
||||
@ -30,13 +28,13 @@ class APIClient extends ChangeNotifier {
|
||||
}
|
||||
|
||||
Future<String> post(String endPoint, String body) async {
|
||||
final url = Auth.getBaseUrl() + endPoint;
|
||||
final url = Cache.getBaseUrl() + endPoint;
|
||||
print(" ------------ http/post endpoint $endPoint body $body - url: $url ");
|
||||
String authToken = Auth().getAuthToken();
|
||||
String authToken = Cache().getAuthToken();
|
||||
if ( authToken.length == 0 ) {
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
Cache.username,
|
||||
Cache.password
|
||||
);
|
||||
authToken = responseJson['token'];
|
||||
}
|
||||
@ -48,14 +46,13 @@ class APIClient extends ChangeNotifier {
|
||||
},
|
||||
body: body,
|
||||
);
|
||||
String decodedResponse = Common.utf8convert(response.body);
|
||||
String decodedResponse = utf8convert(response.body);
|
||||
print(" ------------ response: " + decodedResponse);
|
||||
notifyListeners();
|
||||
return decodedResponse;
|
||||
}
|
||||
|
||||
static dynamic authenticateUser(String email, String password) async {
|
||||
var uri = Auth.getBaseUrl() + "authenticate";
|
||||
var uri = Cache.getBaseUrl() + "authenticate";
|
||||
|
||||
try {
|
||||
final body = '{"username":"$email", "password":"$password"}';
|
||||
@ -82,7 +79,7 @@ class APIClient extends ChangeNotifier {
|
||||
}
|
||||
|
||||
static fetch(var authToken, var endPoint) async {
|
||||
var uri = Auth.getBaseUrl() + endPoint;
|
||||
var uri = Cache.getBaseUrl() + endPoint;
|
||||
|
||||
try {
|
||||
final response = await http.get(
|
||||
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/user.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
|
||||
class CustomerApi {
|
||||
final APIClient _client=new APIClient();
|
||||
@ -44,7 +44,7 @@ class CustomerApi {
|
||||
throw new Exception(jsonDecode(responseBody)['error']);
|
||||
} else {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
Auth().afterRegistration(customer);
|
||||
Cache().afterRegistration(customer);
|
||||
}
|
||||
} on FormatException catch(exception) {
|
||||
throw new Exception(responseBody);
|
||||
@ -61,7 +61,7 @@ class CustomerApi {
|
||||
Customer customer;
|
||||
try {
|
||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
await Auth().afterLogin(customer);
|
||||
await Cache().afterLogin(customer);
|
||||
} on FormatException catch(exception) {
|
||||
throw new Exception(responseBody);
|
||||
}
|
||||
@ -76,12 +76,12 @@ class CustomerApi {
|
||||
"customers/"+customerId.toString(),
|
||||
body);
|
||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||
Auth().afterRegistration(customer);
|
||||
Cache().afterRegistration(customer);
|
||||
} catch (exception) {
|
||||
print ("Exception: " + exception.toString());
|
||||
print (" === go to registration ");
|
||||
Auth().logout();
|
||||
Auth().startPage = "registration";
|
||||
Cache().logout();
|
||||
Cache().startPage = "registration";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'api.dart';
|
||||
|
||||
@ -12,7 +12,7 @@ class ExerciseTreeApi {
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<ExerciseTree> exerciseTree = json.map((exerciseTree) =>
|
||||
ExerciseTree.fromJson(exerciseTree)).toList();
|
||||
Auth().setExerciseTree(exerciseTree);
|
||||
Cache().setExerciseTree(exerciseTree);
|
||||
return exerciseTree;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
|
||||
@ -11,7 +11,7 @@ class ExerciseTypeApi {
|
||||
final body = await _client.get("exercise_type/active", "");
|
||||
final Iterable json = jsonDecode(body);
|
||||
final List<ExerciseType> exerciseTypes = json.map( (exerciseType) => ExerciseType.fromJson(exerciseType) ).toList();
|
||||
Auth().setExerciseTypes(exerciseTypes);
|
||||
Cache().setExerciseTypes(exerciseTypes);
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,20 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class Common {
|
||||
mixin Common {
|
||||
|
||||
static const EMAIL_ERROR = "Please type a right email address here.";
|
||||
static const PASSWORD_ERROR = "The password must have at least 8 characters.";
|
||||
final EMAIL_ERROR = "Please type a right email address here.";
|
||||
final PASSWORD_ERROR = "The password must have at least 8 characters.";
|
||||
|
||||
|
||||
|
||||
static String toJson( Map<String, String> map ) {
|
||||
String toJson( Map<String, String> map ) {
|
||||
String rc = "{";
|
||||
map.forEach((key, value) {
|
||||
rc += "'$key':'$value'";
|
||||
@ -23,9 +23,9 @@ class Common {
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ExerciseType getExerciseType( int exerciseTypeId ) {
|
||||
ExerciseType getExerciseType( int exerciseTypeId ) {
|
||||
ExerciseType returnElement = null;
|
||||
List<ExerciseType> listExerciseType = Auth().getExerciseTypes();
|
||||
List<ExerciseType> listExerciseType = Cache().getExerciseTypes();
|
||||
if ( listExerciseType != null ) {
|
||||
for ( var element in listExerciseType ) {
|
||||
if (exerciseTypeId == element.exerciseTypeId) {
|
||||
@ -37,7 +37,7 @@ class Common {
|
||||
return returnElement;
|
||||
}
|
||||
|
||||
static String getDateLocale( DateTime datetime, bool timeDisplay ) {
|
||||
String getDateLocale( DateTime datetime, bool timeDisplay ) {
|
||||
AppLanguage appLanguage = AppLanguage();
|
||||
var date = datetime;
|
||||
|
||||
@ -49,16 +49,16 @@ class Common {
|
||||
return dateName;
|
||||
}
|
||||
|
||||
static String utf8convert(String text) {
|
||||
String utf8convert(String text) {
|
||||
List<int> bytes = text.toString().codeUnits;
|
||||
return utf8.decode(bytes);
|
||||
}
|
||||
|
||||
static double mediaSizeWidth( BuildContext context ) {
|
||||
double mediaSizeWidth( BuildContext context ) {
|
||||
return MediaQuery.of(context).size.width;
|
||||
}
|
||||
|
||||
static bool validateEmail(UserRepository userRepository) {
|
||||
bool validateEmail(UserRepository userRepository) {
|
||||
final String email = userRepository.user.email;
|
||||
final RegExp _emailRegExp = RegExp(
|
||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
|
||||
@ -66,7 +66,7 @@ class Common {
|
||||
return _emailRegExp.hasMatch(email);
|
||||
}
|
||||
|
||||
static bool validatePassword(UserRepository userRepository) {
|
||||
bool validatePassword(UserRepository userRepository) {
|
||||
final password = userRepository.user.password;
|
||||
final RegExp _passwordRegExp =
|
||||
RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$');
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/service/api.dart';
|
||||
import 'package:aitrainer_app/service/customer_service.dart';
|
||||
import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
||||
@ -7,7 +8,7 @@ import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||
import 'package:devicelocale/devicelocale.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
|
||||
//import '../push_notifications.dart';
|
||||
|
||||
@ -23,7 +24,7 @@ class Session {
|
||||
_sharedPreferences = await _prefs;
|
||||
|
||||
|
||||
if ( Auth().firstLoad ) {
|
||||
if ( Cache().firstLoad ) {
|
||||
|
||||
print (" -- Session: fetch locale..");
|
||||
await appLanguage.fetchLocale();
|
||||
@ -44,7 +45,7 @@ class Session {
|
||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||
try {
|
||||
languages = await Devicelocale.preferredLanguages;
|
||||
Auth().deviceLanguages = languages;
|
||||
Cache().deviceLanguages = languages;
|
||||
print("device langs " + languages.toString());
|
||||
|
||||
} on PlatformException {
|
||||
@ -64,44 +65,49 @@ class Session {
|
||||
_fetchToken(SharedPreferences prefs) async {
|
||||
|
||||
var responseJson = await APIClient.authenticateUser(
|
||||
Auth.username,
|
||||
Auth.password
|
||||
Cache.username,
|
||||
Cache.password
|
||||
);
|
||||
int customerId = 0;
|
||||
print("--- Lang: " + appLanguage.appLocal.toString());
|
||||
if(responseJson['error'] != null) {
|
||||
print("************** Here big error - no authentication");
|
||||
} else if (responseJson['token'] != null) {
|
||||
prefs.setString(Auth.authTokenKey, responseJson['token']);
|
||||
Auth auth = Auth();
|
||||
auth.authToken = responseJson['token'];
|
||||
if (prefs.get(Auth.customerIdKey) == null) {
|
||||
prefs.setString(Cache.authTokenKey, responseJson['token']);
|
||||
Cache().authToken = responseJson['token'];
|
||||
if (prefs.get(Cache.customerIdKey) == null) {
|
||||
print("************** Registration");
|
||||
// registration
|
||||
//Navigator.of(context).pushNamed('registration');
|
||||
prefs.setBool(Auth.isRegisteredKey, true);
|
||||
Auth().startPage = "registration";
|
||||
prefs.setBool(Cache.isRegisteredKey, true);
|
||||
Cache().startPage = "registration";
|
||||
} else {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime lastStoreDate = DateTime.parse(
|
||||
prefs.get(Auth.lastStoreDateKey));
|
||||
prefs.get(Cache.lastStoreDateKey));
|
||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||
|
||||
if (lastStoreDate == null ||
|
||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||
prefs.get(Auth.isLoggedInKey) == null ||
|
||||
prefs.get(Auth.isLoggedInKey) == false) {
|
||||
prefs.get(Cache.isLoggedInKey) == null ||
|
||||
prefs.get(Cache.isLoggedInKey) == false) {
|
||||
print("************* Login");
|
||||
//Navigator.of(context).pushNamed('login');
|
||||
Auth().startPage = "login";
|
||||
Cache().startPage = "login";
|
||||
} else {
|
||||
print("************** Store SharedPreferences");
|
||||
// get API customer
|
||||
await CustomerApi().getCustomer(prefs.getInt(Auth.customerIdKey));
|
||||
Auth().startPage = "home";
|
||||
customerId = prefs.getInt(Cache.customerIdKey);
|
||||
await CustomerApi().getCustomer(customerId);
|
||||
Cache().startPage = "home";
|
||||
}
|
||||
|
||||
await ExerciseTypeApi().getExerciseTypes();
|
||||
await ExerciseTreeApi().getExerciseTree();
|
||||
if ( customerId > 0) {
|
||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
exerciseRepository.getExercisesByCustomer(customerId);
|
||||
}
|
||||
print("--- Session finished");
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import 'package:flutter/cupertino.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AccountPage extends StatelessWidget {
|
||||
// ignore: close_sinks
|
||||
AccountBloc accountBloc;
|
||||
|
||||
@override
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
@ -24,7 +26,6 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
create: (context) =>
|
||||
CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()),
|
||||
child: Builder(builder: (context) {
|
||||
// ignore: close_sinks
|
||||
final exerciseBloc = BlocProvider.of<CustomExerciseFormBloc>(context);
|
||||
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
|
||||
|
||||
@ -189,6 +190,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
}
|
||||
|
||||
SliverGrid gridCalculation(CustomExerciseFormBloc bloc) {
|
||||
LinkedHashMap args = LinkedHashMap();
|
||||
return SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
@ -201,7 +203,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
textFieldBloc: bloc.rmWendlerField,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
@ -211,7 +213,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rmWathenField,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -223,7 +225,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rmOconnerField,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -235,7 +237,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rmMayhewField,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -247,7 +249,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rmAverageField,
|
||||
style: TextStyle(color: Colors.blueAccent, fontSize: 12),
|
||||
@ -259,7 +261,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm90Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -272,7 +274,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm75Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
@ -284,7 +286,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm75OconnorField,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
@ -296,7 +298,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm75WendlerField,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
@ -308,7 +310,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm80Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -320,7 +322,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm70Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -332,7 +334,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm60Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -344,7 +346,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
)),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: true,
|
||||
padding: EdgeInsets.only(left:30),
|
||||
padding: EdgeInsets.only(left:10),
|
||||
maxLines: 1,
|
||||
textFieldBloc: bloc.rm50Field,
|
||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||
@ -353,8 +355,45 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
||||
fillColor: Colors.white,
|
||||
filled: false,
|
||||
labelText: "1RM 50%: ",
|
||||
))
|
||||
])
|
||||
);
|
||||
)
|
||||
),
|
||||
RaisedButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: Colors.blue,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['exerciseRepository'] = bloc.exerciseRepository,
|
||||
args['percent'] = 0.75,
|
||||
Navigator.of(context).pushNamed('exerciseControlPage',
|
||||
arguments: args)
|
||||
},
|
||||
child: Text("Control with 75%",
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
RaisedButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: Colors.green,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
args['exerciseRepository'] = bloc.exerciseRepository,
|
||||
args['percent'] = 0.5,
|
||||
Navigator.of(context).pushNamed('exerciseControlPage',
|
||||
arguments: args )
|
||||
},
|
||||
child: Text("Control with 50%",
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -299,4 +299,4 @@ class CustomerModifyPage extends StatelessWidget{
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
321
lib/view/exercise_control_page.dart
Normal file
321
lib/view/exercise_control_page.dart
Normal file
@ -0,0 +1,321 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/exercise_control_form_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.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 ExerciseControlPage extends StatefulWidget{
|
||||
_ExerciseControlPage createState() => _ExerciseControlPage();
|
||||
}
|
||||
|
||||
class _ExerciseControlPage extends State<ExerciseControlPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
|
||||
final ExerciseRepository exerciseRepository = arguments['exerciseRepository'];
|
||||
final double percent = arguments['percent'];
|
||||
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
ExerciseControlFormBloc(exerciseRepository: exerciseRepository, percentToCalculate: percent),
|
||||
child: BlocBuilder<ExerciseControlFormBloc, FormBlocState>(
|
||||
builder: (context, state) {
|
||||
// ignore: close_sinks
|
||||
final exerciseBloc = BlocProvider.of<ExerciseControlFormBloc>(context);
|
||||
if ( state is FormBlocLoading ) {
|
||||
return LoadingDialog();
|
||||
} else if ( state is FormBlocSuccess) {
|
||||
return getControlForm(exerciseBloc);
|
||||
} else {
|
||||
return getControlForm(exerciseBloc);
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
Form getControlForm( ExerciseControlFormBloc 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.transparent,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
Text("1RM Control"),
|
||||
Image.asset(
|
||||
'asset/image/WT_long_logo.png',
|
||||
fit: BoxFit.cover,
|
||||
height: 65.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back, color: Colors.white),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
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,
|
||||
),
|
||||
FlatButton(
|
||||
child: Row(
|
||||
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Icon(Icons.question_answer),
|
||||
Text(AppLocalizations.of(context).translate(
|
||||
"Why do you need Exercise Control?"),
|
||||
style: TextStyle(
|
||||
color: Colors.blueAccent,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14)),
|
||||
Icon(Icons.arrow_forward_ios),
|
||||
]),
|
||||
textColor: Colors.blueAccent,
|
||||
color: Colors.transparent,
|
||||
onPressed: () =>
|
||||
{
|
||||
//Navigator.of(context).pushNamed('exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository),
|
||||
},
|
||||
),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate("Your 1RM:"),),
|
||||
Text(" " + exerciseBloc.initialRMField.value + " " +exerciseBloc.exerciseRepository.exerciseType
|
||||
.unitQuantityUnit,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate("1st Control Exercise:"),
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != 1,
|
||||
textFieldBloc: exerciseBloc.quantity1Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
||||
],
|
||||
onChanged: (input) => {
|
||||
print("Quantity 1 value $input"),
|
||||
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
||||
//exerciseBloc.exerciseRepository
|
||||
// .setUnit(exerciseBloc.exerciseRepository.exerciseType.unit)
|
||||
},
|
||||
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 + " 12 times!",
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: exerciseBloc.step == 1 ? Colors.blue : Colors.black26,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
exerciseBloc.submit()
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate("Check"),
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate("2nd Control Exercise:"),
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != 2,
|
||||
textFieldBloc: exerciseBloc.quantity2Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
||||
],
|
||||
onChanged: (input) => {
|
||||
print("Quantity 2 value $input"),
|
||||
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
||||
//exerciseBloc.exerciseRepository
|
||||
// .setUnit(exerciseBloc.exerciseRepository.exerciseType.unit)
|
||||
},
|
||||
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.unitQuantity2Field.value + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " 12 times!",
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: exerciseBloc.step == 2 ? Colors.blue : Colors.black26,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
exerciseBloc.submit()
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate("Check"),
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(),
|
||||
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(AppLocalizations.of(context).translate("3rd Control Exercise:"),
|
||||
style: TextStyle(),),
|
||||
TextFieldBlocBuilder(
|
||||
readOnly: exerciseBloc.step != 3,
|
||||
textFieldBloc: exerciseBloc.quantity3Field,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.deepOrange,
|
||||
fontWeight: FontWeight.bold),
|
||||
inputFormatters: [
|
||||
WhitelistingTextInputFormatter (RegExp(r"[\d.]"))
|
||||
],
|
||||
onChanged: (input) => {
|
||||
print("Quantity 3 value $input"),
|
||||
//exerciseBloc.exerciseRepository.setQuantity(double.parse(input)),
|
||||
//exerciseBloc.exerciseRepository
|
||||
// .setUnit(exerciseBloc.exerciseRepository.exerciseType.unit)
|
||||
},
|
||||
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.unitQuantity3Field.value + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " 12 times!",
|
||||
),
|
||||
),
|
||||
RaisedButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
textColor: Colors.white,
|
||||
color: exerciseBloc.step == 3 ? Colors.blue : Colors.black26,
|
||||
focusColor: Colors.blueAccent,
|
||||
onPressed: () =>
|
||||
{
|
||||
exerciseBloc.submit()
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).translate("Check"),
|
||||
style: TextStyle(fontSize: 12),)
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
]),
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import 'package:aitrainer_app/bloc/exercise_form_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -283,7 +283,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
||||
FlatButton(
|
||||
child: Text(AppLocalizations.of(context).translate("Yes")),
|
||||
onPressed: () => {
|
||||
bloc.exerciseRepository.setCustomer(Auth().userLoggedIn),
|
||||
bloc.exerciseRepository.setCustomer(Cache().userLoggedIn),
|
||||
bloc.exerciseRepository.addExercise(),
|
||||
|
||||
Navigator.pop(context),
|
||||
|
@ -26,7 +26,7 @@ class LoginWidget extends StatefulWidget {
|
||||
State<StatefulWidget> createState() => _LoginWidget();
|
||||
}
|
||||
|
||||
class _LoginWidget extends State<LoginWidget> {
|
||||
class _LoginWidget extends State<LoginWidget> with Common {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@ -72,7 +72,7 @@ class _LoginWidget extends State<LoginWidget> {
|
||||
}
|
||||
|
||||
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
|
||||
final cWidth = Common.mediaSizeWidth(context);
|
||||
final cWidth = mediaSizeWidth(context);
|
||||
|
||||
return Form(
|
||||
key: _formKey,
|
||||
|
@ -1,5 +1,7 @@
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_page_widget.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@ -9,39 +11,30 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MenuPage extends StatelessWidget {
|
||||
class MenuPage extends StatefulWidget {
|
||||
static const routeName = '/menu_page';
|
||||
int parent;
|
||||
MenuBloc menuBloc;
|
||||
|
||||
MenuPage({this.parent});
|
||||
|
||||
_MenuPage createState() => _MenuPage();
|
||||
}
|
||||
|
||||
class _MenuPage extends State<MenuPage> {
|
||||
// ignore: close_sinks
|
||||
MenuBloc menuBloc;
|
||||
|
||||
|
||||
|
||||
void checkTest() {
|
||||
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(AppLocalizations.of(context).translate("Tests")),
|
||||
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: () =>
|
||||
{
|
||||
menuBloc.add(MenuTreeUp(parent: 0))
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
appBar: AppBarNav(),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
|
@ -34,13 +34,13 @@ class RegistrationWidget extends StatefulWidget {
|
||||
State<StatefulWidget> createState() => _RegistrationWidget();
|
||||
}
|
||||
|
||||
class _RegistrationWidget extends State<RegistrationWidget> {
|
||||
class _RegistrationWidget extends State<RegistrationWidget> with Common {
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final cWidth = Common.mediaSizeWidth(context);
|
||||
final cWidth = mediaSizeWidth(context);
|
||||
// ignore: close_sinks
|
||||
final accountBloc = BlocProvider.of<AccountBloc>(context);
|
||||
return BlocProvider(
|
||||
|
@ -2,7 +2,7 @@ import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:aitrainer_app/widgets/splash.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
153
lib/widgets/app_bar.dart
Normal file
153
lib/widgets/app_bar.dart
Normal file
@ -0,0 +1,153 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/animations/test_progress_animation.dart';
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:rainbow_color/rainbow_color.dart';
|
||||
|
||||
|
||||
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
||||
final MenuBloc menuBloc;
|
||||
const AppBarNav({this.menuBloc});
|
||||
|
||||
@override
|
||||
_AppBarNav createState() => _AppBarNav();
|
||||
|
||||
@override
|
||||
Size get preferredSize => const Size.fromHeight(60);
|
||||
}
|
||||
|
||||
class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin {
|
||||
Animation<Color> colorAnim;
|
||||
//Animation<double> sizeAnim;
|
||||
AnimationController colorController;
|
||||
//AnimationController sizeController;
|
||||
MenuBloc menuBloc;
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
colorController =
|
||||
AnimationController(duration: Duration(seconds: 4), vsync: this);
|
||||
//sizeController =
|
||||
// AnimationController(duration: Duration(seconds: 3), vsync: this);
|
||||
|
||||
/* final curvedAnimation = CurvedAnimation(
|
||||
parent: sizeController,
|
||||
curve: Curves.easeIn,
|
||||
reverseCurve: Curves.easeInOutBack,
|
||||
);
|
||||
|
||||
sizeAnim =
|
||||
Tween<double>(begin: 0, end: 1.5).animate(curvedAnimation)
|
||||
..addStatusListener((status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
sizeController.reverse();
|
||||
} else if (status == AnimationStatus.dismissed) {
|
||||
Timer(Duration(seconds: 5), () {
|
||||
sizeController.forward();
|
||||
});
|
||||
}
|
||||
}); */
|
||||
colorAnim = RainbowColorTween([Colors.white70,
|
||||
Colors.greenAccent,
|
||||
Colors.lightGreen,
|
||||
Colors.lightGreenAccent,
|
||||
Colors.yellow,
|
||||
Colors.yellowAccent,
|
||||
Colors.orange,
|
||||
Colors.orangeAccent,
|
||||
Colors.white70])
|
||||
.animate(colorController)
|
||||
..addListener(() { setState(() {}); })
|
||||
..addStatusListener((status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
Timer(Duration(seconds: 10), () {
|
||||
colorController.reset();
|
||||
colorController.forward();
|
||||
});
|
||||
} else if (status == AnimationStatus.dismissed) {
|
||||
colorController.forward();
|
||||
}
|
||||
});
|
||||
colorController.forward();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
menuBloc = BlocProvider.of<MenuBloc>(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: () =>
|
||||
{
|
||||
menuBloc.add(MenuTreeUp(parent: 0))
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
//sizeController.dispose();
|
||||
colorController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget getAnimatedWidget() {
|
||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
exerciseRepository.getExerciseList();
|
||||
if ( exerciseRepository.exerciseList == null || exerciseRepository.exerciseList.length == 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 {
|
||||
double percent = 0.61;//exerciseRepository.getBaseExerciseFinishedPercent();
|
||||
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: Colors.blue,
|
||||
animation: true,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import 'package:aitrainer_app/bloc/session/session_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_language.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/view/registration.dart';
|
||||
@ -69,9 +69,9 @@ class _HomePageState extends State<AitrainerHome> {
|
||||
return LoadingScreenMain();
|
||||
} else if (state is SessionReady) {
|
||||
print("ready");
|
||||
if (Auth().startPage == 'login') {
|
||||
if (Cache().startPage == 'login') {
|
||||
return LoginPage();
|
||||
} else if (Auth().startPage == 'registration') {
|
||||
} else if (Cache().startPage == 'registration') {
|
||||
return RegistrationPage();
|
||||
} else {
|
||||
return MenuPage(parent: 0);
|
||||
|
@ -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(
|
||||
|
@ -2,7 +2,7 @@ import 'dart:ui';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/auth.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -75,7 +75,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
menuBloc.add(MenuTreeDown(parent: workoutTree.id));
|
||||
} else {
|
||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||
if (Auth().userLoggedIn == null) {
|
||||
if (Cache().userLoggedIn == null) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
backgroundColor: Colors.orange,
|
||||
content: Text(
|
||||
@ -85,6 +85,9 @@ class MenuPageWidget extends StatelessWidget {
|
||||
if (workoutTree.exerciseType.name == "Custom") {
|
||||
Navigator.of(context).pushNamed('exerciseCustomPage',
|
||||
arguments: workoutTree.exerciseType);
|
||||
} else if (workoutTree.exerciseType.name == "Control") {
|
||||
Navigator.of(context).pushNamed('exerciseControlPage',
|
||||
arguments: workoutTree.exerciseType);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed('exerciseNewPage',
|
||||
arguments: workoutTree.exerciseType);
|
||||
@ -122,7 +125,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
height: 180,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
String url =
|
||||
Auth.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
|
||||
Cache.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
|
||||
Widget image = FadeInImage.assetNetwork(
|
||||
placeholder: 'asset/image/dots.gif',
|
||||
image: url,
|
||||
@ -132,7 +135,7 @@ class MenuPageWidget extends StatelessWidget {
|
||||
},
|
||||
);
|
||||
} on Exception catch (_) {
|
||||
String url = Auth.mediaUrl + '/images/' + workoutTree.imageName;
|
||||
String url = Cache.mediaUrl + '/images/' + workoutTree.imageName;
|
||||
image = FadeInImage.assetNetwork(
|
||||
placeholder: 'asset/image/dots.gif',
|
||||
image: url,
|
||||
|
173
pubspec.lock
173
pubspec.lock
@ -49,7 +49,7 @@ packages:
|
||||
name: bloc_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
version: "7.0.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -57,6 +57,62 @@ packages:
|
||||
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"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -71,6 +127,13 @@ packages:
|
||||
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:
|
||||
@ -85,6 +148,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -127,6 +197,13 @@ packages:
|
||||
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:
|
||||
@ -140,7 +217,7 @@ packages:
|
||||
name: equatable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.3"
|
||||
version: "1.2.4"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -155,6 +232,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.1"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -236,6 +320,20 @@ packages:
|
||||
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
|
||||
@ -248,6 +346,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -304,6 +409,13 @@ packages:
|
||||
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:
|
||||
@ -401,7 +513,7 @@ packages:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -409,6 +521,13 @@ packages:
|
||||
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:
|
||||
@ -450,7 +569,7 @@ packages:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "4.3.2+1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -458,6 +577,13 @@ packages:
|
||||
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:
|
||||
@ -465,6 +591,20 @@ packages:
|
||||
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:
|
||||
@ -485,14 +625,14 @@ packages:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.8"
|
||||
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+1"
|
||||
version: "0.0.2+2"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -547,6 +687,13 @@ packages:
|
||||
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:
|
||||
@ -589,6 +736,13 @@ packages:
|
||||
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:
|
||||
@ -631,6 +785,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.10"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+2"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
14
pubspec.yaml
14
pubspec.yaml
@ -33,9 +33,12 @@ dependencies:
|
||||
flutter_local_notifications: 1.1.1
|
||||
flutter_facebook_login: ^3.0.0
|
||||
flutter_bloc: ^6.0.1
|
||||
equatable: ^1.2.3
|
||||
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
|
||||
|
||||
mockito: ^4.1.1
|
||||
|
||||
@ -46,12 +49,15 @@ dev_dependencies:
|
||||
flutter_driver:
|
||||
sdk: flutter
|
||||
test: any
|
||||
bloc_test: ^7.0.1
|
||||
bloc_test: ^7.0.2
|
||||
|
||||
build_runner:
|
||||
|
||||
|
||||
http: 0.12.1
|
||||
provider: ^4.3.2
|
||||
provider: ^4.3.2+1
|
||||
intl: 0.16.1
|
||||
shared_preferences: ^0.5.8
|
||||
shared_preferences: ^0.5.10
|
||||
|
||||
flutter_launcher_icons: ^0.7.5
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
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());
|
||||
});
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
|
||||
class MockUserRepository extends Mock implements UserRepository {
|
||||
class MockUserRepository extends Mock implements UserRepository {
|
||||
final User user = User();
|
||||
|
||||
setEmail(String email) {
|
||||
@ -43,15 +43,23 @@ class MockUserRepository extends Mock implements UserRepository {
|
||||
class MockLoginBloc extends MockBloc<FormBlocEvent>
|
||||
implements LoginFormBloc {}
|
||||
|
||||
class MockCommon with Common {
|
||||
String getEmailError() {
|
||||
return EMAIL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
group('LoginScreen', () {
|
||||
MockLoginBloc loginBloc;
|
||||
MockUserRepository userRepository;
|
||||
Widget loginWidget;
|
||||
MockCommon common;
|
||||
|
||||
setUp(() {
|
||||
loginBloc = MockLoginBloc();
|
||||
userRepository = MockUserRepository();
|
||||
common = MockCommon();
|
||||
|
||||
loginWidget =
|
||||
MaterialApp(
|
||||
@ -100,7 +108,7 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(okButton);
|
||||
await tester.pump(const Duration(milliseconds: 500)); // add delay
|
||||
final emailErrorFinder = find.text(Common.EMAIL_ERROR);
|
||||
final emailErrorFinder = find.text(common.getEmailError());
|
||||
expect(emailErrorFinder, findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user