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",
|
"Endomorph": "Endomorph",
|
||||||
"Mesomorph": "Mesomorph",
|
"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",
|
"Endomorph":"Endomorf",
|
||||||
"Mesomorph":"Mezomorf",
|
"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 '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/model/customer.dart';
|
||||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
@ -14,8 +14,8 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
|||||||
final CustomerRepository customerRepository;
|
final CustomerRepository customerRepository;
|
||||||
bool loggedIn = false;
|
bool loggedIn = false;
|
||||||
AccountBloc({this.customerRepository}) : super(AccountInitial()) {
|
AccountBloc({this.customerRepository}) : super(AccountInitial()) {
|
||||||
if ( Auth().userLoggedIn != null ) {
|
if ( Cache().userLoggedIn != null ) {
|
||||||
customerRepository.customer = Auth().userLoggedIn;
|
customerRepository.customer = Cache().userLoggedIn;
|
||||||
loggedIn = true;
|
loggedIn = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
|||||||
customerRepository.customer = event.customer;
|
customerRepository.customer = event.customer;
|
||||||
yield AccountLoggedIn();
|
yield AccountLoggedIn();
|
||||||
} else if (event is AccountLogout) {
|
} else if (event is AccountLogout) {
|
||||||
await Auth().logout();
|
await Cache().logout();
|
||||||
customerRepository.customer = null;
|
customerRepository.customer = null;
|
||||||
loggedIn = false;
|
loggedIn = false;
|
||||||
yield AccountLoggedOut();
|
yield AccountLoggedOut();
|
||||||
|
@ -92,9 +92,7 @@ class CustomExerciseFormBloc extends FormBloc<String, String> {
|
|||||||
exerciseRepository.rmWathen =
|
exerciseRepository.rmWathen =
|
||||||
100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
|
100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
|
||||||
rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1));
|
rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1));
|
||||||
double average = (exerciseRepository.rmWendler + exerciseRepository.rmWathen +
|
double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner)/2;
|
||||||
exerciseRepository.rmMayhew + exerciseRepository.rmOconner +
|
|
||||||
exerciseRepository.rmMcglothlin)/4;
|
|
||||||
rmAverageField.updateValue(average.toStringAsFixed(1));
|
rmAverageField.updateValue(average.toStringAsFixed(1));
|
||||||
rm90Field.updateValue((average*0.9).toStringAsFixed(1));
|
rm90Field.updateValue((average*0.9).toStringAsFixed(1));
|
||||||
rm80Field.updateValue((average*0.8).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/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/repository/user_repository.dart';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
import 'package:flutter_form_bloc/flutter_form_bloc.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 AccountBloc accountBloc;
|
||||||
final UserRepository userRepository;
|
final UserRepository userRepository;
|
||||||
|
|
||||||
@ -40,18 +40,18 @@ class LoginFormBloc extends FormBloc<String, String> {
|
|||||||
void onSubmitting() async {
|
void onSubmitting() async {
|
||||||
try {
|
try {
|
||||||
emitLoading(progress: 30);
|
emitLoading(progress: 30);
|
||||||
if ( ! Common.validateEmail(userRepository)) {
|
if ( ! validateEmail(userRepository)) {
|
||||||
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
|
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
|
||||||
|
|
||||||
emitFailure(failureResponse: Common.EMAIL_ERROR);
|
emitFailure(failureResponse: EMAIL_ERROR);
|
||||||
} else if ( ! Common.validatePassword(userRepository)) {
|
} else if ( ! validatePassword(userRepository)) {
|
||||||
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
|
passwordField.addFieldError( PASSWORD_ERROR, isPermanent: true);
|
||||||
emitFailure(failureResponse: Common.PASSWORD_ERROR);
|
emitFailure(failureResponse: PASSWORD_ERROR);
|
||||||
} else {
|
} else {
|
||||||
// Emit either Loaded or Error
|
// Emit either Loaded or Error
|
||||||
await userRepository.getUser();
|
await userRepository.getUser();
|
||||||
emitSuccess(canSubmitAgain: false);
|
emitSuccess(canSubmitAgain: false);
|
||||||
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
|
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
|
||||||
}
|
}
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
emitFailure(failureResponse: ex.toString());
|
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/repository/user_repository.dart';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||||
import 'account/account_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 AccountBloc accountBloc;
|
||||||
final emailField = TextFieldBloc(
|
final emailField = TextFieldBloc(
|
||||||
validators: [
|
validators: [
|
||||||
@ -38,18 +38,18 @@ class RegistrationFormBloc extends FormBloc<String, String> {
|
|||||||
void onSubmitting() async {
|
void onSubmitting() async {
|
||||||
try {
|
try {
|
||||||
emitLoading(progress: 30);
|
emitLoading(progress: 30);
|
||||||
if ( ! Common.validateEmail(userRepository)) {
|
if ( ! validateEmail(userRepository)) {
|
||||||
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
|
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
|
||||||
|
|
||||||
emitFailure(failureResponse: Common.EMAIL_ERROR);
|
emitFailure(failureResponse: EMAIL_ERROR);
|
||||||
} else if ( ! Common.validatePassword(userRepository)) {
|
} else if ( ! validatePassword(userRepository)) {
|
||||||
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
|
passwordField.addFieldError(PASSWORD_ERROR, isPermanent: true);
|
||||||
emitFailure(failureResponse: Common.PASSWORD_ERROR);
|
emitFailure(failureResponse: PASSWORD_ERROR);
|
||||||
} else {
|
} else {
|
||||||
// Emit either Loaded or Error
|
// Emit either Loaded or Error
|
||||||
await userRepository.addUser();
|
await userRepository.addUser();
|
||||||
emitSuccess(canSubmitAgain: false);
|
emitSuccess(canSubmitAgain: false);
|
||||||
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
|
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
|
||||||
}
|
}
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
emitFailure(failureResponse: ex.toString());
|
emitFailure(failureResponse: ex.toString());
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
|
||||||
import 'package:aitrainer_app/util/session.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_goal_page.dart';
|
||||||
import 'package:aitrainer_app/view/customer_modify_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/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/exercise_type_description.dart';
|
||||||
import 'package:aitrainer_app/view/gdpr.dart';
|
import 'package:aitrainer_app/view/gdpr.dart';
|
||||||
import 'package:aitrainer_app/view/login.dart';
|
import 'package:aitrainer_app/view/login.dart';
|
||||||
@ -163,6 +163,7 @@ class AitrainerApp extends StatelessWidget {
|
|||||||
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
||||||
'exerciseNewPage': (context) => ExerciseNewPage(),
|
'exerciseNewPage': (context) => ExerciseNewPage(),
|
||||||
'exerciseCustomPage': (context) => CustomExercisePage(),
|
'exerciseCustomPage': (context) => CustomExercisePage(),
|
||||||
|
'exerciseControlPage': (context) => ExerciseControlPage(),
|
||||||
'login': (context) => LoginPage(),
|
'login': (context) => LoginPage(),
|
||||||
'registration': (context) => RegistrationPage(),
|
'registration': (context) => RegistrationPage(),
|
||||||
'gdpr': (context) => Gdpr(),
|
'gdpr': (context) => Gdpr(),
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/model/customer.dart';
|
import 'package:aitrainer_app/model/customer.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
|
import 'package:aitrainer_app/model/exercise.dart';
|
||||||
|
import 'package:aitrainer_app/model/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/exercise_tree_service.dart';
|
||||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
@ -27,8 +32,8 @@ enum SharePrefsChange {
|
|||||||
- is_logged_in
|
- is_logged_in
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Auth {
|
class Cache {
|
||||||
static final Auth _singleton = Auth._internal();
|
static final Cache _singleton = Cache._internal();
|
||||||
|
|
||||||
// Keys to store and fetch data from SharedPreferences
|
// Keys to store and fetch data from SharedPreferences
|
||||||
static final String authTokenKey = 'auth_token';
|
static final String authTokenKey = 'auth_token';
|
||||||
@ -45,16 +50,20 @@ class Auth {
|
|||||||
String authToken = "";
|
String authToken = "";
|
||||||
Customer userLoggedIn;
|
Customer userLoggedIn;
|
||||||
bool firstLoad = true;
|
bool firstLoad = true;
|
||||||
|
|
||||||
List<ExerciseType> _exerciseTypes;
|
List<ExerciseType> _exerciseTypes;
|
||||||
List<ExerciseTree> _exerciseTree;
|
List<ExerciseTree> _exerciseTree;
|
||||||
|
List<Exercise> _exercises;
|
||||||
|
LinkedHashMap _tree = LinkedHashMap<String, WorkoutTree>();
|
||||||
|
|
||||||
List deviceLanguages;
|
List deviceLanguages;
|
||||||
String startPage;
|
String startPage;
|
||||||
|
|
||||||
factory Auth() {
|
factory Cache() {
|
||||||
return _singleton;
|
return _singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
Auth._internal();
|
Cache._internal();
|
||||||
|
|
||||||
String getAuthToken() {
|
String getAuthToken() {
|
||||||
return this.authToken;
|
return this.authToken;
|
||||||
@ -101,23 +110,26 @@ class Auth {
|
|||||||
sharedPreferences = await prefs;
|
sharedPreferences = await prefs;
|
||||||
|
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
sharedPreferences.setString(Auth.lastStoreDateKey, now.toString());
|
sharedPreferences.setString(Cache.lastStoreDateKey, now.toString());
|
||||||
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
if ( type == SharePrefsChange.registration ) {
|
if ( type == SharePrefsChange.registration ) {
|
||||||
Auth().startPage = "home";
|
Cache().startPage = "home";
|
||||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
sharedPreferences.setInt(Cache.customerIdKey, customerId);
|
||||||
sharedPreferences.setBool(Auth.isRegisteredKey, true);
|
sharedPreferences.setBool(Cache.isRegisteredKey, true);
|
||||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
sharedPreferences.setBool(Cache.isLoggedInKey, true);
|
||||||
await ExerciseTypeApi().getExerciseTypes();
|
await ExerciseTypeApi().getExerciseTypes();
|
||||||
await ExerciseTreeApi().getExerciseTree();
|
await ExerciseTreeApi().getExerciseTree();
|
||||||
|
exerciseRepository.getExercisesByCustomer(customerId);
|
||||||
} else if ( type == SharePrefsChange.login ) {
|
} else if ( type == SharePrefsChange.login ) {
|
||||||
Auth().startPage = "home";
|
Cache().startPage = "home";
|
||||||
sharedPreferences.setInt(Auth.customerIdKey, customerId);
|
sharedPreferences.setInt(Cache.customerIdKey, customerId);
|
||||||
sharedPreferences.setBool(Auth.isLoggedInKey, true);
|
sharedPreferences.setBool(Cache.isLoggedInKey, true);
|
||||||
await ExerciseTypeApi().getExerciseTypes();
|
await ExerciseTypeApi().getExerciseTypes();
|
||||||
await ExerciseTreeApi().getExerciseTree();
|
await ExerciseTreeApi().getExerciseTree();
|
||||||
|
exerciseRepository.getExercisesByCustomer(customerId);
|
||||||
} else if ( type == SharePrefsChange.logout ) {
|
} else if ( type == SharePrefsChange.logout ) {
|
||||||
sharedPreferences.setBool(Auth.isLoggedInKey, false);
|
sharedPreferences.setBool(Cache.isLoggedInKey, false);
|
||||||
sharedPreferences.setInt(Auth.customerIdKey, 0);
|
sharedPreferences.setInt(Cache.customerIdKey, 0);
|
||||||
sharedPreferences.setString(authTokenKey, "");
|
sharedPreferences.setString(authTokenKey, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,6 +142,14 @@ class Auth {
|
|||||||
this._exerciseTree = exerciseTree;
|
this._exerciseTree = exerciseTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setExercises( List<Exercise> exercises ) {
|
||||||
|
this._exercises = exercises;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWorkoutTree( LinkedHashMap<String, WorkoutTree> tree) {
|
||||||
|
this._tree = tree;
|
||||||
|
}
|
||||||
|
|
||||||
List<ExerciseType> getExerciseTypes() {
|
List<ExerciseType> getExerciseTypes() {
|
||||||
return this._exerciseTypes;
|
return this._exerciseTypes;
|
||||||
}
|
}
|
||||||
@ -137,4 +157,13 @@ class Auth {
|
|||||||
List<ExerciseTree> getExerciseTree() {
|
List<ExerciseTree> getExerciseTree() {
|
||||||
return this._exerciseTree;
|
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 nameTranslation;
|
||||||
String descriptionTranslation;
|
String descriptionTranslation;
|
||||||
|
|
||||||
|
bool is1RM;
|
||||||
|
|
||||||
ExerciseType({this.name, this.description});
|
ExerciseType({this.name, this.description});
|
||||||
|
|
||||||
ExerciseType.fromJson(Map json) {
|
ExerciseType.fromJson(Map json) {
|
||||||
@ -41,4 +43,12 @@ class ExerciseType {
|
|||||||
"unitQuantityUnit": unitQuantityUnit,
|
"unitQuantityUnit": unitQuantityUnit,
|
||||||
"active": active
|
"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 email;
|
||||||
String password;
|
String password;
|
||||||
int customerId;
|
int customerId;
|
||||||
|
@ -14,6 +14,8 @@ class WorkoutTree {
|
|||||||
ExerciseType exerciseType;
|
ExerciseType exerciseType;
|
||||||
bool base;
|
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/customer.dart';
|
||||||
import 'package:aitrainer_app/model/exercise.dart';
|
import 'package:aitrainer_app/model/exercise.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
@ -7,6 +8,7 @@ class ExerciseRepository {
|
|||||||
Exercise exercise;
|
Exercise exercise;
|
||||||
Customer customer;
|
Customer customer;
|
||||||
ExerciseType exerciseType;
|
ExerciseType exerciseType;
|
||||||
|
List<Exercise> exerciseList;
|
||||||
|
|
||||||
double rmWendler = 0;
|
double rmWendler = 0;
|
||||||
double rmMcglothlin = 0;
|
double rmMcglothlin = 0;
|
||||||
@ -79,10 +81,51 @@ class ExerciseRepository {
|
|||||||
this.exerciseType = exerciseType;
|
this.exerciseType = exerciseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Future<List<ExerciseRepository>> getExercisesByCustomer( int customerId ) async {
|
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async {
|
||||||
final results = await ExerciseApi().getExercisesByCustomer(customerId);
|
final results = await ExerciseApi().getExercisesByCustomer(customerId);
|
||||||
this.exerciseList = results.map((item) => ExerciseRepository(exercise: item)).toList();
|
this.exerciseList = results;
|
||||||
|
Cache().setExercises(exerciseList);
|
||||||
return this.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 'dart:collection';
|
||||||
import 'package:aitrainer_app/localization/app_language.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/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||||
@ -16,7 +16,7 @@ class MenuTreeRepository {
|
|||||||
final AppLanguage appLanguage = AppLanguage();
|
final AppLanguage appLanguage = AppLanguage();
|
||||||
bool isEnglish = appLanguage.appLocal == Locale('en');
|
bool isEnglish = appLanguage.appLocal == Locale('en');
|
||||||
|
|
||||||
List<ExerciseTree> exerciseTree = Auth().getExerciseTree();
|
List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
|
||||||
if ( exerciseTree == null || exerciseTree.length == 0) {
|
if ( exerciseTree == null || exerciseTree.length == 0) {
|
||||||
await ExerciseTreeApi().getExerciseTree();
|
await ExerciseTreeApi().getExerciseTree();
|
||||||
}
|
}
|
||||||
@ -24,6 +24,10 @@ class MenuTreeRepository {
|
|||||||
exerciseTree.forEach( (treeItem) async {
|
exerciseTree.forEach( (treeItem) async {
|
||||||
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
|
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
|
||||||
String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7);
|
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(
|
this.tree[treeItem.name] = WorkoutTree(
|
||||||
treeItem.treeId,
|
treeItem.treeId,
|
||||||
treeItem.parentId,
|
treeItem.parentId,
|
||||||
@ -33,11 +37,12 @@ class MenuTreeRepository {
|
|||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
null,
|
null,
|
||||||
false
|
false,
|
||||||
|
is1RM
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
List<ExerciseType> exerciseTypes = Auth().getExerciseTypes();
|
List<ExerciseType> exerciseTypes = Cache().getExerciseTypes();
|
||||||
if ( exerciseTypes == null || exerciseTypes.length == 0) {
|
if ( exerciseTypes == null || exerciseTypes.length == 0) {
|
||||||
await ExerciseTypeApi().getExerciseTypes();
|
await ExerciseTypeApi().getExerciseTypes();
|
||||||
}
|
}
|
||||||
@ -46,6 +51,7 @@ class MenuTreeRepository {
|
|||||||
String exerciseTypeName = isEnglish ?
|
String exerciseTypeName = isEnglish ?
|
||||||
exerciseType.name : exerciseType.nameTranslation;
|
exerciseType.name : exerciseType.nameTranslation;
|
||||||
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
||||||
|
bool is1RM = false; //this.isParent1RM(exerciseType.treeId);
|
||||||
this.tree[exerciseType.name] = WorkoutTree(
|
this.tree[exerciseType.name] = WorkoutTree(
|
||||||
exerciseType.exerciseTypeId,
|
exerciseType.exerciseTypeId,
|
||||||
exerciseType.treeId,
|
exerciseType.treeId,
|
||||||
@ -56,11 +62,24 @@ class MenuTreeRepository {
|
|||||||
true,
|
true,
|
||||||
exerciseType.exerciseTypeId,
|
exerciseType.exerciseTypeId,
|
||||||
exerciseType,
|
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 getBranch(int parent) {
|
||||||
LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
|
LinkedHashMap branch = LinkedHashMap<String, WorkoutTree>();
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
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 {
|
Future<String> get(String endPoint, String param) async {
|
||||||
final url = Auth.getBaseUrl() + endPoint + param;
|
final url = Cache.getBaseUrl() + endPoint + param;
|
||||||
String authToken = Auth().getAuthToken();
|
String authToken = Cache().getAuthToken();
|
||||||
if ( authToken.length == 0 ) {
|
if ( authToken.length == 0 ) {
|
||||||
var responseJson = await APIClient.authenticateUser(
|
var responseJson = await APIClient.authenticateUser(
|
||||||
Auth.username,
|
Cache.username,
|
||||||
Auth.password
|
Cache.password
|
||||||
);
|
);
|
||||||
authToken = responseJson['token'];
|
authToken = responseJson['token'];
|
||||||
}
|
}
|
||||||
@ -21,7 +20,6 @@ class APIClient extends ChangeNotifier {
|
|||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization' : "Bearer " + authToken }
|
'Authorization' : "Bearer " + authToken }
|
||||||
);
|
);
|
||||||
notifyListeners();
|
|
||||||
if(response.statusCode == 200) {
|
if(response.statusCode == 200) {
|
||||||
return utf8.decode(response.bodyBytes);
|
return utf8.decode(response.bodyBytes);
|
||||||
} else {
|
} else {
|
||||||
@ -30,13 +28,13 @@ class APIClient extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> post(String endPoint, String body) async {
|
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 ");
|
print(" ------------ http/post endpoint $endPoint body $body - url: $url ");
|
||||||
String authToken = Auth().getAuthToken();
|
String authToken = Cache().getAuthToken();
|
||||||
if ( authToken.length == 0 ) {
|
if ( authToken.length == 0 ) {
|
||||||
var responseJson = await APIClient.authenticateUser(
|
var responseJson = await APIClient.authenticateUser(
|
||||||
Auth.username,
|
Cache.username,
|
||||||
Auth.password
|
Cache.password
|
||||||
);
|
);
|
||||||
authToken = responseJson['token'];
|
authToken = responseJson['token'];
|
||||||
}
|
}
|
||||||
@ -48,14 +46,13 @@ class APIClient extends ChangeNotifier {
|
|||||||
},
|
},
|
||||||
body: body,
|
body: body,
|
||||||
);
|
);
|
||||||
String decodedResponse = Common.utf8convert(response.body);
|
String decodedResponse = utf8convert(response.body);
|
||||||
print(" ------------ response: " + decodedResponse);
|
print(" ------------ response: " + decodedResponse);
|
||||||
notifyListeners();
|
|
||||||
return decodedResponse;
|
return decodedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dynamic authenticateUser(String email, String password) async {
|
static dynamic authenticateUser(String email, String password) async {
|
||||||
var uri = Auth.getBaseUrl() + "authenticate";
|
var uri = Cache.getBaseUrl() + "authenticate";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final body = '{"username":"$email", "password":"$password"}';
|
final body = '{"username":"$email", "password":"$password"}';
|
||||||
@ -82,7 +79,7 @@ class APIClient extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static fetch(var authToken, var endPoint) async {
|
static fetch(var authToken, var endPoint) async {
|
||||||
var uri = Auth.getBaseUrl() + endPoint;
|
var uri = Cache.getBaseUrl() + endPoint;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final response = await http.get(
|
final response = await http.get(
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||||||
import 'package:aitrainer_app/model/customer.dart';
|
import 'package:aitrainer_app/model/customer.dart';
|
||||||
import 'package:aitrainer_app/model/user.dart';
|
import 'package:aitrainer_app/model/user.dart';
|
||||||
import 'package:aitrainer_app/service/api.dart';
|
import 'package:aitrainer_app/service/api.dart';
|
||||||
import 'package:aitrainer_app/model/auth.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
|
|
||||||
class CustomerApi {
|
class CustomerApi {
|
||||||
final APIClient _client=new APIClient();
|
final APIClient _client=new APIClient();
|
||||||
@ -44,7 +44,7 @@ class CustomerApi {
|
|||||||
throw new Exception(jsonDecode(responseBody)['error']);
|
throw new Exception(jsonDecode(responseBody)['error']);
|
||||||
} else {
|
} else {
|
||||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||||
Auth().afterRegistration(customer);
|
Cache().afterRegistration(customer);
|
||||||
}
|
}
|
||||||
} on FormatException catch(exception) {
|
} on FormatException catch(exception) {
|
||||||
throw new Exception(responseBody);
|
throw new Exception(responseBody);
|
||||||
@ -61,7 +61,7 @@ class CustomerApi {
|
|||||||
Customer customer;
|
Customer customer;
|
||||||
try {
|
try {
|
||||||
customer = Customer.fromJson(jsonDecode(responseBody));
|
customer = Customer.fromJson(jsonDecode(responseBody));
|
||||||
await Auth().afterLogin(customer);
|
await Cache().afterLogin(customer);
|
||||||
} on FormatException catch(exception) {
|
} on FormatException catch(exception) {
|
||||||
throw new Exception(responseBody);
|
throw new Exception(responseBody);
|
||||||
}
|
}
|
||||||
@ -76,12 +76,12 @@ class CustomerApi {
|
|||||||
"customers/"+customerId.toString(),
|
"customers/"+customerId.toString(),
|
||||||
body);
|
body);
|
||||||
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
Customer customer = Customer.fromJson(jsonDecode(responseBody));
|
||||||
Auth().afterRegistration(customer);
|
Cache().afterRegistration(customer);
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
print ("Exception: " + exception.toString());
|
print ("Exception: " + exception.toString());
|
||||||
print (" === go to registration ");
|
print (" === go to registration ");
|
||||||
Auth().logout();
|
Cache().logout();
|
||||||
Auth().startPage = "registration";
|
Cache().startPage = "registration";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import 'dart:convert';
|
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 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ class ExerciseTreeApi {
|
|||||||
final Iterable json = jsonDecode(body);
|
final Iterable json = jsonDecode(body);
|
||||||
final List<ExerciseTree> exerciseTree = json.map((exerciseTree) =>
|
final List<ExerciseTree> exerciseTree = json.map((exerciseTree) =>
|
||||||
ExerciseTree.fromJson(exerciseTree)).toList();
|
ExerciseTree.fromJson(exerciseTree)).toList();
|
||||||
Auth().setExerciseTree(exerciseTree);
|
Cache().setExerciseTree(exerciseTree);
|
||||||
return exerciseTree;
|
return exerciseTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:convert';
|
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/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/service/api.dart';
|
import 'package:aitrainer_app/service/api.dart';
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ class ExerciseTypeApi {
|
|||||||
final body = await _client.get("exercise_type/active", "");
|
final body = await _client.get("exercise_type/active", "");
|
||||||
final Iterable json = jsonDecode(body);
|
final Iterable json = jsonDecode(body);
|
||||||
final List<ExerciseType> exerciseTypes = json.map( (exerciseType) => ExerciseType.fromJson(exerciseType) ).toList();
|
final List<ExerciseType> exerciseTypes = json.map( (exerciseType) => ExerciseType.fromJson(exerciseType) ).toList();
|
||||||
Auth().setExerciseTypes(exerciseTypes);
|
Cache().setExerciseTypes(exerciseTypes);
|
||||||
return exerciseTypes;
|
return exerciseTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:aitrainer_app/localization/app_language.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/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
class Common {
|
mixin Common {
|
||||||
|
|
||||||
static const EMAIL_ERROR = "Please type a right email address here.";
|
final EMAIL_ERROR = "Please type a right email address here.";
|
||||||
static const PASSWORD_ERROR = "The password must have at least 8 characters.";
|
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 = "{";
|
String rc = "{";
|
||||||
map.forEach((key, value) {
|
map.forEach((key, value) {
|
||||||
rc += "'$key':'$value'";
|
rc += "'$key':'$value'";
|
||||||
@ -23,9 +23,9 @@ class Common {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ExerciseType getExerciseType( int exerciseTypeId ) {
|
ExerciseType getExerciseType( int exerciseTypeId ) {
|
||||||
ExerciseType returnElement = null;
|
ExerciseType returnElement = null;
|
||||||
List<ExerciseType> listExerciseType = Auth().getExerciseTypes();
|
List<ExerciseType> listExerciseType = Cache().getExerciseTypes();
|
||||||
if ( listExerciseType != null ) {
|
if ( listExerciseType != null ) {
|
||||||
for ( var element in listExerciseType ) {
|
for ( var element in listExerciseType ) {
|
||||||
if (exerciseTypeId == element.exerciseTypeId) {
|
if (exerciseTypeId == element.exerciseTypeId) {
|
||||||
@ -37,7 +37,7 @@ class Common {
|
|||||||
return returnElement;
|
return returnElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String getDateLocale( DateTime datetime, bool timeDisplay ) {
|
String getDateLocale( DateTime datetime, bool timeDisplay ) {
|
||||||
AppLanguage appLanguage = AppLanguage();
|
AppLanguage appLanguage = AppLanguage();
|
||||||
var date = datetime;
|
var date = datetime;
|
||||||
|
|
||||||
@ -49,16 +49,16 @@ class Common {
|
|||||||
return dateName;
|
return dateName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String utf8convert(String text) {
|
String utf8convert(String text) {
|
||||||
List<int> bytes = text.toString().codeUnits;
|
List<int> bytes = text.toString().codeUnits;
|
||||||
return utf8.decode(bytes);
|
return utf8.decode(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double mediaSizeWidth( BuildContext context ) {
|
double mediaSizeWidth( BuildContext context ) {
|
||||||
return MediaQuery.of(context).size.width;
|
return MediaQuery.of(context).size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validateEmail(UserRepository userRepository) {
|
bool validateEmail(UserRepository userRepository) {
|
||||||
final String email = userRepository.user.email;
|
final String email = userRepository.user.email;
|
||||||
final RegExp _emailRegExp = RegExp(
|
final RegExp _emailRegExp = RegExp(
|
||||||
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
|
r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
|
||||||
@ -66,7 +66,7 @@ class Common {
|
|||||||
return _emailRegExp.hasMatch(email);
|
return _emailRegExp.hasMatch(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validatePassword(UserRepository userRepository) {
|
bool validatePassword(UserRepository userRepository) {
|
||||||
final password = userRepository.user.password;
|
final password = userRepository.user.password;
|
||||||
final RegExp _passwordRegExp =
|
final RegExp _passwordRegExp =
|
||||||
RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$');
|
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_language.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/service/api.dart';
|
import 'package:aitrainer_app/service/api.dart';
|
||||||
import 'package:aitrainer_app/service/customer_service.dart';
|
import 'package:aitrainer_app/service/customer_service.dart';
|
||||||
import 'package:aitrainer_app/service/exercise_tree_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:devicelocale/devicelocale.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.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';
|
//import '../push_notifications.dart';
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ class Session {
|
|||||||
_sharedPreferences = await _prefs;
|
_sharedPreferences = await _prefs;
|
||||||
|
|
||||||
|
|
||||||
if ( Auth().firstLoad ) {
|
if ( Cache().firstLoad ) {
|
||||||
|
|
||||||
print (" -- Session: fetch locale..");
|
print (" -- Session: fetch locale..");
|
||||||
await appLanguage.fetchLocale();
|
await appLanguage.fetchLocale();
|
||||||
@ -44,7 +45,7 @@ class Session {
|
|||||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||||
try {
|
try {
|
||||||
languages = await Devicelocale.preferredLanguages;
|
languages = await Devicelocale.preferredLanguages;
|
||||||
Auth().deviceLanguages = languages;
|
Cache().deviceLanguages = languages;
|
||||||
print("device langs " + languages.toString());
|
print("device langs " + languages.toString());
|
||||||
|
|
||||||
} on PlatformException {
|
} on PlatformException {
|
||||||
@ -64,44 +65,49 @@ class Session {
|
|||||||
_fetchToken(SharedPreferences prefs) async {
|
_fetchToken(SharedPreferences prefs) async {
|
||||||
|
|
||||||
var responseJson = await APIClient.authenticateUser(
|
var responseJson = await APIClient.authenticateUser(
|
||||||
Auth.username,
|
Cache.username,
|
||||||
Auth.password
|
Cache.password
|
||||||
);
|
);
|
||||||
|
int customerId = 0;
|
||||||
print("--- Lang: " + appLanguage.appLocal.toString());
|
print("--- Lang: " + appLanguage.appLocal.toString());
|
||||||
if(responseJson['error'] != null) {
|
if(responseJson['error'] != null) {
|
||||||
print("************** Here big error - no authentication");
|
print("************** Here big error - no authentication");
|
||||||
} else if (responseJson['token'] != null) {
|
} else if (responseJson['token'] != null) {
|
||||||
prefs.setString(Auth.authTokenKey, responseJson['token']);
|
prefs.setString(Cache.authTokenKey, responseJson['token']);
|
||||||
Auth auth = Auth();
|
Cache().authToken = responseJson['token'];
|
||||||
auth.authToken = responseJson['token'];
|
if (prefs.get(Cache.customerIdKey) == null) {
|
||||||
if (prefs.get(Auth.customerIdKey) == null) {
|
|
||||||
print("************** Registration");
|
print("************** Registration");
|
||||||
// registration
|
// registration
|
||||||
//Navigator.of(context).pushNamed('registration');
|
//Navigator.of(context).pushNamed('registration');
|
||||||
prefs.setBool(Auth.isRegisteredKey, true);
|
prefs.setBool(Cache.isRegisteredKey, true);
|
||||||
Auth().startPage = "registration";
|
Cache().startPage = "registration";
|
||||||
} else {
|
} else {
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
DateTime lastStoreDate = DateTime.parse(
|
DateTime lastStoreDate = DateTime.parse(
|
||||||
prefs.get(Auth.lastStoreDateKey));
|
prefs.get(Cache.lastStoreDateKey));
|
||||||
DateTime minStoreDate = now.add(Duration(days: -10));
|
DateTime minStoreDate = now.add(Duration(days: -10));
|
||||||
|
|
||||||
if (lastStoreDate == null ||
|
if (lastStoreDate == null ||
|
||||||
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
lastStoreDate.difference(minStoreDate) > Duration(days: 10) ||
|
||||||
prefs.get(Auth.isLoggedInKey) == null ||
|
prefs.get(Cache.isLoggedInKey) == null ||
|
||||||
prefs.get(Auth.isLoggedInKey) == false) {
|
prefs.get(Cache.isLoggedInKey) == false) {
|
||||||
print("************* Login");
|
print("************* Login");
|
||||||
//Navigator.of(context).pushNamed('login');
|
//Navigator.of(context).pushNamed('login');
|
||||||
Auth().startPage = "login";
|
Cache().startPage = "login";
|
||||||
} else {
|
} else {
|
||||||
print("************** Store SharedPreferences");
|
print("************** Store SharedPreferences");
|
||||||
// get API customer
|
// get API customer
|
||||||
await CustomerApi().getCustomer(prefs.getInt(Auth.customerIdKey));
|
customerId = prefs.getInt(Cache.customerIdKey);
|
||||||
Auth().startPage = "home";
|
await CustomerApi().getCustomer(customerId);
|
||||||
|
Cache().startPage = "home";
|
||||||
}
|
}
|
||||||
|
|
||||||
await ExerciseTypeApi().getExerciseTypes();
|
await ExerciseTypeApi().getExerciseTypes();
|
||||||
await ExerciseTreeApi().getExerciseTree();
|
await ExerciseTreeApi().getExerciseTree();
|
||||||
|
if ( customerId > 0) {
|
||||||
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
|
exerciseRepository.getExercisesByCustomer(customerId);
|
||||||
|
}
|
||||||
print("--- Session finished");
|
print("--- Session finished");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import 'package:flutter/cupertino.dart';
|
|||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class AccountPage extends StatelessWidget {
|
class AccountPage extends StatelessWidget {
|
||||||
// ignore: close_sinks
|
|
||||||
AccountBloc accountBloc;
|
AccountBloc accountBloc;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
|
import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
@ -24,7 +26,6 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
create: (context) =>
|
create: (context) =>
|
||||||
CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()),
|
CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
// ignore: close_sinks
|
|
||||||
final exerciseBloc = BlocProvider.of<CustomExerciseFormBloc>(context);
|
final exerciseBloc = BlocProvider.of<CustomExerciseFormBloc>(context);
|
||||||
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
|
exerciseBloc.exerciseRepository.setExerciseType(exerciseType);
|
||||||
|
|
||||||
@ -189,6 +190,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SliverGrid gridCalculation(CustomExerciseFormBloc bloc) {
|
SliverGrid gridCalculation(CustomExerciseFormBloc bloc) {
|
||||||
|
LinkedHashMap args = LinkedHashMap();
|
||||||
return SliverGrid(
|
return SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 3,
|
crossAxisCount: 3,
|
||||||
@ -201,7 +203,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
textFieldBloc: bloc.rmWendlerField,
|
textFieldBloc: bloc.rmWendlerField,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
@ -211,7 +213,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rmWathenField,
|
textFieldBloc: bloc.rmWathenField,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -223,7 +225,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rmOconnerField,
|
textFieldBloc: bloc.rmOconnerField,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -235,7 +237,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rmMayhewField,
|
textFieldBloc: bloc.rmMayhewField,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -247,7 +249,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rmAverageField,
|
textFieldBloc: bloc.rmAverageField,
|
||||||
style: TextStyle(color: Colors.blueAccent, fontSize: 12),
|
style: TextStyle(color: Colors.blueAccent, fontSize: 12),
|
||||||
@ -259,7 +261,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm90Field,
|
textFieldBloc: bloc.rm90Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -272,7 +274,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
|
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm75Field,
|
textFieldBloc: bloc.rm75Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
@ -284,7 +286,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm75OconnorField,
|
textFieldBloc: bloc.rm75OconnorField,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
@ -296,7 +298,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm75WendlerField,
|
textFieldBloc: bloc.rm75WendlerField,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.bold),
|
||||||
@ -308,7 +310,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm80Field,
|
textFieldBloc: bloc.rm80Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -320,7 +322,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm70Field,
|
textFieldBloc: bloc.rm70Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -332,7 +334,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm60Field,
|
textFieldBloc: bloc.rm60Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -344,7 +346,7 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
)),
|
)),
|
||||||
TextFieldBlocBuilder(
|
TextFieldBlocBuilder(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
padding: EdgeInsets.only(left:30),
|
padding: EdgeInsets.only(left:10),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
textFieldBloc: bloc.rm50Field,
|
textFieldBloc: bloc.rm50Field,
|
||||||
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
style: TextStyle(color: Colors.deepOrange, fontSize: 12),
|
||||||
@ -353,8 +355,45 @@ class _CustomExerciseNewPageState extends State<CustomExercisePage> {
|
|||||||
fillColor: Colors.white,
|
fillColor: Colors.white,
|
||||||
filled: false,
|
filled: false,
|
||||||
labelText: "1RM 50%: ",
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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/bloc/exercise_form_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_language.dart';
|
import 'package:aitrainer_app/localization/app_language.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:aitrainer_app/model/auth.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@ -283,7 +283,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> {
|
|||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(AppLocalizations.of(context).translate("Yes")),
|
child: Text(AppLocalizations.of(context).translate("Yes")),
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
bloc.exerciseRepository.setCustomer(Auth().userLoggedIn),
|
bloc.exerciseRepository.setCustomer(Cache().userLoggedIn),
|
||||||
bloc.exerciseRepository.addExercise(),
|
bloc.exerciseRepository.addExercise(),
|
||||||
|
|
||||||
Navigator.pop(context),
|
Navigator.pop(context),
|
||||||
|
@ -26,7 +26,7 @@ class LoginWidget extends StatefulWidget {
|
|||||||
State<StatefulWidget> createState() => _LoginWidget();
|
State<StatefulWidget> createState() => _LoginWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LoginWidget extends State<LoginWidget> {
|
class _LoginWidget extends State<LoginWidget> with Common {
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class _LoginWidget extends State<LoginWidget> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
|
Widget buildLoginForm(LoginFormBloc formBloc, AccountBloc accountBloc) {
|
||||||
final cWidth = Common.mediaSizeWidth(context);
|
final cWidth = mediaSizeWidth(context);
|
||||||
|
|
||||||
return Form(
|
return Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
|
||||||
|
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/menu_page_widget.dart';
|
import 'package:aitrainer_app/widgets/menu_page_widget.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
@ -9,39 +11,30 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
|
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class MenuPage extends StatelessWidget {
|
class MenuPage extends StatefulWidget {
|
||||||
static const routeName = '/menu_page';
|
static const routeName = '/menu_page';
|
||||||
int parent;
|
int parent;
|
||||||
MenuBloc menuBloc;
|
|
||||||
|
|
||||||
MenuPage({this.parent});
|
MenuPage({this.parent});
|
||||||
|
|
||||||
|
_MenuPage createState() => _MenuPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MenuPage extends State<MenuPage> {
|
||||||
|
// ignore: close_sinks
|
||||||
|
MenuBloc menuBloc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void checkTest() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBarNav(),
|
||||||
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))
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
|
@ -34,13 +34,13 @@ class RegistrationWidget extends StatefulWidget {
|
|||||||
State<StatefulWidget> createState() => _RegistrationWidget();
|
State<StatefulWidget> createState() => _RegistrationWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _RegistrationWidget extends State<RegistrationWidget> {
|
class _RegistrationWidget extends State<RegistrationWidget> with Common {
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final cWidth = Common.mediaSizeWidth(context);
|
final cWidth = mediaSizeWidth(context);
|
||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
final accountBloc = BlocProvider.of<AccountBloc>(context);
|
final accountBloc = BlocProvider.of<AccountBloc>(context);
|
||||||
return BlocProvider(
|
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/bloc/settings/settings_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_language.dart';
|
import 'package:aitrainer_app/localization/app_language.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:aitrainer_app/model/auth.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:aitrainer_app/widgets/splash.dart';
|
import 'package:aitrainer_app/widgets/splash.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
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/session/session_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_language.dart';
|
import 'package:aitrainer_app/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/login.dart';
|
||||||
import 'package:aitrainer_app/view/menu_page.dart';
|
import 'package:aitrainer_app/view/menu_page.dart';
|
||||||
import 'package:aitrainer_app/view/registration.dart';
|
import 'package:aitrainer_app/view/registration.dart';
|
||||||
@ -69,9 +69,9 @@ class _HomePageState extends State<AitrainerHome> {
|
|||||||
return LoadingScreenMain();
|
return LoadingScreenMain();
|
||||||
} else if (state is SessionReady) {
|
} else if (state is SessionReady) {
|
||||||
print("ready");
|
print("ready");
|
||||||
if (Auth().startPage == 'login') {
|
if (Cache().startPage == 'login') {
|
||||||
return LoginPage();
|
return LoginPage();
|
||||||
} else if (Auth().startPage == 'registration') {
|
} else if (Cache().startPage == 'registration') {
|
||||||
return RegistrationPage();
|
return RegistrationPage();
|
||||||
} else {
|
} else {
|
||||||
return MenuPage(parent: 0);
|
return MenuPage(parent: 0);
|
||||||
|
@ -6,8 +6,8 @@ class LoadingScreenMain extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Image _backgroundImage = Image.asset('asset/image/WT01_loading_layers.png',
|
Image _backgroundImage = Image.asset('asset/image/WT01_loading_layers.png',
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
height: double.infinity,
|
//height: double.infinity,
|
||||||
width: double.infinity,
|
//width: double.infinity,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
);
|
);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:ui';
|
|||||||
|
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||||
import 'package:aitrainer_app/model/auth.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/workout_tree.dart';
|
import 'package:aitrainer_app/model/workout_tree.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -75,7 +75,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
menuBloc.add(MenuTreeDown(parent: workoutTree.id));
|
menuBloc.add(MenuTreeDown(parent: workoutTree.id));
|
||||||
} else {
|
} else {
|
||||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||||
if (Auth().userLoggedIn == null) {
|
if (Cache().userLoggedIn == null) {
|
||||||
Scaffold.of(context).showSnackBar(SnackBar(
|
Scaffold.of(context).showSnackBar(SnackBar(
|
||||||
backgroundColor: Colors.orange,
|
backgroundColor: Colors.orange,
|
||||||
content: Text(
|
content: Text(
|
||||||
@ -85,6 +85,9 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
if (workoutTree.exerciseType.name == "Custom") {
|
if (workoutTree.exerciseType.name == "Custom") {
|
||||||
Navigator.of(context).pushNamed('exerciseCustomPage',
|
Navigator.of(context).pushNamed('exerciseCustomPage',
|
||||||
arguments: workoutTree.exerciseType);
|
arguments: workoutTree.exerciseType);
|
||||||
|
} else if (workoutTree.exerciseType.name == "Control") {
|
||||||
|
Navigator.of(context).pushNamed('exerciseControlPage',
|
||||||
|
arguments: workoutTree.exerciseType);
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(context).pushNamed('exerciseNewPage',
|
Navigator.of(context).pushNamed('exerciseNewPage',
|
||||||
arguments: workoutTree.exerciseType);
|
arguments: workoutTree.exerciseType);
|
||||||
@ -122,7 +125,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
height: 180,
|
height: 180,
|
||||||
errorBuilder: (context, error, stackTrace) {
|
errorBuilder: (context, error, stackTrace) {
|
||||||
String url =
|
String url =
|
||||||
Auth.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
|
Cache.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
|
||||||
Widget image = FadeInImage.assetNetwork(
|
Widget image = FadeInImage.assetNetwork(
|
||||||
placeholder: 'asset/image/dots.gif',
|
placeholder: 'asset/image/dots.gif',
|
||||||
image: url,
|
image: url,
|
||||||
@ -132,7 +135,7 @@ class MenuPageWidget extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} on Exception catch (_) {
|
} on Exception catch (_) {
|
||||||
String url = Auth.mediaUrl + '/images/' + workoutTree.imageName;
|
String url = Cache.mediaUrl + '/images/' + workoutTree.imageName;
|
||||||
image = FadeInImage.assetNetwork(
|
image = FadeInImage.assetNetwork(
|
||||||
placeholder: 'asset/image/dots.gif',
|
placeholder: 'asset/image/dots.gif',
|
||||||
image: url,
|
image: url,
|
||||||
|
173
pubspec.lock
173
pubspec.lock
@ -49,7 +49,7 @@ packages:
|
|||||||
name: bloc_test
|
name: bloc_test
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -57,6 +57,62 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
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:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -71,6 +127,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.3"
|
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:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -85,6 +148,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
code_builder:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: code_builder
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.4.1"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -127,6 +197,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
|
dart_style:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dart_style
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.6"
|
||||||
devicelocale:
|
devicelocale:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -140,7 +217,7 @@ packages:
|
|||||||
name: equatable
|
name: equatable
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.3"
|
version: "1.2.4"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -155,6 +232,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.1"
|
version: "5.2.1"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.10.11"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -236,6 +320,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.19.1"
|
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:
|
fuchsia_remote_debug_protocol:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -248,6 +346,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
|
graphs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: graphs
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.2.0"
|
||||||
html:
|
html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -304,6 +409,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.2"
|
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:
|
json_rpc_2:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -401,7 +513,7 @@ packages:
|
|||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.3"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -409,6 +521,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.0"
|
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:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -450,7 +569,7 @@ packages:
|
|||||||
name: provider
|
name: provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.2"
|
version: "4.3.2+1"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -458,6 +577,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.4"
|
version: "1.4.4"
|
||||||
|
pubspec_parse:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pubspec_parse
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.5"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -465,6 +591,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
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:
|
rxdart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -485,14 +625,14 @@ packages:
|
|||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.8"
|
version: "0.5.10"
|
||||||
shared_preferences_linux:
|
shared_preferences_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.2+1"
|
version: "0.0.2+2"
|
||||||
shared_preferences_macos:
|
shared_preferences_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -547,6 +687,13 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.99"
|
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:
|
source_map_stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -589,6 +736,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
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:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -631,6 +785,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.10"
|
version: "0.3.10"
|
||||||
|
timing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: timing
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1+2"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
14
pubspec.yaml
14
pubspec.yaml
@ -33,9 +33,12 @@ dependencies:
|
|||||||
flutter_local_notifications: 1.1.1
|
flutter_local_notifications: 1.1.1
|
||||||
flutter_facebook_login: ^3.0.0
|
flutter_facebook_login: ^3.0.0
|
||||||
flutter_bloc: ^6.0.1
|
flutter_bloc: ^6.0.1
|
||||||
equatable: ^1.2.3
|
equatable: ^1.2.4
|
||||||
|
freezed: ^0.11.6
|
||||||
flutter_form_bloc: ^0.19.0
|
flutter_form_bloc: ^0.19.0
|
||||||
spider_chart: ^0.1.5
|
spider_chart: ^0.1.5
|
||||||
|
rainbow_color: ^0.1.1
|
||||||
|
percent_indicator: ^2.1.5
|
||||||
|
|
||||||
mockito: ^4.1.1
|
mockito: ^4.1.1
|
||||||
|
|
||||||
@ -46,12 +49,15 @@ dev_dependencies:
|
|||||||
flutter_driver:
|
flutter_driver:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
test: any
|
test: any
|
||||||
bloc_test: ^7.0.1
|
bloc_test: ^7.0.2
|
||||||
|
|
||||||
|
build_runner:
|
||||||
|
|
||||||
|
|
||||||
http: 0.12.1
|
http: 0.12.1
|
||||||
provider: ^4.3.2
|
provider: ^4.3.2+1
|
||||||
intl: 0.16.1
|
intl: 0.16.1
|
||||||
shared_preferences: ^0.5.8
|
shared_preferences: ^0.5.10
|
||||||
|
|
||||||
flutter_launcher_icons: ^0.7.5
|
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';
|
import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
|
|
||||||
class MockUserRepository extends Mock implements UserRepository {
|
class MockUserRepository extends Mock implements UserRepository {
|
||||||
final User user = User();
|
final User user = User();
|
||||||
|
|
||||||
setEmail(String email) {
|
setEmail(String email) {
|
||||||
@ -43,15 +43,23 @@ class MockUserRepository extends Mock implements UserRepository {
|
|||||||
class MockLoginBloc extends MockBloc<FormBlocEvent>
|
class MockLoginBloc extends MockBloc<FormBlocEvent>
|
||||||
implements LoginFormBloc {}
|
implements LoginFormBloc {}
|
||||||
|
|
||||||
|
class MockCommon with Common {
|
||||||
|
String getEmailError() {
|
||||||
|
return EMAIL_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('LoginScreen', () {
|
group('LoginScreen', () {
|
||||||
MockLoginBloc loginBloc;
|
MockLoginBloc loginBloc;
|
||||||
MockUserRepository userRepository;
|
MockUserRepository userRepository;
|
||||||
Widget loginWidget;
|
Widget loginWidget;
|
||||||
|
MockCommon common;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
loginBloc = MockLoginBloc();
|
loginBloc = MockLoginBloc();
|
||||||
userRepository = MockUserRepository();
|
userRepository = MockUserRepository();
|
||||||
|
common = MockCommon();
|
||||||
|
|
||||||
loginWidget =
|
loginWidget =
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
@ -100,7 +108,7 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(okButton);
|
await tester.tap(okButton);
|
||||||
await tester.pump(const Duration(milliseconds: 500)); // add delay
|
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);
|
expect(emailErrorFinder, findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user