WT 1.1.26+3 bloc migration

This commit is contained in:
Tibor Bossanyi (Freelancer) 2022-04-15 08:47:32 +02:00
parent 60df0bcf2d
commit 225172f950
47 changed files with 1527 additions and 1620 deletions

View File

@ -555,5 +555,12 @@
"in your calendar": "in your calendar", "in your calendar": "in your calendar",
"Development of My Sizes":"Development of My Sizes", "Development of My Sizes":"Development of My Sizes",
"Date": "Date", "Date": "Date",
"Muscle development":"Muscle development" "My Training Logs":"My Training Logs",
"Muscle development":"Muscle development",
"Size development":"Size development",
"Red icon means you have not saved this size.":"Red icon means you have not saved this size.",
"Tap on the green icon to see your development in a diagram":"Tap on the green icon to see your development in a diagram",
"Data Privacy":"Data Privacy",
"Feedback email":"Feedback email"
} }

View File

@ -479,7 +479,7 @@
"The safe and exact execution of this exercise you need a training buddy or a trainer": "A gyakorlat biztonságos és maximális pontosságú végrehajtásához edzőtárs vagy edző segítsége szükséges", "The safe and exact execution of this exercise you need a training buddy or a trainer": "A gyakorlat biztonságos és maximális pontosságú végrehajtásához edzőtárs vagy edző segítsége szükséges",
"Execution at your own risk!": "Végrehajtás CSAK saját felelőségre!", "Execution at your own risk!": "Végrehajtás CSAK saját felelőségre!",
"With the registration I accept the data policy and the terms of use.": "A regisztrációval elfogadom az adatkezelési szabályzatot és a felhasználási feltételeket.", "With the registration I accept the data policy and the terms of use.": "A regisztrációval elfogadom az adatkezelési szabályzatot és a felhasználási feltételeket.",
"Terms Of Use": "Felh. feltételek", "Terms Of Use": "Felhasználási feltételek",
"Execute at least 3 sets with maximum repeats, without resting time, with decreasing the weight.": "Végezz legalább 3 sorozatot pihenés nélkül és maximális ismétlésszámmal úgy, hogy folyamatosan csökkented a súlyt a szettek között.", "Execute at least 3 sets with maximum repeats, without resting time, with decreasing the weight.": "Végezz legalább 3 sorozatot pihenés nélkül és maximális ismétlésszámmal úgy, hogy folyamatosan csökkented a súlyt a szettek között.",
"The goal is to completly exhaust your muscle without lifting a ridiculous weight end the end.": "Cél, hogy a végén nevetségesen kis súlyt se bírj megmozdítani és elérd a maximális bedurranást.", "The goal is to completly exhaust your muscle without lifting a ridiculous weight end the end.": "Cél, hogy a végén nevetségesen kis súlyt se bírj megmozdítani és elérd a maximális bedurranást.",
"DROP": "VETKŐZÉS", "DROP": "VETKŐZÉS",
@ -555,6 +555,12 @@
"in your calendar": "jelöltük a naptárban", "in your calendar": "jelöltük a naptárban",
"Development of My Sizes":"Méretek fejlődése", "Development of My Sizes":"Méretek fejlődése",
"Date": "Dátum", "Date": "Dátum",
"Muscle development":"Izom fejlődése" "My Training Logs":"Edzésnaplóm",
"Muscle development":"Izom fejlődése",
"Size development":"Méreteid fejlődése",
"Red icon means you have not saved this size.":"A piros ikon mutatja, hogy arról méretről nincs még adatod.",
"Tap on the green icon to see your development in a diagram":"Kattints a zöld ikonra, és megmutatjuk a fejlődésed egy diagrammon",
"Data Privacy":"Adatkezelés",
"Feedback email":"Visszajelzés emailben"
} }

View File

@ -1,9 +1,6 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
@ -17,12 +14,60 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
bool loggedIn = false; bool loggedIn = false;
int traineeId = 0; int traineeId = 0;
AccountBloc({required this.customerRepository}) : super(AccountInitial()) { AccountBloc({required this.customerRepository}) : super(AccountInitial()) {
_load();
on<AccountChangeCustomer>(_onAccountChange);
on<AccountLogin>(_onLoginChange);
on<AccountLogInFinished>(_onLoginFinished);
on<AccountLogout>(_onLogout);
on<AccountGetTrainees>(_onGetTrainees);
on<AccountSelectTrainee>(_onSelectTrainees);
}
void _load() {
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
customerRepository.customer = Cache().userLoggedIn!; customerRepository.customer = Cache().userLoggedIn!;
loggedIn = true; loggedIn = true;
} }
} }
void _onAccountChange(AccountChangeCustomer event, Emitter<AccountState> emit) {
emit(AccountLoading());
emit(AccountReady());
}
void _onLoginChange(AccountLogin event, Emitter<AccountState> emit) {
emit(AccountLoading());
emit(AccountReady());
}
void _onLoginFinished(AccountLogInFinished event, Emitter<AccountState> emit) {
emit(AccountLoading());
customerRepository.customer = event.customer;
this.loggedIn = true;
emit(AccountLoggedIn());
}
void _onLogout(AccountLogout event, Emitter<AccountState> emit) async {
emit(AccountLoading());
await Cache().logout();
customerRepository.customer = null;
customerRepository.emptyTrainees();
loggedIn = false;
emit(AccountReady());
}
void _onGetTrainees(AccountGetTrainees event, Emitter<AccountState> emit) async {
emit(AccountLoading());
await customerRepository.getTrainees();
emit(AccountReady());
}
void _onSelectTrainees(AccountSelectTrainee event, Emitter<AccountState> emit) async {
emit(AccountLoading());
await customerRepository.getTrainees();
emit(AccountReady());
}
String getAccurateBodyType() { String getAccurateBodyType() {
String bodyType = ("Set your body type"); String bodyType = ("Set your body type");
int _ecto = 0; int _ecto = 0;
@ -57,42 +102,4 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
} }
return bodyType; return bodyType;
} }
@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;
this.loggedIn = true;
yield AccountLoggedIn();
} else if (event is AccountLogout) {
await Cache().logout();
customerRepository.customer = null;
customerRepository.emptyTrainees();
loggedIn = false;
yield AccountLoggedOut();
} else if (event is AccountGetTrainees) {
yield AccountLoading();
await customerRepository.getTrainees();
yield AccountReady();
} else if (event is AccountSelectTrainee) {
yield AccountLoading();
customerRepository.setTrainee(event.traineeId);
Cache().setTrainee(customerRepository.getTraineeById(event.traineeId)!);
ExerciseRepository exerciseRepository = ExerciseRepository();
await exerciseRepository.getExercisesByCustomer(event.traineeId);
this.traineeId = event.traineeId;
yield AccountReady();
}
} on Exception catch (e) {
yield AccountError(message: e.toString());
}
}
} }

View File

@ -1,14 +1,16 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/bloc/development_diagram/development_diagram_bloc.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart'; import 'package:flutter/material.dart';
part 'body_development_event.dart'; part 'body_development_event.dart';
part 'body_development_state.dart'; part 'body_development_state.dart';
enum DiagramDateFilterGroup { l3m, fm_lm, l3t, yearly }
class BodyDevelopmentBloc extends Bloc<BodyDevelopmentEvent, BodyDevelopmentState> { class BodyDevelopmentBloc extends Bloc<BodyDevelopmentEvent, BodyDevelopmentState> {
final WorkoutTreeRepository workoutTreeRepository; final WorkoutTreeRepository workoutTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
@ -16,28 +18,50 @@ class BodyDevelopmentBloc extends Bloc<BodyDevelopmentEvent, BodyDevelopmentStat
List<int> radarTicks = []; List<int> radarTicks = [];
List<String> radarFeatures = []; List<String> radarFeatures = [];
List<List<int>> radarData = []; List<List<int>> radarData = [];
DiagramGroup group = DiagramGroup.sumMass;
DiagramDateFilterGroup filter = DiagramDateFilterGroup.l3t;
@override @override
BodyDevelopmentBloc({required this.workoutTreeRepository}) : super(BodyDevelopmentInitial()); BodyDevelopmentBloc({required this.workoutTreeRepository}) : super(BodyDevelopmentInitial()) {
on<BodyDevelopmentLoad>(_onLoad);
on<BodyDevelopmentChangeDate>(_onDateFilterChange);
on<BodyDevelopmentChangeGroup>(_onGroupChange);
}
List<MaterialColor> defaultGraphColors = [
Colors.green,
Colors.blue,
Colors.red,
Colors.orange,
];
Future<void> getData() async { Future<void> getData() async {
radarTicks = [20, 40, 60, 80, 100]; radarTicks = [20, 40, 60, 80, 100];
radarFeatures = ["Mell", "Bicepsz", "Tricepsz", "Hát", "Váll"]; radarFeatures = ["Mell", "Bicepsz", "Tricepsz", "Hát", "Váll", "Core", "Comb", "Vádli"];
radarData = [ radarData = [
[80, 95, 45, 67, 83] [80, 95, 45, 67, 83, 40, 56, 78],
[82, 90, 56, 77, 82, 40, 50, 87],
[86, 92, 58, 70, 80, 49, 52, 87],
]; ];
} }
@override void _onLoad(BodyDevelopmentLoad event, Emitter<BodyDevelopmentState> emit) {
Stream<BodyDevelopmentState> mapEventToState(BodyDevelopmentEvent event) async* { emit(BodyDevelopmentLoading());
try { getData();
if (event is BodyDevelopmentLoad) { emit(BodyDevelopmentReady());
yield BodyDevelopmentLoading(); }
await getData();
yield BodyDevelopmentReady(); void _onDateFilterChange(BodyDevelopmentChangeDate event, Emitter<BodyDevelopmentState> emit) {
} emit(BodyDevelopmentLoading());
} on Exception catch (e) { this.filter = event.filter;
yield BodyDevelopmentError(message: e.toString()); getData();
} emit(BodyDevelopmentReady());
}
void _onGroupChange(BodyDevelopmentChangeGroup event, Emitter<BodyDevelopmentState> emit) {
emit(BodyDevelopmentLoading());
this.group = event.group;
getData();
emit(BodyDevelopmentReady());
} }
} }

View File

@ -1,7 +1,7 @@
part of 'body_development_bloc.dart'; part of 'body_development_bloc.dart';
@immutable @immutable
abstract class BodyDevelopmentEvent extends Equatable{ abstract class BodyDevelopmentEvent extends Equatable {
const BodyDevelopmentEvent(); const BodyDevelopmentEvent();
@override @override
List<Object> get props => []; List<Object> get props => [];
@ -10,3 +10,13 @@ abstract class BodyDevelopmentEvent extends Equatable{
class BodyDevelopmentLoad extends BodyDevelopmentEvent { class BodyDevelopmentLoad extends BodyDevelopmentEvent {
const BodyDevelopmentLoad(); const BodyDevelopmentLoad();
} }
class BodyDevelopmentChangeGroup extends BodyDevelopmentEvent {
final DiagramGroup group;
const BodyDevelopmentChangeGroup({required this.group});
}
class BodyDevelopmentChangeDate extends BodyDevelopmentEvent {
final DiagramDateFilterGroup filter;
const BodyDevelopmentChangeDate({required this.filter});
}

View File

@ -20,6 +20,35 @@ class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> {
final weights = List.generate(numberQuestions, (i) => []..length = 3, growable: false); final weights = List.generate(numberQuestions, (i) => []..length = 3, growable: false);
BodytypeBloc({required this.repository}) : super(BodytypeInitial()) { BodytypeBloc({required this.repository}) : super(BodytypeInitial()) {
this._load();
on<BodytypeClick>(_onBodyTypeClick);
on<BodytypeBack>(_onBodyTypeClickBack);
}
void _onBodyTypeClick(BodytypeClick event, Emitter<BodytypeState> emit) async {
emit(BodytypeLoading());
this.value = event.value;
answers[step - 1] = value;
calculateBodyType();
await saveToDB();
if (step >= questions.length) {
emit(BodytypeFinished());
return;
}
step++;
emit(BodytypeReady());
}
void _onBodyTypeClickBack(BodytypeBack event, Emitter<BodytypeState> emit) async {
if (step == 1) {
emit(BodytypeReady());
return;
}
step--;
this.value = answers[step - 1];
}
void _load() {
questions.add("1. Basicly I am skinny and bonny"); questions.add("1. Basicly I am skinny and bonny");
questions.add("2. question"); questions.add("2. question");
questions.add("3. question"); questions.add("3. question");
@ -90,38 +119,6 @@ class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> {
int _mezo = 0; int _mezo = 0;
int _endo = 0; int _endo = 0;
@override
Stream<BodytypeState> mapEventToState(
BodytypeEvent event,
) async* {
try {
if (event is BodytypeClick) {
yield BodytypeLoading();
this.value = event.value;
answers[step - 1] = value;
calculateBodyType();
await saveToDB();
if (step >= questions.length) {
yield BodytypeFinished();
return;
}
step++;
yield BodytypeReady();
} else if (event is BodytypeBack) {
yield BodytypeLoading();
if (step == 1) {
yield BodytypeReady();
return;
}
step--;
this.value = answers[step - 1];
yield BodytypeReady();
}
} on Exception catch (e) {
yield BodytypeError(error: e.toString());
}
}
bool showResults() { bool showResults() {
return this.state == BodytypeFinished() || origBodyTypeValue > 0; return this.state == BodytypeFinished() || origBodyTypeValue > 0;
} }

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/sport.dart'; import 'package:aitrainer_app/model/sport.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
@ -21,6 +19,176 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
double weight = 60; double weight = 60;
double height = 170; double height = 170;
CustomerChangeBloc({required this.customerRepository}) : super(CustomerChangeInitial()) { CustomerChangeBloc({required this.customerRepository}) : super(CustomerChangeInitial()) {
this._load();
on<CustomerLoad>(_onLoad);
on<CustomerGoalChange>(_onGoalChange);
on<CustomerChangePasswordObscure>(_onChangePasswordObscure);
on<CustomerFitnessChange>(_onFitnessChange);
on<CustomerBirthYearChange>(_onBirthyearChange);
on<CustomerWeightChange>(_onWeightChange);
on<CustomerHeightChange>(_onHeightChange);
on<CustomerBodyTypeChange>(_onBodytypeChange);
on<CustomerEmailChange>(_onEmailChange);
on<CustomerPasswordChange>(_onPasswordChange);
on<CustomerFirstNameChange>(_onFirstNameChange);
on<CustomerNameChange>(_onNameChange);
on<CustomerGenderChange>(_onGenderChange);
on<CustomerSportChange>(_onSportChange);
on<CustomerSaveFitness>(_onSaveFitness);
on<CustomerSaveGoal>(_onSaveGoal);
on<CustomerSaveSex>(_onSaveSex);
on<CustomerSaveWeight>(_onSaveWeight);
on<CustomerSaveHeight>(_onSaveHeight);
on<CustomerSave>(_onSave);
}
void _onLoad(CustomerLoad event, Emitter<CustomerChangeState> emit) async {
emit(CustomerChangeLoading());
emit(CustomerDataChanged());
}
void _onGoalChange(CustomerGoalChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setGoal(event.goal);
emit(CustomerDataChanged());
}
void _onChangePasswordObscure(CustomerChangePasswordObscure event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
visiblePassword = !visiblePassword;
emit(CustomerDataChanged());
}
void _onFitnessChange(CustomerFitnessChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setFitnessLevel(event.fitness);
selectedFitnessItem = event.fitness;
emit(CustomerDataChanged());
}
void _onBirthyearChange(CustomerBirthYearChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setBirthYear(event.year);
year = event.year;
emit(CustomerDataChanged());
}
void _onWeightChange(CustomerWeightChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setWeight(event.weight);
weight = event.weight.toDouble();
emit(CustomerDataChanged());
}
void _onHeightChange(CustomerHeightChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setHeight(event.height);
height = event.height.toDouble();
emit(CustomerDataChanged());
}
void _onBodytypeChange(CustomerBodyTypeChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setBodyType(event.bodyType);
emit(CustomerDataChanged());
}
void _onEmailChange(CustomerEmailChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setEmail(event.email);
emit(CustomerDataChanged());
}
void _onPasswordChange(CustomerPasswordChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setPassword(event.password);
emit(CustomerDataChanged());
}
void _onFirstNameChange(CustomerFirstNameChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setFirstName(event.firstName);
emit(CustomerDataChanged());
}
void _onNameChange(CustomerNameChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setName(event.name);
emit(CustomerDataChanged());
}
void _onGenderChange(CustomerGenderChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
customerRepository.setSex(event.gender == 0 ? "m" : "w");
emit(CustomerDataChanged());
}
void _onSportChange(CustomerSportChange event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
selectedSport = event.sport;
print("Selected Sport $selectedSport");
emit(CustomerDataChanged());
}
void _onSaveFitness(CustomerSaveFitness event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.fitnessLevel == null) {
throw Exception("Please select your fitness level");
}
emit(CustomerSaveSuccess());
}
void _onSaveGoal(CustomerSaveGoal event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.goal == null) {
throw Exception("Please select your goal");
}
emit(CustomerSaveSuccess());
}
void _onSaveSex(CustomerSaveSex event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
if (customerRepository.customer!.sex == null) {
throw Exception("Please select your biologial gender");
}
emit(CustomerSaveSuccess());
}
void _onSaveWeight(CustomerSaveWeight event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
emit(CustomerSaveSuccess());
}
void _onSaveHeight(CustomerSaveHeight event, Emitter<CustomerChangeState> emit) {
emit(CustomerChangeLoading());
emit(CustomerSaveSuccess());
}
void _onSave(CustomerSave event, Emitter<CustomerChangeState> emit) async {
emit(CustomerSaving());
if (validation()) {
if (selectedFitnessItem != null) {
customerRepository.setFitnessLevel(selectedFitnessItem!);
}
if (selectedSport != null) {
customerRepository.customer!.sportId = selectedSport!.sportId;
}
if (customerRepository.customer!.lang == null) {
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
}
await customerRepository.saveCustomer();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticDataChange();
Cache().initBadges();
emit(CustomerSaveSuccess());
} else {
emit(CustomerSaveError(message: "Please provide the necessary information"));
}
}
void _load() {
if (this.customerRepository.customer == null) { if (this.customerRepository.customer == null) {
this.customerRepository.createNew(); this.customerRepository.createNew();
} }
@ -38,119 +206,6 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
Sport? selectedSport; Sport? selectedSport;
String? selectedFitnessItem; String? selectedFitnessItem;
@override
Stream<CustomerChangeState> mapEventToState(
CustomerChangeEvent event,
) async* {
try {
print("Event: $event");
if (event is CustomerLoad) {
yield CustomerChangeLoading();
yield CustomerDataChanged();
} else if (event is CustomerGoalChange) {
yield CustomerChangeLoading();
customerRepository.setGoal(event.goal);
yield CustomerDataChanged();
} else if (event is CustomerChangePasswordObscure) {
yield CustomerChangeLoading();
visiblePassword = !visiblePassword;
yield CustomerDataChanged();
} else if (event is CustomerFitnessChange) {
yield CustomerChangeLoading();
customerRepository.setFitnessLevel(event.fitness);
selectedFitnessItem = event.fitness;
yield CustomerDataChanged();
} else if (event is CustomerBirthYearChange) {
yield CustomerChangeLoading();
customerRepository.setBirthYear(event.year);
year = event.year;
yield CustomerDataChanged();
} else if (event is CustomerWeightChange) {
//yield CustomerChangeLoading();
customerRepository.setWeight(event.weight);
weight = event.weight.toDouble();
yield CustomerDataChanged();
} else if (event is CustomerHeightChange) {
yield CustomerChangeLoading();
customerRepository.setHeight(event.height);
height = event.height.toDouble();
yield CustomerDataChanged();
} else if (event is CustomerBodyTypeChange) {
customerRepository.setBodyType(event.bodyType);
yield CustomerDataChanged();
} else if (event is CustomerEmailChange) {
customerRepository.setEmail(event.email);
yield CustomerDataChanged();
} else if (event is CustomerPasswordChange) {
customerRepository.setPassword(event.password);
yield CustomerDataChanged();
} else if (event is CustomerFirstNameChange) {
customerRepository.setFirstName(event.firstName);
yield CustomerDataChanged();
} else if (event is CustomerNameChange) {
customerRepository.setName(event.name);
yield CustomerDataChanged();
} else if (event is CustomerGenderChange) {
yield CustomerChangeLoading();
customerRepository.setSex(event.gender == 0 ? "m" : "w");
yield CustomerDataChanged();
} else if (event is CustomerSportChange) {
yield CustomerChangeLoading();
selectedSport = event.sport;
print("Selected Sport $selectedSport");
yield CustomerDataChanged();
} else if (event is CustomerSaveFitness) {
yield CustomerChangeLoading();
if (customerRepository.customer!.fitnessLevel == null) {
throw Exception("Please select your fitness level");
}
yield CustomerSaveSuccess();
} else if (event is CustomerSaveGoal) {
yield CustomerChangeLoading();
if (customerRepository.customer!.goal == null) {
throw Exception("Please select your goal");
}
yield CustomerSaveSuccess();
} else if (event is CustomerSaveSex) {
yield CustomerChangeLoading();
if (customerRepository.customer!.sex == null) {
throw Exception("Please select your biologial gender");
}
yield CustomerSaveSuccess();
} else if (event is CustomerSaveWeight) {
yield CustomerChangeLoading();
yield CustomerSaveSuccess();
} else if (event is CustomerSaveHeight) {
yield CustomerChangeLoading();
yield CustomerSaveSuccess();
} else if (event is CustomerSave) {
yield CustomerSaving();
if (validation()) {
if (selectedFitnessItem != null) {
customerRepository.setFitnessLevel(selectedFitnessItem!);
}
if (selectedSport != null) {
customerRepository.customer!.sportId = selectedSport!.sportId;
}
if (customerRepository.customer!.lang == null) {
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
}
await customerRepository.saveCustomer();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticDataChange();
Cache().initBadges();
yield CustomerSaveSuccess();
} else {
yield CustomerSaveError(message: "Please provide the necessary information");
}
}
} on Exception catch (e) {
yield CustomerSaveError(message: e.toString());
}
}
bool validation() { bool validation() {
if (customerRepository.customer == null) throw Exception("Customer object not defined"); if (customerRepository.customer == null) throw Exception("Customer object not defined");
return true; return true;

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_device.dart'; import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart'; import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart';
@ -16,36 +14,38 @@ class CustomerExerciseDeviceBloc extends Bloc<CustomerExerciseDeviceEvent, Custo
final List<ExerciseDevice>? devices; final List<ExerciseDevice>? devices;
CustomerExerciseDeviceBloc({required this.repository, required this.devices}) : super(CustomerExerciseDeviceInitial()) { CustomerExerciseDeviceBloc({required this.repository, required this.devices}) : super(CustomerExerciseDeviceInitial()) {
_load();
on<CustomerExerciseDeviceLoad>(_onLoad);
on<CustomerExerciseDeviceAdd>(_onDeviceAdd);
on<CustomerExerciseDeviceRemove>(_onDeviceRemove);
}
void _onLoad(CustomerExerciseDeviceLoad event, Emitter<CustomerExerciseDeviceState> emit) {
emit(CustomerExerciseDeviceLoading());
emit(CustomerExerciseDeviceReady());
}
void _onDeviceAdd(CustomerExerciseDeviceAdd event, Emitter<CustomerExerciseDeviceState> emit) async {
emit(CustomerExerciseDeviceLoading());
await repository.addDevice(event.device);
Cache().initBadges();
emit(CustomerExerciseDeviceReady());
}
void _onDeviceRemove(CustomerExerciseDeviceRemove event, Emitter<CustomerExerciseDeviceState> emit) async {
emit(CustomerExerciseDeviceLoading());
await repository.removeDevice(event.device);
Cache().initBadges();
emit(CustomerExerciseDeviceReady());
}
void _load() {
if (repository.getDevices().isEmpty) { if (repository.getDevices().isEmpty) {
repository.setDevices(Cache().getCustomerDevices()!); repository.setDevices(Cache().getCustomerDevices()!);
} }
Track().track(TrackingEvent.exercise_device); Track().track(TrackingEvent.exercise_device);
} }
@override
Stream<CustomerExerciseDeviceState> mapEventToState(
CustomerExerciseDeviceEvent event,
) async* {
try {
if (event is CustomerExerciseDeviceLoad) {
yield CustomerExerciseDeviceLoading();
yield CustomerExerciseDeviceReady();
} else if (event is CustomerExerciseDeviceAdd) {
yield CustomerExerciseDeviceLoading();
await repository.addDevice(event.device);
Cache().initBadges();
yield CustomerExerciseDeviceReady();
} else if (event is CustomerExerciseDeviceRemove) {
yield CustomerExerciseDeviceLoading();
await repository.removeDevice(event.device);
Cache().initBadges();
yield CustomerExerciseDeviceReady();
}
} on Exception catch (ex) {
yield CustomerExerciseDeviceError(message: ex.toString());
}
}
bool hasCustomerDevice(int exerciseDeviceId) { bool hasCustomerDevice(int exerciseDeviceId) {
return repository.hasDevice(exerciseDeviceId); return repository.hasDevice(exerciseDeviceId);
} }

View File

@ -1,12 +1,9 @@
import 'package:intl/intl.dart';
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/diagram_data.dart'; import 'package:aitrainer_app/util/diagram_data.dart';
@ -18,391 +15,17 @@ import 'package:flutter/material.dart';
part 'development_by_muscle_event.dart'; part 'development_by_muscle_event.dart';
part 'development_by_muscle_state.dart'; part 'development_by_muscle_state.dart';
enum DiagramType { sumMass, oneRepMax, percent }
enum DiagramDateType { daily, weekly, monthly, yearly }
class GroupDate extends GroupData with Common {
final List<Exercise> inputList;
final List<DiagramData> outputList;
String? _origDatePart;
late int _origExerciseTypeId;
late Exercise _origExercise;
late double _sumQuantity;
late double _maxQuantity;
late int _countExercises;
late DiagramType diagramType;
late DiagramDateType dateRate;
GroupDate({required this.inputList, required this.outputList});
double getQuantityByDate(Exercise exercise) {
double sum = 0;
if (this.diagramType == DiagramType.sumMass) {
if (exercise.unitQuantity != null) {
sum = exercise.quantity! * exercise.unitQuantity!;
} else {
sum = exercise.quantity!;
}
} else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
if (exercise.unitQuantity != null) {
sum = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
} else {
sum = exercise.quantity!;
}
}
return sum;
}
@override
void addTempData(Exercise exercise) {
double newQuantity = getQuantityByDate(exercise);
_sumQuantity = _sumQuantity + newQuantity;
if (_maxQuantity < newQuantity) {
_maxQuantity = newQuantity;
}
_countExercises = _countExercises + 1;
_origDatePart = getDatePart(exercise.dateAdd!, dateRate);
_origExerciseTypeId = exercise.exerciseTypeId!;
_origExercise = exercise;
}
@override
bool checkNewType(Exercise exercise) {
String exerciseDatePart = getDatePart(exercise.dateAdd!, dateRate);
return _origDatePart == null || _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
}
String getDatePart(DateTime date, DiagramDateType dateRate) {
String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
if (dateRate == DiagramDateType.weekly) {
datePart = weekNumber(date).toString();
} else if (dateRate == DiagramDateType.monthly) {
datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date);
} else if (dateRate == DiagramDateType.yearly) {
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
} else if (dateRate == DiagramDateType.daily) {
datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
}
return datePart;
}
@override
void iteration() {
this.resetTemp();
Exercise? tempExercise;
inputList.forEach((element) {
tempExercise = element;
if (this.checkNewType(element)) {
if (_origDatePart == null) {
this.addTempData(element);
} else {
this.temp2Output(_origExercise);
this.resetTemp();
this.addTempData(element);
}
} else {
this.addTempData(element);
}
});
if (tempExercise != null) {
this.temp2Output(tempExercise!);
}
}
@override
void temp2Output(Exercise exercise) {
if (exercise.unitQuantity == null) {
return;
}
Exercise newExercise = exercise.copy();
newExercise.datePart = _origDatePart;
if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
newExercise.calculated = _maxQuantity;
} else {
newExercise.calculated = _sumQuantity / _countExercises;
}
DiagramData data = DiagramData(newExercise.datePart!, newExercise.calculated);
outputList.add(data);
}
@override
void resetTemp() {
_countExercises = 0;
_sumQuantity = 0;
_maxQuantity = 0;
}
}
/*
class DiagramType {
static String sumMass = "sumMass";
static String oneRepMax = "oneRepMax";
static String percent = "percent";
}
/*
=========== GROUPDATE CLASS
*/
class GroupDate extends GroupData with Common {
final List<Exercise> inputList;
final List<Exercise> outputList;
String? _origDatePart;
late int _origExerciseTypeId;
late Exercise _origExercise;
late double _sumQuantity;
late double _maxQuantity;
late int _countExercises;
late String diagramType;
late String dateRate;
GroupDate({required this.inputList, required this.outputList});
double getQuantityByDate(Exercise exercise) {
double sum = 0;
if (this.diagramType == DiagramType.sumMass) {
if (exercise.unitQuantity != null) {
sum = exercise.quantity! * exercise.unitQuantity!;
} else {
sum = exercise.quantity!;
}
} else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
if (exercise.unitQuantity != null) {
sum = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
} else {
sum = exercise.quantity!;
}
}
return sum;
}
@override
void addTempData(Exercise exercise) {
double newQuantity = getQuantityByDate(exercise);
_sumQuantity = _sumQuantity + newQuantity;
if (_maxQuantity < newQuantity) {
_maxQuantity = newQuantity;
}
_countExercises = _countExercises + 1;
_origDatePart = getDatePart(exercise.dateAdd!, dateRate);
_origExerciseTypeId = exercise.exerciseTypeId!;
_origExercise = exercise;
}
@override
bool checkNewType(Exercise exercise) {
String exerciseDatePart = getDatePart(exercise.dateAdd!, dateRate);
return _origDatePart == null || _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
}
@override
void iteration() {
this.resetTemp();
Exercise? tempExercise;
inputList.forEach((element) {
tempExercise = element;
if (this.checkNewType(element)) {
if (_origDatePart == null) {
this.addTempData(element);
} else {
this.temp2Output(_origExercise);
this.resetTemp();
this.addTempData(element);
}
} else {
this.addTempData(element);
}
});
if (tempExercise != null) {
this.temp2Output(tempExercise!);
}
}
@override
void temp2Output(Exercise exercise) {
if (exercise.unitQuantity == null) {
return;
}
Exercise newExercise = exercise.copy();
newExercise.datePart = _origDatePart;
if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
newExercise.calculated = _maxQuantity;
} else {
newExercise.calculated = _sumQuantity / _countExercises;
}
outputList.add(newExercise);
}
@override
void resetTemp() {
_countExercises = 0;
_sumQuantity = 0;
_maxQuantity = 0;
}
}
/*
=========== CHART DATA CLASS
*/
class GroupChart extends GroupData with Common {
final List<dynamic> inputList;
LinkedHashMap<int, ChartDataExtended> outputList = LinkedHashMap();
int? _origExerciseTypeId;
late double _minData = 999999999999;
late double _maxData = 0;
late List<BarChartGroupData> _chartData;
late double _basePercent;
String diagramType = DiagramType.sumMass;
GroupChart({required this.inputList, required this.outputList});
double getBasePercent(Exercise exercise) {
if (exercise.unitQuantity != null) {
this._basePercent = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
} else {
this._basePercent = exercise.quantity!;
}
return this._basePercent;
}
double getDiagramValue(Exercise exercise) {
double value = 0;
if (diagramType == DiagramType.percent) {
if (exercise.unitQuantity != null) {
double oneRepMax = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
value = (oneRepMax / this._basePercent) * 100;
} else {
value = (exercise.quantity! / this._basePercent) * 100;
}
} else if (diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) {
value = exercise.calculated!;
}
return value;
}
@override
void addTempData(Exercise exercise) {
double diagramValue = this.getDiagramValue(exercise);
if (_maxData < diagramValue) {
_maxData = diagramValue;
}
if (_minData > diagramValue) {
_minData = diagramValue;
}
BarChartGroupData data = BarChartGroupData(
x: exercise.dateAdd!.millisecondsSinceEpoch, barRods: [BarChartRodData(toY: diagramValue, width: 12, color: Colors.lightBlue)]);
_chartData.add(data);
_origExerciseTypeId = exercise.exerciseTypeId!;
}
@override
bool checkNewType(Exercise exercise) {
return _origExerciseTypeId == null || _origExerciseTypeId != exercise.exerciseTypeId;
}
@override
void iteration() {
this.resetTemp();
Exercise? tempExercise;
inputList.forEach((element) {
tempExercise = element;
if (this.checkNewType(element)) {
if (_origExerciseTypeId == null) {
_basePercent = getBasePercent(element);
this.addTempData(element);
} else {
this.temp2Output(element);
this.resetTemp();
_basePercent = getBasePercent(element);
this.addTempData(element);
}
} else {
this.addTempData(element);
}
});
if (tempExercise != null) {
this.temp2Output(tempExercise!);
}
}
@override
void temp2Output(Exercise exercise) {
double dInterval = ((_maxData + _minData) / 8).roundToDouble();
int gridInterval = (dInterval / 3).floor();
ChartDataExtended extended;
if (outputList[_origExerciseTypeId] == null) {
extended = ChartDataExtended(data: _chartData, interval: dInterval, gridInterval: gridInterval);
outputList[_origExerciseTypeId!] = extended;
} else {
extended = outputList[_origExerciseTypeId]!;
_chartData.forEach((element) {
extended.data.add(element);
});
}
}
@override
void resetTemp() {
_minData = 999999999999;
_maxData = 0;
_chartData = [];
}
}
class ChartDataExtended {
final List<BarChartGroupData> data;
final double interval;
final int gridInterval;
const ChartDataExtended({required this.data, required this.interval, required this.gridInterval});
Map<String, dynamic> toJson() {
List listBarChartData = [];
data.forEach((element) {
element.barRods.forEach((rods) {
var barChartData = {
'x': element.x,
'y': rods.toY,
};
listBarChartData.add(barChartData);
});
});
var chartData = {
"data": listBarChartData.toString(),
"interval": interval.toString(),
"gridInterval": gridInterval,
};
return chartData;
}
} */
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Common, Logging { class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Common, Logging {
final WorkoutTreeRepository workoutTreeRepository; final WorkoutTreeRepository workoutTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
final List<DiagramData> diagramData = []; final List<DiagramData> diagramData = [];
int actualExerciseType = 0;
DiagramType diagramType = DiagramType.sumMass;
DiagramDateType diagramDateType = DiagramDateType.monthly;
@override @override
DevelopmentByMuscleBloc({required this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial()) { DevelopmentByMuscleBloc({required this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial()) {
on<DevelopmentByMuscleLoad>(_onLoad); on<DevelopmentByMuscleLoad>(_onLoad);
} }
Future<void> getData() async { void getTree() {
workoutTreeRepository.sortedTree.clear(); workoutTreeRepository.sortedTree.clear();
workoutTreeRepository.sortByMuscleType(); workoutTreeRepository.sortByMuscleType();
@ -414,11 +37,11 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
}); });
} }
void _onLoad(DevelopmentByMuscleLoad event, Emitter<DevelopmentByMuscleState> emit) async { void _onLoad(DevelopmentByMuscleLoad event, Emitter<DevelopmentByMuscleState> emit) {
emit(DevelopmentByMuscleLoadingState()); emit(DevelopmentByMuscleLoadingState());
Track().track(TrackingEvent.my_muscle_development); Track().track(TrackingEvent.my_muscle_development);
Cache().setActivityDonePrefs(ActivityDone.isMuscleDevelopmentSeen); Cache().setActivityDonePrefs(ActivityDone.isMuscleDevelopmentSeen);
await getData(); getTree();
emit(DevelopmentByMuscleReadyState()); emit(DevelopmentByMuscleReadyState());
} }
} }

View File

@ -11,19 +11,3 @@ abstract class DevelopmentByMuscleEvent extends Equatable {
class DevelopmentByMuscleLoad extends DevelopmentByMuscleEvent { class DevelopmentByMuscleLoad extends DevelopmentByMuscleEvent {
const DevelopmentByMuscleLoad(); const DevelopmentByMuscleLoad();
} }
class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
final DiagramDateType dateRate;
const DevelopmentByMuscleDateRateChange({required this.dateRate});
@override
List<Object> get props => [dateRate];
}
class DevelopmentByMuscleDiagramTypeChange extends DevelopmentByMuscleEvent {
final DiagramType diagramType;
const DevelopmentByMuscleDiagramTypeChange({required this.diagramType});
@override
List<Object> get props => [diagramType];
}

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart'; import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
@ -39,8 +38,14 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
List<Exercise> controlList = []; List<Exercise> controlList = [];
@override @override
ExerciseControlBloc({required this.exerciseRepository, required this.readonly, required this.timerBloc}) ExerciseControlBloc({required this.exerciseRepository, required this.readonly, required this.timerBloc}) : super(ExerciseControlInitial()) {
: super(ExerciseControlInitial()) { _load();
on<ExerciseControlQuantityChange>(_onQuantityChange);
on<ExerciseControlUnitQuantityChange>(_onQuantityUnitChange);
on<ExerciseControlSubmit>(_onSubmit);
}
void _load() {
print("Exercise ${exerciseRepository.exercise!.toJson()}"); print("Exercise ${exerciseRepository.exercise!.toJson()}");
exerciseTypeLocal = ExerciseTypeLocal.oneRepMax; exerciseTypeLocal = ExerciseTypeLocal.oneRepMax;
@ -69,47 +74,46 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
timerBloc.add(TimerStart(duration: 300)); timerBloc.add(TimerStart(duration: 300));
} }
@override void _onQuantityChange(ExerciseControlQuantityChange event, Emitter<ExerciseControlState> emit) {
Stream<ExerciseControlState> mapEventToState(ExerciseControlEvent event) async* { emit(ExerciseControlLoading());
try { if (event.step == step) {
if (event is ExerciseControlQuantityChange) { exerciseRepository.setQuantity(event.quantity);
if (event.step == step) { quantity = event.quantity;
exerciseRepository.setQuantity(event.quantity); controlList[step - 1].quantity = quantity;
quantity = event.quantity;
controlList[step - 1].quantity = quantity;
}
} else if (event is ExerciseControlUnitQuantityChange) {
yield ExerciseControlLoading();
print("event step ${event.step} quantity ${event.quantity}");
if (event.step == step) {
this.unitQuantity = event.quantity;
exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity;
quantity = calculateQuantityByUnitQuantity().toDouble();
exerciseRepository.setQuantity(quantity);
controlList[step - 1].unitQuantity = event.quantity;
controlList[step - 1].quantity = quantity;
}
yield ExerciseControlReady();
} else if (event is ExerciseControlSubmit) {
yield ExerciseControlLoading();
if (event.step == step) {
step++;
scrollOffset = step * 400.0;
if (exerciseRepository.exercise!.quantity == null) {
exerciseRepository.setQuantity(quantity);
}
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd(duration: 300));
}
yield ExerciseControlReady();
}
} on Exception catch (e) {
yield ExerciseControlError(message: e.toString());
} }
emit(ExerciseControlReady());
}
void _onQuantityUnitChange(ExerciseControlUnitQuantityChange event, Emitter<ExerciseControlState> emit) {
emit(ExerciseControlLoading());
print("event step ${event.step} quantity ${event.quantity}");
if (event.step == step) {
this.unitQuantity = event.quantity;
exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity;
quantity = calculateQuantityByUnitQuantity().toDouble();
exerciseRepository.setQuantity(quantity);
controlList[step - 1].unitQuantity = event.quantity;
controlList[step - 1].quantity = quantity;
}
emit(ExerciseControlReady());
}
void _onSubmit(ExerciseControlSubmit event, Emitter<ExerciseControlState> emit) async {
emit(ExerciseControlLoading());
if (event.step == step) {
step++;
scrollOffset = step * 400.0;
if (exerciseRepository.exercise!.quantity == null) {
exerciseRepository.setQuantity(quantity);
}
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd(duration: 300));
}
emit(ExerciseControlReady());
} }
double calculate1RM({bool percent75 = true}) { double calculate1RM({bool percent75 = true}) {

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/repository/mautic_repository.dart'; import 'package:aitrainer_app/repository/mautic_repository.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:aitrainer_app/main.dart'; import 'package:aitrainer_app/main.dart';
@ -56,11 +55,28 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
); );
late int timerValue; late int timerValue;
late ExerciseType exerciseType;
@override @override
ExerciseNewBloc( ExerciseNewBloc({required this.exerciseRepository, required this.menuBloc, required this.customerRepository, required this.exerciseType})
{required this.exerciseRepository, required this.menuBloc, required this.customerRepository, required ExerciseType exerciseType})
: super(ExerciseNewInitial()) { : super(ExerciseNewInitial()) {
exerciseRepository.exerciseType = exerciseType; this._load();
on<ExerciseNewQuantityChange>(_onQuantityChange);
on<ExerciseNewQuantityUnitChange>(_onQuantityUnitChange);
on<ExerciseNewWeightChange>(_onWeightChange);
on<ExerciseNewFitnessLevelChange>(_onFitnessLevelChange);
on<ExerciseNewBirthyearChange>(_onBirthyearChange);
on<ExerciseNewHeightChange>(_onHeightChange);
on<ExerciseNewSaveWeight>(_onSaveWeight);
on<ExerciseNewSizeChange>(_onSizeChange);
on<ExerciseNewSubmit>(_onSubmit);
on<ExerciseNewSubmitNoRegistration>(_onSubmitNoRegistration);
on<ExerciseNewBMIAnimate>(_onBMIAnimate);
on<ExerciseNewAddError>(_onAddError);
}
void _load() {
exerciseRepository.exerciseType = this.exerciseType;
exerciseRepository.setUnit(exerciseType.unit); exerciseRepository.setUnit(exerciseType.unit);
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
@ -78,110 +94,120 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
} }
} }
void _onQuantityChange(ExerciseNewQuantityChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
log("Event quantity " + event.quantity.toStringAsFixed(0));
this.setQuantity(event.quantity);
emit(ExerciseNewReady());
}
void _onQuantityUnitChange(ExerciseNewQuantityUnitChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
log("Event quantityUnit " + event.quantity.toStringAsFixed(0));
exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity;
emit(ExerciseNewReady());
}
void _onWeightChange(ExerciseNewWeightChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
customerRepository.setWeight(event.value);
changedWeight = true;
weight = event.value;
getBMI();
getGoalBMI();
getBMR();
emit(ExerciseNewReady());
}
void _onFitnessLevelChange(ExerciseNewFitnessLevelChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
customerRepository.setFitnessLevel(event.value);
fitnessLevel = event.value;
changedWeight = true;
getBMR();
emit(ExerciseNewReady());
}
void _onBirthyearChange(ExerciseNewBirthyearChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
changedWeight = true;
customerRepository.setBirthYear(event.value.toInt());
birthYear = event.value;
emit(ExerciseNewReady());
}
void _onHeightChange(ExerciseNewHeightChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
customerRepository.setHeight(event.value.toInt());
changedWeight = true;
height = event.value;
getBMI();
getGoalBMI();
getBMR();
emit(ExerciseNewReady());
}
void _onSaveWeight(ExerciseNewSaveWeight event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
customerRepository.saveCustomer();
changedWeight = false;
this.changedSizes = false;
Cache().initBadges();
Track().track(TrackingEvent.sizes);
emit(ExerciseNewReady());
}
void _onSizeChange(ExerciseNewSizeChange event, Emitter<ExerciseNewState> emit) {
emit(ExerciseNewLoading());
this.changedSizes = true;
this.customerRepository.updateSizes(event.propertyName, event.value);
customerRepository.setCustomerProperty(event.propertyName, event.value);
emit(ExerciseNewReady());
}
void _onSubmit(ExerciseNewSubmit event, Emitter<ExerciseNewState> emit) async {
emit(ExerciseNewLoading());
if (quantity == -1 || unitQuantity == -1) {
emit(ExerciseNewReady());
throw Exception("Please type in a real number");
}
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
if (!isInDebugMode) {
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges();
Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name);
emit(ExerciseNewReady());
}
void _onSubmitNoRegistration(ExerciseNewSubmitNoRegistration event, Emitter<ExerciseNewState> emit) async {
emit(ExerciseNewLoading());
exerciseRepository.addExerciseNoRegistration();
menuBloc.add(MenuTreeDown(parent: 0));
Track().track(TrackingEvent.exercise_new_no_registration, eventValue: exerciseRepository.exerciseType!.name);
emit(ExerciseNewReady());
}
void _onBMIAnimate(ExerciseNewBMIAnimate event, Emitter<ExerciseNewState> emit) async {
emit(ExerciseNewLoading());
emit(ExerciseNewReady());
}
void _onAddError(ExerciseNewAddError event, Emitter<ExerciseNewState> emit) async {
emit(ExerciseNewLoading());
emit(ExerciseNewReady());
}
void setQuantity(double quantity) { void setQuantity(double quantity) {
this.quantity = quantity; this.quantity = quantity;
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
} }
@override
Stream<ExerciseNewState> mapEventToState(ExerciseNewEvent event) async* {
try {
if (event is ExerciseNewLoad) {
yield ExerciseNewLoading();
yield ExerciseNewReady();
} else if (event is ExerciseNewQuantityChange) {
yield ExerciseNewLoading();
log("Event quantity " + event.quantity.toStringAsFixed(0));
this.setQuantity(event.quantity);
yield ExerciseNewReady();
} else if (event is ExerciseNewQuantityUnitChange) {
yield ExerciseNewLoading();
log("Event quantityUnit " + event.quantity.toStringAsFixed(0));
exerciseRepository.setUnitQuantity(event.quantity);
unitQuantity = event.quantity;
yield ExerciseNewReady();
} else if (event is ExerciseNewWeightChange) {
yield ExerciseNewLoading();
customerRepository.setWeight(event.value);
changedWeight = true;
weight = event.value;
getBMI();
getGoalBMI();
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewFitnessLevelChange) {
yield ExerciseNewLoading();
customerRepository.setFitnessLevel(event.value);
fitnessLevel = event.value;
changedWeight = true;
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewBirthyearChange) {
yield ExerciseNewLoading();
changedWeight = true;
customerRepository.setBirthYear(event.value.toInt());
birthYear = event.value;
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewHeightChange) {
yield ExerciseNewLoading();
customerRepository.setHeight(event.value.toInt());
changedWeight = true;
height = event.value;
getBMI();
getGoalBMI();
getBMR();
yield ExerciseNewReady();
} else if (event is ExerciseNewSaveWeight) {
yield ExerciseNewLoading();
customerRepository.saveCustomer();
changedWeight = false;
this.changedSizes = false;
Cache().initBadges();
Track().track(TrackingEvent.sizes);
yield ExerciseNewReady();
} else if (event is ExerciseNewSizeChange) {
yield ExerciseNewLoading();
this.changedSizes = true;
this.customerRepository.updateSizes(event.propertyName, event.value);
customerRepository.setCustomerProperty(event.propertyName, event.value);
yield ExerciseNewReady();
} else if (event is ExerciseNewSubmit) {
yield ExerciseNewLoading();
if (quantity == -1 || unitQuantity == -1) {
yield ExerciseNewReady();
throw Exception("Please type in a real number");
}
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
if (!isInDebugMode) {
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
// exerciseRepository.initExercise();
menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges();
Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name);
yield ExerciseNewSaved();
} else if (event is ExerciseNewSubmitNoRegistration) {
yield ExerciseNewLoading();
exerciseRepository.addExerciseNoRegistration();
menuBloc.add(MenuTreeDown(parent: 0));
Track().track(TrackingEvent.exercise_new_no_registration, eventValue: exerciseRepository.exerciseType!.name);
yield ExerciseNewSaved();
} else if (event is ExerciseNewBMIAnimate) {
yield ExerciseNewLoading();
yield ExerciseNewReady();
} else if (event is ExerciseNewAddError) {
yield ExerciseNewLoading();
yield ExerciseNewError(message: event.message);
}
} on Exception catch (e) {
yield ExerciseNewError(message: e.toString());
}
}
double getBMI() { double getBMI() {
if (weight == null || height == null || height == 0 || weight == 0) { if (weight == null || height == null || height == 0 || weight == 0) {
this.bmi = 0; this.bmi = 0;

View File

@ -20,7 +20,72 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository(); ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
late int customerId; late int customerId;
ExercisePlanBloc({required this.menuTreeRepository}) : super(ExercisePlanInitial()); ExercisePlanBloc({required this.menuTreeRepository}) : super(ExercisePlanInitial()) {
on<ExercisePlanLoad>(_onLoad);
on<ExercisePlanUpdateUI>(_onUpdateUI);
on<ExercisePlanAddExercise>(_onAddExercise);
on<ExercisePlanRemoveExercise>(_onRemoveExercise);
}
void _onLoad(ExercisePlanLoad event, Emitter<ExercisePlanState> emit) async {
if (Cache().userLoggedIn == null || Cache().userLoggedIn!.customerId == null) {
throw Exception("Please log in");
}
emit(ExercisePlanLoading());
customerId = Cache().userLoggedIn!.customerId!;
await this.getData();
Track().track(TrackingEvent.my_custom_exercise_plan);
emit(ExercisePlanReady());
}
void _onUpdateUI(ExercisePlanUpdateUI event, Emitter<ExercisePlanState> emit) {
emit(ExercisePlanLoading());
WorkoutMenuTree workoutTree = event.workoutTree;
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType!);
workoutTree.selected = true;
emit(ExercisePlanReady());
}
void _onAddExercise(ExercisePlanAddExercise event, Emitter<ExercisePlanState> emit) async {
emit(ExercisePlanLoading());
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.actualPlanDetail = planDetail;
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
await exercisePlanRepository.saveExercisePlan();
}
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = true;
}
});
});
emit(ExercisePlanReady());
}
void _onRemoveExercise(ExercisePlanRemoveExercise event, Emitter<ExercisePlanState> emit) async {
emit(ExercisePlanLoading());
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(planDetail.exerciseTypeId);
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = false;
}
});
});
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
await exercisePlanRepository.saveExercisePlan();
Track().track(TrackingEvent.my_custom_exercise_plan_save);
}
emit(ExercisePlanReady());
}
Future<void> getData() async { Future<void> getData() async {
exercisePlanRepository.setCustomerId(customerId); exercisePlanRepository.setCustomerId(customerId);
@ -45,71 +110,4 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
} }
void setExercisePlanRepository(ExercisePlanRepository repo) => exercisePlanRepository = repo; void setExercisePlanRepository(ExercisePlanRepository repo) => exercisePlanRepository = repo;
@override
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
try {
if (event is ExercisePlanLoad) {
if (Cache().userLoggedIn == null || Cache().userLoggedIn!.customerId == null) {
throw Exception("Please log in");
}
yield ExercisePlanLoading();
customerId = Cache().userLoggedIn!.customerId!;
await this.getData();
Track().track(TrackingEvent.my_custom_exercise_plan);
yield ExercisePlanReady();
}
if (event is ExercisePlanUpdateUI) {
yield ExercisePlanLoading();
WorkoutMenuTree workoutTree = event.workoutTree;
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType!);
workoutTree.selected = true;
yield ExercisePlanReady();
} else if (event is ExercisePlanAddExercise) {
yield ExercisePlanLoading();
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.actualPlanDetail = planDetail;
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
await exercisePlanRepository.saveExercisePlan();
}
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = true;
}
});
});
yield ExercisePlanReady();
} else if (event is ExercisePlanRemoveExercise) {
yield ExercisePlanLoading();
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(planDetail.exerciseTypeId);
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = false;
}
});
});
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
exercisePlanRepository.saveExercisePlan();
Track().track(TrackingEvent.my_custom_exercise_plan_save);
}
yield ExercisePlanReady();
}
} on Exception catch (e) {
yield ExercisePlanError(message: e.toString());
}
}
} }

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart'; import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
@ -7,7 +6,6 @@ import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
part 'exercise_plan_custom_add_event.dart'; part 'exercise_plan_custom_add_event.dart';
part 'exercise_plan_custom_add_state.dart'; part 'exercise_plan_custom_add_state.dart';
class ExercisePlanDetailChange { class ExercisePlanDetailChange {
@ -29,16 +27,18 @@ class ExercisePlanCustomAddBloc extends Bloc<ExercisePlanCustomAddEvent, Exercis
@override @override
ExercisePlanCustomAddBloc({required this.exercisePlanRepository, required this.planBloc, required this.workoutMenuTree}) ExercisePlanCustomAddBloc({required this.exercisePlanRepository, required this.planBloc, required this.workoutMenuTree})
: super(ExercisePlanCustomAddInitial()) { : super(ExercisePlanCustomAddInitial()) {
// init(); on<ExercisePlanCustomAddLoad>(_onLoad);
on<ExercisePlanCustomAddChangeSerie>(_onChangeSerie);
on<ExercisePlanCustomAddChangeQuantity>(_onChangeQuantity);
on<ExercisePlanCustomAddChangeQuantityUnit>(_onChangeQuantityUnit);
on<ExercisePlanCustomAddSubmit>(_onSubmit);
on<ExercisePlanCustomAddRemove>(_onRemove);
} }
void init() { void init() {
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutMenuTree.exerciseType!); exercisePlanRepository.setActualPlanDetailByExerciseType(workoutMenuTree.exerciseType!);
quantity = exercisePlanRepository.getActualPlanDetail()!.repeats != null quantity = exercisePlanRepository.getActualPlanDetail()!.repeats != null ? exercisePlanRepository.getActualPlanDetail()!.repeats!.toDouble() : 12;
? exercisePlanRepository.getActualPlanDetail()!.repeats!.toDouble() serie = exercisePlanRepository.getActualPlanDetail()!.serie != null ? exercisePlanRepository.getActualPlanDetail()!.serie!.toDouble() : 3;
: 12;
serie =
exercisePlanRepository.getActualPlanDetail()!.serie != null ? exercisePlanRepository.getActualPlanDetail()!.serie!.toDouble() : 3;
quantityUnit = exercisePlanRepository.getActualPlanDetail()!.weightEquation != null quantityUnit = exercisePlanRepository.getActualPlanDetail()!.weightEquation != null
? double.parse(exercisePlanRepository.getActualPlanDetail()!.weightEquation!) ? double.parse(exercisePlanRepository.getActualPlanDetail()!.weightEquation!)
: 30; : 30;
@ -48,47 +48,49 @@ class ExercisePlanCustomAddBloc extends Bloc<ExercisePlanCustomAddEvent, Exercis
exercisePlanRepository.getActualPlanDetail()!.repeats = quantity.toInt(); exercisePlanRepository.getActualPlanDetail()!.repeats = quantity.toInt();
} }
@override void _onLoad(ExercisePlanCustomAddLoad event, Emitter<ExercisePlanCustomAddState> emit) {
Stream<ExercisePlanCustomAddState> mapEventToState(ExercisePlanCustomAddEvent event) async* { emit(ExercisePlanCustomAddLoading());
try { init();
if (event is ExercisePlanCustomAddLoad) { emit(ExercisePlanCustomAddReady());
yield ExercisePlanCustomAddLoading(); }
init();
yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeSerie) {
yield ExercisePlanCustomAddLoading();
serie = event.quantity;
exercisePlanRepository.getActualPlanDetail()!.serie = event.quantity.toInt();
yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeQuantity) {
yield ExercisePlanCustomAddLoading();
quantity = event.quantity;
exercisePlanRepository.getActualPlanDetail()!.repeats = event.quantity.toInt();
yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeQuantityUnit) {
yield ExercisePlanCustomAddLoading();
quantityUnit = event.quantity;
exercisePlanRepository.getActualPlanDetail()!.weightEquation = event.quantity.toStringAsFixed(0);
yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddSubmit) {
yield ExercisePlanCustomAddLoading();
if (exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null) {
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.add;
} else {
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.update;
}
exercisePlanRepository.addDetailToPlan();
planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddRemove) {
yield ExercisePlanCustomAddLoading();
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.delete;
planBloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
yield ExercisePlanCustomAddReady(); void _onChangeSerie(ExercisePlanCustomAddChangeSerie event, Emitter<ExercisePlanCustomAddState> emit) {
} emit(ExercisePlanCustomAddLoading());
} on Exception catch (e) { serie = event.quantity;
yield ExercisePlanCustomAddError(message: e.toString()); exercisePlanRepository.getActualPlanDetail()!.serie = event.quantity.toInt();
emit(ExercisePlanCustomAddReady());
}
void _onChangeQuantity(ExercisePlanCustomAddChangeQuantity event, Emitter<ExercisePlanCustomAddState> emit) {
emit(ExercisePlanCustomAddLoading());
quantity = event.quantity;
exercisePlanRepository.getActualPlanDetail()!.repeats = event.quantity.toInt();
emit(ExercisePlanCustomAddReady());
}
void _onChangeQuantityUnit(ExercisePlanCustomAddChangeQuantityUnit event, Emitter<ExercisePlanCustomAddState> emit) {
emit(ExercisePlanCustomAddLoading());
quantityUnit = event.quantity;
exercisePlanRepository.getActualPlanDetail()!.weightEquation = event.quantity.toStringAsFixed(0);
emit(ExercisePlanCustomAddReady());
}
void _onSubmit(ExercisePlanCustomAddSubmit event, Emitter<ExercisePlanCustomAddState> emit) {
emit(ExercisePlanCustomAddLoading());
if (exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null) {
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.add;
} else {
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.update;
} }
exercisePlanRepository.addDetailToPlan();
planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
emit(ExercisePlanCustomAddReady());
}
void _onRemove(ExercisePlanCustomAddRemove event, Emitter<ExercisePlanCustomAddState> emit) {
emit(ExercisePlanCustomAddLoading());
exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.delete;
planBloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
emit(ExercisePlanCustomAddReady());
} }
} }

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/faq.dart'; import 'package:aitrainer_app/model/faq.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
@ -12,22 +10,17 @@ class FaqBloc extends Bloc<FaqEvent, FaqState> {
List<Faq>? faqs; List<Faq>? faqs;
FaqBloc() : super(FaqInitial()) { FaqBloc() : super(FaqInitial()) {
faqs = Cache().getFaqs(); faqs = Cache().getFaqs();
on<FaqLoad>(_onLoad);
on<FaqClickDetail>(_onClick);
} }
@override void _onLoad(FaqLoad event, Emitter<FaqState> emit) {
Stream<FaqState> mapEventToState( emit(FaqLoading());
FaqEvent event, emit(FaqReady());
) async* { }
try {
if (event is FaqLoad) { void _onClick(FaqClickDetail event, Emitter<FaqState> emit) {
yield FaqLoading(); emit(FaqLoading());
yield FaqReady(); emit(FaqReady());
} else if (event is FaqClickDetail) {
yield FaqLoading();
yield FaqReady();
}
} on Exception catch (e) {
yield FaqError(message: e.toString());
}
} }
} }

View File

@ -34,13 +34,26 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
Color testColor = Colors.green[800]!; Color testColor = Colors.green[800]!;
bool emailCheckbox = true; bool emailCheckbox = true;
LoginBloc( LoginBloc({required this.accountBloc, required this.userRepository, required this.context, required this.isRegistration, this.customerRepository})
{required this.accountBloc,
required this.userRepository,
required this.context,
required this.isRegistration,
this.customerRepository})
: super(LoginInitial()) { : super(LoginInitial()) {
this._init();
on<LoginEmailChange>(_onEmailChange);
on<LoginPasswordChange>(_onPasswordChange);
on<LoginSubmit>(_onSubmit);
on<LoginFB>(_onLoginFB);
on<LoginGoogle>(_onLoginGoogle);
on<LoginApple>(_onLoginApple);
on<RegistrationSubmit>(_onRegistrationSubmit);
on<RegistrationFB>(_onRegistrationFB);
on<RegistrationGoogle>(_onRegistrationGoogle);
on<RegistrationApple>(_onRegistrationApple);
on<DataProtectionClicked>(_onDataProtectionClicked);
on<EmailSubscriptionClicked>(_onEmailSubscriptionClicked);
on<LoginPasswordChangeObscure>(_onPasswordChangeObscure);
on<LoginSkip>(_onLoginSkip);
}
void _init() {
String colorString = splitTestRepository.getSplitTestValue("registration_skip"); String colorString = splitTestRepository.getSplitTestValue("registration_skip");
if (colorString == "red") { if (colorString == "red") {
testColor = Colors.red[800]!; testColor = Colors.red[800]!;
@ -54,112 +67,126 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
} }
} }
@override void _onEmailChange(LoginEmailChange event, Emitter<LoginState> emit) {
Stream<LoginState> mapEventToState( emit(LoginLoading());
LoginEvent event, final String email = event.email;
) async* { userRepository.setEmail(email);
try { emit(LoginReady());
if (event is LoginEmailChange) { }
yield LoginLoading();
final String email = event.email;
userRepository.setEmail(email);
yield LoginReady();
} else if (event is LoginPasswordChange) {
yield LoginLoading();
final String password = event.password;
userRepository.setPassword(password);
yield LoginReady();
} else if (event is LoginSubmit) {
yield LoginLoading();
await userRepository.getUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "email");
Cache().setLoginType(LoginType.email);
yield LoginSuccess();
} else if (event is LoginFB) {
yield LoginLoading();
Cache().setLoginType(LoginType.fb);
await userRepository.getUserByFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "FB");
yield LoginSuccess();
} else if (event is LoginGoogle) {
yield LoginLoading();
Cache().setLoginType(LoginType.google);
await userRepository.getUserByGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Google");
yield LoginSuccess();
} else if (event is LoginApple) {
yield LoginLoading();
Cache().setLoginType(LoginType.apple);
await userRepository.getUserByApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Apple");
yield LoginSuccess();
} else if (event is RegistrationSubmit) {
yield LoginLoading();
final String? validationError = validate(); void _onPasswordChange(LoginPasswordChange event, Emitter<LoginState> emit) {
if (validationError != null) { emit(LoginLoading());
yield LoginError(message: validationError); final String password = event.password;
} else { userRepository.setPassword(password);
await userRepository.addUser(); emit(LoginReady());
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); }
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("email");
Cache().setLoginType(LoginType.email);
yield LoginSuccess();
}
} else if (event is RegistrationFB) {
yield LoginLoading();
Cache().setLoginType(LoginType.fb); void _onSubmit(LoginSubmit event, Emitter<LoginState> emit) async {
await userRepository.addUserFB(); emit(LoginLoading());
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); await userRepository.getUser();
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
await afterRegistration("FB"); Track().track(TrackingEvent.login, eventValue: "email");
yield LoginSuccess(); Cache().setLoginType(LoginType.email);
} else if (event is RegistrationGoogle) {
yield LoginLoading();
Cache().setLoginType(LoginType.google); emit(LoginReady());
await userRepository.addUserGoogle(); }
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Google");
yield LoginSuccess();
} else if (event is RegistrationApple) {
yield LoginLoading();
Cache().setLoginType(LoginType.apple); void _onLoginFB(LoginFB event, Emitter<LoginState> emit) async {
await userRepository.addUserApple(); emit(LoginLoading());
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!)); Cache().setLoginType(LoginType.fb);
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0; await userRepository.getUserByFB();
await afterRegistration("Apple"); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "FB");
emit(LoginReady());
}
yield LoginSuccess(); void _onLoginGoogle(LoginGoogle event, Emitter<LoginState> emit) async {
} else if (event is DataProtectionClicked) { emit(LoginLoading());
yield LoginLoading(); Cache().setLoginType(LoginType.google);
this.dataPolicyAllowed = !dataPolicyAllowed; await userRepository.getUserByGoogle();
yield LoginReady(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
} else if (event is EmailSubscriptionClicked) { Track().track(TrackingEvent.login, eventValue: "Google");
yield LoginLoading();
this.emailSubscription = !emailSubscription; emit(LoginSuccess());
yield LoginReady(); }
} else if (event is LoginPasswordChangeObscure) {
yield LoginLoading(); void _onLoginApple(LoginApple event, Emitter<LoginState> emit) async {
this.obscure = !this.obscure; emit(LoginLoading());
yield LoginReady(); Cache().setLoginType(LoginType.apple);
} else if (event is LoginSkip) { await userRepository.getUserByApple();
yield LoginLoading(); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login_skip); Track().track(TrackingEvent.login, eventValue: "Apple");
Cache().startPage = "home"; emit(LoginSuccess());
yield LoginSkipped(); }
}
} on Exception catch (e) { void _onRegistrationSubmit(RegistrationSubmit event, Emitter<LoginState> emit) async {
yield LoginError(message: e.toString()); emit(LoginLoading());
final String? validationError = this.validate();
if (validationError != null) {
emit(LoginError(message: validationError));
} else {
await userRepository.addUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("email");
Cache().setLoginType(LoginType.email);
} }
emit(LoginSuccess());
}
void _onRegistrationFB(RegistrationFB event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.fb);
await userRepository.addUserFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("FB");
emit(LoginSuccess());
}
void _onRegistrationGoogle(RegistrationGoogle event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.google);
await userRepository.addUserGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Google");
emit(LoginSuccess());
}
void _onRegistrationApple(RegistrationApple event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Cache().setLoginType(LoginType.apple);
await userRepository.addUserApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
await afterRegistration("Apple");
emit(LoginSuccess());
}
void _onDataProtectionClicked(DataProtectionClicked event, Emitter<LoginState> emit) async {
emit(LoginLoading());
this.dataPolicyAllowed = !dataPolicyAllowed;
emit(LoginReady());
}
void _onEmailSubscriptionClicked(EmailSubscriptionClicked event, Emitter<LoginState> emit) async {
emit(LoginLoading());
this.emailSubscription = !emailSubscription;
emit(LoginReady());
}
void _onPasswordChangeObscure(LoginPasswordChangeObscure event, Emitter<LoginState> emit) async {
emit(LoginLoading());
this.obscure = !this.obscure;
emit(LoginReady());
}
void _onLoginSkip(LoginSkip event, Emitter<LoginState> emit) async {
emit(LoginLoading());
Track().track(TrackingEvent.login_skip);
Cache().startPage = "home";
emit(LoginSkipped());
} }
Future<void> afterRegistration(String event) async { Future<void> afterRegistration(String event) async {

View File

@ -1,19 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/repository/mautic_repository.dart';
import 'package:intl/intl.dart';
import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_device_repository.dart'; import 'package:aitrainer_app/repository/exercise_device_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
@ -40,13 +33,87 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
MenuBloc({required this.menuTreeRepository}) : super(MenuInitial()) { MenuBloc({required this.menuTreeRepository}) : super(MenuInitial()) {
parent = 0; parent = 0;
on<MenuCreate>(_onCreate);
on<MenuRecreateTree>(_onRecreateTree);
on<MenuTreeDown>(_onTreeDown);
on<MenuTreeUp>(_onTreeUp);
on<MenuTreeJump>(_onTreeJump);
on<MenuFilterExerciseType>(_onFilterExercise);
}
void _onCreate(MenuCreate event, Emitter<MenuState> emit) {
emit(MenuLoading());
if (Cache().getDevices() != null) {
exerciseDeviceRepository.setDevices(Cache().getDevices()!);
}
emit(MenuReady());
}
void _onRecreateTree(MenuRecreateTree event, Emitter<MenuState> emit) {
emit(MenuLoading());
// ie. at language changes
menuTreeRepository.createTree();
emit(MenuReady());
}
Future<void> _onTreeDown(MenuTreeDown event, Emitter<MenuState> emit) async {
emit(MenuLoading());
parent = event.parent;
workoutItem = event.item;
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent);
await getImages(branch);
emit(MenuReady());
}
Future<void> _onTreeUp(MenuTreeUp event, Emitter<MenuState> emit) async {
emit(MenuLoading());
// get parent menus or exercises
parent = event.parent;
workoutItem = menuTreeRepository.getParentItem(parent);
LinkedHashMap<String, WorkoutMenuTree> branch;
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch);
}
emit(MenuReady());
}
Future<void> _onTreeJump(MenuTreeJump event, Emitter<MenuState> emit) async {
emit(MenuLoading());
parent = event.parent;
workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) {
setAbility(workoutItem!.internalName);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch);
emit(MenuReady());
}
Future<void> _onFilterExercise(MenuFilterExerciseType event, Emitter<MenuState> emit) async {
emit(MenuLoading());
final int deviceId = event.deviceId;
if (selectedDevice(deviceId)) {
listFilterDevice.add(deviceId);
} else {
listFilterDevice.remove(deviceId);
}
emit(MenuReady());
} }
void setContext(BuildContext context) { void setContext(BuildContext context) {
this.context = context; this.context = context;
} }
@override /* @override
Stream<MenuState> mapEventToState( Stream<MenuState> mapEventToState(
MenuEvent event, MenuEvent event,
) async* { ) async* {
@ -141,7 +208,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
} on Exception catch (ex) { } on Exception catch (ex) {
yield MenuError(message: ex.toString()); yield MenuError(message: ex.toString());
} }
} } */
void setAbility(String name) { void setAbility(String name) {
switch (name) { switch (name) {

View File

@ -41,14 +41,6 @@ class MenuTreeJump extends MenuEvent {
List<Object> get props => [parent]; List<Object> get props => [parent];
} }
class MenuClickExercise extends MenuEvent {
final int exerciseTypeId;
const MenuClickExercise({required this.exerciseTypeId});
@override
List<Object> get props => [exerciseTypeId];
}
class MenuRecreateTree extends MenuEvent { class MenuRecreateTree extends MenuEvent {
const MenuRecreateTree(); const MenuRecreateTree();
} }
@ -60,11 +52,3 @@ class MenuFilterExerciseType extends MenuEvent {
@override @override
List<Object> get props => [deviceId]; List<Object> get props => [deviceId];
} }
class MenuStartTrial extends MenuEvent {
final DateTime start;
const MenuStartTrial({required this.start});
@override
List<Object> get props => [start];
}

View File

@ -1,5 +1,3 @@
import 'dart:async';
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:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
@ -10,26 +8,22 @@ part 'password_reset_state.dart';
class PasswordResetBloc extends Bloc<PasswordResetEvent, PasswordResetState> { class PasswordResetBloc extends Bloc<PasswordResetEvent, PasswordResetState> {
final UserRepository userRepository; final UserRepository userRepository;
PasswordResetBloc({required this.userRepository}) : super(PasswordResetInitial()); PasswordResetBloc({required this.userRepository}) : super(PasswordResetInitial()) {
on<PasswordResetEmailChange>(_onEmailChange);
on<PasswordResetSubmit>(_onSubmit);
}
@override void _onEmailChange(PasswordResetEmailChange event, Emitter<PasswordResetState> emit) {
Stream<PasswordResetState> mapEventToState( emit(PasswordResetLoading());
PasswordResetEvent event, final String email = event.email;
) async* { userRepository.setEmail(email);
try { emit(PasswordResetReady());
if (event is PasswordResetEmailChange) { }
yield PasswordResetLoading();
final String email = event.email; void _onSubmit(PasswordResetSubmit event, Emitter<PasswordResetState> emit) async {
userRepository.setEmail(email); emit(PasswordResetLoading());
yield PasswordResetReady(); await userRepository.resetPassword();
} else if (event is PasswordResetSubmit) { emit(PasswordResetReady());
yield PasswordResetLoading();
await userRepository.resetPassword();
yield PasswordResetFinished();
}
} on Exception catch (e) {
yield PasswordResetError(message: e.toString());
}
} }
String? emailValidation(String email) { String? emailValidation(String email) {

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/model/result.dart'; import 'package:aitrainer_app/model/result.dart';
import 'package:aitrainer_app/repository/evaluation_repository.dart'; import 'package:aitrainer_app/repository/evaluation_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
@ -37,6 +35,11 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
]; */ ]; */
ResultBloc({required this.resultRepository, required this.exerciseRepository, required this.context}) : super(ResultInitial()) { ResultBloc({required this.resultRepository, required this.exerciseRepository, required this.context}) : super(ResultInitial()) {
this._load();
on<ResultLoad>(_onLoad);
}
void _load() {
this.startTime = exerciseRepository.start; this.startTime = exerciseRepository.start;
this.endTime = exerciseRepository.end; this.endTime = exerciseRepository.end;
if (this.startTime == null) { if (this.startTime == null) {
@ -45,22 +48,10 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
} }
} }
@override void _onLoad(ResultLoad event, Emitter<ResultState> emit) {
Stream<ResultState> mapEventToState( emit(ResultLoading());
ResultEvent event, _matchExerciseData();
) async* { emit(ResultReady());
try {
if (event is ResultLoad) {
yield ResultLoading();
//await _fetchHealthData();
_matchExerciseData();
//await resultRepository.saveExerciseResults();
yield ResultReady();
}
} on Exception catch (ex) {
yield ResultError(error: ex.toString());
}
} }
void _matchExerciseData() { void _matchExerciseData() {

View File

@ -27,12 +27,51 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
int productSet = -1; int productSet = -1;
final DescriptionRepository descriptionRepository = DescriptionRepository(); final DescriptionRepository descriptionRepository = DescriptionRepository();
SalesBloc() : super(SalesInitial()); SalesBloc() : super(SalesInitial()) {
on<SalesLoad>(_onLoad);
on<SalesPurchase>(_onPurchase);
}
String? salesText; String? salesText;
String? premiumFunctions = ""; String? premiumFunctions = "";
String? trial = ""; String? trial = "";
void _onLoad(SalesLoad event, Emitter<SalesState> emit) async {
emit(SalesLoading());
await init();
emit(SalesReady());
}
void _onPurchase(SalesPurchase event, Emitter<SalesState> emit) async {
if (Cache().hasPurchased) {
throw Exception("You have already a successfull subscription");
}
emit(SalesLoading());
final int productId = event.productId;
log("Requesting purchase for: " + productId.toString());
Track().track(TrackingEvent.purchase_request);
final Product? selectedProduct = this.getSelectedProduct(productId);
log("SelectedProduct for purchase $selectedProduct");
if (selectedProduct != null) {
await RevenueCatPurchases().makePurchase(selectedProduct);
if (Cache().hasPurchased) {
Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
purchase.dateAdd = DateTime.now();
purchase.purchaseSum = 0;
purchase.currency = "EUR";
await PurchaseApi().savePurchase(purchase);
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticPurchase();
}
emit(SalesSuccessful());
} else {
emit(SalesError(message: "No selected product"));
}
}
Future<void> init() async { Future<void> init() async {
if (Cache().userLoggedIn == null) { if (Cache().userLoggedIn == null) {
throw Exception("Please log in"); throw Exception("Please log in");
@ -60,51 +99,6 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
Track().track(TrackingEvent.sales_page); Track().track(TrackingEvent.sales_page);
} }
@override
Stream<SalesState> mapEventToState(
SalesEvent event,
) async* {
try {
if (event is SalesLoad) {
log(" -- start SalesLoad");
yield SalesLoading();
await init();
yield SalesReady();
log(" -- finish SalesLoad");
} else if (event is SalesPurchase) {
if (Cache().hasPurchased) {
throw Exception("You have already a successfull subscription");
}
yield SalesLoading();
final int productId = event.productId;
log("Requesting purchase for: " + productId.toString());
Track().track(TrackingEvent.purchase_request);
final Product? selectedProduct = this.getSelectedProduct(productId);
log("SelectedProduct for purchase $selectedProduct");
if (selectedProduct != null) {
await RevenueCatPurchases().makePurchase(selectedProduct);
if (Cache().hasPurchased) {
Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
purchase.dateAdd = DateTime.now();
purchase.purchaseSum = 0;
purchase.currency = "EUR";
await PurchaseApi().savePurchase(purchase);
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticPurchase();
}
yield SalesSuccessful();
} else {
yield SalesError(message: "No selected product");
}
}
} on Exception catch (ex) {
yield SalesError(message: ex.toString());
}
}
void getProductsTexts() { void getProductsTexts() {
Product product; Product product;
if (product2Display.isNotEmpty) { if (product2Display.isNotEmpty) {

View File

@ -14,35 +14,30 @@ part 'session_state.dart';
class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging { class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
final Session session; final Session session;
StreamSubscription? _sub; StreamSubscription? _sub;
SettingsBloc? settingsBloc;
SessionBloc({required this.session}) : super(SessionInitial()); SessionBloc({required this.session}) : super(SessionInitial()) {
on<SessionStart>(_onStart);
}
@override void _onStart(SessionStart event, Emitter<SessionState> emit) async {
Stream<SessionState> mapEventToState( log(" -------- Session starting...");
SessionEvent event, emit(SessionLoading());
) async* {
try { this.settingsBloc = event.settingsBloc;
if (event is SessionStart) { await session.fetchSessionAndNavigate();
log(" -------- Session starting..."); FirebaseApi().setupRemoteConfig();
yield SessionLoading(); String lang = AppLanguage().appLocal.languageCode;
// ignore: close_sinks log("Change lang to $lang");
SettingsBloc settingsBloc = event.settingsBloc; settingsBloc!.add(SettingsChangeLanguage(language: lang));
await session.fetchSessionAndNavigate(); emit(SessionReady());
FirebaseApi().setupRemoteConfig();
String lang = AppLanguage().appLocal.languageCode;
log("Change lang to $lang");
settingsBloc.add(SettingsChangeLanguage(language: lang));
yield SessionReady();
}
} on Exception catch (ex) {
yield SessionFailure(message: ex.toString());
}
} }
@override @override
Future<void> close() async { Future<void> close() async {
await this.close(); await this.close();
_sub?.cancel(); _sub?.cancel();
settingsBloc?.close();
super.close(); super.close();
} }
} }

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart'; import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
@ -25,9 +23,11 @@ class TestSetControlBloc extends Bloc<TestSetControlEvent, TestSetControlState>
late double oneRepMax; late double oneRepMax;
late int step; late int step;
TestSetControlBloc({required this.exercisePlanDetail, required this.executeBloc, required this.exerciseType}) TestSetControlBloc({required this.exercisePlanDetail, required this.executeBloc, required this.exerciseType}) : super(TestSetControlInitial()) {
: super(TestSetControlInitial()) {
initBloc(); initBloc();
on<TestSetControlQuantityChange>(_onQuantityChange);
on<TestSetControlUnitQuantityChange>(_onUnitQuantityChange);
on<TestSetControlSubmit>(_onSubmit);
} }
void initBloc() { void initBloc() {
@ -42,29 +42,29 @@ class TestSetControlBloc extends Bloc<TestSetControlEvent, TestSetControlState>
exerciseRepository.exerciseType = exerciseType; exerciseRepository.exerciseType = exerciseType;
} }
@override void _onQuantityChange(TestSetControlQuantityChange event, Emitter<TestSetControlState> emit) {
Stream<TestSetControlState> mapEventToState( emit(TestSetControlLoading());
TestSetControlEvent event, quantity = event.quantity;
) async* { emit(TestSetControlReady());
try { }
if (event is TestSetControlQuantityChange) {
quantity = event.quantity;
} else if (event is TestSetControlUnitQuantityChange) {
unitQuantity = event.quantity;
} else if (event is TestSetControlSubmit) {
final Exercise exercise = Exercise();
exercise.quantity = quantity;
exercise.unit = exerciseType.unit;
exercise.unitQuantity = unitQuantity;
exercise.dateAdd = DateTime.now();
exerciseRepository.exercise = exercise;
await exerciseRepository.addExercise(); void _onUnitQuantityChange(TestSetControlUnitQuantityChange event, Emitter<TestSetControlState> emit) {
executeBloc.add( emit(TestSetControlLoading());
TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity)); unitQuantity = event.quantity;
} emit(TestSetControlReady());
} on Exception catch (e) { }
yield TestSetControlError(message: e.toString());
} void _onSubmit(TestSetControlSubmit event, Emitter<TestSetControlState> emit) async {
emit(TestSetControlLoading());
final Exercise exercise = Exercise();
exercise.quantity = quantity;
exercise.unit = exerciseType.unit;
exercise.unitQuantity = unitQuantity;
exercise.dateAdd = DateTime.now();
exerciseRepository.exercise = exercise;
await exerciseRepository.addExercise();
executeBloc.add(TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity));
emit(TestSetControlReady());
} }
} }

View File

@ -1,6 +1,4 @@
import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/exercise_ability.dart';
@ -32,9 +30,16 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
final HashMap<int, List<ExerciseType>?> _displayPlanDetails = HashMap(); final HashMap<int, List<ExerciseType>?> _displayPlanDetails = HashMap();
int? sliderIndex; int? sliderIndex;
TestSetEditBloc( TestSetEditBloc({required this.templateName, required this.templateNameTranslation, required this.workoutTreeRepository, required this.menuBloc})
{required this.templateName, required this.templateNameTranslation, required this.workoutTreeRepository, required this.menuBloc})
: super(TestSetEditInitial()) { : super(TestSetEditInitial()) {
this._init();
on<TestSetEditChangeExerciseType>(_onChangeExerciseType);
on<TestSetEditDeleteExerciseType>(_onDeleteExerciseType);
on<TestSetEditAddExerciseType>(_onAddExerciseType);
on<TestSetEditSubmit>(_onSubmit);
}
void _init() {
if (Cache().exercisePlanTemplates.isNotEmpty) { if (Cache().exercisePlanTemplates.isNotEmpty) {
Cache().exercisePlanTemplates.forEach((element) { Cache().exercisePlanTemplates.forEach((element) {
final ExercisePlanTemplate template = element as ExercisePlanTemplate; final ExercisePlanTemplate template = element as ExercisePlanTemplate;
@ -65,60 +70,56 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
} }
} }
@override void _onChangeExerciseType(TestSetEditChangeExerciseType event, Emitter<TestSetEditState> emit) {
Stream<TestSetEditState> mapEventToState(TestSetEditEvent event) async* { emit(TestSetEditLoading());
try { ExerciseType? exerciseType;
if (event is TestSetEditChangeExerciseType) { if (_exercisePlanDetails[event.indexKey] == null) {
yield TestSetEditLoading(); exerciseType = displayPlanDetails[event.indexKey][0];
ExerciseType? exerciseType; } else {
if (_exercisePlanDetails[event.indexKey] == null) { exerciseType = displayPlanDetails[event.indexKey][event.index];
exerciseType = displayPlanDetails[event.indexKey][0];
} else {
exerciseType = displayPlanDetails[event.indexKey][event.index];
}
_exercisePlanDetails[event.indexKey] = exerciseType;
this.sliderIndex = event.index;
yield TestSetEditReady();
} else if (event is TestSetEditDeleteExerciseType) {
yield TestSetEditLoading();
_exercisePlanDetails[event.indexKey] = null;
yield TestSetEditReady();
} else if (event is TestSetEditAddExerciseType) {
yield TestSetEditLoading();
ExerciseType exerciseType = displayPlanDetails[event.indexKey][0];
_exercisePlanDetails[event.indexKey] = exerciseType;
yield TestSetEditReady();
} else if (event is TestSetEditSubmit) {
yield TestSetEditLoading();
ExercisePlan exercisePlan = ExercisePlan(templateNameTranslation, Cache().userLoggedIn!.customerId!);
exercisePlan.private = true;
exercisePlan.type = ExerciseAbility.mini_test_set.enumToString();
exercisePlan.dateAdd = DateTime.now();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan);
List<ExercisePlanDetail> details = [];
for (var entry in _exercisePlanDetails.entries) {
if (entry.value != null) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(entry.value!.exerciseTypeId);
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId!;
exercisePlanDetail.serie = 1;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.exercises = [];
details.add(exercisePlanDetail);
}
}
Cache().saveActiveExercisePlan(exercisePlan, details);
Track().track(TrackingEvent.test_set_edit, eventValue: templateName);
yield TestSetEditSaved();
} else if (event is TestSetEditAddError) {
yield TestSetEditError(message: event.message);
}
} on Exception catch (e) {
yield TestSetEditError(message: e.toString());
} }
_exercisePlanDetails[event.indexKey] = exerciseType;
this.sliderIndex = event.index;
emit(TestSetEditReady());
}
void _onDeleteExerciseType(TestSetEditDeleteExerciseType event, Emitter<TestSetEditState> emit) {
emit(TestSetEditLoading());
_exercisePlanDetails[event.indexKey] = null;
emit(TestSetEditReady());
}
void _onAddExerciseType(TestSetEditAddExerciseType event, Emitter<TestSetEditState> emit) {
emit(TestSetEditLoading());
ExerciseType exerciseType = displayPlanDetails[event.indexKey][0];
_exercisePlanDetails[event.indexKey] = exerciseType;
emit(TestSetEditReady());
}
void _onSubmit(TestSetEditSubmit event, Emitter<TestSetEditState> emit) async {
emit(TestSetEditLoading());
ExercisePlan exercisePlan = ExercisePlan(templateNameTranslation, Cache().userLoggedIn!.customerId!);
exercisePlan.private = true;
exercisePlan.type = ExerciseAbility.mini_test_set.enumToString();
exercisePlan.dateAdd = DateTime.now();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan);
List<ExercisePlanDetail> details = [];
for (var entry in _exercisePlanDetails.entries) {
if (entry.value != null) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(entry.value!.exerciseTypeId);
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId!;
exercisePlanDetail.serie = 1;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.exercises = [];
details.add(exercisePlanDetail);
}
}
Cache().saveActiveExercisePlan(exercisePlan, details);
Track().track(TrackingEvent.test_set_edit, eventValue: templateName);
emit(TestSetEditSaved());
} }
List get exerciseTypes => this._exerciseTypes; List get exerciseTypes => this._exerciseTypes;

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
@ -30,7 +29,153 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
List<ExercisePlanDetail>? exercisePlanDetails; List<ExercisePlanDetail>? exercisePlanDetails;
TestSetExecuteBloc() : super(TestSetExecuteInitial()); TestSetExecuteBloc() : super(TestSetExecuteInitial()) {
on<TestSetExecuteLoad>(_onLoad);
on<TestSetExecuteDeleteActive>(_onDeleteActive);
on<TestSetExecuteDeleteAllActive>(_onDeleteAllActive);
on<TestSetExecuteExerciseFinished>(_onExerciseFinished);
on<TestSetExecuteNewExercise>(_onNewExercise);
on<TestSetExecuteDeleteExercise>(_onDeleteExercise);
on<TestSetExecuteFinish>(_onFinish);
}
void _onLoad(TestSetExecuteLoad event, Emitter<TestSetExecuteState> emit) {
emit(TestSetExecuteLoading());
initExercisePlan();
if (exerciseTypeId != null) {
int step = 0;
if (exercisePlanDetails != null) {
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == this.exerciseTypeId) {
scrollOffset = (step * 85).toDouble() + 10;
}
step++;
});
}
}
emit(TestSetExecuteReady());
}
void _onDeleteActive(TestSetExecuteDeleteActive event, Emitter<TestSetExecuteState> emit) async {
emit(TestSetExecuteLoading());
print("Delete: ${exercisePlan!.type} paralellTest: $paralellTest");
if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!)) {
exercisePlan = null;
if (exercisePlanDetails != null) {
exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
}
await Cache().deleteActiveExercisePlan();
}
emit(TestSetExecuteReady());
}
void _onDeleteAllActive(TestSetExecuteDeleteAllActive event, Emitter<TestSetExecuteState> emit) async {
emit(TestSetExecuteLoading());
if (exercisePlan != null) {
print("DeleteAll Test Set: ${exercisePlan!.type}");
exercisePlan = null;
if (exercisePlanDetails != null) {
exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
}
await Cache().deleteActiveExercisePlan();
}
emit(TestSetExecuteReady());
}
void _onExerciseFinished(TestSetExecuteExerciseFinished event, Emitter<TestSetExecuteState> emit) {
emit(TestSetExecuteLoading());
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == event.exerciseTypeId) {
element.repeats = event.quantity.toInt();
element.weightEquation = event.unitQuantity.toString();
if (element.exercises == null) {
element.exercises = [];
}
final Exercise exercise = Exercise();
exercise.customerId = Cache().userLoggedIn!.customerId!;
exercise.exerciseTypeId = event.exerciseTypeId;
exercise.quantity = event.quantity;
exercise.unit = element.exerciseType!.unit;
exercise.unitQuantity = event.unitQuantity;
exercise.dateAdd = DateTime.now();
element.exercises!.add(exercise);
setPlanDetailState(element);
}
});
Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
if (this.isDone100Percent()) {
add(TestSetExecuteFinish());
} else {
emit(TestSetExecuteReady());
}
emit(TestSetExecuteReady());
}
void _onNewExercise(TestSetExecuteNewExercise event, Emitter<TestSetExecuteState> emit) async {
emit(TestSetExecuteLoading());
if (exercisePlan == null) {
exercisePlan = ExercisePlan(Cache().userLoggedIn!.name! + " Custom Test", Cache().userLoggedIn!.customerId!);
exercisePlan!.private = true;
exercisePlan!.dateAdd = DateTime.now();
exercisePlan!.type = ExerciseAbility.paralell_test.enumToString();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan!);
exercisePlan = savedExercisePlan;
exercisePlanDetails = [];
}
if (!this.existsInPlanDetails(event.exerciseTypeId)) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(event.exerciseTypeId);
if (exercisePlan!.exercisePlanId != null) {
exercisePlanDetail.exercisePlanId = exercisePlan!.exercisePlanId!;
}
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId)!;
exercisePlanDetail.serie = exerciseType.unitQuantityUnit == null ? 1 : 4;
exercisePlanDetail.exerciseType = exerciseType;
exercisePlanDetail.exerciseTypeId = event.exerciseTypeId;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.state = ExercisePlanDetailState.start;
exercisePlanDetail.exercises = [];
if (exercisePlanDetails == null) {
exercisePlanDetails = [];
}
exercisePlanDetails!.add(exercisePlanDetail);
await Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
paralellTest = true;
}
emit(TestSetExecuteReady());
}
void _onDeleteExercise(TestSetExecuteDeleteExercise event, Emitter<TestSetExecuteState> emit) {
emit(TestSetExecuteLoading());
ExercisePlanDetail? deleteDetail;
if (exercisePlanDetails != null) {
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == event.exerciseTypeId) {
deleteDetail = element;
}
});
if (deleteDetail != null) {
exercisePlanDetails!.remove(deleteDetail);
if (exercisePlanDetails!.isEmpty) {
exercisePlan = null;
exercisePlanDetails = null;
Cache().deleteActiveExercisePlan();
}
}
}
emit(TestSetExecuteReady());
}
void _onFinish(TestSetExecuteFinish event, Emitter<TestSetExecuteState> emit) {
emit(TestSetExecuteLoading());
Cache().deleteActiveExercisePlan();
isDone100 = isDone100Percent();
// Animation
// Home
emit(TestSetExecuteReady());
}
void setExerciseTypeId(int id) => exerciseTypeId = id; void setExerciseTypeId(int id) => exerciseTypeId = id;
@ -59,135 +204,6 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
} }
} }
@override
Stream<TestSetExecuteState> mapEventToState(
TestSetExecuteEvent event,
) async* {
try {
if (event is TestSetExecuteLoad) {
yield TestSetExecuteLoading();
initExercisePlan();
if (exerciseTypeId != null) {
int step = 0;
if (exercisePlanDetails != null) {
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == this.exerciseTypeId) {
scrollOffset = (step * 85).toDouble() + 10;
}
step++;
});
}
}
yield TestSetExecuteReady();
} else if (event is TestSetExecuteDeleteActive) {
print("Delete: ${exercisePlan!.type} paralellTest: $paralellTest");
if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!)) {
exercisePlan = null;
if (exercisePlanDetails != null) {
exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
}
await Cache().deleteActiveExercisePlan();
}
} else if (event is TestSetExecuteDeleteAllActive) {
if (exercisePlan != null) {
print("DeleteAll Test Set: ${exercisePlan!.type}");
exercisePlan = null;
if (exercisePlanDetails != null) {
exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
}
await Cache().deleteActiveExercisePlan();
}
} else if (event is TestSetExecuteExerciseFinished) {
yield TestSetExecuteLoading();
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == event.exerciseTypeId) {
element.repeats = event.quantity.toInt();
element.weightEquation = event.unitQuantity.toString();
if (element.exercises == null) {
element.exercises = [];
}
final Exercise exercise = Exercise();
exercise.customerId = Cache().userLoggedIn!.customerId!;
exercise.exerciseTypeId = event.exerciseTypeId;
exercise.quantity = event.quantity;
exercise.unit = element.exerciseType!.unit;
exercise.unitQuantity = event.unitQuantity;
exercise.dateAdd = DateTime.now();
element.exercises!.add(exercise);
setPlanDetailState(element);
}
});
Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
if (this.isDone100Percent()) {
add(TestSetExecuteFinish());
} else {
yield TestSetExecuteReady();
}
} else if (event is TestSetExecuteNewExercise) {
yield TestSetExecuteLoading();
if (exercisePlan == null) {
exercisePlan = ExercisePlan(Cache().userLoggedIn!.name! + " Custom Test", Cache().userLoggedIn!.customerId!);
exercisePlan!.private = true;
exercisePlan!.dateAdd = DateTime.now();
exercisePlan!.type = ExerciseAbility.paralell_test.enumToString();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan!);
exercisePlan = savedExercisePlan;
exercisePlanDetails = [];
}
if (!this.existsInPlanDetails(event.exerciseTypeId)) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(event.exerciseTypeId);
if (exercisePlan!.exercisePlanId != null) {
exercisePlanDetail.exercisePlanId = exercisePlan!.exercisePlanId!;
}
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId)!;
exercisePlanDetail.serie = exerciseType.unitQuantityUnit == null ? 1 : 4;
exercisePlanDetail.exerciseType = exerciseType;
exercisePlanDetail.exerciseTypeId = event.exerciseTypeId;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.state = ExercisePlanDetailState.start;
exercisePlanDetail.exercises = [];
if (exercisePlanDetails == null) {
exercisePlanDetails = [];
}
exercisePlanDetails!.add(exercisePlanDetail);
await Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
paralellTest = true;
}
yield TestSetExecuteReady();
} else if (event is TestSetExecuteDeleteExercise) {
yield TestSetExecuteLoading();
ExercisePlanDetail? deleteDetail;
if (exercisePlanDetails != null) {
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == event.exerciseTypeId) {
deleteDetail = element;
}
});
if (deleteDetail != null) {
exercisePlanDetails!.remove(deleteDetail);
if (exercisePlanDetails!.isEmpty) {
exercisePlan = null;
exercisePlanDetails = null;
Cache().deleteActiveExercisePlan();
}
}
}
yield TestSetExecuteReady();
} else if (event is TestSetExecuteFinish) {
Cache().deleteActiveExercisePlan();
isDone100 = isDone100Percent();
// Animation
// Home
yield TestSetExecuteFinished();
}
} on Exception catch (e) {
yield TestSetExecuteError(message: e.toString());
}
}
bool hasBegun() { bool hasBegun() {
if (exercisePlanDetails == null || if (exercisePlanDetails == null ||
exercisePlanDetails!.isEmpty || exercisePlanDetails!.isEmpty ||

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/main.dart'; import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart'; import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
@ -23,9 +22,15 @@ class TestSetNewBloc extends Bloc<TestSetNewEvent, TestSetNewState> {
late double quantity; late double quantity;
late double unitQuantity; late double unitQuantity;
TestSetNewBloc( TestSetNewBloc({required this.exerciseRepository, required this.exerciseType, required this.exercisePlanDetailId, required this.executeBloc})
{required this.exerciseRepository, required this.exerciseType, required this.exercisePlanDetailId, required this.executeBloc})
: super(TestSetNewInitial()) { : super(TestSetNewInitial()) {
this._load();
on<TestSetNewChangeQuantity>(_onChangeQuantity);
on<TestSetNewChangeQuantityUnit>(_onChangeQuantityUnit);
on<TestSetNewSubmit>(_onSubmit);
}
void _load() {
exerciseRepository.exerciseType = exerciseType; exerciseRepository.exerciseType = exerciseType;
quantity = 12; quantity = 12;
unitQuantity = 30; unitQuantity = 30;
@ -37,34 +42,33 @@ class TestSetNewBloc extends Bloc<TestSetNewEvent, TestSetNewState> {
exerciseRepository.setCustomer(Cache().userLoggedIn!); exerciseRepository.setCustomer(Cache().userLoggedIn!);
} }
@override void _onChangeQuantity(TestSetNewChangeQuantity event, Emitter<TestSetNewState> emit) {
Stream<TestSetNewState> mapEventToState( emit(TestSetNewLoading());
TestSetNewEvent event, quantity = event.quantity;
) async* { exerciseRepository.setQuantity(quantity);
try { emit(TestSetNewReady());
if (event is TestSetNewChangeQuantity) { }
quantity = event.quantity;
exerciseRepository.setQuantity(quantity);
} else if (event is TestSetNewChangeQuantityUnit) {
unitQuantity = event.quantity;
exerciseRepository.setUnitQuantity(unitQuantity);
} else if (event is TestSetNewSubmit) {
yield TestSetNewLoading();
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
executeBloc.add(
TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity));
if (!isInDebugMode) {
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
Track().track(TrackingEvent.test_set_new, eventValue: exerciseType.name); void _onChangeQuantityUnit(TestSetNewChangeQuantityUnit event, Emitter<TestSetNewState> emit) {
} emit(TestSetNewLoading());
} on Exception catch (e) { unitQuantity = event.quantity;
yield TestSetNewError(message: e.toString()); exerciseRepository.setUnitQuantity(unitQuantity);
emit(TestSetNewReady());
}
void _onSubmit(TestSetNewSubmit event, Emitter<TestSetNewState> emit) async {
emit(TestSetNewLoading());
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise();
executeBloc.add(TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity));
if (!isInDebugMode) {
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = Cache().userLoggedIn;
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
} }
Track().track(TrackingEvent.test_set_new, eventValue: exerciseType.name);
emit(TestSetNewReady());
} }
} }

View File

@ -29,7 +29,42 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
// ignore: cancel_subscriptions // ignore: cancel_subscriptions
StreamSubscription<int>? _tickerSubscription; StreamSubscription<int>? _tickerSubscription;
TimerBloc() : super(TimerReady(300)); TimerBloc() : super(TimerReady(300)) {
on<TimerStart>(_onStart);
on<TimerPause>(_onPause);
on<TimerResume>(_onResume);
on<TimerReset>(_onReset);
on<TimerTick>(_onTick);
on<TimerEnd>(_onEnd);
}
Stream<TimerState> _onStart(TimerStart event, Emitter<TimerState> emit) async* {
yield* _mapStartToState(event);
}
Stream<TimerState> _onPause(TimerPause event, Emitter<TimerState> emit) async* {
yield* _mapPauseToState(event);
}
Stream<TimerState> _onResume(TimerResume event, Emitter<TimerState> emit) async* {
yield* _mapResumeToState(event);
}
Stream<TimerState> _onReset(TimerReset event, Emitter<TimerState> emit) async* {
yield* _mapResetToState(event);
}
Stream<TimerState> _onTick(TimerTick event, Emitter<TimerState> emit) async* {
yield* _mapTickToState(event);
}
void _onEnd(TimerEnd event, Emitter<TimerState> emit) {
print("$event");
if (_tickerSubscription != null) {
_tickerSubscription!.cancel();
}
emit(TimerFinished(state.duration));
}
@override @override
void onTransition(Transition<TimerEvent, TimerState> transition) { void onTransition(Transition<TimerEvent, TimerState> transition) {
@ -37,29 +72,6 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
//print(transition); //print(transition);
} }
@override
Stream<TimerState> mapEventToState(
TimerEvent event,
) async* {
if (event is TimerStart) {
yield* _mapStartToState(event);
} else if (event is TimerPause) {
yield* _mapPauseToState(event);
} else if (event is TimerResume) {
yield* _mapResumeToState(event);
} else if (event is TimerReset) {
yield* _mapResetToState(event);
} else if (event is TimerTick) {
yield* _mapTickToState(event);
} else if (event is TimerEnd) {
print("$event");
if (_tickerSubscription != null) {
_tickerSubscription!.cancel();
}
yield TimerFinished(state.duration);
}
}
@override @override
Future<void> close() { Future<void> close() {
if (_tickerSubscription != null) { if (_tickerSubscription != null) {

View File

@ -16,7 +16,8 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
final TrainingPlanBloc trainingPlanBloc; final TrainingPlanBloc trainingPlanBloc;
final String day; final String day;
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) { TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) {
on<TrainingEvaluationLoad>(_onLoad); _load();
//on<TrainingEvaluationLoad>(_onLoad);
} }
String duration = "-"; String duration = "-";
@ -42,6 +43,20 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
} }
} }
void _load() {
getDuration();
getTotalLift();
getMaxRepeats();
getTotalRepeats();
createEvaluationData();
getMaxLift();
if (end == null || DateTime.now().difference(end!).inMinutes > 5) {
emit(TrainingEvaluationReady());
} else {
emit(TrainingEvaluationVictoryReady());
}
}
void createEvaluationData() { void createEvaluationData() {
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
return; return;

View File

@ -1,4 +1,3 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/tutorial.dart'; import 'package:aitrainer_app/model/tutorial.dart';
@ -36,7 +35,67 @@ class TutorialBloc extends Bloc<TutorialEvent, TutorialState> with Logging {
MenuBloc? menuBloc; MenuBloc? menuBloc;
TutorialBloc({required this.tutorialName}) : super(TutorialInitial()); TutorialBloc({required this.tutorialName}) : super(TutorialInitial()) {
on<TutorialLoad>(_onLoad);
on<TutorialNext>(_onNext);
on<TutorialWrongAction>(_onWrongAction);
on<TutorialStart>(_onStart);
on<TutorialFinished>(_onFinished);
}
void _onLoad(TutorialLoad event, Emitter<TutorialState> emit) {
emit(TutorialLoading());
init();
if (menuBloc != null) {
menuBloc!.add(MenuCreate());
}
emit(TutorialReady());
}
void _onNext(TutorialNext event, Emitter<TutorialState> emit) {
print("Tutorial Next: ${event.text}");
if (tutorial != null) {
emit(TutorialLoading());
step = this.getNextStep(step);
if (step == -1) {
print("Tutorial $tutorialName finished!");
return;
}
print("Step: $step");
setNextStepData(step);
if (menuBloc != null) {
menuBloc!.add(MenuCreate());
}
Track().track(TrackingEvent.tutorial_step, eventValue: step.toString());
}
}
void _onWrongAction(TutorialWrongAction event, Emitter<TutorialState> emit) {
emit(TutorialLoading());
actualText = tutorial!.steps![step].errorTextTranslation!;
emit(TutorialReady());
}
void _onStart(TutorialStart event, Emitter<TutorialState> emit) {
emit(TutorialLoading());
canActivate = true;
step = 0;
emit(TutorialReady());
}
void _onFinished(TutorialFinished event, Emitter<TutorialState> emit) async {
emit(TutorialLoading());
isActive = false;
canActivate = false;
ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName);
if (activityDone != null) {
await Cache().setActivityDonePrefs(activityDone);
}
Track().track(TrackingEvent.tutorial_finished);
emit(TutorialReady());
}
init() { init() {
if (Cache().tutorials != null) { if (Cache().tutorials != null) {
@ -146,52 +205,4 @@ class TutorialBloc extends Bloc<TutorialEvent, TutorialState> with Logging {
} }
return nextStep; return nextStep;
} }
@override
Stream<TutorialState> mapEventToState(TutorialEvent event) async* {
if (event is TutorialLoad) {
init();
if (menuBloc != null) {
menuBloc!.add(MenuCreate());
}
} else if (event is TutorialNext) {
print("Tutorial Next: ${event.text}");
if (tutorial != null) {
yield TutorialLoading();
step = this.getNextStep(step);
if (step == -1) {
print("Tutorial $tutorialName finished!");
return;
}
print("Step: $step");
setNextStepData(step);
if (menuBloc != null) {
menuBloc!.add(MenuCreate());
}
Track().track(TrackingEvent.tutorial_step, eventValue: step.toString());
yield TutorialReady();
}
} else if (event is TutorialWrongAction) {
yield TutorialLoading();
actualText = tutorial!.steps![step].errorTextTranslation!;
yield TutorialReady();
} else if (event is TutorialStart) {
yield TutorialLoading();
canActivate = true;
step = 0;
yield TutorialReady();
} else if (event is TutorialFinished) {
yield TutorialLoading();
isActive = false;
canActivate = false;
ActivityDone? activityDone = ActivityDone.tutorialBasic.searchByString(tutorialName);
if (activityDone != null) {
await Cache().setActivityDonePrefs(activityDone);
}
Track().track(TrackingEvent.tutorial_finished);
yield TutorialReady();
}
}
} }

View File

@ -38,7 +38,7 @@ class LiquidCircularProgressIndicator extends ProgressIndicator {
Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor; Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor;
Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).accentColor; Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).colorScheme.secondary;
@override @override
State<StatefulWidget> createState() => _LiquidCircularProgressIndicatorState(); State<StatefulWidget> createState() => _LiquidCircularProgressIndicatorState();

View File

@ -28,7 +28,7 @@ class LiquidCustomProgressIndicator extends ProgressIndicator {
Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor; Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor;
Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).accentColor; Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).colorScheme.secondary;
@override @override
State<StatefulWidget> createState() => _LiquidCustomProgressIndicatorState(); State<StatefulWidget> createState() => _LiquidCustomProgressIndicatorState();

View File

@ -40,7 +40,7 @@ class LiquidLinearProgressIndicator extends ProgressIndicator {
Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor; Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).backgroundColor;
Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).accentColor; Color _getValueColor(BuildContext context) => valueColor?.value ?? Theme.of(context).colorScheme.secondary;
@override @override
State<StatefulWidget> createState() => _LiquidLinearProgressIndicatorState(); State<StatefulWidget> createState() => _LiquidLinearProgressIndicatorState();
@ -126,8 +126,7 @@ class _LinearBorderPainter extends CustomPainter {
} }
@override @override
bool shouldRepaint(_LinearBorderPainter oldDelegate) => bool shouldRepaint(_LinearBorderPainter oldDelegate) => color != oldDelegate.color || width != oldDelegate.width || radius != oldDelegate.radius;
color != oldDelegate.color || width != oldDelegate.width || radius != oldDelegate.radius;
} }
class _LinearClipper extends CustomClipper<Path> { class _LinearClipper extends CustomClipper<Path> {

View File

@ -104,8 +104,7 @@ Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
); );
final String platform = Platform.isAndroid ? "Android" : "iOS"; final String platform = Platform.isAndroid ? "Android" : "iOS";
final String version = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : ""; final String version = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : "";
final sentryId = final sentryId = await Sentry.captureException(error, stackTrace: stackTrace, hint: "Platform: $platform, Version: $version, User: $customerId");
await Sentry.captureException(error, stackTrace: stackTrace, hint: "Platform: $platform, Version: $version, User: $customerId");
print('Capture exception result : SentryId : $sentryId'); print('Capture exception result : SentryId : $sentryId');
} }
@ -163,7 +162,6 @@ Future<Null> main() async {
} }
await initThirdParty(); await initThirdParty();
final FirebaseAnalytics analytics = FirebaseAnalytics.instance; final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
;
print(" -- FireBase init.."); print(" -- FireBase init..");
@ -196,8 +194,7 @@ Future<Null> main() async {
BlocProvider<TestSetExecuteBloc>( BlocProvider<TestSetExecuteBloc>(
create: (BuildContext context) => TestSetExecuteBloc(), create: (BuildContext context) => TestSetExecuteBloc(),
), ),
BlocProvider<TutorialBloc>( BlocProvider<TutorialBloc>(create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
BlocProvider<TrainingPlanBloc>(create: (context) { BlocProvider<TrainingPlanBloc>(create: (context) {
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context); final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository()); return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());

View File

@ -780,25 +780,4 @@ class Cache with Logging {
} }
this._customerPropertyAll!.add(property); this._customerPropertyAll!.add(property);
} }
bool canTrial() {
bool can = true;
if (Cache().userLoggedIn == null) {
can = false;
return can;
}
for (var element in _purchases) {
if (element.customerId == Cache().userLoggedIn!.customerId) {
can = false;
}
}
if (userLoggedIn!.trialDate != null) {
can = false;
}
print("Can Trial $can");
return can;
}
} }

View File

@ -8,9 +8,6 @@ mixin Trans {
} }
String t(String text) { String t(String text) {
if (context == null) {
throw Exception("Translation: initialize the context");
}
return AppLocalizations.of(context)!.translate(text); return AppLocalizations.of(context)!.translate(text);
} }
} }

View File

@ -41,11 +41,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
return BlocProvider( return BlocProvider(
create: (context) => ExerciseNewBloc( create: (context) => ExerciseNewBloc(
exerciseRepository: ExerciseRepository(), exerciseRepository: ExerciseRepository(), menuBloc: menuBloc, customerRepository: CustomerRepository(), exerciseType: exerciseType),
menuBloc: menuBloc,
customerRepository: CustomerRepository(),
exerciseType: exerciseType)
..add(ExerciseNewLoad()),
child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>( child: BlocConsumer<ExerciseNewBloc, ExerciseNewState>(
listener: (context, state) { listener: (context, state) {
if (state is ExerciseNewError) { if (state is ExerciseNewError) {

View File

@ -1,5 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/development_diagram/development_diagram_bloc.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/library/radar_chart.dart'; import 'package:aitrainer_app/library/radar_chart.dart';
import 'package:aitrainer_app/widgets/app_bar.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';
@ -11,6 +13,7 @@ import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:aitrainer_app/bloc/body_development/body_development_bloc.dart'; import 'package:aitrainer_app/bloc/body_development/body_development_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
class MyDevelopmentBodyPage extends StatefulWidget { class MyDevelopmentBodyPage extends StatefulWidget {
@ -55,7 +58,7 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bloc = BlocProvider.of<BodyDevelopmentBloc>(context); final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
LinkedHashMap arguments = ModalRoute.of(context)!.settings.arguments as LinkedHashMap; LinkedHashMap arguments = ModalRoute.of(context)!.settings.arguments as LinkedHashMap;
final int customerId = arguments['customerId']; final int customerId = arguments['customerId'];
setContext(context); setContext(context);
@ -73,41 +76,181 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
alignment: Alignment.center, alignment: Alignment.center,
), ),
), ),
child: BlocConsumer<BodyDevelopmentBloc, BodyDevelopmentState>( child: BlocProvider(
listener: (context, state) {}, create: (context) => BodyDevelopmentBloc(workoutTreeRepository: menuBloc.menuTreeRepository),
builder: (context, state) { child: BlocConsumer<BodyDevelopmentBloc, BodyDevelopmentState>(
if (state is BodyDevelopmentInitial) { listener: (context, state) {
return Container(); if (state is BodyDevelopmentError) {
} else { ScaffoldMessenger.of(context)
return ModalProgressHUD( .showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
child: developmentWidget(customerId), }
inAsyncCall: state is BodyDevelopmentLoading, },
opacity: 0.5, builder: (context, state) {
color: Colors.black54, final bloc = BlocProvider.of<BodyDevelopmentBloc>(context);
progressIndicator: CircularProgressIndicator(), return ModalProgressHUD(
); child: developmentWidget(customerId, bloc),
} inAsyncCall: state is BodyDevelopmentLoading,
}, opacity: 0.5,
)), color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
},
))),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 1), bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
); );
} }
Widget developmentWidget(int customerId) { Widget getFilterData(BodyDevelopmentBloc bloc) {
return Container(
color: Colors.transparent,
// padding: EdgeInsets.all(5),
child: Wrap(
direction: Axis.horizontal,
spacing: 10,
runSpacing: 5,
children: [
ChoiceChip(
avatar: Icon(
Icons.bubble_chart,
),
label: Text(t('Sum Of Mass')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.lightBlueAccent,
selected: bloc.group == DiagramGroup.sumMass,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeGroup(group: DiagramGroup.sumMass))},
),
ChoiceChip(
avatar: Icon(Icons.accessibility_new),
label: Text(t('One Rep Max')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.lightBlueAccent,
selected: bloc.group == DiagramGroup.oneRepMax,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeGroup(group: DiagramGroup.oneRepMax))},
),
ChoiceChip(
avatar: Icon(Icons.perm_device_information),
label: Text(t('Percent')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.lightBlueAccent,
selected: bloc.group == DiagramGroup.percent,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeGroup(group: DiagramGroup.percent))},
),
],
),
);
}
Widget getGroupDate(BodyDevelopmentBloc bloc) {
return Container(
color: Colors.transparent,
//padding: EdgeInsets.all(5),
child: Wrap(
direction: Axis.horizontal,
spacing: 10,
runSpacing: 5,
children: [
ChoiceChip(
labelPadding: EdgeInsets.only(right: 5),
avatar: Icon(Icons.timer),
label: Text(t('L3M')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
disabledColor: Colors.black26,
selectedColor: Colors.greenAccent,
selected: bloc.filter == DiagramDateFilterGroup.l3m,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeDate(filter: DiagramDateFilterGroup.l3m))},
),
ChoiceChip(
labelPadding: EdgeInsets.only(right: 5),
avatar: Icon(Icons.timer),
label: Text(t('FM-LM')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.greenAccent,
disabledColor: Colors.white12,
selected: bloc.filter == DiagramDateFilterGroup.fm_lm,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeDate(filter: DiagramDateFilterGroup.fm_lm))},
),
ChoiceChip(
labelPadding: EdgeInsets.only(right: 5),
avatar: Icon(Icons.timer),
label: Text(t('L3T')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.greenAccent,
disabledColor: Colors.black26,
selected: bloc.filter == DiagramDateFilterGroup.l3t,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeDate(filter: DiagramDateFilterGroup.l3t))},
),
ChoiceChip(
labelPadding: EdgeInsets.only(right: 5),
avatar: Icon(Icons.timer),
label: Text(t('Yearly')),
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
selectedColor: Colors.greenAccent,
disabledColor: Colors.white70,
selected: bloc.filter == DiagramDateFilterGroup.yearly,
onSelected: (value) => {bloc.add(BodyDevelopmentChangeDate(filter: DiagramDateFilterGroup.yearly))},
),
],
),
);
}
Widget getLegend(BodyDevelopmentBloc bloc) {
if (bloc.filter == DiagramDateFilterGroup.yearly) {
return Offstage();
}
return Wrap(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 100,
height: 6,
color: Colors.green,
),
Text("First Month", style: GoogleFonts.inter(fontSize: 14)),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 100,
height: 6,
color: Colors.blue,
),
Text("First Month", style: GoogleFonts.inter(fontSize: 14)),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
width: 100,
height: 6,
color: Colors.red,
),
Text("First Month", style: GoogleFonts.inter(fontSize: 14)),
],
)
],
);
}
Widget developmentWidget(int customerId, BodyDevelopmentBloc bloc) {
return Column(children: [ return Column(children: [
explanationWidget(), explanationWidget(),
getFilterData(bloc),
getGroupDate(bloc),
getLegend(bloc),
Expanded( Expanded(
child: exerciseWidget(customerId), child: exerciseWidget(customerId, bloc),
), ),
]); ]);
} }
Widget exerciseWidget(int customerId) { Widget exerciseWidget(int customerId, BodyDevelopmentBloc bloc) {
return RadarChart.light( return RadarChart.light(ticks: bloc.radarTicks, features: bloc.radarFeatures, data: bloc.radarData);
ticks: bloc.radarTicks,
features: bloc.radarFeatures,
data: bloc.radarData,
);
} }
Widget explanationWidget() { Widget explanationWidget() {

View File

@ -87,9 +87,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
builder: (BuildContext context) { builder: (BuildContext context) {
return DialogCommon( return DialogCommon(
title: t("Premium function"), title: t("Premium function"),
descriptions: Cache().canTrial() descriptions: t("This is a premium function, you can reach it only with a valid subscription"),
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
: t("This is a premium function, you can reach it only with a valid subscription"),
onCancel: () => Navigator.of(context).pop(), onCancel: () => Navigator.of(context).pop(),
onTap: () => Navigator.of(context).pop(), onTap: () => Navigator.of(context).pop(),
text: '', text: '',
@ -151,9 +149,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
builder: (BuildContext context) { builder: (BuildContext context) {
return DialogCommon( return DialogCommon(
title: t("Premium function"), title: t("Premium function"),
descriptions: Cache().canTrial() descriptions: t("This is a premium function, you can reach it only with a valid subscription"),
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
: t("This is a premium function, you can reach it only with a valid subscription"),
onCancel: () => Navigator.of(context).pop(), onCancel: () => Navigator.of(context).pop(),
onTap: () => Navigator.of(context).pop(), onTap: () => Navigator.of(context).pop(),
text: '', text: '',

View File

@ -160,7 +160,7 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
HashMap<String, dynamic> args = HashMap(); HashMap<String, dynamic> args = HashMap();
args['customerRepository'] = bloc.customerRepository; args['customerRepository'] = bloc.customerRepository;
args['property'] = element; args['property'] = element;
args['title'] = t("Size development: ") + " " + propertyName; args['title'] = t("Size development") + ": " + t(propertyName);
Navigator.of(context).pushNamed('developmentDiagramPage', arguments: args); Navigator.of(context).pushNamed('developmentDiagramPage', arguments: args);
} }
@ -177,8 +177,8 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
), ),
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8), padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
child: Column(children: [ child: Column(children: [
Row( Wrap(
mainAxisAlignment: MainAxisAlignment.start, //mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Icon( Icon(
Icons.info, Icons.info,
@ -187,7 +187,7 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
Text(" "), Text(" "),
Text( Text(
t("Red icon means you have not saved this size."), t("Red icon means you have not saved this size."),
overflow: TextOverflow.clip, //overflow: TextOverflow.clip,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 14, fontSize: 14,
color: Colors.white, color: Colors.white,
@ -197,7 +197,7 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
), ),
Text( Text(
t("Tap on the green icon to see your development in a diagram"), t("Tap on the green icon to see your development in a diagram"),
overflow: TextOverflow.clip, //overflow: TextOverflow.clip,
style: GoogleFonts.inter( style: GoogleFonts.inter(
fontSize: 14, fontSize: 14,
color: Colors.white, color: Colors.white,

View File

@ -185,7 +185,7 @@ class SettingsPage extends StatelessWidget with Trans {
leading: Icon(CustomIcon.user_cog), leading: Icon(CustomIcon.user_cog),
title: TextButton( title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("Terms Of Use", style: TextStyle(color: Colors.black)), Text(t("Terms Of Use"), style: TextStyle(color: Colors.black)),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.indigo, color: Colors.indigo,
@ -212,7 +212,7 @@ class SettingsPage extends StatelessWidget with Trans {
leading: Icon(Icons.enhanced_encryption), leading: Icon(Icons.enhanced_encryption),
title: TextButton( title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("Data Privacy", style: TextStyle(color: Colors.black)), Text(t("Data Privacy"), style: TextStyle(color: Colors.black)),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.indigo, color: Colors.indigo,
@ -239,7 +239,7 @@ class SettingsPage extends StatelessWidget with Trans {
leading: Icon(CustomIcon.question), leading: Icon(CustomIcon.question),
title: TextButton( title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("Frequently Asked Questions", style: TextStyle(color: Colors.indigo)), Text(t("Frequently Asked Questions"), style: TextStyle(color: Colors.indigo)),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.indigo, color: Colors.indigo,
@ -282,7 +282,7 @@ class SettingsPage extends StatelessWidget with Trans {
leading: Icon(CustomIcon.mail_1), leading: Icon(CustomIcon.mail_1),
title: TextButton( title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("Feedback email", style: TextStyle(color: Colors.indigo)), Text(t("Feedback email"), style: TextStyle(color: Colors.indigo)),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.indigo, color: Colors.indigo,

View File

@ -51,12 +51,11 @@ class TrainingEvaluationPage extends StatelessWidget with Trans {
), ),
), ),
child: BlocProvider( child: BlocProvider(
create: (context) => create: (context) => TrainingEvaluationBloc(trainingPlanBloc: trainingPlanBloc, day: dayName),
TrainingEvaluationBloc(trainingPlanBloc: trainingPlanBloc, day: dayName)..add(TrainingEvaluationLoad()),
child: BlocConsumer<TrainingEvaluationBloc, TrainingEvaluationState>(listener: (context, state) { child: BlocConsumer<TrainingEvaluationBloc, TrainingEvaluationState>(listener: (context, state) {
if (state is TrainingEvaluationError) { if (state is TrainingEvaluationError) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context)
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); .showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is TrainingEvaluationVictoryReady) { } else if (state is TrainingEvaluationVictoryReady) {
showDialog( showDialog(
context: context, context: context,
@ -373,8 +372,7 @@ class ExerciseTile extends StatelessWidget with Trans {
hasWeight hasWeight
? skipped ? skipped
? extra ? extra
? TextSpan( ? TextSpan(text: "-", style: GoogleFonts.inter(fontSize: 12, color: Colors.grey[400], fontWeight: FontWeight.bold))
text: "-", style: GoogleFonts.inter(fontSize: 12, color: Colors.grey[400], fontWeight: FontWeight.bold))
: TextSpan( : TextSpan(
text: t("skipped") + "!", text: t("skipped") + "!",
style: GoogleFonts.inter(fontSize: 12, color: Colors.grey[400], fontWeight: FontWeight.bold)) style: GoogleFonts.inter(fontSize: 12, color: Colors.grey[400], fontWeight: FontWeight.bold))
@ -433,8 +431,7 @@ class ExerciseTile extends StatelessWidget with Trans {
skipped || extra skipped || extra
? TextSpan() ? TextSpan()
: TextSpan( : TextSpan(
text: t("Trend") + ": ", text: t("Trend") + ": ", style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[400], fontWeight: FontWeight.bold)),
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[400], fontWeight: FontWeight.bold)),
skipped || extra skipped || extra
? TextSpan() ? TextSpan()
: TextSpan( : TextSpan(

View File

@ -204,9 +204,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
builder: (BuildContext context) { builder: (BuildContext context) {
return DialogCommon( return DialogCommon(
title: t("Premium function"), title: t("Premium function"),
descriptions: Cache().canTrial() descriptions: t("This is a premium function, you can reach it only with a valid subscription"),
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
: t("This is a premium function, you can reach it only with a valid subscription"),
onCancel: () => Navigator.of(context).pop(), onCancel: () => Navigator.of(context).pop(),
onTap: () => Navigator.of(context).pop(), onTap: () => Navigator.of(context).pop(),
text: '', text: '',
@ -478,8 +476,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
return DialogCommon( return DialogCommon(
title: t("Dropset"), title: t("Dropset"),
descriptions: t("A drop set is an advanced resistance training technique "), descriptions: t("A drop set is an advanced resistance training technique "),
description2: description2: t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
text: "OK", text: "OK",
onTap: () => { onTap: () => {
Navigator.of(context).pop(), Navigator.of(context).pop(),

View File

@ -333,8 +333,8 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
String description2 = ""; String description2 = "";
if (next.exerciseTypeId != detail.exerciseTypeId) { if (next.exerciseTypeId != detail.exerciseTypeId) {
title = AppLocalizations.of(context)!.translate("Stop!"); title = AppLocalizations.of(context)!.translate("Stop!");
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") + description =
next.exerciseType!.nameTranslation; AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") + next.exerciseType!.nameTranslation;
} else { } else {
final HashMap args = HashMap(); final HashMap args = HashMap();
args['exerciseType'] = next.exerciseType; args['exerciseType'] = next.exerciseType;
@ -388,8 +388,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) { bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
if (prev == null || (prev != null && prev!.exerciseTypeId != element.exerciseTypeId)) { if (prev == null || (prev != null && prev!.exerciseTypeId != element.exerciseTypeId)) {
tiles.add(GestureDetector( tiles.add(GestureDetector(
onTap: () => onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
child: ExerciseTile( child: ExerciseTile(
bloc: bloc, bloc: bloc,
detail: element, detail: element,
@ -544,8 +543,7 @@ class ExerciseTile extends StatelessWidget with Trans {
List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) { List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) {
final List<Widget> list = []; final List<Widget> list = [];
if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null && if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null && bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
int index = 0; int index = 0;
for (CustomerTrainingPlanDetails alternative in bloc.alternatives[detail.customerTrainingPlanDetailsId]) { for (CustomerTrainingPlanDetails alternative in bloc.alternatives[detail.customerTrainingPlanDetailsId]) {
final Widget widget = getTile(alternative, index); final Widget widget = getTile(alternative, index);
@ -565,8 +563,7 @@ class ExerciseTile extends StatelessWidget with Trans {
final int step = bloc.getStep(detail); final int step = bloc.getStep(detail);
final int highlightStep = bloc.getHighlightStep(detail); final int highlightStep = bloc.getHighlightStep(detail);
final bool hasLeftAlternative = detail.alternatives.length > 0 && index > 0; final bool hasLeftAlternative = detail.alternatives.length > 0 && index > 0;
final bool hasRightAlternative = final bool hasRightAlternative = detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
return Container( return Container(
child: Stack(alignment: Alignment.centerRight, children: [ child: Stack(alignment: Alignment.centerRight, children: [
@ -601,8 +598,7 @@ class ExerciseTile extends StatelessWidget with Trans {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return DialogHTML( return DialogHTML(
title: detail.exerciseType!.nameTranslation, title: detail.exerciseType!.nameTranslation, htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
}), }),
icon: Icon( icon: Icon(
Icons.info_outline, Icons.info_outline,
@ -676,13 +672,13 @@ class ExerciseTile extends StatelessWidget with Trans {
height: 1.1, height: 1.1,
shadows: <Shadow>[ shadows: <Shadow>[
Shadow( Shadow(
offset: Offset(16.0, 16.0), offset: Offset(8.0, 8.0),
blurRadius: 16.0, blurRadius: 8.0,
color: Colors.black54, color: Colors.black54,
), ),
Shadow( Shadow(
offset: Offset(16.0, 16.0), offset: Offset(8.0, 8.0),
blurRadius: 16.0, blurRadius: 8.0,
color: Colors.black54, color: Colors.black54,
), ),
], ],

View File

@ -191,7 +191,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
percent > 0.6 ? Icons.mood : Icons.mood_bad, percent > 0.6 ? Icons.mood : Icons.mood_bad,
color: colorAnim.value, color: colorAnim.value,
), ),
linearStrokeCap: LinearStrokeCap.roundAll, barRadius: Radius.circular(8),
backgroundColor: colorAnim.value, backgroundColor: colorAnim.value,
progressColor: Color(0xff73e600), progressColor: Color(0xff73e600),
animation: true, animation: true,

View File

@ -75,32 +75,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
await initDynamicLinks(); await initDynamicLinks();
} }
if (Cache().canTrial()) {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogTrialWidget(
title: t("10 days Premium for free"),
description: t("Would you like to try all premium functions for 10 days, without any subscription or bank card data?"),
widget: Column(children: [
Text(
t("If you click to 'OK', all premium functions will be available right now."),
style: GoogleFonts.inter(color: Colors.white),
),
Divider(),
/* Text(
t("If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free."),
style: GoogleFonts.inter(color: Colors.white),
), */
]),
onCancel: () => {
Navigator.of(context).pop(),
menuBloc.add(MenuStartTrial(start: DateTime.parse("1900-01-01 00:00:00"))),
},
onTap: () => {Navigator.of(context).pop(), menuBloc.add(MenuStartTrial(start: DateTime.now()))},
);
});
}
}); });
} }
@ -128,7 +102,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
menuBloc = BlocProvider.of<MenuBloc>(context); menuBloc = BlocProvider.of<MenuBloc>(context);
//tutorialBloc = BlocProvider.of<TutorialBloc>(context);
setContext(context); setContext(context);
double cWidth = MediaQuery.of(context).size.width; double cWidth = MediaQuery.of(context).size.width;
double cHeight = MediaQuery.of(context).size.height; double cHeight = MediaQuery.of(context).size.height;
@ -139,9 +112,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
return Stack(children: [ return Stack(children: [
CustomScrollView( CustomScrollView(
controller: scrollController, controller: scrollController, scrollDirection: Axis.vertical, slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
scrollDirection: Axis.vertical,
slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
]); ]);
} }
@ -163,15 +134,13 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
padding: EdgeInsets.only(top: 15.0), padding: EdgeInsets.only(top: 15.0),
child: Center( child: Center(
child: Stack(alignment: Alignment.bottomLeft, children: [ child: Stack(alignment: Alignment.bottomLeft, children: [
Text(AppLocalizations.of(context)!.translate("All Exercises has been filtered out"), Text(AppLocalizations.of(context)!.translate("All Exercises has been filtered out"), style: GoogleFonts.inter(color: Colors.white)),
style: GoogleFonts.inter(color: Colors.white)),
])))); ]))));
} else { } else {
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) { menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
WorkoutMenuTree workoutTree = value; WorkoutMenuTree workoutTree = value;
_columnChildren.add(Container( _columnChildren.add(Container(
padding: EdgeInsets.only(top: 15.0, left: cWidth * 0.04, right: cWidth * 0.04), padding: EdgeInsets.only(top: 15.0, left: cWidth * 0.04, right: cWidth * 0.04),
//height: (cHeight / 3) - cWidth * 0.16,
child: Badge( child: Badge(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
position: BadgePosition.bottomEnd(end: 0), position: BadgePosition.bottomEnd(end: 0),
@ -384,8 +353,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
Navigator.of(context).pushNamed("myTrainingPlanActivate", arguments: args); Navigator.of(context).pushNamed("myTrainingPlanActivate", arguments: args);
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id)); menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
} else if (workoutTree.internalName == "training_execute") { } else if (workoutTree.internalName == "training_execute") {
/* Cache().myTrainingPlan = null;
Cache().deleteMyTrainingPlan(); */
if (Cache().myTrainingPlan != null) { if (Cache().myTrainingPlan != null) {
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context); final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
bloc.setMyPlan(Cache().myTrainingPlan); bloc.setMyPlan(Cache().myTrainingPlan);
@ -417,8 +384,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id)); menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
} }
} else { } else {
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
if (workoutTree.exerciseType!.name == "Custom" && Cache().userLoggedIn!.admin == 1) { if (workoutTree.exerciseType!.name == "Custom" && Cache().userLoggedIn!.admin == 1) {
Navigator.of(context).pushNamed('exerciseCustomPage', arguments: workoutTree.exerciseType); Navigator.of(context).pushNamed('exerciseCustomPage', arguments: workoutTree.exerciseType);
} else { } else {
@ -430,10 +395,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
dynamic getShape(WorkoutMenuTree workoutTree) { dynamic getShape(WorkoutMenuTree workoutTree) {
bool base = workoutTree.base; bool base = workoutTree.base;
dynamic returnCode = (base == true) dynamic returnCode = (base == true)
? RoundedRectangleBorder( ? RoundedRectangleBorder(side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0)))
side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0))) : RoundedRectangleBorder(side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
: RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
return returnCode; return returnCode;
} }

View File

@ -56,14 +56,14 @@ packages:
name: bloc name: bloc
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "7.2.1" version: "8.0.3"
bloc_test: bloc_test:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: bloc_test name: bloc_test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.5.0" version: "9.0.3"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -523,7 +523,7 @@ packages:
name: flutter_bloc name: flutter_bloc
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "7.3.3" version: "8.0.1"
flutter_facebook_auth: flutter_facebook_auth:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -28,7 +28,7 @@ dependencies:
google_fonts: ^2.1.0 google_fonts: ^2.1.0
devicelocale: ^0.5.0 devicelocale: ^0.5.0
sentry_flutter: ^6.4.0 sentry_flutter: ^6.4.0
flutter_bloc: ^7.3.3 flutter_bloc: ^8.0.1
equatable: ^2.0.3 equatable: ^2.0.3
radar_chart: ^2.1.0 radar_chart: ^2.1.0
@ -100,7 +100,7 @@ dev_dependencies:
test: '>=1.0.0 <2.0.0' test: '>=1.0.0 <2.0.0'
flutter_test: flutter_test:
sdk: flutter sdk: flutter
bloc_test: ^8.5.0 bloc_test: ^9.0.3
build_runner: build_runner: