WT1.1.23 TrainingPlans generation extension, minor fixes

This commit is contained in:
bossanyit 2021-09-11 07:42:10 +02:00
parent 4e9afbd4b3
commit cc836605fa
28 changed files with 236 additions and 96 deletions

View File

@ -2,5 +2,5 @@
The WorkoutTest Mobile Application The WorkoutTest Mobile Application
live 1.1.5 live 1.1.22

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@ -540,5 +540,6 @@
"If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.": "If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.", "If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.": "If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.",
"Based on your initial data, we will generate the personalized training plan for you.": "Based on your initial data, we will generate the personalized training plan for you.", "Based on your initial data, we will generate the personalized training plan for you.": "Based on your initial data, we will generate the personalized training plan for you.",
"No selected Training Plan": "No selected Training Plan", "No selected Training Plan": "No selected Training Plan",
"Min. 10 minutes": "Min. 10 minutes" "Min. 10 minutes": "Min. 10 minutes",
"You want to skip really the entire exercise?": "You want to skip really the entire exercise?"
} }

View File

@ -540,5 +540,6 @@
"If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.": "Ha a 'Nem'-re kattintasz, használhatod az összes alapfunkciót, de elveszted a lehetőséget, hogy a prémium funkciókat ingyen kipróbáld.", "If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.": "Ha a 'Nem'-re kattintasz, használhatod az összes alapfunkciót, de elveszted a lehetőséget, hogy a prémium funkciókat ingyen kipróbáld.",
"Based on your initial data, we will generate the personalized training plan for you.": "A megadott adataid alapján most személyre szabott edzéstervet generálunk neked.", "Based on your initial data, we will generate the personalized training plan for you.": "A megadott adataid alapján most személyre szabott edzéstervet generálunk neked.",
"No selected Training Plan": "Nincs kiválasztott edzésterved", "No selected Training Plan": "Nincs kiválasztott edzésterved",
"Min. 10 minutes": "Minimum 10 perc" "Min. 10 minutes": "Minimum 10 perc",
"You want to skip really the entire exercise?": "Átugrod az egész gyakorlatot?"
} }

View File

@ -388,7 +388,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 5; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -405,7 +405,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 1.1.22; MARKETING_VERSION = 1.1.23;
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app; PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -531,7 +531,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 5; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -548,7 +548,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 1.1.22; MARKETING_VERSION = 1.1.23;
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app; PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -566,7 +566,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 5; CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -583,7 +583,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
MARKETING_VERSION = 1.1.22; MARKETING_VERSION = 1.1.23;
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app; PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View File

@ -1,6 +1,7 @@
import 'dart:async'; 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/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';
@ -153,10 +154,13 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
yield ExerciseNewReady(); yield ExerciseNewReady();
throw Exception("Please type in a real number"); throw Exception("Please type in a real number");
} }
exerciseRepository.end = DateTime.now(); exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository); if (!isInDebugMode) {
await mauticRepository.sendMauticExercise(); MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
// exerciseRepository.initExercise(); // exerciseRepository.initExercise();
menuBloc.add(MenuTreeDown(parent: 0)); menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges(); Cache().initBadges();

View File

@ -1,7 +1,9 @@
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: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';
@ -129,6 +131,11 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
Cache().hasPurchased = true; Cache().hasPurchased = true;
log("Trial mode on!"); log("Trial mode on!");
Track().track(TrackingEvent.trial, eventValue: DateFormat('yyyy-MM-dd HH:mm:ss').format(start)); Track().track(TrackingEvent.trial, eventValue: DateFormat('yyyy-MM-dd HH:mm:ss').format(start));
if (!isInDebugMode) {
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticTrial();
}
} }
yield MenuReady(); yield MenuReady();
} }

View File

@ -1,5 +1,5 @@
import 'dart:async'; import 'dart:async';
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';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
@ -54,10 +54,12 @@ class TestSetNewBloc extends Bloc<TestSetNewEvent, TestSetNewState> {
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
executeBloc.add( executeBloc.add(
TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity)); TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity));
CustomerRepository customerRepository = CustomerRepository(); if (!isInDebugMode) {
customerRepository.customer = Cache().userLoggedIn; CustomerRepository customerRepository = CustomerRepository();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository); customerRepository.customer = Cache().userLoggedIn;
await mauticRepository.sendMauticExercise(); MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
Track().track(TrackingEvent.test_set_new, eventValue: exerciseType.name); Track().track(TrackingEvent.test_set_new, eventValue: exerciseType.name);
} }

View File

@ -1,5 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/main.dart';
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/customer_training_plan.dart'; import 'package:aitrainer_app/model/customer_training_plan.dart';
@ -123,6 +123,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
// recalculate the weight to the original planned repeats for the next details // recalculate the weight to the original planned repeats for the next details
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) { if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
for (var nextDetail in _myPlan!.details) { for (var nextDetail in _myPlan!.details) {
print("NextDetail detail: $nextDetail");
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail); double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId &&
nextDetail.weight == -2 && nextDetail.weight == -2 &&
@ -132,6 +133,9 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
} else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && weightFromPlan == -1 && nextDetail.set! > 1) { } else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && weightFromPlan == -1 && nextDetail.set! > 1) {
print("recalculating -1 ${event.detail.customerTrainingPlanDetailsId}"); print("recalculating -1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail); nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail);
} else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && nextDetail.weight == -1 && nextDetail.set! == 1) {
print("recalculating -1, set 1 ${event.detail.customerTrainingPlanDetailsId}");
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, event.detail);
} }
} }
} }
@ -145,10 +149,12 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
Cache().myTrainingPlan = _myPlan; Cache().myTrainingPlan = _myPlan;
await Cache().saveMyTrainingPlan(); await Cache().saveMyTrainingPlan();
} }
CustomerRepository customerRepository = CustomerRepository(); if (!isInDebugMode) {
customerRepository.customer = Cache().userLoggedIn; CustomerRepository customerRepository = CustomerRepository();
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository); customerRepository.customer = Cache().userLoggedIn;
await mauticRepository.sendMauticExercise(); MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
await mauticRepository.sendMauticExercise();
}
Track().track(TrackingEvent.training_plan_execute, eventValue: event.detail.exerciseType!.name); Track().track(TrackingEvent.training_plan_execute, eventValue: event.detail.exerciseType!.name);
if (isDayDone()) { if (isDayDone()) {
@ -166,6 +172,21 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
} else { } else {
yield TrainingPlanReady(); yield TrainingPlanReady();
} }
} else if (event is TrainingPlanSkipEntireExercise) {
yield TrainingPlanLoading();
List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(event.detail);
list.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished)) {
element.state = ExercisePlanDetailState.skipped;
}
Cache().myTrainingPlan = _myPlan;
});
await Cache().saveMyTrainingPlan();
if (isDayDone()) {
this.add(TrainingPlanFinishDay());
} else {
yield TrainingPlanReady();
}
} else if (event is TrainingPlanFinishDay) { } else if (event is TrainingPlanFinishDay) {
yield TrainingPlanLoading(); yield TrainingPlanLoading();
celebrating = true; celebrating = true;
@ -545,7 +566,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
break; break;
} }
if (prev != null && prev.exerciseTypeId != detail.exerciseTypeId && detail.state != ExercisePlanDetailState.extra) { if (prev != null && prev.exerciseTypeId != detail.exerciseTypeId || detail.state == ExercisePlanDetailState.extra) {
//print(" --- offset + 1"); //print(" --- offset + 1");
indexInStart++; indexInStart++;
indexInProgress++; indexInProgress++;
@ -553,7 +574,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
prev = detail; prev = detail;
} }
int index = indexInStart > indexInProgress ? indexInStart : indexInProgress; int index = indexInStart > indexInProgress ? indexInStart : indexInProgress;
offset = (index) * 270; offset = (index) * 300;
print("Offset: $offset day: $day ($indexInStart, $indexInProgress)"); print("Offset: $offset day: $day ($indexInStart, $indexInProgress)");
return offset; return offset;
} }
@ -707,7 +728,8 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
bool allFinished = true; bool allFinished = true;
List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(detail); List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(detail);
for (var listDetail in list) { for (var listDetail in list) {
allFinished = allFinished && listDetail.exercises.length >= listDetail.set!; allFinished =
allFinished && (listDetail.exercises.length >= listDetail.set! || listDetail.state.equalsTo(ExercisePlanDetailState.skipped));
} }
return allFinished; return allFinished;
} }

View File

@ -83,6 +83,14 @@ class TrainingPlanSkipExercise extends TrainingPlanEvent {
List<Object> get props => [detail]; List<Object> get props => [detail];
} }
class TrainingPlanSkipEntireExercise extends TrainingPlanEvent {
final CustomerTrainingPlanDetails detail;
const TrainingPlanSkipEntireExercise({required this.detail});
@override
List<Object> get props => [detail];
}
class TrainingPlanAddExerciseType extends TrainingPlanEvent { class TrainingPlanAddExerciseType extends TrainingPlanEvent {
const TrainingPlanAddExerciseType(); const TrainingPlanAddExerciseType();
} }

View File

@ -125,6 +125,7 @@ class Cache with Logging {
AccessToken? accessTokenFacebook; AccessToken? accessTokenFacebook;
Customer? userLoggedIn; Customer? userLoggedIn;
String? firebaseUid; String? firebaseUid;
String? firebaseMessageToken;
LoginType? loginType; LoginType? loginType;
PackageInfo? packageInfo; PackageInfo? packageInfo;
@ -699,6 +700,14 @@ class Cache with Logging {
await isActivityDonePrefs(activity); await isActivityDonePrefs(activity);
}); });
print("Firebase token save: $firebaseMessageToken");
if (userLoggedIn!.firebaseRegToken == null && firebaseMessageToken != null) {
userLoggedIn!.firebaseRegToken = firebaseMessageToken;
CustomerRepository customerRepository = CustomerRepository();
customerRepository.customer = userLoggedIn;
customerRepository.saveCustomer();
}
await getMyTrainingPlan(); await getMyTrainingPlan();
Cache().startPage = "home"; Cache().startPage = "home";

View File

@ -26,6 +26,7 @@ class Customer {
int? sportId; int? sportId;
DateTime? syncedDate; DateTime? syncedDate;
DateTime? trialDate; DateTime? trialDate;
String? firebaseRegToken;
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap(); LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
@ -68,6 +69,7 @@ class Customer {
this.trainer = json['trainer']; this.trainer = json['trainer'];
this.firebaseUid = json['firebaseUid']; this.firebaseUid = json['firebaseUid'];
this.firebaseRegToken = json['firebaseRegToken'];
this.dataPolicyAllowed = json['dataPolicyAllowed']; this.dataPolicyAllowed = json['dataPolicyAllowed'];
this.emailSubscription = json['emailSubscription']; this.emailSubscription = json['emailSubscription'];
@ -100,6 +102,7 @@ class Customer {
"sportId": this.sportId, "sportId": this.sportId,
"syncedDate": this.syncedDate == null ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(this.syncedDate!), "syncedDate": this.syncedDate == null ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(this.syncedDate!),
"trialDate": this.trialDate == null ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(this.trialDate!), "trialDate": this.trialDate == null ? null : DateFormat('yyyy-MM-dd HH:mm:ss').format(this.trialDate!),
"firebaseRegToken": this.firebaseRegToken,
}; };
@override @override

View File

@ -10,6 +10,7 @@ class Mautic {
String? language; String? language;
String? purchaseDate; String? purchaseDate;
String? exerciseDate; String? exerciseDate;
String? trialDate;
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"formId": this.formId, "formId": this.formId,
@ -31,10 +32,11 @@ class Mautic {
form += this.fitnessLevel == null ? "" : "&mauticform[fitness_level]=${this.fitnessLevel}"; form += this.fitnessLevel == null ? "" : "&mauticform[fitness_level]=${this.fitnessLevel}";
form += this.goal == null ? "" : "&mauticform[goal]=${this.goal}"; form += this.goal == null ? "" : "&mauticform[goal]=${this.goal}";
form += this.subscriptionDate == null ? "" : "&mauticform[subscribed]=${this.subscriptionDate}"; form += this.subscriptionDate == null ? "" : "&mauticform[subscribed]=${this.subscriptionDate}";
form += this.databaseId == null ? "" : "&mauticform[database_id]=${this.databaseId}"; form += this.databaseId == null ? "" : "&mauticform[databaseid]=${this.databaseId}";
form += this.language == null ? "" : "&mauticform[language]=${this.language}"; form += this.language == null ? "" : "&mauticform[language]=${this.language}";
form += this.purchaseDate == null ? "" : "&mauticform[purchase_date]=${this.purchaseDate}"; form += this.purchaseDate == null ? "" : "&mauticform[purchase_date]=${this.purchaseDate}";
form += this.exerciseDate == null ? "" : "&mauticform[last_exercise]=${this.exerciseDate}"; form += this.exerciseDate == null ? "" : "&mauticform[last_exercise]=${this.exerciseDate}";
form += this.trialDate == null ? "" : "&mauticform[trialdate]=${this.trialDate}";
return form; return form;
} }

View File

@ -71,6 +71,20 @@ class MauticRepository {
return; return;
} }
mautic.exerciseDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now()); mautic.exerciseDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
mautic.databaseId = Cache().userLoggedIn!.customerId!;
await MauticApi().sendMauticForm(mautic);
}
Future<void> sendMauticTrial() async {
Mautic mautic = Mautic();
mautic.formId = 6;
mautic.email = customerRepository.customer!.email == null ? "" : customerRepository.customer!.email!;
if (mautic.email == null || mautic.email!.contains("privaterelay.appleid.com")) {
return;
}
mautic.trialDate = DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now());
mautic.databaseId = Cache().userLoggedIn!.customerId!;
await MauticApi().sendMauticForm(mautic); await MauticApi().sendMauticForm(mautic);
} }

View File

@ -237,6 +237,22 @@ class TrainingPlanRepository {
return detail; return detail;
} }
CustomerTrainingPlanDetails recalculateDetailFixRepeatsSet1(
int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails detailWithData) {
TrainingPlan? plan = getTrainingPlanById(trainingPlanId);
if (plan == null) {
return detail;
}
int originalRepeats = getOriginalRepeats(trainingPlanId, detail);
detail.weight =
Common.calculateWeigthByChangedQuantity(detailWithData.weight!, detailWithData.repeats!.toDouble(), originalRepeats.toDouble());
detail.weight = Common.roundWeight(detail.weight!);
print("Recalculated weight: ${detail.weight}");
detail.repeats = originalRepeats;
return detail;
}
CustomerTrainingPlanDetails recalculateDetail( CustomerTrainingPlanDetails recalculateDetail(
int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) { int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) {
CustomerTrainingPlanDetails recalculatedDetail = nextDetail; CustomerTrainingPlanDetails recalculatedDetail = nextDetail;
@ -277,15 +293,35 @@ class TrainingPlanRepository {
if (Cache().userLoggedIn!.goal == "shape_forming") { if (Cache().userLoggedIn!.goal == "shape_forming") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) { if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner") : getTrainingPlanByInternalName("man_routine1"); trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L1") : getTrainingPlanByInternalName("man_routine1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) { } else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner_split") : getTrainingPlanByInternalName("man_routine3"); trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L2") : getTrainingPlanByInternalName("man_routine3");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) { } else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_advanced") : getTrainingPlanByInternalName("man_routine4"); trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L3") : getTrainingPlanByInternalName("man_routine4");
} else { } else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_routine2") : getTrainingPlanByInternalName("man_routine2"); trainingPlanId = isWoman ? getTrainingPlanByInternalName("women_shape_L4") : getTrainingPlanByInternalName("man_routine2");
} }
} else { } else if (Cache().userLoggedIn!.goal == "muscle_endurance") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l1") : getTrainingPlanByInternalName("man_se_l1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l2") : getTrainingPlanByInternalName("man_se_l2");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l3") : getTrainingPlanByInternalName("man_se_l3");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_se_l4") : getTrainingPlanByInternalName("man_se_l4");
}
} else if (Cache().userLoggedIn!.goal == "gain_strength") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l1") : getTrainingPlanByInternalName("man_power_l1");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l2") : getTrainingPlanByInternalName("man_power_l2");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l3") : getTrainingPlanByInternalName("man_power_l3");
} else {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("man_power_l4") : getTrainingPlanByInternalName("man_power_l4");
}
} else if (Cache().userLoggedIn!.goal == "gain_muscle") {
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) { if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner") : getTrainingPlanByInternalName("beginner_man"); trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner") : getTrainingPlanByInternalName("beginner_man");
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) { } else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {

View File

@ -23,6 +23,7 @@ class FirebaseApi with logging.Logging {
static const String REGISTER_EMAIL_IN_USE = "email-already-in-use"; static const String REGISTER_EMAIL_IN_USE = "email-already-in-use";
late UserCredential userCredential; late UserCredential userCredential;
String? firebaseRegToken;
factory FirebaseApi() => FirebaseApi._internal(); factory FirebaseApi() => FirebaseApi._internal();
@ -61,9 +62,10 @@ class FirebaseApi with logging.Logging {
badge: true, badge: true,
sound: true, sound: true,
); );
String? token = await FirebaseMessaging.instance.getToken(); this.firebaseRegToken = await FirebaseMessaging.instance.getToken();
Cache().firebaseMessageToken = firebaseRegToken;
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
log("FirebaseMessaging token $token"); log("FirebaseMessaging token $firebaseRegToken");
} catch (e) { } catch (e) {
// Set `_error` state to true if Firebase initialization fails // Set `_error` state to true if Firebase initialization fails
log("Error initializing Firebase"); log("Error initializing Firebase");

View File

@ -23,7 +23,7 @@ class MauticApi with Logging {
client.close(); client.close();
if (!(result.statusCode == 200 || result.statusCode == 302)) { if (!(result.statusCode == 200 || result.statusCode == 302)) {
trace("mautic response: ${result.statusCode}"); trace("mautic response: ${result.statusCode}");
throw Exception("Network error, try again later!"); //throw Exception("Network error, try again later!");
} }
} }
} }

View File

@ -7,8 +7,12 @@ class TrackingApi with Logging {
final APIClient _client = new APIClient(); final APIClient _client = new APIClient();
Future<void> saveTracking(Tracking tracking) async { Future<void> saveTracking(Tracking tracking) async {
String body = JsonEncoder().convert(tracking.toJson()); try {
log(" ===== saving tracking:" + body); String body = JsonEncoder().convert(tracking.toJson());
await _client.post("tracking/", body); log(" ===== saving tracking:" + body);
await _client.post("tracking/", body);
} catch (exception) {
log("exception in tracking: ${exception.toString()}");
}
} }
} }

View File

@ -20,7 +20,6 @@ class Track with Logging {
Track._internal(); Track._internal();
void track(TrackingEvent event, {String eventValue = ""}) { void track(TrackingEvent event, {String eventValue = ""}) {
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
if (!isInDebugMode) { if (!isInDebugMode) {
FlurryData.logEvent(event.enumToString()); FlurryData.logEvent(event.enumToString());
// Smartlook.setGlobalEventProperty(event.toString(), eventValue, false); // Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
@ -33,8 +32,11 @@ class Track with Logging {
tracking.eventValue = eventValue; tracking.eventValue = eventValue;
} }
tracking.dateAdd = DateTime.now(); tracking.dateAdd = DateTime.now();
FirebaseMessaging.instance.subscribeToTopic(event.enumToString());
TrackingApi().saveTracking(tracking); TrackingApi().saveTracking(tracking);
FirebaseMessaging.instance.subscribeToTopic(event.enumToString());
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
} }
} }
} }

View File

@ -12,7 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.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';
enum Goals { gain_muscle, weight_loss, endurance, muscle_endurance, flexibility, gain_strength, explosiveness, shape_forming } enum Goals { gain_muscle, muscle_endurance, gain_strength, shape_forming } //weight_loss, endurance, explosiveness,flexibility,
extension GoalsExt on Goals { extension GoalsExt on Goals {
String toStr() => this.toString().split(".").last; String toStr() => this.toString().split(".").last;
@ -21,20 +21,13 @@ extension GoalsExt on Goals {
String description(Goals goal) { String description(Goals goal) {
switch (goal) { switch (goal) {
case Goals.endurance:
return "Endurance";
case Goals.weight_loss:
return "Loss Weight";
case Goals.gain_muscle: case Goals.gain_muscle:
return "Gain Muscle"; return "Gain Muscle";
case Goals.gain_strength: case Goals.gain_strength:
return "Gain Strength"; return "Gain Strength";
case Goals.muscle_endurance: case Goals.muscle_endurance:
return "Muscle Endurance"; return "Muscle Endurance";
case Goals.flexibility:
return "Flexibility";
case Goals.explosiveness:
return "Explosiveness";
case Goals.shape_forming: case Goals.shape_forming:
return "Shape Forming"; return "Shape Forming";
default: default:
@ -42,6 +35,18 @@ extension GoalsExt on Goals {
} }
} }
/*
case Goals.endurance:
return "Endurance";
case Goals.weight_loss:
return "Loss Weight";
case Goals.explosiveness:
return "Explosiveness";
case Goals.flexibility:
return "Flexibility";
*/
Goals getGoal(Goals goal) { Goals getGoal(Goals goal) {
Goals selected = Goals.gain_muscle; Goals selected = Goals.gain_muscle;
Goals.values.forEach((element) { Goals.values.forEach((element) {
@ -186,18 +191,18 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
SizedBox( SizedBox(
height: h, height: h,
), ),
getItem(changeBloc, Goals.weight_loss), /* getItem(changeBloc, Goals.weight_loss),
SizedBox( SizedBox(
height: h, height: h,
), ), */
getItem(changeBloc, Goals.shape_forming), getItem(changeBloc, Goals.shape_forming),
SizedBox( SizedBox(
height: h, height: h,
), ),
getItem(changeBloc, Goals.endurance), /* getItem(changeBloc, Goals.endurance),
SizedBox( SizedBox(
height: h, height: h,
), ), */
getItem(changeBloc, Goals.gain_strength), getItem(changeBloc, Goals.gain_strength),
SizedBox( SizedBox(
height: h, height: h,
@ -206,14 +211,14 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
SizedBox( SizedBox(
height: h, height: h,
), ),
getItem(changeBloc, Goals.flexibility), /* getItem(changeBloc, Goals.flexibility),
SizedBox( SizedBox(
height: h, height: h,
), ),
getItem(changeBloc, Goals.explosiveness), getItem(changeBloc, Goals.explosiveness),
SizedBox( SizedBox(
height: h, height: h,
), ), */
], ],
), ),
)); ));

View File

@ -37,7 +37,29 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
child: Column( child: Column(
children: [ children: [
SizedBox( SizedBox(
height: 200, height: 5,
),
FadeIn(
child: Container(
width: 160,
height: 80,
child: GestureDetector(
onTap: () => Navigator.of(context).popAndPushNamed("home"),
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 80),
Text(
t("Next"),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
),
],
),
)),
duration: Duration(seconds: 6),
),
SizedBox(
height: 110,
), ),
CircularPercentIndicator( CircularPercentIndicator(
radius: 250.0, radius: 250.0,
@ -75,25 +97,6 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
SizedBox( SizedBox(
height: 90, height: 90,
), ),
FadeIn(
child: Container(
width: 160,
height: 80,
child: GestureDetector(
onTap: () => Navigator.of(context).popAndPushNamed("home"),
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 80),
Text(
t("Next"),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
),
],
),
)),
duration: Duration(seconds: 6),
),
], ],
), ),
))), ))),

View File

@ -87,6 +87,7 @@ class SettingsPage extends StatelessWidget with Trans {
getPrivacy(), getPrivacy(),
mailTo(), mailTo(),
getVersion(), getVersion(),
//welcome(),
//getDevice(settingsBloc), //getDevice(settingsBloc),
]); ]);
} }
@ -264,6 +265,16 @@ class SettingsPage extends StatelessWidget with Trans {
); );
} }
ListTile welcome() {
return ListTile(
title: TextButton(
child: Text("Welcome"),
onPressed: () => {
Navigator.of(context).pushNamed("customerWelcomePage"),
}),
);
}
ListTile mailTo() { ListTile mailTo() {
return ListTile( return ListTile(
leading: Icon(CustomIcon.mail_1), leading: Icon(CustomIcon.mail_1),

View File

@ -308,6 +308,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
void animate() { void animate() {
offset = widget.bloc.getOffset(); offset = widget.bloc.getOffset();
print("Offset: $offset");
if (scrollController.hasClients) { if (scrollController.hasClients) {
scrollController.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn); scrollController.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
} }
@ -531,8 +532,8 @@ class ExerciseTile extends StatelessWidget with Trans {
elevation: 0, elevation: 0,
padding: EdgeInsets.all(0), padding: EdgeInsets.all(0),
position: BadgePosition.topStart(top: 5, start: 5), position: BadgePosition.topStart(top: 5, start: 5),
animationDuration: Duration(milliseconds: 500), animationDuration: Duration(milliseconds: 1000),
animationType: BadgeAnimationType.slide, animationType: BadgeAnimationType.scale,
badgeColor: Colors.transparent, badgeColor: Colors.transparent,
showBadge: true, showBadge: true,
badgeContent: IconButton( badgeContent: IconButton(
@ -638,7 +639,7 @@ class ExerciseTile extends StatelessWidget with Trans {
useRootNavigator: true, useRootNavigator: true,
context: context, context: context,
builder: (_) => CupertinoAlertDialog( builder: (_) => CupertinoAlertDialog(
title: Text(t("You want to skip really this exercise?")), title: Text(t("You want to skip really the entire exercise?")),
content: Column(children: [ content: Column(children: [
Divider(), Divider(),
]), ]),
@ -652,7 +653,7 @@ class ExerciseTile extends StatelessWidget with Trans {
child: Text(t("Yes")), child: Text(t("Yes")),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
bloc.add(TrainingPlanSkipExercise(detail: detail)); bloc.add(TrainingPlanSkipEntireExercise(detail: detail));
}, },
) )
], ],

View File

@ -86,6 +86,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
getTrainingPlan(t("Training Plans for Women"), "asset/menu/training_plans_q_woman.jpg", "for_woman"), getTrainingPlan(t("Training Plans for Women"), "asset/menu/training_plans_q_woman.jpg", "for_woman"),
getTrainingPlan(t("Training Plans of Celebrities"), "asset/menu/training_plans_q_celebrities.jpg", "celebrities"), getTrainingPlan(t("Training Plans of Celebrities"), "asset/menu/training_plans_q_celebrities.jpg", "celebrities"),
getTrainingPlan(t("Training Plans for Gain Strength"), "asset/menu/training_plans_q_gain_strength.jpg", "gain_strength"), getTrainingPlan(t("Training Plans for Gain Strength"), "asset/menu/training_plans_q_gain_strength.jpg", "gain_strength"),
getTrainingPlan(t("Training Plans for Muscle Endurance"), "asset/menu/strenght_endurance.jpg", "muscle_endurance"),
getTrainingPlan(t("Physical Prepare Program for Footgolfers"), "asset/menu/FG_2_edz.jpg", "footgolf"), getTrainingPlan(t("Physical Prepare Program for Footgolfers"), "asset/menu/FG_2_edz.jpg", "footgolf"),
]), ]),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(

View File

@ -696,6 +696,22 @@ class _ExplanationWidgetState extends State<ExplanationWidget> with Trans {
color: Colors.transparent, color: Colors.transparent,
child: Column( child: Column(
children: [ children: [
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white38),
child: CheckboxListTile(
value: _selected,
onChanged: (bool? checked) {
setState(() {
_selected = checked!;
});
},
checkColor: Colors.white,
activeColor: Colors.orange[600],
controlAffinity: ListTileControlAffinity.leading,
title: Text(
t("Show this tip no more"),
style: GoogleFonts.inter(color: Colors.grey),
))),
Padding( Padding(
padding: const EdgeInsets.only(top: 10, left: 10, right: 10), padding: const EdgeInsets.only(top: 10, left: 10, right: 10),
child: Text(t(expl.getExplanation(Explanations.intro)), child: Text(t(expl.getExplanation(Explanations.intro)),
@ -805,22 +821,6 @@ class _ExplanationWidgetState extends State<ExplanationWidget> with Trans {
), ),
], ],
)), )),
Theme(
data: ThemeData(unselectedWidgetColor: Colors.white38),
child: CheckboxListTile(
value: _selected,
onChanged: (bool? checked) {
setState(() {
_selected = checked!;
});
},
checkColor: Colors.white,
activeColor: Colors.orange[600],
controlAffinity: ListTileControlAffinity.leading,
title: Text(
t("Show this tip no more"),
style: GoogleFonts.inter(color: Colors.grey),
)))
], ],
)); ));
} }

View File

@ -74,7 +74,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
} }
Future runDelayedEvent() async { Future runDelayedEvent() async {
await Future.delayed(Duration(milliseconds: 3000), () async { await Future.delayed(Duration(milliseconds: 500), () async {
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
await initDynamicLinks(); await initDynamicLinks();
} }

View File

@ -1,5 +1,5 @@
name: aitrainer_app name: aitrainer_app
description: Aitrainer Mobile Application in Flutter/Dart description: Workout Test Mobile Application in Flutter/Dart
# The following line prevents the package from being accidentally published to # The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages. # pub.dev using `pub publish`. This is preferred for private packages.
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.22+94 version: 1.1.23+95
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
@ -386,6 +386,7 @@ flutter:
- asset/menu/standing_barbell_curl.jpg - asset/menu/standing_barbell_curl.jpg
- asset/menu/standing_biceps_cable_curl.jpg - asset/menu/standing_biceps_cable_curl.jpg
- asset/menu/standing_cable_triceps_extension.jpg - asset/menu/standing_cable_triceps_extension.jpg
- asset/menu/standing_calf_machine.jpg
- asset/menu/standing_face_pull.jpg - asset/menu/standing_face_pull.jpg
- asset/menu/standing_leg_curls.jpg - asset/menu/standing_leg_curls.jpg
- asset/menu/standing_military_presses.jpg - asset/menu/standing_military_presses.jpg
@ -396,6 +397,7 @@ flutter:
- asset/menu/stiff_legged_deadlift.jpg - asset/menu/stiff_legged_deadlift.jpg
- asset/menu/straight_arm_pulldown.jpg - asset/menu/straight_arm_pulldown.jpg
- asset/menu/straight-arm_rope_pull-down.jpg - asset/menu/straight-arm_rope_pull-down.jpg
- asset/menu/strength_endurance.jpg
- asset/menu/stretching.jpg - asset/menu/stretching.jpg
- asset/menu/t_bar_rows.jpg - asset/menu/t_bar_rows.jpg
- asset/menu/test_center.jpg - asset/menu/test_center.jpg