wt1.1a flutter_bloc

This commit is contained in:
Bossanyi Tibor
2020-08-17 12:38:47 +02:00
parent 8363d7772f
commit ac1c6be8f3
90 changed files with 4281 additions and 2854 deletions
+46
View File
@@ -0,0 +1,46 @@
import 'dart:async';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
part 'account_event.dart';
part 'account_state.dart';
class AccountBloc extends Bloc<AccountEvent, AccountState> {
final CustomerRepository customerRepository;
bool loggedIn = false;
AccountBloc({this.customerRepository}) : super(AccountInitial()) {
if ( Auth().userLoggedIn != null ) {
customerRepository.customer = Auth().userLoggedIn;
loggedIn = true;
}
}
@override
Stream<AccountState> mapEventToState(
AccountEvent event,
) async* {
try {
if (event is AccountChangeCustomer) {
// route to Customer Change page
yield AccountReady();
} else if (event is AccountLogin) {
//route to Login Page
} else if (event is AccountLogInFinished) {
customerRepository.customer = event.customer;
yield AccountLoggedIn();
} else if (event is AccountLogout) {
await Auth().logout();
customerRepository.customer = null;
loggedIn = false;
yield AccountLoggedOut();
}
} on Exception catch(e) {
yield AccountError(message: e.toString());
}
}
}
+46
View File
@@ -0,0 +1,46 @@
part of 'account_bloc.dart';
@immutable
abstract class AccountEvent extends Equatable {
const AccountEvent();
@override
List<Object> get props => [];
}
class AccountChangeCustomer extends AccountEvent {
final Customer customer;
const AccountChangeCustomer({this.customer});
@override
List<Object> get props => [customer];
}
class AccountLogout extends AccountEvent {
final Customer customer;
const AccountLogout({this.customer});
@override
List<Object> get props => [customer];
}
class AccountLogin extends AccountEvent {
final Customer customer;
const AccountLogin({this.customer});
@override
List<Object> get props => [customer];
}
class AccountLogInFinished extends AccountEvent {
final Customer customer;
const AccountLogInFinished({this.customer});
@override
List<Object> get props => [customer];
}
+36
View File
@@ -0,0 +1,36 @@
part of 'account_bloc.dart';
@immutable
abstract class AccountState extends Equatable {
const AccountState();
@override
List<Object> get props => [];
}
class AccountInitial extends AccountState {
const AccountInitial();
}
class AccountLoading extends AccountState {
const AccountLoading();
}
class AccountReady extends AccountState {
const AccountReady();
}
class AccountLoggedOut extends AccountState {
const AccountLoggedOut();
}
class AccountLoggedIn extends AccountState {
const AccountLoggedIn();
}
class AccountError extends AccountState {
final String message;
const AccountError({this.message});
@override
List<Object> get props => [message];
}
+127
View File
@@ -0,0 +1,127 @@
import 'dart:math';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomExerciseFormBloc extends FormBloc<String, String> {
final ExerciseRepository exerciseRepository;
final quantityField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final unitQuantityField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
//1RM calculated Fields
final rmWendlerField = TextFieldBloc( initialValue: "0",);
final rmMcGothlinField = TextFieldBloc( initialValue: "0");
final rmLombardiField = TextFieldBloc( initialValue: "0");
final rmMayhewField = TextFieldBloc( initialValue: "0");
final rmOconnerField = TextFieldBloc( initialValue: "0");
final rmWathenField = TextFieldBloc( initialValue: "0");
final rmAverageField = TextFieldBloc( initialValue: "0");
final rm90Field = TextFieldBloc( initialValue: "0");
final rm80Field = TextFieldBloc( initialValue: "0");
final rm70Field = TextFieldBloc( initialValue: "0");
final rm60Field = TextFieldBloc( initialValue: "0");
final rm50Field = TextFieldBloc( initialValue: "0");
CustomExerciseFormBloc({this.exerciseRepository}) {
addFieldBlocs(fieldBlocs: [
quantityField,
unitQuantityField,
rmWendlerField,
rmMcGothlinField,
rmLombardiField,
rmMayhewField,
rmOconnerField,
rmWathenField,
rmAverageField,
rm90Field,
rm80Field,
rm70Field,
rm60Field,
rm50Field
]);
quantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setQuantity(current.valueToDouble);
calculate1RM();
});
unitQuantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setUnitQuantity(current.valueToDouble);
calculate1RM();
});
}
@override
void onSubmitting() async {
print("on Submitting Custom form");
try {
emitLoading(progress: 30);
// Emit either Loaded or Error
emitSuccess(canSubmitAgain: false);
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
void calculate1RM() {
double weight = exerciseRepository.exercise.unitQuantity;
double repeat = exerciseRepository.exercise.quantity;
if ( weight == 0 || repeat == 0) {
return;
}
print("Calculating 1RM");
exerciseRepository.rmWendler = weight * repeat * 0.0333 + weight;
rmWendlerField.updateValue(exerciseRepository.rmWendler.toString());
exerciseRepository.rmMcglothlin = 100 * weight / (101.3 - 2.67123 * repeat);
rmMcGothlinField.updateValue(exerciseRepository.rmMcglothlin.toString());
exerciseRepository.rmLombardi = pow(weight * repeat, 0.1);
rmLombardiField.updateValue(exerciseRepository.rmLombardi.toString());
exerciseRepository.rmOconner = weight * (1 + repeat / 40);
rmOconnerField.updateValue(exerciseRepository.rmOconner.toString());
exerciseRepository.rmMayhew =
100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat));
rmMayhewField.updateValue(exerciseRepository.rmMayhew.toString());
exerciseRepository.rmWathen =
100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
rmWathenField.updateValue(exerciseRepository.rmWathen.toString());
double average = (exerciseRepository.rmWendler + exerciseRepository.rmWathen +
exerciseRepository.rmMayhew + exerciseRepository.rmOconner +
exerciseRepository.rmMcglothlin)/5;
rmAverageField.updateValue(average.toString());
rm90Field.updateValue((average*0.9).toString());
rm80Field.updateValue((average*0.8).toString());
rm70Field.updateValue((average*0.7).toString());
rm60Field.updateValue((average*0.6).toString());
rm50Field.updateValue((average*0.5).toString());
}
//@override
Future<void> close() {
quantityField.close();
unitQuantityField.close();
rmWendlerField.close();
rmMcGothlinField.close();
rmLombardiField.close();
rmMayhewField.close();
rmOconnerField.close();
rmWathenField.close();
rmAverageField.close();
rm90Field.close();
rm80Field.close();
rm70Field.close();
rm60Field.close();
rm50Field.close();
return super.close();
}
}
@@ -0,0 +1,38 @@
import 'dart:async';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
part 'customer_change_event.dart';
part 'customer_change_state.dart';
class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState> {
final CustomerRepository customerRepository;
CustomerChangeBloc({this.customerRepository}) : super(CustomerChangeInitial());
@override
Stream<CustomerChangeState> mapEventToState(
CustomerChangeEvent event,
) async* {
try {
if (event is CustomerGoalChange) {
customerRepository.setGoal(event.goal);
yield CustomerDataChanged();
} else if (event is CustomerFitnessChange) {
customerRepository.setFitnessLevel(event.fitness);
yield CustomerDataChanged();
} else if (event is CustomerBodyTypeChange) {
customerRepository.setBodyType(event.bodyType);
yield CustomerDataChanged();
} else if (event is CustomerSave) {
yield CustomerSaving();
await customerRepository.saveCustomer();
yield CustomerSaveSuccess();
}
} on Exception catch(e) {
yield CustomerSaveError(message: e.toString());
}
}
}
@@ -0,0 +1,36 @@
part of 'customer_change_bloc.dart';
@immutable
abstract class CustomerChangeEvent extends Equatable {
const CustomerChangeEvent();
@override
List<Object> get props => [];
}
class CustomerGoalChange extends CustomerChangeEvent {
final String goal;
const CustomerGoalChange({this.goal});
@override
List<Object> get props => [goal];
}
class CustomerFitnessChange extends CustomerChangeEvent {
final String fitness;
const CustomerFitnessChange({this.fitness});
@override
List<Object> get props => [fitness];
}
class CustomerBodyTypeChange extends CustomerChangeEvent {
final String bodyType;
const CustomerBodyTypeChange({this.bodyType});
@override
List<Object> get props => [bodyType];
}
class CustomerSave extends CustomerChangeEvent {
const CustomerSave();
}
@@ -0,0 +1,32 @@
part of 'customer_change_bloc.dart';
@immutable
abstract class CustomerChangeState extends Equatable {
const CustomerChangeState();
@override
List<Object> get props => [];
}
class CustomerChangeInitial extends CustomerChangeState {
const CustomerChangeInitial();
}
class CustomerSaving extends CustomerChangeState {
const CustomerSaving();
}
class CustomerDataChanged extends CustomerChangeState {
const CustomerDataChanged();
}
class CustomerSaveSuccess extends CustomerChangeState {
const CustomerSaveSuccess();
}
class CustomerSaveError extends CustomerChangeState {
final String message;
const CustomerSaveError({this.message});
@override
List<Object> get props => [message];
}
+101
View File
@@ -0,0 +1,101 @@
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomerChangeFormBloc extends FormBloc<String, String> {
final CustomerRepository customerRepository;
final emailField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final firstNameField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final nameField = TextFieldBloc();
final passwordField = TextFieldBloc(
validators: [
//FieldBlocValidators.confirmPassword(passwordField),
],
);
final birthYearField = TextFieldBloc();
final weightField = TextFieldBloc();
final genderField = SelectFieldBloc();
final goalField = TextFieldBloc();
CustomerChangeFormBloc({this.customerRepository}) {
addFieldBlocs(fieldBlocs: [
emailField,
firstNameField,
nameField,
passwordField,
birthYearField,
weightField,
genderField,
goalField,
]);
emailField.updateInitialValue(customerRepository.customer.email);
firstNameField.updateInitialValue(customerRepository.customer.firstname);
nameField.updateInitialValue(customerRepository.customer.name);
birthYearField.updateInitialValue(customerRepository.customer.birthYear.toString());
weightField.updateInitialValue(customerRepository.customer.weight.toString());
genderField.updateInitialValue(customerRepository.getGenderByDBValue(customerRepository.sex));
firstNameField.onValueChanges(onData: (previous, current) async* {
customerRepository.setFirstName(current.value);
});
nameField.onValueChanges(onData: (previous, current) async* {
customerRepository.setName(current.value);
});
birthYearField.onValueChanges(onData: (previous, current) async* {
customerRepository.setBirthYear(current.valueToInt);
});
weightField.onValueChanges(onData: (previous, current) async* {
customerRepository.setWeight(current.valueToInt);
});
customerRepository.genders.forEach((element) {
genderField.addItem(element.name);
});
genderField.onValueChanges(onData: (previous, current) async* {
String dbValue = customerRepository.getGenderByName(current.value);
customerRepository.setSex(dbValue);
});
}
@override
void onSubmitting() async {
print("on Submitting Custom form");
try {
emitLoading(progress: 30);
// Emit either Loaded or Error
await customerRepository.saveCustomer();
emitSuccess(canSubmitAgain: false);
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
@override
Future<void> close() {
emailField.close();
firstNameField.close();
nameField.close();
passwordField.close();
birthYearField.close();
weightField.close();
genderField.close();
return super.close();
}
}
+64
View File
@@ -0,0 +1,64 @@
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseFormBloc extends FormBloc<String, String> {
final ExerciseRepository exerciseRepository;
final quantityField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final unitField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final unitQuantityField = TextFieldBloc();
final unitQuantityUnitField = TextFieldBloc();
ExerciseFormBloc({this.exerciseRepository}) {
addFieldBlocs(fieldBlocs: [
quantityField,
unitField,
unitQuantityField,
unitQuantityUnitField
]);
quantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setQuantity(current.valueToDouble);
});
unitField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setUnit(current.value);
});
unitQuantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setUnitQuantity(current.valueToDouble);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
// Emit either Loaded or Error
await exerciseRepository.addExercise();
emitSuccess(canSubmitAgain: false);
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
@override
Future<void> close() {
unitQuantityField.close();
unitQuantityUnitField.close();
return super.close();
}
}
+61
View File
@@ -0,0 +1,61 @@
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class LoginFormBloc extends FormBloc<String, String> {
final AccountBloc accountBloc;
final UserRepository userRepository;
final emailField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final passwordField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
]
);
LoginFormBloc({this.userRepository, this.accountBloc}) {
addFieldBlocs(fieldBlocs: [
emailField,
passwordField
]);
emailField.onValueChanges(onData: (previous, current) async* {
userRepository.setEmail(current.value);
});
passwordField.onValueChanges(onData: (previous, current) async* {
userRepository.setPassword(current.value);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
if ( ! Common.validateEmail(userRepository)) {
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
emitFailure(failureResponse: Common.EMAIL_ERROR);
} else if ( ! Common.validatePassword(userRepository)) {
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
emitFailure(failureResponse: Common.PASSWORD_ERROR);
} else {
// Emit either Loaded or Error
await userRepository.getUser();
emitSuccess(canSubmitAgain: false);
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
}
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
}
+51
View File
@@ -0,0 +1,51 @@
import 'dart:async';
import 'package:aitrainer_app/model/workout_tree.dart';
import 'package:aitrainer_app/repository/menu_tree_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
part 'menu_event.dart';
part 'menu_state.dart';
class MenuBloc extends Bloc<MenuEvent, MenuState> {
final MenuTreeRepository menuTreeRepository;
int parent;
MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) {
parent = 0;
}
@override
Stream<MenuState> mapEventToState(
MenuEvent event,
) async* {
try {
if ( event is MenuCreate ) {
yield MenuLoading();
await menuTreeRepository.createTree();
yield MenuReady();
} else if (event is MenuTreeDown) {
// get child menus or exercises
yield MenuLoading();
parent = event.parent;
menuTreeRepository.getBranch(event.parent);
yield MenuReady();
} else if (event is MenuTreeUp) {
yield MenuLoading();
// get parent menus or exercises
parent = event.parent;
menuTreeRepository.getBranch(parent);
yield MenuReady();
} else if (event is MenuClickExercise) {
yield MenuLoading();
// get exercise page
yield MenuReady();
}
} on Exception catch(ex) {
yield MenuError(message: ex.toString());
}
}
}
+41
View File
@@ -0,0 +1,41 @@
part of 'menu_bloc.dart';
@immutable
abstract class MenuEvent extends Equatable {
const MenuEvent();
@override
List<Object> get props => [];
}
class MenuCreate extends MenuEvent {
const MenuCreate();
@override
List<Object> get props => [];
}
class MenuTreeDown extends MenuEvent {
final int parent;
const MenuTreeDown({this.parent});
@override
List<Object> get props => [parent];
}
class MenuTreeUp extends MenuEvent {
final int parent;
const MenuTreeUp({this.parent});
@override
List<Object> get props => [parent];
}
class MenuClickExercise extends MenuEvent {
final int exerciseTypeId;
const MenuClickExercise({this.exerciseTypeId});
@override
List<Object> get props => [exerciseTypeId];
}
+34
View File
@@ -0,0 +1,34 @@
part of 'menu_bloc.dart';
@immutable
abstract class MenuState extends Equatable {
const MenuState();
@override
List<Object> get props => [];
}
class MenuInitial extends MenuState {
const MenuInitial();
}
class MenuLoading extends MenuState {
}
class MenuReady extends MenuState {
final WorkoutTree workoutTree;
const MenuReady({this.workoutTree});
@override
List<Object> get props => [workoutTree];
}
class MenuError extends MenuState {
final String message;
const MenuError({this.message});
@override
List<Object> get props => [message];
}
+61
View File
@@ -0,0 +1,61 @@
import 'package:aitrainer_app/model/auth.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'account/account_bloc.dart';
class RegistrationFormBloc extends FormBloc<String, String> {
final AccountBloc accountBloc;
final emailField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final passwordField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
]
);
final UserRepository userRepository;
RegistrationFormBloc({this.userRepository, this.accountBloc}) {
addFieldBlocs(fieldBlocs: [
emailField,
passwordField
]);
emailField.onValueChanges(onData: (previous, current) async* {
userRepository.setEmail(current.value);
});
passwordField.onValueChanges(onData: (previous, current) async* {
userRepository.setPassword(current.value);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
if ( ! Common.validateEmail(userRepository)) {
emailField.addFieldError(Common.EMAIL_ERROR, isPermanent: true);
emitFailure(failureResponse: Common.EMAIL_ERROR);
} else if ( ! Common.validatePassword(userRepository)) {
passwordField.addFieldError(Common.PASSWORD_ERROR, isPermanent: true);
emitFailure(failureResponse: Common.PASSWORD_ERROR);
} else {
// Emit either Loaded or Error
await userRepository.addUser();
emitSuccess(canSubmitAgain: false);
accountBloc.add(AccountLogInFinished(customer: Auth().userLoggedIn));
}
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
}
+35
View File
@@ -0,0 +1,35 @@
import 'dart:async';
import 'package:aitrainer_app/util/session.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
part 'session_event.dart';
part 'session_state.dart';
class SessionBloc extends Bloc<SessionEvent, SessionState> {
final Session session;
SessionBloc({this.session}) : super(SessionInitial());
@override
Stream<SessionState> mapEventToState(
SessionEvent event,
) async* {
try {
if (event is SessionStart) {
yield SessionLoading();
await session.fetchSessionAndNavigate();
yield SessionReady();
}
} on Exception catch(ex) {
yield SessionFailure(message: ex.toString());
}
}
@override
Future<void> close() async {
await this.close(); super.close();
}
}
+16
View File
@@ -0,0 +1,16 @@
part of 'session_bloc.dart';
@immutable
abstract class SessionEvent extends Equatable {
const SessionEvent();
@override
List<Object> get props => [];
}
class SessionStart extends SessionEvent {
const SessionStart();
@override
List<Object> get props => [];
}
+32
View File
@@ -0,0 +1,32 @@
part of 'session_bloc.dart';
@immutable
abstract class SessionState extends Equatable {
const SessionState();
@override
List<Object> get props => [];
}
class SessionInitial extends SessionState {
const SessionInitial();
}
class SessionLoading extends SessionState {
const SessionLoading();
}
class SessionReady extends SessionState {
const SessionReady();
}
class SessionFailure extends SessionState {
final String message;
const SessionFailure({this.message});
@override
List<Object> get props => [message];
}
+55
View File
@@ -0,0 +1,55 @@
import 'dart:async';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:meta/meta.dart';
part 'settings_event.dart';
part 'settings_state.dart';
class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
String language;
Locale _locale;
BuildContext context;
SettingsBloc({this.context}) : super(SettingsInitial());
@override
Stream<SettingsState> mapEventToState(
SettingsEvent event,
) async* {
if (event is SettingsChangeLanguage) {
yield SettingsLoading();
await _changeLang( event.language);
yield SettingsReady(_locale);
}
}
Future<void> _changeLang( String lang ) async{
switch ( lang ) {
case "English":
case "Angol":
_locale = Locale('en');
break;
case "Hungarian":
case "Magyar":
_locale = Locale('hu');
break;
}
this.language = lang;
await loadLang();
}
Future<void> loadLang() async{
final AppLanguage appLanguage = AppLanguage();
appLanguage.changeLanguage(_locale);
if ( context != null ) {
AppLocalizations.of(context).setLocale(_locale);
await AppLocalizations.of(context).load();
}
}
}
+13
View File
@@ -0,0 +1,13 @@
part of 'settings_bloc.dart';
@immutable
abstract class SettingsEvent extends Equatable {
const SettingsEvent();
@override
List<Object> get props => [];
}
class SettingsChangeLanguage extends SettingsEvent {
final String language;
const SettingsChangeLanguage({this.language});
}
+46
View File
@@ -0,0 +1,46 @@
part of 'settings_bloc.dart';
@immutable
abstract class SettingsState extends Equatable {
const SettingsState();
@override
List<Object> get props => [];
}
// ignore: must_be_immutable
class SettingsInitial extends SettingsState {
Locale locale;
SettingsInitial();
setLocale(locale) {
this.locale = locale;
}
@override
List<Object> get props => [locale];
}
class SettingsLoading extends SettingsState {
final Locale locale;
const SettingsLoading({this.locale});
@override
List<Object> get props => [locale];
}
class SettingsReady extends SettingsState {
final Locale locale;
const SettingsReady(this.locale);
@override
List<Object> get props => [locale];
}
class SettingsError extends SettingsState {
final String message;
const SettingsError(this.message);
@override
List<Object> get props => [message];
}