From 48a0c3f7decb1d3e3a35a666e40e771d4c693c3a Mon Sep 17 00:00:00 2001 From: bossanyit Date: Mon, 5 Jul 2021 22:10:32 +0200 Subject: [PATCH] WT 1.1.20(4) Training plan improvements --- asset/image/drop_set.png | Bin 0 -> 183268 bytes asset/image/pict_1rm.png | Bin 0 -> 26947 bytes asset/image/pict_history.png | Bin 0 -> 38319 bytes i18n/en.json | 33 +- i18n/hu.json | 33 +- ios/Podfile.lock | 6 + ios/Runner.xcodeproj/project.pbxproj | 6 +- lib/bloc/exercise_new/exercise_new_bloc.dart | 31 +- lib/bloc/exercise_new/exercise_new_event.dart | 4 + lib/bloc/sales/sales_bloc.dart | 6 + .../training_evaluation_bloc.dart | 274 +++++++++ .../training_evaluation_event.dart | 12 + .../training_evaluation_state.dart | 32 + .../training_plan/training_plan_bloc.dart | 94 ++- .../training_plan/training_plan_event.dart | 9 + .../dropdown_search/dropdown_search.dart | 8 +- lib/main.dart | 7 +- lib/model/cache.dart | 1 + lib/model/exercise_plan_detail.dart | 2 +- lib/model/training_evaluation_exercise.dart | 33 + lib/repository/exercise_repository.dart | 45 +- lib/repository/training_plan_repository.dart | 45 +- lib/service/firebase_api.dart | 6 +- lib/util/common.dart | 16 +- lib/util/enums.dart | 8 +- lib/view/customer_fitness_page.dart | 8 +- lib/view/customer_modify_page.dart | 97 +-- lib/view/evaluation_page.dart | 567 +++++++++--------- lib/view/exercise_control_page.dart | 4 +- lib/view/exercise_new_page.dart | 52 +- lib/view/login.dart | 4 +- lib/view/mydevelopment_muscle_page.dart | 4 +- lib/view/registration.dart | 61 +- lib/view/sales_page.dart | 34 +- lib/view/settings.dart | 27 +- lib/view/training_evaluation_page.dart | 442 ++++++++++++++ lib/view/training_plan_activate_page.dart | 21 +- lib/view/training_plan_execute_page.dart | 168 +++--- lib/view/training_plan_exercise.dart | 233 +++---- lib/view/training_plans_page.dart | 4 +- lib/widgets/bmi_widget.dart | 54 +- lib/widgets/bmr_widget.dart | 29 +- lib/widgets/dialog_long.dart | 403 ------------- lib/widgets/dialog_web_browser.dart | 28 + lib/widgets/exercise_save.dart | 99 ++- lib/widgets/home.dart | 2 - lib/widgets/menu_page_widget.dart | 6 +- lib/widgets/menu_search_bar.dart | 8 +- lib/widgets/tutorial_widget.dart | 71 +++ lib/widgets/weight_control.dart | 112 ++++ pubspec.lock | 58 +- pubspec.yaml | 8 +- 52 files changed, 2086 insertions(+), 1229 deletions(-) create mode 100755 asset/image/drop_set.png create mode 100644 asset/image/pict_1rm.png create mode 100644 asset/image/pict_history.png create mode 100644 lib/bloc/training_evaluation/training_evaluation_bloc.dart create mode 100644 lib/bloc/training_evaluation/training_evaluation_event.dart create mode 100644 lib/bloc/training_evaluation/training_evaluation_state.dart create mode 100644 lib/model/training_evaluation_exercise.dart create mode 100644 lib/view/training_evaluation_page.dart delete mode 100644 lib/widgets/dialog_long.dart create mode 100644 lib/widgets/dialog_web_browser.dart create mode 100644 lib/widgets/weight_control.dart diff --git a/asset/image/drop_set.png b/asset/image/drop_set.png new file mode 100755 index 0000000000000000000000000000000000000000..e4559704f88bc289d2982fd5d708dfddae857c3b GIT binary patch literal 183268 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 z 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 literal 0 HcmV?d00001 diff --git a/asset/image/pict_history.png b/asset/image/pict_history.png new file mode 100644 index 0000000000000000000000000000000000000000..44d2fa476d0654bad6f18f148b6ca987a8c2f0f8 GIT binary patch literal 38319 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 7.0.3) + - share (0.0.1): + - Flutter - shared_preferences (0.0.1): - Flutter - sign_in_with_apple (0.0.1): @@ -250,6 +252,7 @@ DEPENDENCIES: - path_provider (from `.symlinks/plugins/path_provider/ios`) - purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`) - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) + - share (from `.symlinks/plugins/share/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) @@ -331,6 +334,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/purchases_flutter/ios" sentry_flutter: :path: ".symlinks/plugins/sentry_flutter/ios" + share: + :path: ".symlinks/plugins/share/ios" shared_preferences: :path: ".symlinks/plugins/shared_preferences/ios" sign_in_with_apple: @@ -394,6 +399,7 @@ SPEC CHECKSUMS: PurchasesHybridCommon: d65a799a61d688588534b80338edbcbf604ca93d Sentry: 5b16f877da362d23716d827e04db642455b26b40 sentry_flutter: 602dc1902e152269256115e2386e1029511f3440 + share: 0b2c3e82132f5888bccca3351c504d0003b3b410 shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d sign_in_with_apple: 34f3f5456a45fd7ac5fb42905e2ad31dae061b4a sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 028c493..448db08 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -388,7 +388,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -531,7 +531,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -566,7 +566,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/bloc/exercise_new/exercise_new_bloc.dart b/lib/bloc/exercise_new/exercise_new_bloc.dart index 7db6f21..e221448 100644 --- a/lib/bloc/exercise_new/exercise_new_bloc.dart +++ b/lib/bloc/exercise_new/exercise_new_bloc.dart @@ -36,11 +36,11 @@ class ExerciseNewBloc extends Bloc with Logg double bmiAngle = 0; double bmiTop = 0; double bmiLeft = 0; - late double weight; - late double height; + double? weight; + double? height; double bmrEnergy = 0; - late int birthYear; - late String fitnessLevel; + int? birthYear; + String? fitnessLevel; bool changedWeight = false; bool changedSizes = false; @@ -155,6 +155,12 @@ class ExerciseNewBloc extends Bloc with Logg 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(); @@ -168,18 +174,18 @@ class ExerciseNewBloc extends Bloc with Logg } double getBMI() { - if (height == 0 || weight == 0) { + if (weight == null || height == null || height == 0 || weight == 0) { this.bmi = 0; return 0; } - this.bmi = weight / (height * height / 10000); + this.bmi = weight! / (height! * height! / 10000); this.getGoalBMI(); return this.bmi; } double getBMR() { var date = DateTime.now(); - if (height == 0 || weight == 0) { + if (weight == null || height == null || height == 0 || weight == 0) { this.bmi = 0; return 0; } @@ -188,10 +194,10 @@ class ExerciseNewBloc extends Bloc with Logg if (customerRepository.customer!.sex == "m") { //66.47 + ( 13.75 × tömeg kg-ban ) + ( 5.003 × magasság cm-ben ) − ( 6.755 × életkor évben kifejezve ) - bmr = 66.47 + (13.75 * weight) + (5.003 * height) - (6.755 * (year - customerRepository.customer!.birthYear!)); + bmr = 66.47 + (13.75 * weight!) + (5.003 * height!) - (6.755 * (year - customerRepository.customer!.birthYear!)); } else { //BMR = 655.1 + ( 9.563 × ömeg kg-ban ) + ( 1.85 × magasság cm-ben) − ( 4.676 × életkor évben kifejezve ) - bmr = 655.1 + (9.563 * weight) + (1.85 * height) - (4.676 * (year - customerRepository.customer!.birthYear!)); + bmr = 655.1 + (9.563 * weight!) + (1.85 * height!) - (4.676 * (year - customerRepository.customer!.birthYear!)); } bmrEnergy = bmr; @@ -208,6 +214,9 @@ class ExerciseNewBloc extends Bloc with Logg } double getGoalBMI() { + if (weight == null || height == null) { + return 0; + } if (this.bmi == 0) { getBMI(); } @@ -226,8 +235,8 @@ class ExerciseNewBloc extends Bloc with Logg } goalBMI = 24; - this.goalWeight = goalBMI * (height * height / 10000); - this.goalMilestoneWeight = goalMilestoneBMI * (height * height / 10000); + this.goalWeight = goalBMI * (height! * height! / 10000); + this.goalMilestoneWeight = goalMilestoneBMI * (height! * height! / 10000); //print("Angle: " + bmiAngle.toStringAsFixed(1)); diff --git a/lib/bloc/exercise_new/exercise_new_event.dart b/lib/bloc/exercise_new/exercise_new_event.dart index 77f30fa..67ba9bb 100644 --- a/lib/bloc/exercise_new/exercise_new_event.dart +++ b/lib/bloc/exercise_new/exercise_new_event.dart @@ -83,6 +83,10 @@ class ExerciseNewSubmit extends ExerciseNewEvent { const ExerciseNewSubmit(); } +class ExerciseNewSubmitNoRegistration extends ExerciseNewEvent { + const ExerciseNewSubmitNoRegistration(); +} + class ExerciseNewAddError extends ExerciseNewEvent { final String message; const ExerciseNewAddError({required this.message}); diff --git a/lib/bloc/sales/sales_bloc.dart b/lib/bloc/sales/sales_bloc.dart index 4716255..03cc536 100644 --- a/lib/bloc/sales/sales_bloc.dart +++ b/lib/bloc/sales/sales_bloc.dart @@ -29,6 +29,7 @@ class SalesBloc extends Bloc with Logging { String? salesText; String? premiumFunctions = ""; + String? trial = ""; Future init() async { if (Cache().userLoggedIn == null) { @@ -47,6 +48,11 @@ class SalesBloc extends Bloc with Logging { premiumFunctions = ""; } + trial = descriptionRepository.getDescriptionByName("trial"); + if (trial == null || trial!.isEmpty) { + trial = ""; + } + await RevenueCatPurchases().getOfferings(); this.getProductSet(); Track().track(TrackingEvent.sales_page); diff --git a/lib/bloc/training_evaluation/training_evaluation_bloc.dart b/lib/bloc/training_evaluation/training_evaluation_bloc.dart new file mode 100644 index 0000000..ee19179 --- /dev/null +++ b/lib/bloc/training_evaluation/training_evaluation_bloc.dart @@ -0,0 +1,274 @@ +import 'dart:async'; + +import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart'; +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/customer_training_plan_details.dart'; +import 'package:aitrainer_app/model/exercise_plan_detail.dart'; +import 'package:aitrainer_app/model/training_evaluation_exercise.dart'; +import 'package:aitrainer_app/util/common.dart'; +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; + +part 'training_evaluation_event.dart'; +part 'training_evaluation_state.dart'; + +class TrainingEvaluationBloc extends Bloc { + final TrainingPlanBloc trainingPlanBloc; + final String day; + TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()); + + String duration = "-"; + String totalLift = "0"; + String maxTotalLift = "0"; + String maxRepeats = "0"; + DateTime? end; + + List evaluationList = []; + + @override + Stream mapEventToState( + TrainingEvaluationEvent event, + ) async* { + try { + if (event is TrainingEvaluationLoad) { + yield TrainingEvaluationLoading(); + await saveResult(); + getDuration(); + getTotalLift(); + getMaxRepeats(); + createEvaluationData(); + //getMaxTotalLift(); + if (end == null || DateTime.now().difference(end!).inMinutes > 5) { + yield TrainingEvaluationReady(); + } else { + yield TrainingEvaluationVictoryReady(); + } + } + } on Exception catch (e) { + yield TrainingEvaluationError(message: e.toString()); + } + } + + Future saveResult() async {} + + void createEvaluationData() { + if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { + return; + } + + trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { + if (!element.state.equalsTo(ExercisePlanDetailState.extra)) { + if (!findExerciseInEvaluationList(element.exerciseTypeId!)) { + addEvaluationExercise(element); + } else { + //editEvaluationExercise(element); + } + } + }); + } + + bool findExerciseInEvaluationList(int exerciseTypeId) { + bool found = false; + for (var exercise in evaluationList) { + if (exercise.exerciseTypeId == exerciseTypeId) { + found = true; + break; + } + } + return found; + } + + void addEvaluationExercise(CustomerTrainingPlanDetails detail) { + TrainingEvaluationExercise exercise = TrainingEvaluationExercise(); + exercise.exerciseTypeId = detail.exerciseTypeId!; + exercise.name = detail.exerciseType!.nameTranslation; + exercise.state = detail.state; + + if (detail.state.equalsTo(ExercisePlanDetailState.skipped)) { + TrainingEvaluationExercise exercise = TrainingEvaluationExercise(); + exercise.exerciseTypeId = detail.exerciseTypeId!; + exercise.name = detail.exerciseType!.nameTranslation; + exercise.state = ExercisePlanDetailState.skipped; + exercise.type = TrainingEvaluationExerciseType.weightBased; + this.evaluationList.add(exercise); + } else { + if (detail.exerciseType!.unitQuantityUnit == null) { + exercise.type = TrainingEvaluationExerciseType.repeatBased; + exercise.repeats = detail.repeats; + exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!); + exercise.trend = getTrendEvaluationRepeats(exercise); + } else { + exercise.type = TrainingEvaluationExerciseType.weightBased; + exercise.oneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble()); + exercise.max1RM = getMax1RMByExerciseType(detail.exerciseTypeId!); + exercise.totalLift = (detail.weight! * detail.repeats!).round(); + exercise.maxTotalLift = getMaxTotalLiftByExerciseType(detail.exerciseTypeId!).round(); + exercise.trend = this.getTrendWeight(exercise.oneRepMax!, exercise.max1RM, exercise.totalLift, exercise.maxTotalLift); + } + exercise.trendText = getTrendText(exercise.trend!); + exercise.trendColor = getTrendColor(exercise.trend!); + this.evaluationList.add(exercise); + } + } + + double getTrendEvaluationRepeats(TrainingEvaluationExercise exercise) { + double rate = exercise.repeats! / exercise.maxRepeats!; + return rate; + } + + String getTrendText(double rate) { + if (rate > 1.10) { + return "Strongly Growing"; + } else if (rate > 1.05) { + return "Growing"; + } else if (rate < 0.90) { + return "Strongly Sinking"; + } else if (rate < 0.95) { + return "Sinking"; + } else { + return "Stagnant"; + } + } + + Color getTrendColor(double rate) { + if (rate > 1.10) { + return Colors.green[900]!; + } else if (rate > 1.05) { + return Colors.green[300]!; + } else if (rate < 0.90) { + return Colors.red[900]!; + } else if (rate < 0.95) { + return Colors.green[400]!; + } else { + return Colors.white; + } + } + + void getDuration() { + if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { + return; + } + int index = 0; + DateTime? start; + + trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { + if (element.state.equalsTo(ExercisePlanDetailState.finished)) { + if (index++ == 0) { + start = element.exercises[0].dateAdd!; + } else { + if (element.exercises.length > 0) { + this.end = element.exercises[element.exercises.length - 1].dateAdd!; + } + } + //print("Exercise Date ${element.exercises[0].dateAdd!}"); + } + }); + if (start == null) { + this.duration = "00:00:00"; + } else if (this.end == null) { + this.duration = "00:01:00"; + this.end = start; + } else { + this.duration = end!.difference(start!).inMinutes.toString(); + } + } + + void getTotalLift() { + if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { + return; + } + double total = 0; + trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { + if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unitQuantityUnit != null) { + total += element.weight! * element.repeats!; + } + }); + totalLift = total.toStringAsFixed(0); + } + + void getMaxRepeats() { + if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) { + return; + } + int max = 0; + trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) { + if (element.state.equalsTo(ExercisePlanDetailState.finished) && element.exerciseType!.unit != "second") { + print("Repeats ${element.repeats}"); + if (max < element.repeats!) { + max = element.repeats!; + } + } + }); + maxRepeats = max.toStringAsFixed(0); + } + + double getMaxTotalLiftByExerciseType(int exerciseTypeId) { + if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { + return 0; + } + double maxTotal = 0; + Cache().getExercises()!.forEach((element) { + if (element.exerciseTypeId == exerciseTypeId) { + final double total = element.quantity! * element.unitQuantity!; + if (maxTotal < total) { + maxTotal = total; + } + } + }); + + return maxTotal; + } + + double getMax1RMByExerciseType(int exerciseTypeId) { + if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { + return 0; + } + double max1RM = 0; + Cache().getExercises()!.forEach((element) { + if (element.exerciseTypeId == exerciseTypeId) { + final double oneRepMax = Common.calculate1RM(element.unitQuantity!, element.quantity!); + if (max1RM < oneRepMax) { + max1RM = oneRepMax; + } + } + }); + return max1RM; + } + + int getMaxRepeatsByExerciseType(int exerciseTypeId) { + if (Cache().getExercises() == null || Cache().getExercises()!.length == 0) { + return 0; + } + int maxRepeats = 0; + Cache().getExercises()!.forEach((element) { + if (element.exerciseTypeId == exerciseTypeId) { + final int repeats = element.quantity!.toInt(); + if (maxRepeats < repeats) { + maxRepeats = repeats; + } + } + }); + return maxRepeats; + } + + double getOneRepMax(CustomerTrainingPlanDetails detail) { + if (detail.weight == null) { + return 0; + } + return Common.calculate1RM(detail.weight!, detail.repeats!.toDouble()); + } + + double getTotalLiftExercise(CustomerTrainingPlanDetails detail) { + if (detail.weight == null) { + return 0; + } + return detail.weight! * detail.repeats!; + } + + double getTrendWeight(double oneRepMax, max1RM, totalLift, maxTotalLift) { + double oneRepMaxRate = oneRepMax / max1RM; + double totalLiftRate = totalLift / maxTotalLift; + return (oneRepMaxRate + totalLiftRate) / 2; + } +} diff --git a/lib/bloc/training_evaluation/training_evaluation_event.dart b/lib/bloc/training_evaluation/training_evaluation_event.dart new file mode 100644 index 0000000..4632e9a --- /dev/null +++ b/lib/bloc/training_evaluation/training_evaluation_event.dart @@ -0,0 +1,12 @@ +part of 'training_evaluation_bloc.dart'; + +abstract class TrainingEvaluationEvent extends Equatable { + const TrainingEvaluationEvent(); + + @override + List get props => []; +} + +class TrainingEvaluationLoad extends TrainingEvaluationEvent { + const TrainingEvaluationLoad(); +} diff --git a/lib/bloc/training_evaluation/training_evaluation_state.dart b/lib/bloc/training_evaluation/training_evaluation_state.dart new file mode 100644 index 0000000..e4077cc --- /dev/null +++ b/lib/bloc/training_evaluation/training_evaluation_state.dart @@ -0,0 +1,32 @@ +part of 'training_evaluation_bloc.dart'; + +abstract class TrainingEvaluationState extends Equatable { + const TrainingEvaluationState(); + + @override + List get props => []; +} + +class TrainingEvaluationInitial extends TrainingEvaluationState { + const TrainingEvaluationInitial(); +} + +class TrainingEvaluationLoading extends TrainingEvaluationState { + const TrainingEvaluationLoading(); +} + +class TrainingEvaluationReady extends TrainingEvaluationState { + const TrainingEvaluationReady(); +} + +class TrainingEvaluationVictoryReady extends TrainingEvaluationState { + const TrainingEvaluationVictoryReady(); +} + +class TrainingEvaluationError extends TrainingEvaluationState { + final String message; + const TrainingEvaluationError({required this.message}); + + @override + List get props => [message]; +} diff --git a/lib/bloc/training_plan/training_plan_bloc.dart b/lib/bloc/training_plan/training_plan_bloc.dart index c60b6a3..2f94a73 100644 --- a/lib/bloc/training_plan/training_plan_bloc.dart +++ b/lib/bloc/training_plan/training_plan_bloc.dart @@ -11,7 +11,9 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/training_plan_repository.dart'; import 'package:aitrainer_app/service/exercise_service.dart'; import 'package:aitrainer_app/util/app_language.dart'; +import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/enums.dart'; +import 'package:aitrainer_app/util/track.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; @@ -56,12 +58,22 @@ class TrainingPlanBloc extends Bloc { this.activateDays(); Cache().myTrainingPlan = _myPlan; await Cache().saveMyTrainingPlan(); + Track().track(TrackingEvent.training_plan_start, eventValue: event.trainingPlanId.toString()); yield TrainingPlanFinished(); } else if (event is TrainingPlanWeightChange) { yield TrainingPlanExerciseLoading(); event.detail.weight = event.weight; yield TrainingPlanExerciseReady(); + yield TrainingPlanReady(); + } else if (event is TrainingPlanWeightChangeRecalculate) { + yield TrainingPlanExerciseLoading(); + + event.detail.repeats = + Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.weight); + event.detail.weight = event.weight; + print(" weight: ${event.weight} new repeats: ${event.detail.repeats}"); + yield TrainingPlanReady(); } else if (event is TrainingPlanRepeatsChange) { yield TrainingPlanExerciseLoading(); @@ -77,38 +89,51 @@ class TrainingPlanBloc extends Bloc { yield TrainingPlanReady(); } else if (event is TrainingPlanSaveExercise) { yield TrainingPlanLoading(); - - event.detail.state = ExercisePlanDetailState.inProgress; - final Exercise exercise = Exercise(); - exercise.customerId = Cache().userLoggedIn!.customerId!; - exercise.exerciseTypeId = event.detail.exerciseTypeId; - exercise.quantity = event.detail.repeats!.toDouble(); - exercise.unit = event.detail.exerciseType!.unit; - exercise.unitQuantity = event.detail.weight; - exercise.dateAdd = DateTime.now(); - event.detail.exercises.add(exercise); - if (event.detail.exercises.length >= event.detail.set!) { + if (event.detail.weight == -3) { + print("DropSet"); event.detail.state = ExercisePlanDetailState.finished; - } else if (event.detail.exercises.length >= 0) { - event.detail.state = ExercisePlanDetailState.inProgress; - } - // recalculate the weight to the original planned repeats for the next details - if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) { - for (var nextDetail in _myPlan!.details) { - if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && nextDetail.weight == -2) { - trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail); + yield TrainingPlanReady(); + } else { + final Exercise exercise = Exercise(); + exercise.customerId = Cache().userLoggedIn!.customerId!; + exercise.exerciseTypeId = event.detail.exerciseTypeId; + exercise.quantity = event.detail.repeats!.toDouble(); + exercise.unit = event.detail.exerciseType!.unit; + exercise.unitQuantity = event.detail.weight; + exercise.dateAdd = DateTime.now(); + event.detail.exercises.add(exercise); + if (event.detail.exercises.length >= event.detail.set!) { + event.detail.state = ExercisePlanDetailState.finished; + } else if (event.detail.exercises.length >= 0) { + event.detail.state = ExercisePlanDetailState.inProgress; + } + // recalculate the weight to the original planned repeats for the next details + + if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) { + for (var nextDetail in _myPlan!.details) { + double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail); + if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && + nextDetail.weight == -2 && + nextDetail.customerTrainingPlanDetailsId != event.detail.customerTrainingPlanDetailsId) { + print("recalculating -2 ${event.detail.customerTrainingPlanDetailsId}"); + trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, event.detail, nextDetail); + } else if (nextDetail.exerciseTypeId == event.detail.exerciseTypeId && weightFromPlan == -1 && nextDetail.set! > 1) { + print("recalculating -1 ${event.detail.customerTrainingPlanDetailsId}"); + nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail); + } } } + + exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId; + + // save Exercise + Exercise savedExercise = await ExerciseApi().addExercise(exercise); + Cache().addExercise(savedExercise); + + Cache().myTrainingPlan = _myPlan; + await Cache().saveMyTrainingPlan(); } - - exercise.trainingPlanDetailsId = _myPlan!.trainingPlanId; - - // save Exercise - Exercise savedExercise = await ExerciseApi().addExercise(exercise); - Cache().addExercise(savedExercise); - - Cache().myTrainingPlan = _myPlan; - await Cache().saveMyTrainingPlan(); + Track().track(TrackingEvent.training_plan_execute, eventValue: event.detail.exerciseType!.name); if (isDayDone()) { this.add(TrainingPlanFinishDay()); @@ -128,6 +153,7 @@ class TrainingPlanBloc extends Bloc { } else if (event is TrainingPlanFinishDay) { yield TrainingPlanLoading(); celebrating = true; + Track().track(TrackingEvent.training_plan_finished); yield TrainingPlanDayFinished(); } else if (event is TrainingPlanGoToRestart) { yield TrainingPlanLoading(); @@ -178,6 +204,7 @@ class TrainingPlanBloc extends Bloc { } else { _myDetail!.weight = 0; } + Track().track(TrackingEvent.training_plan_custom, eventValue: event.exerciseType.name); yield TrainingPlanReady(); } } on Exception catch (e) { @@ -186,6 +213,9 @@ class TrainingPlanBloc extends Bloc { } void addNewPlan() { + if (Cache().userLoggedIn == null) { + throw Exception("Please log in"); + } if (_myPlan == null) { _myPlan = CustomerTrainingPlan(); } else { @@ -254,6 +284,7 @@ class TrainingPlanBloc extends Bloc { } _myPlan!.days[dayName]!.add(element); }); + this.addExtraExerciseType("Stretching", previousDay); if (dayNames.length == 0) { dayName = ""; @@ -280,6 +311,7 @@ class TrainingPlanBloc extends Bloc { detail.parallel = false; detail.restingTime = 0; detail.exerciseType = exerciseType; + detail.state = ExercisePlanDetailState.extra; if (_myPlan!.days[dayName] == null) { _myPlan!.days[dayName] = []; } @@ -372,7 +404,10 @@ class TrainingPlanBloc extends Bloc { bool isDone = true; final String day = dayNames[activeDayIndex]; for (var detail in _myPlan!.days[day]!) { - if (!detail.state.equalsTo(ExercisePlanDetailState.finished) && !detail.state.equalsTo(ExercisePlanDetailState.skipped)) { + //print("daydone ${detail.state}"); + if (!detail.state.equalsTo(ExercisePlanDetailState.extra) && + !detail.state.equalsTo(ExercisePlanDetailState.finished) && + !detail.state.equalsTo(ExercisePlanDetailState.skipped)) { isDone = false; } } @@ -400,6 +435,7 @@ class TrainingPlanBloc extends Bloc { } int index = indexInStart > indexInProgress ? indexInStart : indexInProgress; offset = index * 80; + print("Offset: $offset day: $day ($indexInStart, $indexInProgress)"); return offset; } diff --git a/lib/bloc/training_plan/training_plan_event.dart b/lib/bloc/training_plan/training_plan_event.dart index 673f976..9d34c99 100644 --- a/lib/bloc/training_plan/training_plan_event.dart +++ b/lib/bloc/training_plan/training_plan_event.dart @@ -28,6 +28,15 @@ class TrainingPlanWeightChange extends TrainingPlanEvent { List get props => [weight, detail]; } +class TrainingPlanWeightChangeRecalculate extends TrainingPlanEvent { + final CustomerTrainingPlanDetails detail; + final double weight; + const TrainingPlanWeightChangeRecalculate({required this.weight, required this.detail}); + + @override + List get props => [weight, detail]; +} + class TrainingPlanRepeatsChange extends TrainingPlanEvent { final CustomerTrainingPlanDetails detail; final int repeats; diff --git a/lib/library/dropdown_search/dropdown_search.dart b/lib/library/dropdown_search/dropdown_search.dart index 9c5f4bc..14c315e 100644 --- a/lib/library/dropdown_search/dropdown_search.dart +++ b/lib/library/dropdown_search/dropdown_search.dart @@ -13,10 +13,10 @@ typedef Future> DropdownSearchOnFind(String text); typedef String DropdownSearchItemAsString(T item); typedef bool DropdownSearchFilterFn(T item, String filter); typedef bool DropdownSearchCompareFn(T item, T selectedItem); -typedef Widget DropdownSearchBuilder(BuildContext context, T selectedItem, String itemAsString); +typedef Widget DropdownSearchBuilder(BuildContext context, T? selectedItem, String itemAsString); typedef Widget DropdownSearchPopupItemBuilder( BuildContext context, - T item, + T? item, bool isSelected, ); typedef bool DropdownSearchPopupItemEnabled(T item); @@ -59,7 +59,7 @@ class DropdownSearch extends StatefulWidget { final DropdownSearchOnFind? onFind; ///called when a new item is selected - final ValueChanged? onChanged; + final ValueChanged? onChanged; ///to customize list of items UI final DropdownSearchBuilder? dropdownBuilder; @@ -77,7 +77,7 @@ class DropdownSearch extends StatefulWidget { final Widget? popupTitle; ///customize the fields the be shown - final DropdownSearchItemAsString? itemAsString; + final DropdownSearchItemAsString? itemAsString; /// custom filter function final DropdownSearchFilterFn? filterFn; diff --git a/lib/main.dart b/lib/main.dart index bf39926..3c30bed 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,6 +63,7 @@ import 'bloc/session/session_bloc.dart'; import 'bloc/settings/settings_bloc.dart'; import 'bloc/timer/timer_bloc.dart'; import 'model/cache.dart'; +import 'view/training_evaluation_page.dart'; const dsn = 'https://0f635b7225564abc9089f8106f25eb5c@sentry.aitrainer.app/1'; @@ -109,7 +110,6 @@ Future main() async { if (isInDebugMode) { // In development mode simply print to console. FlutterError.dumpErrorToConsole(details); - FlurryData.logEvent("enter_test"); } else { // In production mode report to the application zone to report to // Sentry. @@ -147,6 +147,7 @@ Future main() async { print(" -- FireBase init.."); await FirebaseApi().initializeFlutterFire(); + FlurryData.logEvent("enter_test"); runApp(MultiBlocProvider( providers: [ @@ -177,7 +178,8 @@ Future main() async { BlocProvider( create: (BuildContext context) => TestSetExecuteBloc(), ), - BlocProvider(create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialBasic.toStr())), + BlocProvider( + create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())), BlocProvider(create: (context) { final MenuBloc menuBloc = BlocProvider.of(context); return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository()); @@ -276,6 +278,7 @@ class WorkoutTestApp extends StatelessWidget { 'myTrainingPlanActivate': (context) => TrainingPlanActivatePage(), 'myTrainingPlanExecute': (context) => TrainingPlanExecutePage(), 'myTrainingPlanExercise': (context) => TrainingPlanExercise(), + 'myTrainingEvaluation': (context) => TrainingEvaluationPage(), }, initialRoute: 'home', title: 'WorkoutTest', diff --git a/lib/model/cache.dart b/lib/model/cache.dart index c72ff3e..56f103e 100644 --- a/lib/model/cache.dart +++ b/lib/model/cache.dart @@ -65,6 +65,7 @@ enum SharePrefsChange { */ enum ActivityDone { + tutorialExecuteFirstTest, tutorialBasic, tutorialBasicChestPress, tutorialBasicLegPress, diff --git a/lib/model/exercise_plan_detail.dart b/lib/model/exercise_plan_detail.dart index 417254e..5b015eb 100644 --- a/lib/model/exercise_plan_detail.dart +++ b/lib/model/exercise_plan_detail.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; -enum ExercisePlanDetailState { start, inProgress, skipped, finished } +enum ExercisePlanDetailState { start, inProgress, skipped, finished, extra } extension ExericisePlanDetailStateExt on ExercisePlanDetailState { bool equalsTo(ExercisePlanDetailState state) => this.toString() == state.toString(); diff --git a/lib/model/training_evaluation_exercise.dart b/lib/model/training_evaluation_exercise.dart new file mode 100644 index 0000000..b09eae6 --- /dev/null +++ b/lib/model/training_evaluation_exercise.dart @@ -0,0 +1,33 @@ +import 'package:aitrainer_app/model/exercise_plan_detail.dart'; +import 'package:aitrainer_app/model/exercise_type.dart'; +import 'package:flutter/material.dart'; + +enum TrainingEvaluationExerciseType { weightBased, repeatBased, secondBased } + +extension TrainingEvaluationExerciseTypeExt on TrainingEvaluationExerciseType { + String toStr() => this.toString().split(".").last; + bool equalsTo(TrainingEvaluationExerciseType value) => this.toString() == value.toString(); + bool equalsStringTo(String value) => this.toString() == value; +} + +class TrainingEvaluationExercise { + late int exerciseTypeId; + late String name; + late TrainingEvaluationExerciseType type; + late ExerciseType exerciseType; + + int? repeats; + int? maxRepeats; + + int? totalLift; + int? maxTotalLift; + + double? oneRepMax; + double? max1RM; + + late double? trend; + late String trendText; + late Color trendColor; + + late ExercisePlanDetailState state; +} diff --git a/lib/repository/exercise_repository.dart b/lib/repository/exercise_repository.dart index 44387c6..db3aef9 100644 --- a/lib/repository/exercise_repository.dart +++ b/lib/repository/exercise_repository.dart @@ -16,6 +16,7 @@ class ExerciseRepository { List? exerciseList; List? exerciseLogList = []; List? actualExerciseList = []; + bool noRegistration = false; double rmWendler = 0; double rmMcglothlin = 0; @@ -100,6 +101,19 @@ class ExerciseRepository { return savedExercise; } + void addExerciseNoRegistration() { + final Exercise modelExercise = this.exercise!; + modelExercise.exerciseTypeId = this.exerciseType!.exerciseTypeId; + if (exerciseType!.unitQuantity != "1") { + modelExercise.unitQuantity = null; + } + Exercise copy = modelExercise.copy(); + this.actualExerciseList!.add(copy); + this.exerciseList = []; + this.exerciseList!.add(copy); + this.noRegistration = true; + } + void initExercise() { this.createNew(); this.exerciseType = exerciseType; @@ -271,7 +285,9 @@ class ExerciseRepository { } void getSameExercise(int exerciseTypeId, String day) { - this.actualExerciseList = []; + if (!this.noRegistration) { + this.actualExerciseList = []; + } if (exerciseList != null) { int index = 0; for (int i = 0; i < this.exerciseList!.length; i++) { @@ -299,7 +315,7 @@ class ExerciseRepository { return average; } - double getBest1RMPercent(Exercise exercise) { + double getBest1RM(Exercise exercise) { double result = 0; if (this.exerciseList == null || this.exerciseList!.isEmpty) { this.exerciseList = Cache().getExercises(); @@ -307,9 +323,13 @@ class ExerciseRepository { final int exerciseTypeId = exercise.exerciseTypeId!; double toCompare = this.calculate1RM(exercise); + result = toCompare; final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(DateTime.now()); List oldExercises = []; + if (exerciseList == null) { + return toCompare; + } this.exerciseList!.forEach((exercise) { final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) { @@ -333,7 +353,8 @@ class ExerciseRepository { double withCompare = this.calculate1RM(oldExercises.last); - result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100; + //result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100; + result = toCompare >= withCompare ? toCompare : withCompare; } return result; } @@ -349,6 +370,10 @@ class ExerciseRepository { final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); List oldExercises = []; + + if (exerciseList == null) { + return result; + } this.exerciseList!.forEach((exercise) { final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) { @@ -363,7 +388,7 @@ class ExerciseRepository { return result; } - double getBestExercisePercent(Exercise exercise) { + double getBestVolume(Exercise exercise) { double result = 0; if (this.exerciseList == null || this.exerciseList!.isEmpty) { this.exerciseList = Cache().getExercises(); @@ -371,9 +396,13 @@ class ExerciseRepository { final int exerciseTypeId = exercise.exerciseTypeId!; double toCompare = exercise.unitQuantity != null ? exercise.quantity! * exercise.unitQuantity! : exercise.quantity!; + result = toCompare; final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(DateTime.now()); List oldExercises = []; + if (exerciseList == null) { + return toCompare; + } this.exerciseList!.forEach((exercise) { final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) { @@ -399,8 +428,9 @@ class ExerciseRepository { ? oldExercises.last.quantity! * oldExercises.last.unitQuantity! : oldExercises.last.quantity!; - result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100; - print("Last Best: ${oldExercises.last} - result: $result"); + //result = toCompare >= withCompare ? (1 - toCompare / withCompare) * 100 : (1 - toCompare / withCompare) * -100; + //print("Last Best: ${oldExercises.last} - result: $result"); + result = toCompare >= withCompare ? toCompare : withCompare; } return result; } @@ -416,6 +446,9 @@ class ExerciseRepository { final String today = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); List oldExercises = []; + if (exerciseList == null) { + return result; + } this.exerciseList!.forEach((exercise) { final String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd!); if (exercise.exerciseTypeId == exerciseTypeId && exerciseDate.compareTo(today) < 0) { diff --git a/lib/repository/training_plan_repository.dart b/lib/repository/training_plan_repository.dart index 84ad968..0cd52ea 100644 --- a/lib/repository/training_plan_repository.dart +++ b/lib/repository/training_plan_repository.dart @@ -172,6 +172,48 @@ class TrainingPlanRepository { return detail; } + int getOriginalRepeats(int trainingPlanId, CustomerTrainingPlanDetails detail) { + TrainingPlan? plan = getTrainingPlanById(trainingPlanId); + if (plan == null) { + return 0; + } + int originalRepeats = 0; + plan.details!.forEach((element) { + if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) { + originalRepeats = element.repeats ?? 0; + } + }); + return originalRepeats; + } + + double getOriginalWeight(int trainingPlanId, CustomerTrainingPlanDetails detail) { + TrainingPlan? plan = getTrainingPlanById(trainingPlanId); + if (plan == null) { + return 0; + } + double originalWeight = 0; + plan.details!.forEach((element) { + if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) { + originalWeight = element.weight ?? 0; + } + }); + return originalWeight; + } + + CustomerTrainingPlanDetails recalculateDetailFixRepeats(int trainingPlanId, CustomerTrainingPlanDetails detail) { + TrainingPlan? plan = getTrainingPlanById(trainingPlanId); + if (plan == null) { + return detail; + } + int originalRepeats = getOriginalRepeats(trainingPlanId, detail); + + detail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble()); + detail.weight = Common.roundWeight(detail.weight!); + print("Recalculated weight: ${detail.weight}"); + detail.repeats = originalRepeats; + return detail; + } + CustomerTrainingPlanDetails recalculateDetail( int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) { CustomerTrainingPlanDetails recalculatedDetail = nextDetail; @@ -188,7 +230,6 @@ class TrainingPlanRepository { int originalRepeats = detail.repeats!; plan.details!.forEach((element) { if (element.trainingPlanDetailId == detail.trainingPlanDetailsId) { - print("element $element"); originalRepeats = element.repeats ?? 0; } }); @@ -198,7 +239,7 @@ class TrainingPlanRepository { Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble()); recalculatedDetail.weight = Common.roundWeight(recalculatedDetail.weight!); print("recalculated repeats for $originalRepeats: ${recalculatedDetail.weight}"); - recalculatedDetail.repeats = originalRepeats; + //recalculatedDetail.repeats = originalRepeats; return recalculatedDetail; } diff --git a/lib/service/firebase_api.dart b/lib/service/firebase_api.dart index 7369aef..f75ba91 100644 --- a/lib/service/firebase_api.dart +++ b/lib/service/firebase_api.dart @@ -400,8 +400,8 @@ class FirebaseApi with logging.Logging { try { remoteConfig = RemoteConfig.instance; await remoteConfig.setConfigSettings(RemoteConfigSettings( - fetchTimeout: const Duration(seconds: 60), - minimumFetchInterval: const Duration(hours: 6), + fetchTimeout: const Duration(seconds: 10), + minimumFetchInterval: const Duration(seconds: 1), )); RemoteConfigValue(null, ValueSource.valueStatic); @@ -412,6 +412,8 @@ class FirebaseApi with logging.Logging { await remoteConfig.setDefaults({ 'sales_page_text_a': '', 'product_set_2': '', + 'registration_skip_color': '', + 'email_checkbox': '', }); Cache().setRemoteConfig(remoteConfig); } diff --git a/lib/util/common.dart b/lib/util/common.dart index e190bbe..62ed7bf 100644 --- a/lib/util/common.dart +++ b/lib/util/common.dart @@ -154,7 +154,7 @@ mixin Common { double rmWendler = weight * repeat * 0.0333 + weight; double rmOconner = weight * (1 + repeat / 40); - //print("Weight: $weight repeat: $repeat, $rmWendler, Oconner: $rmOconner"); + print("Weight: $weight repeat: $repeat, $rmWendler, Oconner: $rmOconner"); double average = (rmWendler + rmOconner) / 2; return average; @@ -200,7 +200,19 @@ mixin Common { final double repeatWendler = (rmWendler - weight) / 0.0333 / weight; final double repeatOconner = (rmOconner / weight - 1) * 40; final newRepeat = ((repeatOconner + repeatWendler) / 2).ceil(); - //print("Initial 1RM: $initialRM Weight: $weight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat"); + print("Initial 1RM: $initialRM Weight: $weight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat"); + return newRepeat; + } + + static int reCalculateRepeatsByChangedWeight(double weight, double repeat, double changedWeight) { + final double rmWendler = weight * repeat * 0.0333 + weight; + final double rmOconner = weight * (1 + repeat / 40); + + final double repeatWendler = (rmWendler - changedWeight) / 0.0333 / changedWeight; + final double repeatOconner = (rmOconner / changedWeight - 1) * 40; + final newRepeat = ((repeatOconner + repeatWendler) / 2).ceil(); + print( + "Weight: $weight changedWeight: $changedWeight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat"); return newRepeat; } diff --git a/lib/util/enums.dart b/lib/util/enums.dart index 7d156d6..66e56db 100644 --- a/lib/util/enums.dart +++ b/lib/util/enums.dart @@ -22,6 +22,7 @@ enum TrackingEvent { purchase_request, purchase_successful, exercise_new, + exercise_new_no_registration, exercise_new_paralell, result, exercise_log, @@ -50,7 +51,12 @@ enum TrackingEvent { tutorial_activate, terms_of_use, data_privacy, - faq + faq, + training_plan_open, + training_plan_start, + training_plan_execute, + training_plan_finished, + training_plan_custom, } T enumFromString(Iterable values, String value) { diff --git a/lib/view/customer_fitness_page.dart b/lib/view/customer_fitness_page.dart index 21cde39..6c26d57 100644 --- a/lib/view/customer_fitness_page.dart +++ b/lib/view/customer_fitness_page.dart @@ -288,9 +288,9 @@ class _CustomerFitnessPageState extends State with Trans { }, showSelectedItem: true, selectedItem: selected, - itemAsString: (data) => t(data.sportNameTranslation), + itemAsString: (data) => t(data!.sportNameTranslation), onChanged: (data) { - bloc.add(CustomerSportChange(sport: data)); + bloc.add(CustomerSportChange(sport: data!)); }, dropdownBuilder: _customDropDownItem, popupItemBuilder: _customMenuBuilder, @@ -305,7 +305,7 @@ class _CustomerFitnessPageState extends State with Trans { //items: FitnessItem().toList())); } - Widget _customMenuBuilder(BuildContext context, Sport sport, bool isSelected) { + Widget _customMenuBuilder(BuildContext context, Sport? sport, bool isSelected) { return Container( decoration: !isSelected ? BoxDecoration(color: Colors.grey[300]) @@ -317,7 +317,7 @@ class _CustomerFitnessPageState extends State with Trans { child: ListTile( selected: isSelected, title: Text( - t(sport.sportNameTranslation), + t(sport!.sportNameTranslation), style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.blue[600]), ), subtitle: Text( diff --git a/lib/view/customer_modify_page.dart b/lib/view/customer_modify_page.dart index 58200ac..13bce29 100644 --- a/lib/view/customer_modify_page.dart +++ b/lib/view/customer_modify_page.dart @@ -281,86 +281,16 @@ class CustomerModifyPage extends StatelessWidget with Trans { Divider( color: Colors.transparent, ), - SfLinearGauge( - minimum: 40, - maximum: 150, - labelPosition: LinearLabelPosition.outside, - tickPosition: LinearElementPosition.outside, - markerPointers: [ - LinearWidgetPointer( - value: customerBloc.weight, - offset: 5, - position: LinearElementPosition.outside, - markerAlignment: LinearMarkerAlignment.center, - child: Container( - height: 14, - width: 44, - color: Colors.transparent, - child: Text(customerBloc.weight.toStringAsFixed(1), - style: GoogleFonts.inter( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.indigo, - )), - ), - ), - LinearShapePointer( - position: LinearElementPosition.inside, - shapeType: LinearShapePointerType.triangle, - value: customerBloc.weight, - height: 55, - width: 25, - color: Colors.blue, - onValueChanged: (value) => { - customerBloc.add(CustomerWeightChange(weight: value)), - }, - ), - ], - orientation: LinearGaugeOrientation.horizontal, - majorTickStyle: LinearTickStyle(length: 20), - axisLabelStyle: TextStyle(fontSize: 12.0, color: Colors.black), - axisTrackStyle: LinearAxisTrackStyle( - color: Colors.cyan, edgeStyle: LinearEdgeStyle.bothFlat, thickness: 1.0, borderColor: Colors.grey)), + NumberPickerWidget( + minValue: 40, + maxValue: 150, + initalValue: customerBloc.weight.toInt(), + unit: t("kg"), + color: Colors.blue[800]!, + onChange: (value) => customerBloc.add(CustomerWeightChange(weight: value))), Divider( color: Colors.transparent, ), - /* SfRadialGauge( - axes: [ - RadialAxis( - axisLineStyle: AxisLineStyle( - thickness: 0.1, - thicknessUnit: GaugeSizeUnit.factor, - gradient: const SweepGradient(colors: [Color(0xffb4f500), Colors.blue], stops: [0.1, 0.9]), - ), - minimum: 40, - maximum: 160, - pointers: [ - WidgetPointer( - value: customerBloc.weight.toDouble(), - child: Container( - height: 55, - width: 60, - color: Colors.transparent, - child: Text(customerBloc.weight.toStringAsFixed(1), - style: GoogleFonts.inter( - fontSize: 14, - color: Colors.indigo, - )), - )), - NeedlePointer( - needleColor: Colors.blue[200], - knobStyle: KnobStyle(color: Colors.blue[800]), - value: customerBloc.weight.toDouble(), - enableAnimation: true, - //enableDragging: true, - needleStartWidth: 1, - needleEndWidth: 12, - //onValueChanged: (value) => {customerBloc.add(CustomerWeightChange(weight: value))}, - ) - ], - ) - ], - ), */ ]), ), Divider( @@ -455,19 +385,6 @@ class CustomerModifyPage extends StatelessWidget with Trans { }, ), Divider(), - /* TextButton( - onPressed: () => {customerBloc.add(CustomerSave())}, - child: Stack( - alignment: Alignment.center, - children: [ - Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), - Text( - fulldata ? t("Save") : t("Next"), - style: TextStyle(fontSize: 16, color: Colors.white), - ), - ], - ), - ), */ ], ), ), diff --git a/lib/view/evaluation_page.dart b/lib/view/evaluation_page.dart index 4821960..c2b6345 100644 --- a/lib/view/evaluation_page.dart +++ b/lib/view/evaluation_page.dart @@ -1,7 +1,6 @@ import 'dart:collection'; import 'dart:ui'; import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart'; -import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/widgets/tutorial_widget.dart'; import 'package:intl/intl.dart'; import 'package:aitrainer_app/bloc/result/result_bloc.dart'; @@ -23,6 +22,7 @@ import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; // ignore: must_be_immutable class EvaluationPage extends StatelessWidget with Trans { + bool noRegistration = false; @override Widget build(BuildContext context) { dynamic arguments = ModalRoute.of(context)!.settings.arguments; @@ -33,9 +33,14 @@ class EvaluationPage extends StatelessWidget with Trans { exerciseRepository = ExerciseRepository(); } + final TutorialBloc bloc = BlocProvider.of(context); + noRegistration = bloc.actualCheck == "directTest"; + ResultType resultType = ResultType.none; String imageUrl = ""; - if (Cache().userLoggedIn!.sex == "m") { + if (Cache().userLoggedIn == null) { + imageUrl = 'asset/image/WT_Results_for_men.jpg'; + } else if (Cache().userLoggedIn!.sex == "m") { resultType = ResultType.man; imageUrl = 'asset/image/WT_Results_for_men.jpg'; } else { @@ -59,7 +64,7 @@ class EvaluationPage extends StatelessWidget with Trans { } final TutorialBloc tutorialBloc = BlocProvider.of(context); - print("Evaluation page tutorial isActive? ${tutorialBloc.isActive}"); + print("Evaluation page tutorial isActive? ${tutorialBloc.isActive} ${exerciseRepository.exercise!.quantity}"); if (tutorialBloc.isActive == false) { TutorialWidget().close(); } @@ -107,6 +112,26 @@ class EvaluationPage extends StatelessWidget with Trans { String exerciseName = AppLanguage().appLocal == Locale("en") ? resultBloc.exerciseRepository.exerciseType!.name : resultBloc.exerciseRepository.exerciseType!.nameTranslation; + + String? volume, volumeEver, oneRepMax, oneRepMaxEver; + + if (resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null) { + oneRepMax = resultBloc.exerciseRepository.calculate1RM(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(1) + + " " + + t("kg"); + + volume = (resultBloc.exerciseRepository.actualExerciseList![0].quantity! * + resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity!) + .toStringAsFixed(0) + + " " + + t("kg"); + volumeEver = resultBloc.exerciseRepository.getBestVolume(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(0) + + " " + + t("kg"); + oneRepMaxEver = + resultBloc.exerciseRepository.getBest1RM(resultBloc.exerciseRepository.actualExerciseList![0]).toStringAsFixed(1) + " " + t("kg"); + } + return Container( padding: EdgeInsets.only(left: 10, right: 10), child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ @@ -123,8 +148,8 @@ class EvaluationPage extends StatelessWidget with Trans { maxLines: 3, //softWrap: true, style: GoogleFonts.archivoBlack( - fontSize: 20, - color: Colors.yellow[300], + fontSize: 28, + color: Colors.orange[300], shadows: [ Shadow( offset: Offset(5.0, 5.0), @@ -140,61 +165,268 @@ class EvaluationPage extends StatelessWidget with Trans { )), ), ), + + //getResultSummary(resultBloc), SliverList( - delegate: SliverChildListDelegate([ - Text(DateFormat('y-M-d HH:mm', AppLanguage().appLocal.toString()).format(resultBloc.exerciseRepository.start!), - textAlign: TextAlign.center, - maxLines: 2, - softWrap: true, - style: GoogleFonts.archivoBlack( - fontSize: 20, - color: Colors.white, - shadows: [ - Shadow( - offset: Offset(5.0, 5.0), - blurRadius: 12.0, - color: Colors.black54, - ), - Shadow( - offset: Offset(-3.0, 3.0), - blurRadius: 12.0, - color: Colors.black54, - ), - ], - )), - Divider(color: Colors.transparent), - Divider(color: Colors.transparent), - Text(t("Summary of your test"), - textAlign: TextAlign.center, - maxLines: 2, - softWrap: true, - style: GoogleFonts.archivoBlack( - fontSize: 20, - color: Colors.yellow[300], - shadows: [ - Shadow( - offset: Offset(5.0, 5.0), - blurRadius: 12.0, - color: Colors.black54, - ), - Shadow( - offset: Offset(-3.0, 3.0), - blurRadius: 12.0, - color: Colors.black54, - ), - ], - )), - ]), - ), - getResultSummary(resultBloc), + delegate: SliverChildListDelegate([ + getEvaluationWidget(resultBloc), + getSummary(resultBloc), + Divider(), + summaryRow("asset/image/pict_time_h.png", "Start of the Exercise", + DateFormat('y-M-d HH:mm', AppLanguage().appLocal.toString()).format(resultBloc.exerciseRepository.start!)), + Divider(), + oneRepMax != null ? summaryRow("asset/image/pict_1rm.png", "Your One Rep Max", oneRepMax) : Offstage(), + Divider(), + resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null + ? summaryRow("asset/image/pict_weight_volumen_tonna.png", "Total Lift", volume!) + : Offstage(), + Divider(), + resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null + ? summaryRow("asset/image/pict_history.png", "Total Lift Ever", volumeEver!) + : Offstage(), + Divider(), + resultBloc.exerciseRepository.actualExerciseList![0].unitQuantity != null + ? summaryRow("asset/image/pict_1rm.png", "Your One Rep Max Ever", oneRepMaxEver!) + : Offstage(), + ])), + + cta(resultBloc), getSuggestionTitle(resultBloc), getSuggestion(resultBloc), - emptySliver(), + //emptySliver(), //getResultTitle(resultBloc), //getResults(resultBloc), ])); } + Widget getEvaluationWidget(ResultBloc bloc) { + List resultList = []; + print("Act ${bloc.exerciseRepository.actualExerciseList}"); + if (bloc.exerciseRepository.actualExerciseList == null || bloc.exerciseRepository.actualExerciseList!.isEmpty) { + return Offstage(); + } + final int exerciseTypeId = bloc.exerciseRepository.actualExerciseList![0].exerciseTypeId!; + final double quantity = bloc.exerciseRepository.actualExerciseList![0].quantity!; + String eval = bloc.evaluationRepository.getEvaluationTextByExerciseType(exerciseTypeId, quantity); + Color color = bloc.evaluationRepository.getEvaluationColor(eval); + + //if (!EvaluationText.fair.equalsStringTo(eval)) { + resultList.add(RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + children: [ + TextSpan(text: t("Your result is") + ": "), + TextSpan( + text: t(eval), + style: GoogleFonts.archivoBlack( + fontWeight: FontWeight.bold, + color: color, + ), + ), + ]), + )); + + resultList.add(Divider(color: Colors.transparent)); + //} + + return Column(children: resultList); + } + + Widget cta(ResultBloc resultBloc) { + return SliverList( + delegate: SliverChildListDelegate( + ctaSales(resultBloc), + ), + ); + } + + List ctaSales(ResultBloc resultBloc) { + final List resultList = []; + + if (this.noRegistration) { + resultList.add(Divider()); + resultList.add(RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.white, + ), + children: [ + TextSpan( + text: t('Reach all basic functions, suggestions and'), + style: GoogleFonts.inter( + color: Colors.white, + ), + ), + TextSpan(text: " "), + TextSpan( + text: t('optimized training plans, customized to your fitness state and strength:'), + style: GoogleFonts.inter( + color: Colors.white, + ), + ), + ]))); + resultList.add( + TextButton( + onPressed: () => Navigator.of(context).pushNamed("registration"), + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), + Text( + t("Register"), + style: GoogleFonts.inter( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + ), + ); + } else { + if (!Cache().hasPurchased) { + resultList.add(Divider()); + resultList.add(Divider()); + resultList.add(RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 20, + fontWeight: FontWeight.normal, + color: Colors.white, + ), + children: [ + TextSpan( + text: t('How can serve you this result?'), + style: GoogleFonts.inter( + color: Colors.white, + ), + ), + ]), + )); + resultList.add(RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 20, + fontWeight: FontWeight.normal, + color: Colors.white, + ), + children: [ + TextSpan( + text: t('Get the Fastlane to your'), + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ]), + )); + resultList.add(RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 20, + fontWeight: FontWeight.normal, + color: Colors.white, + ), + children: [ + TextSpan( + text: t('Development'), + style: GoogleFonts.inter( + fontWeight: FontWeight.bold, + color: Colors.yellow[300], + ), + ) + ]))); + + resultList.add(TextButton( + onPressed: () => {Navigator.of(context).pushNamed("salesPage")}, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), + Text( + t("Go"), + style: GoogleFonts.inter( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + )); + } + } + + return resultList; + } + + Widget summaryRow(String imageUrl, String title, String data) { + return Row( + children: [ + Image.asset( + imageUrl, + height: 40, + ), + SizedBox( + width: 10, + ), + Flexible( + fit: FlexFit.tight, + flex: 1, + child: Text(t(title), + textAlign: TextAlign.start, + maxLines: 2, + softWrap: true, + style: GoogleFonts.archivoBlack( + fontSize: 18, + color: Colors.orange[400], + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + ))), + SizedBox( + width: 10, + ), + Text(data, + textAlign: TextAlign.center, + maxLines: 2, + softWrap: true, + style: GoogleFonts.archivoBlack( + fontSize: 20, + color: Colors.white, + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )) + ], + ); + } + Widget getSuggestionTitle(ResultBloc resultBloc) { if (resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null) { return SliverList( @@ -294,6 +526,14 @@ class EvaluationPage extends StatelessWidget with Trans { String unitQuantityUnit = resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit == null ? "" : resultBloc.exerciseRepository.exerciseType!.unitQuantityUnit!; + + String weight = resultBloc.calculate1RM(percent: percent).toStringAsFixed(0); + if (this.noRegistration) { + repeats = "____"; + weight = "_____"; + restTime = "__"; + } + return Column( children: [ Text(t(title), @@ -353,7 +593,7 @@ class EvaluationPage extends StatelessWidget with Trans { ), Row( children: [ - Text(t("Weight") + ": " + resultBloc.calculate1RM(percent: percent).toStringAsFixed(0) + " " + unitQuantityUnit, + Text(t("Weight") + ": " + weight + " " + unitQuantityUnit, textAlign: TextAlign.center, maxLines: 2, softWrap: true, @@ -454,225 +694,14 @@ class EvaluationPage extends StatelessWidget with Trans { return Column(children: resultList); } - Widget getEvaluationWidget(ResultBloc bloc) { - List resultList = []; - print("Act ${bloc.exerciseRepository.actualExerciseList}"); - if (bloc.exerciseRepository.actualExerciseList == null || bloc.exerciseRepository.actualExerciseList!.isEmpty) { - return Offstage(); - } - final int exerciseTypeId = bloc.exerciseRepository.actualExerciseList![0].exerciseTypeId!; - final double quantity = bloc.exerciseRepository.actualExerciseList![0].quantity!; - String eval = bloc.evaluationRepository.getEvaluationTextByExerciseType(exerciseTypeId, quantity); - Color color = bloc.evaluationRepository.getEvaluationColor(eval); - double compareBest = bloc.exerciseRepository.getBestExercisePercent(bloc.exerciseRepository.actualExerciseList![0]); - double compareLast = bloc.exerciseRepository.getLastExercisePercent(bloc.exerciseRepository.actualExerciseList![0]); - bool has1RM = bloc.exerciseRepository.actualExerciseList![0].unitQuantity != null; - double? bestCompared1RM; - double? lastCompared1RM; - if (has1RM) { - lastCompared1RM = bloc.exerciseRepository.getLast1RMPercent(bloc.exerciseRepository.actualExerciseList![0]); - bestCompared1RM = bloc.exerciseRepository.getBest1RMPercent(bloc.exerciseRepository.actualExerciseList![0]); - } - - if (!EvaluationText.fair.equalsStringTo(eval)) { - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 30, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - children: [ - TextSpan(text: t("Your result is: ")), - TextSpan( - text: eval, - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - color: color, - ), - ), - ]), - )); - - resultList.add(Divider(color: Colors.transparent)); - } - - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - color: Colors.white, - ), - children: [ - TextSpan(text: t("Compared with...")), - ]), - )); - - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - color: Colors.white, - ), - children: [ - TextSpan(text: t("your best")), - TextSpan(text: " "), - TextSpan(text: has1RM ? t("volumen") : t("exercise")), - TextSpan(text: ": "), - TextSpan( - text: compareBest.toStringAsFixed(1) + "%", - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - color: compareBest >= 0 ? Colors.green : Colors.red[600], - ), - ), - ]), - )); - - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - color: Colors.white, - ), - children: [ - TextSpan(text: t("your last")), - TextSpan(text: " "), - TextSpan(text: has1RM ? t("volumen") : t("exercise")), - TextSpan(text: ": "), - TextSpan( - text: compareLast.toStringAsFixed(1) + "%", - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - color: compareLast >= 0 ? Colors.green : Colors.red[600], - ), - ), - ]), - )); - resultList.add(Divider(color: Colors.transparent)); - - if (has1RM) { - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - color: Colors.white, - ), - children: [ - TextSpan(text: t("best")), - TextSpan(text: " "), - TextSpan(text: t("1RM")), - TextSpan(text: ": "), - TextSpan( - text: bestCompared1RM!.toStringAsFixed(1) + "%", - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - color: bestCompared1RM >= 0 ? Colors.green : Colors.red[600], - ), - ), - ]), - )); - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - color: Colors.white, - ), - children: [ - TextSpan(text: t("last")), - TextSpan(text: " "), - TextSpan(text: t("1RM")), - TextSpan(text: ": "), - TextSpan( - text: lastCompared1RM!.toStringAsFixed(1) + "%", - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - color: lastCompared1RM >= 0 ? Colors.green : Colors.red[600], - ), - ), - ]), - )); - } - - if (!Cache().hasPurchased) { - resultList.add(Divider()); - resultList.add(Divider()); - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - fontWeight: FontWeight.normal, - color: Colors.white, - ), - children: [ - TextSpan( - text: t('How can serve you this result?'), - style: GoogleFonts.inter( - color: Colors.white, - ), - ), - ]), - )); - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - fontWeight: FontWeight.normal, - color: Colors.white, - ), - children: [ - TextSpan( - text: t('Get the Fastlane to your'), - style: GoogleFonts.inter( - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - ]), - )); - resultList.add(RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 20, - fontWeight: FontWeight.normal, - color: Colors.white, - ), - children: [ - TextSpan( - text: t('Development'), - style: GoogleFonts.inter( - fontWeight: FontWeight.bold, - color: Colors.yellow[300], - ), - ) - ]))); - - resultList.add(TextButton( - onPressed: () => {Navigator.of(context).pushNamed("salesPage")}, - child: Stack( - alignment: Alignment.center, - children: [ - Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), - Text( - t("Go"), - style: GoogleFonts.inter( - fontSize: 20, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - ], - ), - )); - } - - return Column(children: resultList); - } - Widget getResultSummary(ResultBloc resultBloc) { return SliverList( delegate: SliverChildListDelegate( - [Divider(color: Colors.transparent), getSummary(resultBloc), Divider(color: Colors.transparent), getEvaluationWidget(resultBloc)], + [ + Divider(color: Colors.transparent), + getSummary(resultBloc), + Divider(color: Colors.transparent), + ], ), ); } diff --git a/lib/view/exercise_control_page.dart b/lib/view/exercise_control_page.dart index 2a2d9d1..9b13066 100644 --- a/lib/view/exercise_control_page.dart +++ b/lib/view/exercise_control_page.dart @@ -436,8 +436,8 @@ class _UnitQuantityControlState extends State with Trans { height: 20, ), NumberPickerWidget( - minValue: (widget.exerciseBloc.unitQuantity - 10).round(), - maxValue: (widget.exerciseBloc.unitQuantity + 10).round(), + minValue: (widget.exerciseBloc.unitQuantity - 30).round(), + maxValue: (widget.exerciseBloc.unitQuantity + 30).round(), initalValue: widget.exerciseBloc.unitQuantity.round(), unit: t("kg"), color: Colors.yellow[50]!, diff --git a/lib/view/exercise_new_page.dart b/lib/view/exercise_new_page.dart index c373ad8..65a8516 100644 --- a/lib/view/exercise_new_page.dart +++ b/lib/view/exercise_new_page.dart @@ -15,7 +15,6 @@ import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bmi_widget.dart'; import 'package:aitrainer_app/widgets/bmr_widget.dart'; -import 'package:aitrainer_app/widgets/bottom_bar_multiple_exercises.dart'; import 'package:aitrainer_app/widgets/dialog_common.dart'; import 'package:aitrainer_app/widgets/exercise_save.dart'; import 'package:aitrainer_app/widgets/size_widget.dart'; @@ -72,14 +71,21 @@ class _ExerciseNewPageState extends State with Trans, Logging { // ignore: close_sinks final bloc = BlocProvider.of(context); - if (bloc.exerciseRepository.exerciseType!.unitQuantityUnit == null) { + // ignore: close_sinks + final TutorialBloc tutorialBloc = BlocProvider.of(context); + if (tutorialBloc.actualCheck == "directTest") { args['exerciseRepository'] = bloc.exerciseRepository; Navigator.of(context).pushNamed('evaluationPage', arguments: args); - } else if (menuBloc.ability!.equalsTo(ExerciseAbility.oneRepMax)) { - args['exerciseRepository'] = bloc.exerciseRepository; - args['percent'] = 0.75; - args['readonly'] = false; - Navigator.of(context).pushNamed('exerciseControlPage', arguments: args); + } else { + if (bloc.exerciseRepository.exerciseType!.unitQuantityUnit == null) { + args['exerciseRepository'] = bloc.exerciseRepository; + Navigator.of(context).pushNamed('evaluationPage', arguments: args); + } else if (menuBloc.ability!.equalsTo(ExerciseAbility.oneRepMax)) { + args['exerciseRepository'] = bloc.exerciseRepository; + args['percent'] = 0.75; + args['readonly'] = false; + Navigator.of(context).pushNamed('exerciseControlPage', arguments: args); + } } } } @@ -99,25 +105,13 @@ class _ExerciseNewPageState extends State with Trans, Logging { Widget getExerciseSaveWidget(ExerciseNewBloc exerciseBloc, ExerciseType exerciseType, MenuBloc menuBloc) { if (exerciseBloc.exerciseRepository.exerciseType!.name == "BMR") { - if (Cache().userLoggedIn == null) { - exerciseBloc.add(ExerciseNewAddError(message: "Please log in")); - } else { - return BMR(exerciseBloc: exerciseBloc); - } + return BMR(exerciseBloc: exerciseBloc); } if (exerciseBloc.exerciseRepository.exerciseType!.name == "BMI") { - if (Cache().userLoggedIn == null) { - exerciseBloc.add(ExerciseNewAddError(message: "Please log in")); - } else { - return BMI(exerciseBloc: exerciseBloc); - } + return BMI(exerciseBloc: exerciseBloc); } if (exerciseBloc.exerciseRepository.exerciseType!.name == "Sizes") { - if (Cache().userLoggedIn == null) { - exerciseBloc.add(ExerciseNewAddError(message: "Please log in")); - } else { - return SizeWidget(exerciseBloc: exerciseBloc); - } + return SizeWidget(exerciseBloc: exerciseBloc); } return Scaffold( @@ -159,10 +153,10 @@ class _ExerciseNewPageState extends State with Trans, Logging { style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 12), ), ), - bottomNavigationBar: BottomBarMultipleExercises( + /* bottomNavigationBar: BottomBarMultipleExercises( isSet: false, exerciseTypeId: exerciseType.exerciseTypeId, - ), + ), */ ); } @@ -192,11 +186,11 @@ class _ExerciseNewPageState extends State with Trans, Logging { if (executeBloc != null && executeBloc.existsActivePlan() == true) { confirmationOverride(bloc); } else { - confirmationSave(bloc, menuBloc); + confirmationSave(bloc, menuBloc, tutorialBloc); } } - void confirmationSave(ExerciseNewBloc bloc, MenuBloc menuBloc) { + void confirmationSave(ExerciseNewBloc bloc, MenuBloc menuBloc, TutorialBloc tutorialBloc) { if (bloc.exerciseRepository.exercise!.quantity == null) { return; } @@ -251,7 +245,11 @@ class _ExerciseNewPageState extends State with Trans, Logging { onPressed: () { if (Cache().userLoggedIn == null) { Navigator.pop(context); - bloc.add(ExerciseNewAddError(message: "Please log in, because we can calculate the best suggestions for you")); + if (tutorialBloc.actualCheck == "directTest") { + bloc.add(ExerciseNewSubmitNoRegistration()); + } else { + bloc.add(ExerciseNewAddError(message: "Please log in, because we can calculate the best suggestions for you")); + } } else { saveAll(bloc); if (executeBloc.existsActivePlan() == true) { diff --git a/lib/view/login.dart b/lib/view/login.dart index ee6397e..2daa973 100644 --- a/lib/view/login.dart +++ b/lib/view/login.dart @@ -6,7 +6,7 @@ import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/dialog_common.dart'; -import 'package:aitrainer_app/widgets/dialog_long.dart'; +import 'package:aitrainer_app/widgets/dialog_web_browser.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -233,7 +233,7 @@ class LoginPage extends StatelessWidget with Trans { showDialog( context: context, builder: (BuildContext context) { - return DialogGDPR(); + return DialogWebBrowser(url: 'https://workouttest.com/privacy/', javascriptEnabled: true); }) }), ]), diff --git a/lib/view/mydevelopment_muscle_page.dart b/lib/view/mydevelopment_muscle_page.dart index 91b9eb0..f507bee 100644 --- a/lib/view/mydevelopment_muscle_page.dart +++ b/lib/view/mydevelopment_muscle_page.dart @@ -285,7 +285,6 @@ class _MyDevelopmentMuscleState extends State with Comm getTextStyles: (_) => TextStyle(fontSize: 8, color: Colors.blueGrey), getTitles: (double value) { var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt()); - //String strDate = DateFormat('MM.dd.', AppLanguage().appLocal.toString()).format(date); String strDate = getDatePart(date, bloc.dateRate); return strDate; }, @@ -293,7 +292,8 @@ class _MyDevelopmentMuscleState extends State with Comm leftTitles: SideTitles( showTitles: true, getTextStyles: (_) => TextStyle(fontSize: 8, color: Colors.blueGrey), - interval: bloc.listChartData[element.exerciseTypeId] == null + interval: bloc.listChartData[element.exerciseTypeId] == null || + bloc.listChartData[element.exerciseTypeId]!.interval == 0 ? 100 : bloc.listChartData[element.exerciseTypeId]!.interval, margin: 10, diff --git a/lib/view/registration.dart b/lib/view/registration.dart index 2e59dde..3c5be48 100644 --- a/lib/view/registration.dart +++ b/lib/view/registration.dart @@ -6,7 +6,7 @@ import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/dialog_common.dart'; -import 'package:aitrainer_app/widgets/dialog_long.dart'; +import 'package:aitrainer_app/widgets/dialog_web_browser.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -102,9 +102,9 @@ class RegistrationPage extends StatelessWidget with Trans { GestureDetector( onTap: () => loginBloc.add(LoginSkip()), child: Text( - t("Skip"), + t("I Execute My First Test Now"), textAlign: TextAlign.right, - style: GoogleFonts.inter(color: loginBloc.testColor, decoration: TextDecoration.underline), + style: GoogleFonts.inter(color: loginBloc.testColor, decoration: TextDecoration.underline, fontWeight: FontWeight.bold), )), SizedBox( height: 120, @@ -207,6 +207,16 @@ class RegistrationPage extends StatelessWidget with Trans { Divider( color: Colors.transparent, ), + ListTile( + leading: Icon( + Icons.check, + color: Colors.green, + ), + title: Text( + t("With the registration I accept the data policy and the terms of use."), + style: GoogleFonts.inter(color: Colors.indigo), + ), + ), Row(mainAxisAlignment: MainAxisAlignment.start, children: [ TextButton( key: LibraryKeys.loginOKButton, @@ -236,7 +246,20 @@ class RegistrationPage extends StatelessWidget with Trans { ), onTap: () => Navigator.of(context).pushNamed('login'), ), - Spacer(flex: 2), + Spacer(flex: 1), + InkWell( + child: Text( + t('Terms Of Use'), + style: GoogleFonts.inter(decoration: TextDecoration.underline), + ), + onTap: () => { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogWebBrowser(url: 'https://workouttest.com/terms-of-use/', javascriptEnabled: true); + }) + }), + Spacer(flex: 1), InkWell( child: Text( t('Privacy'), @@ -246,39 +269,11 @@ class RegistrationPage extends StatelessWidget with Trans { showDialog( context: context, builder: (BuildContext context) { - return DialogGDPR(); + return DialogWebBrowser(url: 'https://workouttest.com/privacy/', javascriptEnabled: true); }) }), ]), ])), ); } - - Widget getDataProtection(LoginBloc loginBloc) { - return CheckboxListTile( - title: Text(t("Please accept our data protection policy.")), - subtitle: Text(t("For more information please click on 'Privacy'")), - dense: true, - value: loginBloc.dataPolicyAllowed, - activeColor: Colors.indigo, - onChanged: (value) { - loginBloc.add(DataProtectionClicked(marked: value!)); - }, - controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox - ); - } - - Widget getEmailSubscription(LoginBloc loginBloc) { - return CheckboxListTile( - title: Text(t("Email notifications")), - subtitle: Text(t("We may ask you about your opinion, send events in email")), - dense: true, - value: loginBloc.emailSubscription, - activeColor: Colors.indigo, - onChanged: (value) { - loginBloc.add(EmailSubscriptionClicked(marked: value!)); - }, - controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox - ); - } } diff --git a/lib/view/sales_page.dart b/lib/view/sales_page.dart index 44caab2..fca40c8 100644 --- a/lib/view/sales_page.dart +++ b/lib/view/sales_page.dart @@ -232,7 +232,7 @@ class SalesPage extends StatelessWidget with Trans, Logging { }).toList(), ), - getTrialDescription(), + getTrialDescription(bloc), Html( data: bloc.premiumFunctions, //Optional parameters: @@ -297,22 +297,15 @@ class SalesPage extends StatelessWidget with Trans, Logging { style: GoogleFonts.inter(fontSize: 12, color: Colors.white), )), Divider(), - Container( - padding: EdgeInsets.only(left: 55, right: 55), - child: Text( - t("Account will be charged for renewal within 24 hours prior to the end of the current period"), - style: GoogleFonts.inter(fontSize: 12, color: Colors.white), - )), ])), ])); } - Widget getTrialDescription() { - final trialText = t("Try free for 3 days!"); + Widget getTrialDescription(SalesBloc bloc) { return Container( padding: EdgeInsets.only(left: 55, right: 55), child: Html( - data: "

" + trialText + "

", + data: bloc.trial, //Optional parameters: style: { "p": Style( @@ -329,9 +322,28 @@ class SalesPage extends StatelessWidget with Trans, Logging { ], ), "strong": Style( - color: Colors.yellow[600], + color: Colors.orange[600], fontSize: FontSize(13), ), + "h2": Style( + color: Colors.orange[600], + fontWeight: FontWeight.bold, + fontSize: FontSize(18), + textAlign: TextAlign.center, + textShadow: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + //padding: const EdgeInsets.all(4), + ), }, )); } diff --git a/lib/view/settings.dart b/lib/view/settings.dart index 385f3f9..ed807d5 100644 --- a/lib/view/settings.dart +++ b/lib/view/settings.dart @@ -10,6 +10,7 @@ import 'package:aitrainer_app/util/track.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; +import 'package:aitrainer_app/widgets/dialog_web_browser.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -157,7 +158,7 @@ class SettingsPage extends StatelessWidget with Trans { inactiveFgColor: Colors.grey[900], labels: [t('Basic Tutorial'), t('Activate')], onToggle: (index) { - ActivityDone activity = ActivityDone.tutorialBasic; + ActivityDone activity = ActivityDone.tutorialExecuteFirstTest; if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn!.sex == "m") { activity = ActivityDone.tutorialBasicChestPress; @@ -190,7 +191,11 @@ class SettingsPage extends StatelessWidget with Trans { ), onPressed: () => { Track().track(TrackingEvent.terms_of_use), - _launchInBrowser("https://workouttest.com/terms-of-use/"), + showDialog( + context: context, + builder: (BuildContext context) { + return DialogWebBrowser(url: 'https://workouttest.com/terms-of-use/', javascriptEnabled: true); + }) }, ), ); @@ -213,7 +218,11 @@ class SettingsPage extends StatelessWidget with Trans { ), onPressed: () => { Track().track(TrackingEvent.data_privacy), - _launchInBrowser("https://workouttest.com/privacy/"), + showDialog( + context: context, + builder: (BuildContext context) { + return DialogWebBrowser(url: 'https://workouttest.com/privacy/', javascriptEnabled: true); + }) }, ), ); @@ -242,18 +251,6 @@ class SettingsPage extends StatelessWidget with Trans { ); } - Future _launchInBrowser(String url) async { - if (await canLaunch(url)) { - await launch( - url, - forceSafariVC: false, - forceWebView: false, - ); - } else { - throw 'Could not launch $url'; - } - } - ListTile getVersion() { final String version = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : ""; return ListTile( diff --git a/lib/view/training_evaluation_page.dart b/lib/view/training_evaluation_page.dart new file mode 100644 index 0000000..f877126 --- /dev/null +++ b/lib/view/training_evaluation_page.dart @@ -0,0 +1,442 @@ +import 'dart:collection'; + +import 'package:aitrainer_app/bloc/training_evaluation/training_evaluation_bloc.dart'; +import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart'; +import 'package:aitrainer_app/library/custom_icon_icons.dart'; +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/exercise_plan_detail.dart'; +import 'package:aitrainer_app/model/training_evaluation_exercise.dart'; +import 'package:aitrainer_app/util/trans.dart'; +import 'package:aitrainer_app/widgets/app_bar_min.dart'; +import 'package:aitrainer_app/widgets/bottom_nav.dart'; +import 'package:aitrainer_app/widgets/menu_image.dart'; +import 'package:aitrainer_app/widgets/victory_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:timeline_tile/timeline_tile.dart'; + +// ignore: must_be_immutable +class TrainingEvaluationPage extends StatelessWidget with Trans { + TrainingEvaluationPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + setContext(context); + String imageUrl = ""; + if (Cache().userLoggedIn == null) { + imageUrl = 'asset/image/WT_Results_for_men.jpg'; + } else if (Cache().userLoggedIn!.sex == "m") { + imageUrl = 'asset/image/WT_Results_for_men.jpg'; + } else { + imageUrl = 'asset/image/WT_Results_for_female.jpg'; + } + final HashMap args = ModalRoute.of(context)!.settings.arguments as HashMap; + final TrainingPlanBloc trainingPlanBloc = args["bloc"]; + final dayName = args["day"]; + return Scaffold( + appBar: AppBarMin( + back: true, + ), + body: Container( + height: double.infinity, + width: double.infinity, + alignment: Alignment.center, + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage(imageUrl), + fit: BoxFit.cover, + alignment: Alignment.topCenter, + ), + ), + child: BlocProvider( + create: (context) => + TrainingEvaluationBloc(trainingPlanBloc: trainingPlanBloc, day: dayName)..add(TrainingEvaluationLoad()), + child: BlocConsumer(listener: (context, state) { + if (state is TrainingEvaluationError) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); + } else if (state is TrainingEvaluationVictoryReady) { + showDialog( + context: context, + barrierDismissible: true, + builder: (BuildContext context) { + return Victory( + victory: true, + ); + }); + } + }, builder: (context, state) { + final bloc = BlocProvider.of(context); + return ModalProgressHUD( + child: getEvaluationWidgets(bloc, dayName), + inAsyncCall: state is TrainingEvaluationLoading, + opacity: 0.5, + color: Colors.black54, + progressIndicator: CircularProgressIndicator(), + ); + }))), + bottomNavigationBar: BottomNavigator(bottomNavIndex: 0)); + } + + Widget getEvaluationWidgets(TrainingEvaluationBloc bloc, String dayName) { + return Container( + padding: EdgeInsets.only(left: 10, right: 10), + child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ + SliverAppBar( + pinned: true, + backgroundColor: Colors.transparent, + expandedHeight: 100.0, + collapsedHeight: 100, + toolbarHeight: 40, + automaticallyImplyLeading: false, + flexibleSpace: FlexibleSpaceBar( + title: Column(children: [ + Divider(), + Text(bloc.trainingPlanBloc.getMyPlan()!.name!, + textAlign: TextAlign.center, + maxLines: 4, + style: GoogleFonts.archivoBlack( + fontSize: 24, + color: Colors.orange[300], + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )), + Text(t("Training Summary"), + textAlign: TextAlign.center, + maxLines: 3, + style: GoogleFonts.archivoBlack( + fontSize: 20, + color: Colors.white, + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )), + ]), + ), + ), + + //getResultSummary(resultBloc), + SliverList( + delegate: SliverChildListDelegate([ + summaryRow("asset/image/pict_time_h.png", "Duration", bloc.duration + " " + t("mins")), + Divider(color: Colors.transparent), + summaryRow("asset/image/pict_weight_volumen_tonna.png", "Total Lift", bloc.totalLift + " " + t("kg")), + Divider(color: Colors.transparent), + summaryRow("asset/image/pict_hypertrophy.png", "Maximum Repeats", "${bloc.maxRepeats}" + " " + t("reps")), + Divider(color: Colors.transparent), + //summaryRow("asset/image/pict_reps_volumen_db.png", "Total Lift Ever", "100 kg"), + //Divider(color: Colors.transparent), + Text(t("Details"), + textAlign: TextAlign.center, + maxLines: 3, + style: GoogleFonts.archivoBlack( + fontSize: 20, + color: Colors.white, + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )), + ])), + SliverList( + delegate: SliverChildListDelegate( + getExerciseLists(bloc, dayName), + )) + ])); + } + + Widget summaryRow(String imageUrl, String title, String data) { + return Row( + children: [ + Image.asset( + imageUrl, + height: 40, + ), + SizedBox( + width: 10, + ), + Flexible( + fit: FlexFit.tight, + flex: 1, + child: Text(t(title), + textAlign: TextAlign.start, + maxLines: 2, + softWrap: true, + style: GoogleFonts.archivoBlack( + fontSize: 18, + color: Colors.orange[400], + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + ))), + SizedBox( + width: 10, + ), + Text(t(data), + textAlign: TextAlign.center, + maxLines: 2, + softWrap: true, + style: GoogleFonts.archivoBlack( + fontSize: 20, + color: Colors.white, + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )) + ], + ); + } + + List getExerciseLists(TrainingEvaluationBloc bloc, String dayName) { + List list = []; + bloc.evaluationList.forEach((element) { + list.add(ExerciseTile(bloc: bloc, exercise: element)); + }); + return list; + } +} + +// ignore: must_be_immutable +class ExerciseTile extends StatelessWidget with Trans { + final TrainingEvaluationBloc bloc; + final TrainingEvaluationExercise exercise; + + ExerciseTile({required this.bloc, required this.exercise}); + + Widget getIndicator(ExercisePlanDetailState state) { + if (state.equalsTo(ExercisePlanDetailState.inProgress)) { + return ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Container( + color: Colors.green, + child: Icon( + CustomIcon.calendar_2, + size: 28, + color: Colors.white, + ))); + } else if (state.equalsTo(ExercisePlanDetailState.finished)) { + return ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Container( + color: Colors.white, + child: Icon( + CustomIcon.ok_circled, + size: 40, + color: Colors.green, + ))); + } else if (state.equalsTo(ExercisePlanDetailState.skipped)) { + return ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Container( + color: Colors.white, + child: Icon( + CustomIcon.stop_1, + size: 40, + color: Colors.grey, + ))); + } else if (state.equalsTo(ExercisePlanDetailState.extra)) { + return ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Container( + color: Colors.white, + child: Icon( + CustomIcon.stopwatch_20, + size: 40, + color: Colors.blue[800], + ))); + } else { + return Image.asset( + "asset/image/pict_reps_volumen_db.png", + ); + } + } + + Widget build(BuildContext context) { + setContext(context); + bool hasWeight = exercise.type.equalsTo(TrainingEvaluationExerciseType.weightBased); + bool skipped = exercise.state.equalsTo(ExercisePlanDetailState.skipped); + + return Container( + color: Colors.transparent, + child: TimelineTile( + alignment: TimelineAlign.manual, + lineXY: 0.1, + beforeLineStyle: const LineStyle( + color: Color(0xffb4f500), + thickness: 6, + ), + afterLineStyle: const LineStyle( + color: Color(0xffb4f500), + thickness: 6, + ), + indicatorStyle: IndicatorStyle( + width: 40, + height: 40, + indicator: getIndicator(exercise.state), + ), + endChild: Container( + padding: EdgeInsets.only(left: 10), + child: Row(children: [ + Container( + width: 120, + height: 80, + child: MenuImage( + imageName: bloc.trainingPlanBloc.getActualImageName(exercise.exerciseTypeId), + workoutTreeId: bloc.trainingPlanBloc.getActualWorkoutTreeId(exercise.exerciseTypeId)!, + radius: 12, + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + children: [ + TextSpan( + text: exercise.name, + style: GoogleFonts.inter( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.orange[500], + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + )), + TextSpan(text: "\n"), + hasWeight + ? skipped + ? TextSpan( + text: t("skipped") + "!", + style: GoogleFonts.inter(fontSize: 12, color: Colors.grey[400], fontWeight: FontWeight.bold)) + : TextSpan( + text: t("One Rep Max") + ": ", + style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[400], fontWeight: FontWeight.bold)) + : TextSpan(), + hasWeight + ? skipped + ? TextSpan() + : TextSpan( + text: exercise.oneRepMax!.toStringAsFixed(0) + + " " + + t("kg") + + " (Max: " + + exercise.max1RM!.toStringAsFixed(0) + + " " + + t("kg") + + ")", + style: GoogleFonts.inter(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold)) + : TextSpan(), + TextSpan(text: "\n"), + hasWeight + ? skipped + ? TextSpan() + : TextSpan( + text: t("Total Lift") + ": ", + style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[400], fontWeight: FontWeight.bold)) + : TextSpan(), + hasWeight + ? skipped + ? TextSpan() + : TextSpan( + text: exercise.totalLift!.toStringAsFixed(0) + + " " + + t("kg") + + " (Max: " + + exercise.maxTotalLift!.toStringAsFixed(0) + + " " + + t("kg") + + ")", + style: GoogleFonts.inter(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold)) + : skipped + ? TextSpan() + : TextSpan( + text: exercise.repeats!.toStringAsFixed(0) + + " " + + t("reps") + + " (Max: " + + exercise.maxRepeats!.toStringAsFixed(0) + + " " + + t("reps") + + ")", + style: GoogleFonts.inter(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold)), + TextSpan(text: "\n"), + skipped + ? TextSpan() + : TextSpan( + text: t("Trend") + ": ", + style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[400], fontWeight: FontWeight.bold)), + skipped + ? TextSpan() + : TextSpan( + text: exercise.trendText, + style: GoogleFonts.inter(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold)), + ]), + )), + ]), + ), + ), + ); + } +} diff --git a/lib/view/training_plan_activate_page.dart b/lib/view/training_plan_activate_page.dart index 43d7021..be8ee66 100644 --- a/lib/view/training_plan_activate_page.dart +++ b/lib/view/training_plan_activate_page.dart @@ -93,12 +93,21 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans { List _getTreeChildren(TrainingPlanBloc bloc) { final List plans = bloc.trainingPlanRepository.getPlansByParent(parentName); - final String parentTitle = - bloc.trainingPlanRepository.parentTree != null ? bloc.trainingPlanRepository.parentTree!.nameTranslation : ""; - final String parentDescription = - bloc.trainingPlanRepository.parentTree != null && bloc.trainingPlanRepository.parentTree!.descriptionTranslation != null - ? bloc.trainingPlanRepository.parentTree!.descriptionTranslation! + String parentDescription = ""; + String parentTitle = ""; + if (bloc.trainingPlanRepository.parentTree != null) { + parentTitle = AppLanguage().appLocal.toString() == "en" + ? bloc.trainingPlanRepository.parentTree!.name + : bloc.trainingPlanRepository.parentTree!.nameTranslation; + + if (bloc.trainingPlanRepository.parentTree!.description != null) { + parentDescription = bloc.trainingPlanRepository.parentTree!.descriptionTranslation != null + ? AppLanguage().appLocal.toString() == "en" + ? bloc.trainingPlanRepository.parentTree!.description! + : bloc.trainingPlanRepository.parentTree!.descriptionTranslation! : ""; + } + } List listWidget = []; Card explanation = Card( @@ -237,7 +246,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans { ? Container( padding: EdgeInsets.only(bottom: 8), child: Text( - "Soon! Check back later for the plan details", + t("Soon! Check back later for the plan details"), style: GoogleFonts.inter( color: Colors.orange[800], shadows: [ diff --git a/lib/view/training_plan_execute_page.dart b/lib/view/training_plan_execute_page.dart index fb23b98..0f4bdb2 100644 --- a/lib/view/training_plan_execute_page.dart +++ b/lib/view/training_plan_execute_page.dart @@ -10,11 +10,11 @@ import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/dialog_common.dart'; import 'package:aitrainer_app/widgets/dialog_html.dart'; import 'package:aitrainer_app/widgets/menu_image.dart'; -import 'package:aitrainer_app/widgets/victory_widget.dart'; +import 'package:aitrainer_app/widgets/weight_control.dart'; import 'package:badges/badges.dart'; import 'package:extended_tabs/extended_tabs.dart'; -import 'package:ezanimation/ezanimation.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -33,6 +33,7 @@ class _TrainingPlanExecutePageState extends State with @override Widget build(BuildContext context) { + final HashMap args = HashMap(); bloc = BlocProvider.of(context); bloc!.activateDays(); setContext(context); @@ -52,15 +53,10 @@ class _TrainingPlanExecutePageState extends State with ScaffoldMessenger.of(context).showSnackBar( SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); } else if (state is TrainingPlanDayFinished) { - showDialog( - context: context, - barrierDismissible: true, - builder: (BuildContext context) { - return Victory( - victory: true, - ); - }); bloc!.celebrating = false; + args["bloc"] = bloc; + args["day"] = bloc!.dayNames[bloc!.activeDayIndex]; + Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args); } else if (state is TrainingPlanDayReadyToRestart) { if (!bloc!.celebrating) { showCupertinoDialog( @@ -100,9 +96,13 @@ class _TrainingPlanExecutePageState extends State with }), ), floatingActionButton: FloatingActionButton.extended( - onPressed: () => bloc!.getNext() != null - ? _ExerciseListState.executeExercise(bloc!, bloc!.getNext()!, context) - : Navigator.of(context).pushNamed('home'), + onPressed: () => { + args["bloc"] = bloc, + args["day"] = bloc!.dayNames[bloc!.activeDayIndex], + bloc!.getNext() != null + ? _ExerciseListState.executeExercise(bloc!, bloc!.getNext()!, context) + : Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args), + }, backgroundColor: Colors.orange[800], icon: Icon(CustomIcon.weight_hanging), label: Text( @@ -446,12 +446,14 @@ class _ExerciseListState extends State with Trans { bloc.getMyPlan()!.days[widget.dayName] != null && bloc.getMyPlan()!.days[widget.dayName]!.isNotEmpty) { bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) { - tiles.add(GestureDetector( + tiles.add( + /* GestureDetector( onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'), - child: ExerciseTile( - bloc: bloc, - detail: element, - ))); + child: */ + ExerciseTile( + bloc: bloc, + detail: element, + )); }); } @@ -507,23 +509,31 @@ class ExerciseTile extends StatefulWidget { } class _ExerciseTileState extends State with Trans { - final EzAnimation animation = EzAnimation(1.0, 30.0, Duration(seconds: 3), reverseCurve: Curves.easeIn); + GestureRecognizer? _tapRecognizer; @override void initState() { - animation.start(); - animation.addStatusListener((status) { - if (status == AnimationStatus.completed) {} - }); - + _tapRecognizer = TapGestureRecognizer()..onTap = _onPlusMinusWeight; super.initState(); } @override - bool didUpdateWidget(ExerciseTile oldWidget) { - super.didUpdateWidget(oldWidget); - Future.delayed(Duration(milliseconds: 400)).then((value) => animation.start()); - return true; + void dispose() { + if (_tapRecognizer != null) { + _tapRecognizer!.dispose(); + } + super.dispose(); + } + + void _onPlusMinusWeight() { + showDialog( + context: context, + builder: (BuildContext context) { + return WeightControl( + initialValue: widget.detail.weight != null ? widget.detail.weight! : 30, + onTap: (value) => widget.bloc.add(TrainingPlanWeightChangeRecalculate(detail: widget.detail, weight: value)), + ); + }); } Widget getIndicator(ExercisePlanDetailState state) { @@ -564,6 +574,16 @@ class _ExerciseTileState extends State with Trans { size: 40, color: Colors.grey, ))); + } else if (state.equalsTo(ExercisePlanDetailState.extra)) { + return ClipRRect( + borderRadius: BorderRadius.circular(24.0), + child: Container( + color: Colors.white, + child: Icon( + CustomIcon.stopwatch_20, + size: 40, + color: Colors.blue[800], + ))); } else { return Image.asset( "asset/image/pict_reps_volumen_db.png", @@ -574,7 +594,6 @@ class _ExerciseTileState extends State with Trans { @override Widget build(BuildContext context) { setContext(context); - print("detail ${widget.detail}"); final ExercisePlanDetailState state = widget.detail.state; final bool done = state.equalsTo(ExercisePlanDetailState.finished) || state.equalsTo(ExercisePlanDetailState.skipped); final String countSerie = widget.detail.set.toString(); @@ -582,13 +601,13 @@ class _ExerciseTileState extends State with Trans { String weight = widget.detail.weight != null ? widget.detail.weight!.toStringAsFixed(1) : "-"; bool isDrop = false; if (widget.detail.weight == -3) { - weight = t("DROP"); + weight = "DROP"; isDrop = true; } String restingTime = widget.detail.restingTime == null ? "" : widget.detail.restingTime!.toStringAsFixed(0); bool isTest = false; if (widget.detail.weight != null && widget.detail.weight! == -1) { - weight = t("TEST"); + weight = "TEST"; isTest = true; } String repeats = widget.detail.repeats!.toString(); @@ -741,11 +760,22 @@ class _ExerciseTileState extends State with Trans { : TextSpan(), widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise ? TextSpan( - text: weight, + text: t(weight), style: GoogleFonts.inter( fontSize: 12, )) : TextSpan(), + widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise && weight != "TEST" && weight != "DROP" + ? TextSpan( + text: " - +", + style: GoogleFonts.archivoBlack( + color: Colors.blue, + fontSize: 16, + ), + recognizer: _tapRecognizer, + mouseCursor: SystemMouseCursors.precise, + ) + : TextSpan(), TextSpan( text: "\n", ), @@ -796,21 +826,46 @@ class _ExerciseTileState extends State with Trans { ]), )), isTest - ? AnimatedBuilder( - animation: animation, - builder: (context, snapshot) { - return Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + ? Container( + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + GestureDetector( + onTap: () => showDialog( + context: context, + builder: (BuildContext context) { + return DialogCommon( + warning: false, + title: t("Why Test?"), + descriptions: t("This is your first exercise after at least 3 weeks."), + description2: + t("The first exercise will be a test. The following sets will be recalculated base on your test."), + description3: t("This is the most optimal way for your development"), + text: "OK", + onTap: () => Navigator.of(context).pop(), + onCancel: () => { + Navigator.of(context).pop(), + }, + ); + }), + child: Icon( + CustomIcon.question_circle, + color: Colors.yellowAccent[700], + size: 16, + )), + ])) + : isDrop + ? Container( + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () => showDialog( context: context, builder: (BuildContext context) { return DialogCommon( warning: false, - title: t("Why Test?"), - descriptions: t("This is your first exercise after at least 3 weeks."), + title: t("Drop Set"), + descriptions: t( + "Execute at least 3 sets with maximum repeats, without resting time, with decreasing the weight."), description2: - t("The first exercise will be a test. The following sets will be recalculated base on your test."), - description3: t("This is the most optimal way for your development"), + t("The goal is to completly exhaust your muscle without lifting a ridiculous weight end the end."), text: "OK", onTap: () => Navigator.of(context).pop(), onCancel: () => { @@ -820,39 +875,10 @@ class _ExerciseTileState extends State with Trans { }), child: Icon( CustomIcon.question_circle, - color: Colors.yellowAccent[700], + color: Colors.orange[200], size: 16, )), - ]); - }) - : isDrop - ? AnimatedBuilder( - animation: animation, - builder: (context, snapshot) { - return Column(mainAxisAlignment: MainAxisAlignment.center, children: [ - GestureDetector( - onTap: () => showDialog( - context: context, - builder: (BuildContext context) { - return DialogCommon( - warning: false, - title: t("Drop set"), - descriptions: t("Drop set"), - description2: t("Recommended method:"), - text: "OK", - onTap: () => Navigator.of(context).pop(), - onCancel: () => { - Navigator.of(context).pop(), - }, - ); - }), - child: Icon( - CustomIcon.question_circle, - color: Colors.orange[200], - size: 16, - )), - ]); - }) + ])) : Offstage() ]), ), diff --git a/lib/view/training_plan_exercise.dart b/lib/view/training_plan_exercise.dart index 4adfa5d..c8dba62 100644 --- a/lib/view/training_plan_exercise.dart +++ b/lib/view/training_plan_exercise.dart @@ -19,7 +19,7 @@ class TrainingPlanExercise extends StatelessWidget with Trans { final CustomerTrainingPlanDetails detail = args['customerTrainingPlanDetails']; // ignore: close_sinks final TrainingPlanBloc bloc = BlocProvider.of(context); - + final bool isDropSet = detail.weight == -3; setContext(context); return Scaffold( appBar: AppBarNav(depth: 1), @@ -75,7 +75,7 @@ class TrainingPlanExercise extends StatelessWidget with Trans { backgroundColor: Colors.orange[800], icon: Icon(CustomIcon.save), label: Text( - t("Save"), + isDropSet ? t("Done") : t("Save"), style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16), ), ), @@ -83,147 +83,100 @@ class TrainingPlanExercise extends StatelessWidget with Trans { } Widget getExercises(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail) { - final String noTestTextWithWeight = "Please try to execute this exercise with exact weight and repeats what is suggested"; - final String noTestTextNoWeight = "Please try to execute this exercise with exact repeats what is suggested"; - final String testMaxRepeats = "Please repeat as much times as you can! MAXIMIZE it!"; - final String testWeight = "Please take a relative bigger weight and at least 12 times and do your best! MAXIMIZE it!"; - return ExerciseSave( - exerciseName: detail.exerciseType!.nameTranslation, - exerciseDescription: detail.exerciseType!.descriptionTranslation, - exerciseTask: detail.exerciseType!.unitQuantityUnit != null - ? detail.weight == -1 - ? t(testWeight) - : detail.repeats == -1 - ? t(testMaxRepeats) - : t(noTestTextWithWeight) - : detail.repeats == -1 - ? t(testMaxRepeats) - : noTestTextNoWeight, - unit: detail.exerciseType!.unit, - unitQuantityUnit: detail.exerciseType!.unitQuantityUnit, - hasUnitQuantity: detail.exerciseType!.unitQuantityUnit != null, - weight: detail.weight == -1 ? 30 : detail.weight, - repeats: detail.repeats == -1 ? 99 : detail.repeats, - set: detail.set, - exerciseNr: detail.exercises.length + 1, - onUnitQuantityChanged: (value) => bloc.add(TrainingPlanWeightChange(weight: value, detail: detail)), - onQuantityChanged: (value) => bloc.add(TrainingPlanRepeatsChange(repeats: value.toInt(), detail: detail)), - exerciseTypeId: detail.exerciseType!.exerciseTypeId, - ); + int? originalQuantity = bloc.trainingPlanRepository.getOriginalRepeats(bloc.getMyPlan()!.trainingPlanId!, detail); + if (detail.weight != -3) { + return ExerciseSave( + exerciseName: detail.exerciseType!.nameTranslation, + exerciseDescription: detail.exerciseType!.descriptionTranslation, + exerciseTask: getExerciseTask(detail), + unit: detail.exerciseType!.unit, + unitQuantityUnit: detail.exerciseType!.unitQuantityUnit, + hasUnitQuantity: detail.exerciseType!.unitQuantityUnit != null, + weight: detail.weight == -1 ? 0 : detail.weight, + repeats: detail.repeats == -1 ? 99 : detail.repeats, + set: detail.set, + exerciseNr: detail.exercises.length + 1, + onUnitQuantityChanged: (value) => bloc.add(TrainingPlanWeightChange(weight: value, detail: detail)), + onQuantityChanged: (value) => bloc.add(TrainingPlanRepeatsChange(repeats: value.toInt(), detail: detail)), + exerciseTypeId: detail.exerciseType!.exerciseTypeId, + originalQuantity: originalQuantity, + ); + } else { + return getDropSet(bloc, detail); + } } - /* Widget getExerciseForm(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail) { + String getExerciseTask(CustomerTrainingPlanDetails detail) { + String desc = ""; + if (detail.exerciseType!.unit == "second") { + return desc; + } + if (detail.exerciseType!.unitQuantityUnit != null) { + if (detail.weight == -1) { + return "Please take a relative bigger weight and at least 12 times and do your best! MAXIMIZE it!"; + } else if (detail.repeats == -1) { + return "Please repeat as much times as you can! MAXIMIZE it!"; + } else { + return "Please try to execute this exercise with exact weight and repeats what is suggested"; + } + } else { + if (detail.repeats == -1) { + return "Please repeat as much times as you can! MAXIMIZE it!"; + } else { + return "Please try to execute this exercise with exact repeats what is suggested"; + } + } + } + + Widget getDropSet(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail) { return Container( - padding: const EdgeInsets.only(top: 10, left: 25, right: 25), - child: SingleChildScrollView( - scrollDirection: Axis.vertical, - child: Column( - children: [ - Text( - detail.exerciseType!.nameTranslation, - style: GoogleFonts.archivoBlack( - fontWeight: FontWeight.bold, - fontSize: 24, - color: Colors.white, - shadows: [ - Shadow( - offset: Offset(2.0, 2.0), - blurRadius: 6.0, - color: Colors.black54, - ), - Shadow( - offset: Offset(-3.0, 3.0), - blurRadius: 12.0, - color: Colors.black54, - ), - ], - ), - overflow: TextOverflow.fade, - textAlign: TextAlign.center, - maxLines: 2, - softWrap: true, - ), - Divider( - color: Colors.transparent, - ), - Divider(), - detail.weight != -1 ? numberPickForm(bloc, detail) : numberPickForm(bloc, detail), - ], - ))); - } - - Widget numberPickForm(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail) { - final String strTimes = detail.repeats!.toStringAsFixed(1); // : "maximum"; - - List listWidgets = [ - GestureDetector( - onTap: () => {}, - child: RichText( - text: TextSpan( - style: GoogleFonts.inter( - fontSize: 16, - fontWeight: FontWeight.normal, - color: Colors.yellow[300], - ), - children: [ - TextSpan(text: t("Please repeat with ")), - TextSpan( - text: detail.weight!.toStringAsFixed(1) + " " + detail.exerciseType!.unitQuantityUnit!, - style: GoogleFonts.inter( - decoration: TextDecoration.underline, - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.yellow[100], - ), - ), - TextSpan(text: t("hu_with") + " "), - TextSpan( - text: strTimes + " ", - style: GoogleFonts.inter( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.yellow[100], - )), - TextSpan( - text: t( - "times!", - )), - ]), - )), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NumberPickerWidget( - minValue: 0, - maxValue: 200, - initalValue: detail.repeats!, - unit: t("reps"), - color: Colors.yellow[50]!, - onChange: (value) => {}), - TextButton( - style: TextButton.styleFrom( - padding: EdgeInsets.all(0), - primary: Colors.white, - onSurface: Colors.blueAccent, - ), - onPressed: () => {}, - child: Stack( - alignment: Alignment.center, - children: [ - Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 60), - Text( - t("Save"), - style: TextStyle(fontSize: 16, color: Colors.white), - ), - ], - )), - ], + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("asset/image/drop_set.png"), + //fit: BoxFit.cover, + alignment: Alignment.center, + ), ), - ]; - - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: listWidgets, + padding: EdgeInsets.only(top: 20, left: 30), + child: RichText( + text: TextSpan( + style: GoogleFonts.inter( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Colors.yellow[300], + ), + children: [ + TextSpan( + text: t("Drop Set"), + style: GoogleFonts.inter( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.yellow[100], + ), + ), + TextSpan( + text: "\n", + ), + TextSpan( + text: "\n", + ), + TextSpan(text: t("Execute at least 3 sets with maximum repeats, without resting time, with decreasing the weight.")), + TextSpan( + text: "\n", + ), + TextSpan( + text: "\n", + ), + TextSpan( + text: t("The goal is to completly exhaust your muscle without lifting a ridiculous weight end the end."), + style: GoogleFonts.inter( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.yellow[100], + ), + ), + ], + )), ); - } */ + } } diff --git a/lib/view/training_plans_page.dart b/lib/view/training_plans_page.dart index 1216a3f..90436f3 100644 --- a/lib/view/training_plans_page.dart +++ b/lib/view/training_plans_page.dart @@ -3,6 +3,7 @@ import 'dart:collection'; import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart'; import 'package:aitrainer_app/model/cache.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/widgets/app_bar.dart'; @@ -112,7 +113,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging { left: 5, textColor: color, onTap: () { - // if (Cache().userLoggedIn != null) { + Track().track(TrackingEvent.training_plan_open, eventValue: route); if (route == "myTrainingPlanActivate") { HashMap args = HashMap(); args['parentName'] = parentName; @@ -142,7 +143,6 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging { } else { Navigator.of(context).pushNamed(route); } - // } }, isLocked: false, ); diff --git a/lib/widgets/bmi_widget.dart b/lib/widgets/bmi_widget.dart index e12b60f..644ea5a 100644 --- a/lib/widgets/bmi_widget.dart +++ b/lib/widgets/bmi_widget.dart @@ -292,7 +292,9 @@ class _BMIState extends State with Trans { } Widget getHeightInput() { - if (widget.exerciseBloc.customerRepository.customer!.birthYear! < 2003) { + int birthYear = widget.exerciseBloc.birthYear != null ? widget.exerciseBloc.birthYear! : 0; + double height = widget.exerciseBloc.height != null ? widget.exerciseBloc.height! : 0; + if (birthYear < 2003) { return Flexible( child: TextFormField( focusNode: _nodeText2, @@ -308,7 +310,7 @@ class _BMIState extends State with Trans { borderSide: BorderSide(color: Colors.white12, width: 0.4), ), ), - initialValue: widget.exerciseBloc.height.toStringAsFixed(0), + initialValue: height.toStringAsFixed(0), keyboardType: TextInputType.numberWithOptions(decimal: false), textInputAction: TextInputAction.done, style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), @@ -327,6 +329,7 @@ class _BMIState extends State with Trans { } Widget getWeightInput() { + double weight = widget.exerciseBloc.weight != null ? widget.exerciseBloc.weight! : 0; return Container( padding: EdgeInsets.only(top: 15, left: 65, right: 65, bottom: 10), alignment: Alignment.center, @@ -338,50 +341,7 @@ class _BMIState extends State with Trans { width: 10, ), Flexible( - child: - /* SfLinearGauge( - minimum: widget.exerciseBloc.weight > 0 ? (widget.exerciseBloc.weight - 10).floor().toDouble() : 40, - maximum: widget.exerciseBloc.weight > 0 ? (widget.exerciseBloc.weight + 10).ceil().toDouble() : 150, - labelPosition: LinearLabelPosition.outside, - tickPosition: LinearElementPosition.outside, - markerPointers: [ - LinearWidgetPointer( - value: widget.exerciseBloc.weight, - offset: 5, - position: LinearElementPosition.outside, - markerAlignment: LinearMarkerAlignment.center, - child: Container( - height: 14, - width: 44, - color: Colors.transparent, - child: Text(widget.exerciseBloc.weight.toStringAsFixed(1), - style: GoogleFonts.inter( - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.white, - )), - ), - ), - LinearShapePointer( - position: LinearElementPosition.inside, - shapeType: LinearShapePointerType.triangle, - value: widget.exerciseBloc.weight, - height: 45, - width: 20, - color: Colors.yellow[200], - onValueChanged: (value) => {widget.exerciseBloc.add(ExerciseNewWeightChange(value: value))}, - ), - ], - orientation: LinearGaugeOrientation.horizontal, - majorTickStyle: LinearTickStyle(length: 20, color: Colors.yellow[50]), - axisLabelStyle: TextStyle(fontSize: 12.0, color: Colors.yellow[50]), - axisTrackStyle: LinearAxisTrackStyle( - color: Colors.cyan, - edgeStyle: LinearEdgeStyle.bothFlat, - thickness: 1.0, - borderColor: Colors - .grey)), */ - TextFormField( + child: TextFormField( focusNode: _nodeText1, decoration: InputDecoration( contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5), @@ -395,7 +355,7 @@ class _BMIState extends State with Trans { borderSide: BorderSide(color: Colors.white12, width: 0.4), ), ), - initialValue: widget.exerciseBloc.weight.toStringAsFixed(1), + initialValue: weight.toStringAsFixed(1), keyboardType: TextInputType.numberWithOptions(decimal: true), textInputAction: TextInputAction.done, style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), diff --git a/lib/widgets/bmr_widget.dart b/lib/widgets/bmr_widget.dart index dc28516..3246869 100644 --- a/lib/widgets/bmr_widget.dart +++ b/lib/widgets/bmr_widget.dart @@ -1,5 +1,4 @@ import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart'; -//import 'package:aitrainer_app/library/dropdown_search.dart'; import 'package:aitrainer_app/util/app_localization.dart'; import 'package:aitrainer_app/model/fitness_state.dart'; import 'package:aitrainer_app/util/trans.dart'; @@ -196,7 +195,12 @@ class _BMRState extends State with Trans { } Widget getHeightInput() { - if (widget.exerciseBloc.customerRepository.customer!.birthYear! < 2003) { + int birthYear = + widget.exerciseBloc.customerRepository.customer != null && widget.exerciseBloc.customerRepository.customer!.birthYear != null + ? widget.exerciseBloc.customerRepository.customer!.birthYear! + : 0; + double height = widget.exerciseBloc.height != null ? widget.exerciseBloc.height! : 0; + if (birthYear < 2003) { return Flexible( child: TextFormField( focusNode: _nodeText2, @@ -212,7 +216,7 @@ class _BMRState extends State with Trans { borderSide: BorderSide(color: Colors.white12, width: 0.4), ), ), - initialValue: widget.exerciseBloc.height.toStringAsFixed(0), + initialValue: height.toStringAsFixed(0), keyboardType: TextInputType.numberWithOptions(decimal: false), textInputAction: TextInputAction.done, style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), @@ -231,6 +235,7 @@ class _BMRState extends State with Trans { } Widget getBirthyearInput() { + int birthYear = widget.exerciseBloc.birthYear != null ? widget.exerciseBloc.birthYear! : 0; return Flexible( child: TextFormField( focusNode: _nodeText3, @@ -246,7 +251,7 @@ class _BMRState extends State with Trans { borderSide: BorderSide(color: Colors.white12, width: 0.4), ), ), - initialValue: widget.exerciseBloc.birthYear.toStringAsFixed(0), + initialValue: birthYear.toStringAsFixed(0), keyboardType: TextInputType.numberWithOptions(decimal: false), textInputAction: TextInputAction.done, style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), @@ -261,7 +266,10 @@ class _BMRState extends State with Trans { } Widget getFitnessLevel() { - String fitnessLevel = widget.exerciseBloc.fitnessLevel; + String? fitnessLevel = widget.exerciseBloc.fitnessLevel; + if (fitnessLevel == null) { + return Container(); + } return Container( padding: EdgeInsets.only(left: 65, right: 65), child: DropdownSearch( @@ -281,9 +289,9 @@ class _BMRState extends State with Trans { compareFn: (FitnessState i, FitnessState s) => i.isEqual(s), showSelectedItem: true, selectedItem: FitnessItem().getItem(fitnessLevel), - itemAsString: (data) => t(data.stateText), + itemAsString: (data) => t(data!.stateText), onChanged: (data) { - widget.exerciseBloc.add(ExerciseNewFitnessLevelChange(value: data.value)); + widget.exerciseBloc.add(ExerciseNewFitnessLevelChange(value: data!.value)); }, dropdownBuilder: _customDropDownItem, popupItemBuilder: _customMenuBuilder, @@ -296,8 +304,8 @@ class _BMRState extends State with Trans { //items: FitnessItem().toList())); } - Widget _customMenuBuilder(BuildContext context, FitnessState item, bool isSelected) { - bool selected = item.value == widget.exerciseBloc.fitnessLevel; + Widget _customMenuBuilder(BuildContext context, FitnessState? item, bool isSelected) { + bool selected = item!.value == widget.exerciseBloc.fitnessLevel; return Container( decoration: !selected ? BoxDecoration(color: Colors.black54) @@ -345,6 +353,7 @@ class _BMRState extends State with Trans { } Widget getWeightInput() { + double weight = widget.exerciseBloc.weight != null ? widget.exerciseBloc.weight! : 0; return Container( padding: EdgeInsets.only(top: 15, left: 35, right: 35, bottom: 10), alignment: Alignment.center, @@ -374,7 +383,7 @@ class _BMRState extends State with Trans { borderSide: BorderSide(color: Colors.white12, width: 0.4), ), ), - initialValue: widget.exerciseBloc.weight.toStringAsFixed(1), + initialValue: weight.toStringAsFixed(1), keyboardType: TextInputType.numberWithOptions(decimal: true), textInputAction: TextInputAction.done, style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.yellow[300]), diff --git a/lib/widgets/dialog_long.dart b/lib/widgets/dialog_long.dart deleted file mode 100644 index 576974c..0000000 --- a/lib/widgets/dialog_long.dart +++ /dev/null @@ -1,403 +0,0 @@ -import 'package:aitrainer_app/util/trans.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_html/flutter_html.dart'; -import 'package:flutter_html/style.dart'; -import 'package:google_fonts/google_fonts.dart'; - -// ignore: must_be_immutable -class DialogGDPR extends StatefulWidget { - DialogGDPR({Key? key}) : super(key: key); - - @override - _DialogPremiumState createState() { - return _DialogPremiumState(); - } -} - -const htmlData = """ - -

WorkoutTest Data Policy

-

Principle of anonymous data use

-In principle, our website can be used without providing personal data. The use of individual services and offers (Workout Test app, workouttest.com website) on our website and in our apps can entail divergent regulations which in this case are explained separately below. The legal basis for data protection can be found in the General Data Protection Regulation (GDPR). - -When you access our website or Apps, some information, such as IP address, is transferred. You are also providing information about the end device used (computer, smartphone, tablet etc.), the browser used (Internet Explorer, Safari, Firefox etc.), time of visit to the website, the so-called referrer and volume of data transferred. - -We cannot use this data to identify an individual user. We only use this information to determine how attractive our offers are and to improve their performance or content, if necessary, and make their design even more appealing to you. - -Please bear in mind, however, that in the case of a static - -IP address, personal identification is possible by RIPE query in individual cases, although we do not perform this. Nevertheless, this website is accessible for both static and dynamic IP addresses assigned. - -  -

Collection and processing of personal data

-We only collect personal data if you provide it to us, for example when you contact us, in particular by registering a Workout Test account, placing an order, requesting information or publishing personal data in our Workout Test in your profile or in the feed. - -We use the personal data you provide only to the extent that your data is necessary for rendering or processing our services. - -We store your data for as long as is necessary to achieve the intended purpose or until you delete your account or for as long as legal retention periods require data to be stored. Your data is subsequently deleted in accordance with legal requirements or processing is restricted. - -In the case of use purely for information, i.e. if you do not register or send us information another way, we only collect personal data which your browser transfers to our servers. If you want to view our website, we collect the following data, which we require for technical purposes in order to show you our content and guarantee stability and security (legal basis is a legitimate interest pursuant to Article 6 (1) (f) GDPR). - -In the context of the balance of interests in accordance with Article 6 (1) (f) GDPR, we have considered and weighed our interest in website and app provisioning and your interest in data protection compliant processing of your personal data. As the data below is technically required for the provision of our service in order to offer you our services and also guarantee stability and security, in particular protection against misuse, we have reached the conclusion that, with a state-of-the-art oriented data security guarantee, this data can be processed whereby appropriate consideration will be given to your interest in data protection compliant processing. - -  - -The collection of data for website provision and the storage of data in log files is imperative for website and operation. Consequently, users may not object to this. -

Registering a Workout Test Account

-Using our login system, you can create a Workout Test account for yourself that you can use to log in to all of our services (Workout Test, Workouttest.com). In the process, we use cookies – small files – on your browser in order to identify you. All data that you save to your account is stored at a database at the server of Contabo GmbH. Some of our services are only accessible if you have set up your Workout Test account. This includes Workout Test app. We will request the following data when registering (some of it is required). In addition, you must take note of our Data Protection Statement, as well as accept our General Terms and Conditions of Business and Withdrawal Policy. - -  -

Registering with Facebook or Google

-We also offer you the opportunity to create your Workout Test account using your Facebook or Google account, or to link your Workout Test account to your Facebook or Google account. You can register or log in to Workout Test using your Facebook or Google account if you simply use Facebook or Google instead of the other options while registering your Workout Test account. You will then be forwarded to Facebook or Google (where you must be logged in or require an account) and receive an explanation of which of your data we need from Facebook or Google, namely your public profile information such as first and last name, gender, and the email address you are using there. This information is required for identification purposes in order to create a secure Workout Test account for you. When you log in using your Facebook account, this allows us to show you which of your friends are already with Workout Test. Your Facebook or Google account and your Workout Test account will be permanently linked using your email address. We store your email information in-house and will send you information using this address as needed. We can also tell that you have logged in using Facebook or Google. As soon as you log in to Facebook or Google, you can log in to Workout Test. We will not submit any information on you to Facebook or Google without your consent. - -Important: We do not record your Facebook or Google login data in any way, and cannot post anything to your Facebook or Google profile without your having expressly consented to this. - -You can learn how Facebook handles privacy settings using Facebook's privacy policy and terms of use; these also include the applicable conditions for the previously specified option of logging in and registering to Workout Test. You can learn how Google handles privacy settings using Google's privacy policy and terms of use; these also include the applicable conditions for the previously specified option of logging in and registering to Workout Test. - -  -

Data collection, processing and use in the context of Workout Test Service

-

Community Profile

-You need a Workout Test account in order to use our Workout Test Apps. The data collected for this purpose has already been explained above. To provide you with the best Workout Test experience possible, our approach is partly based on publishing specific information relating to our users within the Workout Test community, i.e. even your information. We are going to introduce our program to you in more detail below so that you can decide for yourself whether and which data you want to publish. This introduction includes the following data in particular which is visible to other users: -
    -
  • public profile (photo, first name, surname, nickname, weight, height, personal measurement data, training location, motivation, Workout Test level)
  • -
  • fitness (progress, desired objective, skills)
  • -
  • training information (duration and type of training unit, total number of training sessions, notes, photo)
  • -
  • social media profile (Facebook, Twitter, Instagram)
  • -
  • food intake (meal type, notes, photo)
  • -
  • followed by/follows (persons who follow the user, persons followed by the user)
  • -
-You become visible in Workout Test Apps with the data in your public profile. This information helps other users to find you in Workout Test Apps. At the same time, other users can see your name and surname (if provided), your training location, your motivation and your profile photo and they can recognize you using this information if necessary. You have already agreed under our General Terms and Conditions of Business that upon beginning your Workout Test journey and provided that you make no changes to your privacy settings, all Workout Test users will be able to view your profile, your training data, your posts, your training spots, etc., without special consent. This is designed to make it easier to follow you and/or support you during your journey with comments and motivation. If you do not want this anymore, you can set your privacy settings to ‘private’ at any time, which only allows select athletes to access the information referred to above. - -Workout Test Apps save all your successfully completed training units or the meals you have consumed as well as related information such as self- uploaded photos or notes. Other users can see this data and can consider them as an incentive for themselves, leave comments or decide whether they want to follow you. - -Moreover, our Workout Test Apps also provide users with the option to be followed (‘followed by’) to support or encourage them in their training experiences, or to compete with one another. For this purpose, users can be searched for by the name registered in the public profile or, after linking a Workout Test account to a Facebook account, via their Friends list. You will be notified about new followers in the mobile app and by push notification where applicable. - -Consequently, some of your information is available to other users in Workout Test Apps. Our aim is that nobody is left alone with their training. Instead, users’ performance is appreciated and can become an incentive for new members. - -If you do not want to make it possible to link your performance to yourself, you are free to refrain from providing any personal data on your profile or training sessions and linking your account to Facebook. Moreover, you should not save any training photos or enter any notes in this case. For this reason, we have ensured that each user can change their personal information, which can be viewed by other users, and each user is free to use their own name or a fictitious name in their Workout Test Apps. - -  -

Analysis of location data

-Within the framework of our Workout Test Apps, in particular, Workout Test Running and Workout Test Training, it is possible to map runs. For this purpose, we need access to location data. This data allows us to calculate distances covered at the relevant time and thereby correctly determine the end for predefined distances or determine distances covered. - -Based on your location, you can also find training spots and users near you, as well as adjust your training plan to your current environment. At training spots, you can check-in after your workout and show the other users in your community where you exercised. To determine the parts of the world in which most users are based, we perform a statistical analysis of your location data. If you edit your saved training, you can remove the selected training spot later and therefore withdraw your consent. - -  -

Access rights

-We require these access options and information to ensure the technical function of our app and to provide the services offered with the app, in particular, to access your camera or your photos, to determine your running distances and your activity calories or to send you push-notifications to inform you about new followers or comments. During the installation procedure or before you use the app for the first time, we request permission to access individual functions and information. We will only access these functions with your approval. You can revoke access rights manually in the settings for each operating system. You can find out how this works in the manufacturer instructions for your mobile OS. However, please note that you can only use the app to a limited extent or you cannot use it at all without the relevant approval. - -Before you either use the app for the first time or use a function for the first time, we ask the user for the permissions for the purpose described below: - -  -

Contact form

-You have the option of contacting us via our e-mail address or the contact form. - -We will, of course, use the personal data transmitted to us only for the purpose for which you make it available by contacting us. - -The legal basis is in this respect our legitimate interest in accordance with Art. 6 para. 1 sent. 1(f) of the GDPR. If the aim of your request is to conclude a contract (e.g., purchasing a subscription), the legal basis for the processing of the communicated data is also the necessity for providing (pre-) contractual services, in accordance with Art. 6 para. 1 sent. 1(b) of the GDPR. - -If we request entries in our contact form that are required for establishing contact, we have marked them as compulsory (*). Any information without an asterisk is optional. We use this information to put your request into specific terms and handle your concern more effectively. Providing this information is entirely voluntary and with your consent. If the information in question refers to communication channels (for example, e-mail address or phone number), you also give consent for us to contact you via these communication channels to respond to your concern. - -You can, of course, withdraw your declarations of consent at any time with future effect. If you wish to withdraw your consent, please contact the office indicated at the end of this declaration. - -  -

Push notifications as part of the user experience

-We require your consent if you wish to receive our push notifications on your mobile iOS device even if the app is not open. Our app only uses push notifications if you have given your explicit consent to these. You can disable push notifications in settings at any time. If you use an Android device, push notifications are permitted automatically unless you disable this in your settings. - -  - -  -

Push notifications for marketing purposes

-We require your consent if you wish to receive our push notifications for marketing purposes on your mobile iOS device even if the app is not open. Our app only uses push notifications for marketing purposes if you have given your explicit consent to these. You can disable push-notifications in settings at any time. If you use an Android device, push notifications are permitted automatically unless you disable this in your settings. - -  -

Apple Health Kit

-We use the HealthKit framework from Apple (Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, USA; “Apple”), which provides a central storage location for health and fitness data on the iPhone or Apple Watch and – with the express consent of the user – allows apps to communicate with the HealthKit store in order to access and share these data. - -With your express approval, we will process your heart rate (where appropriate) as well as information about your workout (start and end of training (date)), training duration, type of training, indoor or outdoor), which is obtained through the HealthKit framework in order to track and display your health and fitness activities. - -If you activate the HealthKit framework in your iPhone’s or Apple Watch settings, Workout Test is able to send, with your approval, the calories burned by the activity, route (walking and running), as well as your workouts (start and end of training [date], training duration, type of training, indoor or outdoor) to Apple, so that you can track and display your health and fitness activity. - -New data attributes can be added to the HealthKit framework, which are then displayed in the product and must be approved. You can prevent Apple from accessing your data at any time, and thus prevent it from being shared, by changing your mobile device settings. You can find more information about HealthKit here: [https://developer.apple.com/documentation/healthkit] https://developer.apple.com/documentation/healthkit - -  -

Google Fit

-We use Google Fit from Google (Google Ireland Limited, Gordon House, Barrow Street, Dublin 4, Ireland; “Google”), which provides a central storage location for health and fitness data on your Android phone and – with the express consent of the user – allows apps to communicate with Google Fit in order to access and share these data. - -With your express approval, we will send information about your workout (start and end of training (date), training duration, type of training, and name of the workout) to Google Fit, so that you can track and display your health and fitness activity. New data attributes can be added to Google Fit, which is then displayed in the product and must be approved. - -You can prevent Google from accessing your data at any time, and thus prevent it from being shared, by changing your mobile device settings. You can find more information about Google Fit here. - -  -

Cookies, tracking pixels and similar technologies

-To improve our web service and make your experience as comfortable as possible, we use cookies, tracking pixels, or similar technologies. Cookies are small text files saved on your computer when you visit our website. They help us recognize your browser as yours. Cookies save information such as your language settings or the duration of your visit to our website. They save data entries you make on the website, like when you log in, so you don’t need to enter your data each time you use our services. Cookies help us to recognize your preferences and adjust our website to your areas of interest. - -Every time our website loads, we record how often it is visited and clicked on by using tags on our website called tracking pixels. These tracking pixels do not interfere with your computer. - -Most browsers accept cookies automatically. If you want to prevent cookies from being saved, you can select the - -‘Accept no cookies’ option in your browser settings. To find out exactly how this works, you can consult your browser manufacturer’s instructions. You can delete cookies that have already been saved on your computer at any time. To find out exactly how this works, you can consult your browser manufacturer’s instructions. If you want to prevent performance cookies and advertising cookies from being saved, you can change your cookie preferences at any time by changing your cookie settings above. - -We use cookies and tracking pixels for different purposes, which also means they have different legal bases and storage periods. You will find more information about that in the following sections: -

Required and functional cookies

-Some cookies are required for the site to function and cannot be disabled. Without these cookies, you will not be able to view our site properly. We also use functional cookies, which help us to improve our website performance. - -- Analytical tools are used to analyze data based on your browser behaviour in order to improve the functionality and design of our site. - -- Quality assurance tools are used to measure errors presented on a website, to make sure we fix bugs or any issues promptly. - -- A/B testing tools or multivariate testing tools are used to ensure a consistent design of the website and a consistent user experience in the current and subsequent sessions. - -The legal basis is in this respect our legitimate interest in accordance with Art. 6 para. 1 sent. 1(f) GDPR -

Performance Cookies and Advertising Cookies

-These cookies allow us to analyze site usage so we can measure and improve performance. They are also used by advertising companies to serve ads that are relevant to your interests. These cookies contain a unique key to distinguish individual users’ browsing habits. We also use these cookies to limit the number of times a user sees a particular ad on a website and to measure the effectiveness of a particular campaign. The identifier stored by these cookies is provided by our partners. We cannot use the same identifier in our own systems. - -If you want to prevent performance cookies and advertising cookies from being saved, you can change your cookie preferences at any time by changing your cookie settings above. - -The legal basis for performance cookies and advertising cookies is consent in accordance with Art. 6 para. 1 sent. 1(a) GDPR. Obviously, you can withdraw your declarations of consent for the future at any time. If you no longer agree to us providing your data to the service providers mentioned in our privacy policy, you can opt- out in the cookie settings on our website or within your profile settings. - -Please note: it is possible that you can still see advertisements from Workout Test on third-party platforms even if you do not choose this functionality, but these advertisements are at random and won’t be personalized. -

Google Analytics

-We use the Google Analytics service from Google Ireland Limited (Gordon House, Barrow Street, Dublin 4, Ireland) to analyze our website visitors. Google uses cookies to track the use of the online product or service by users and the information is generally transferred to a Google server in the USA and stored there. - -Google will use this information on our behalf to evaluate the use of our online products and services by users, to compile reports on the activities within these online products and services and to provide us with further services associated with the use of these online products and services and the use of the internet. Pseudonymous user profiles can be created from the processed data. - -We use Google Analytics only with IP anonymization enabled. This means that Google will truncate the IP address of users within Member States of the European Union or in other states that are party to the Agreement - -on the European Economic Area. Only in exceptional cases will the full IP address be transmitted to a Google server in the USA and truncated there. The IP address transmitted by the user’s browser is not merged with other Google data. Users can prevent cookies from being stored by adjusting the settings to their browser software accordingly. We have made data protection friendly default settings. - -The legal basis for the use of this service is Art. 6 paragraph 1 sentence 1 letter f GDPR. Users can prevent the collection of data generated by cookies by downloading and installing the browser plug-in that is available here. As a guarantee pursuant of Art. 44ff of the General Data Protection Regulation (GDPR), Google has signed the EU standard contractual clauses. - -If you do not wish to be tracked by Google Analytics in the future, you can opt out at any time by writing an email to service@workouttest.com. -

-

Flurry

-We use Flurry (360 3rd Street, Suite 750, San Francisco, CA 94107, US) within our app in order to analyze your app usage behaviour. When you visit our website or app the information listed below is collected and analyzed by Flurry, which uses an identifier (ID) that allows analysis of your use of our services. - -On behalf of us, Flurry will use this information to evaluate your use of the app and to compile reports on the use of the website. This information may be used by us, if activated by you, to send you specific information (so-called push notifications or in-app messages) about Workout Test services or specific advertising. If you do not want to receive any in-app messages, please contact service@workouttest.com. For further information about push-notifications, see here. - -If Flurry transfers personal data to the USA, it does so on the basis of an agreement with the EU standard contractual clauses. The legal basis is Art. 6 para. 1 lit. f) DSGVO. If you do not wish to be tracked by Flurry in the future, you can opt-out at any time by writing an email to service@workouttest.com. - -  -

Google Marketing Services

-On our apps we use the marketing and re-marketing services of Google Ireland Limited (Gordon House, Barrow Street, Dublin 4, Ireland) that allow us to display advertisements in a more targeted manner in order to present advertisements of interest to users. Through (re- )marketing ads and products are displayed to users relating to an interest established by activity on other apps within the Google Network. For these purposes, a code is used by Google when our app is accessed and what are referred to as (re-)marketing tags are incorporated into the app. With their help, an individual cookie, i.e. a small file, is stored on the user’s device (comparable technologies may also be used instead of cookies). Cookies can be set by various domains. This file records which apps users have visited, which content they are interested in and which offers have been used. In addition, technical information about the browser and operating system, referring apps, the length of the visit as well as any additional data about the use of the online products and services are stored. The IP address of users is also recorded, although we would like inform you that within the framework of Google Analytics, IP addresses within Member States of the European Union or in other contracting states to the Agreement on the European Economic Area are truncated. - -All user data will only be processed as pseudonymous data. Google does not store any names or email addresses. All displayed ads are therefore not displayed specifically for a person, but for the owner of the cookie. This information is collected by Google and transmitted to and stored by servers in the USA. - -One of the Google marketing services we use is the online advertising program Google AdWords. In the case of Google AdWords, each AdWords customer receives a - -different conversion cookie. Cookies can therefore not be tracked through the apps of AdWords customers. The information collected by the cookie is used to generate conversion statistics for AdWords customers who have opted for conversion tracking. AdWords customers see the total number of users who clicked on their ad and were redirected to a page with a conversion tracking tag. However, they will not receive any information that personally identifies users. - -We may include third-party advertisements based on the Google Marketing Service called DoubleClick. DoubleClick uses cookies to enable Google and its partner apps to place ads based on users’ visits to this app or other apps on the Internet. - -Google services make use of Google’s Tag Manager. For more information about Google’s use of data for marketing purposes, please see the summary page, Google’s privacy policy is available here. - -The legal basis for the use of this service is Article Art. 6 paragraph 1 sentence 1 letter f GDPR. If you wish to object to interest-based advertising by Google marketing services, you can do so using the settings and opt-out options provided by Google. As a guarantee pursuant of Art. 44ff of the General Data Protection Regulation (GDPR), Google has signed the EU standard contractual clauses. - -There is another Google service we use called Google Audience, that allows us to show targeted messages to users within the Google Network (such as Gmail, YouTube, Google Feed, etc.). For this, we may provide Google with a customer list that includes the email address or other data such as the device ID you provide to us when you register. This allows Google to create a profile about your usage patterns in our app and on our website in order to display advertisements in a more targeted manner in order to present Workout Test advertisements of interest to users on other apps and websites within the Google Network. Please find more information about the Google Personalized Advertising Service here: https://support.google.com/adspolicy/answer/143465? hl=en - -The legal basis for our processing is Art. 6 Para. 1 Sentence 1 Letter a GDPR. We only actively provide Google with customer lists that include your email address or other personal data with your consent. Obviously, you can withdraw your declarations of consent for the future at any time. If you no longer agree to us providing your data to Google, you can opt-out in our app-settings. It is possible, that you can then still see advertisements from Workout Test even if you withdrew your consent or did not consent in the first place, but these advertisements on third party platforms are at random - -  -

Facebook Marketing Services

-We use the “visitor action pixels” from Facebook Inc. (Menlo Park, California) on our website so that user behavior can be tracked after users have been redirected to the provider’s website by clicking on a Facebook ad. This enables us to measure the effectiveness of Facebook ads for statistical and market research purposes. The data collected in this way is anonymous to us, i.e. we do not see the personal data of individual users. However, this data is stored and processed by Facebook, which is why we are informing you, based on our knowledge of the situation. Facebook may link this information to your Facebook account and also use it for its own promotional purposes, in accordance with Facebook’s Data Usage Policy. You can allow Facebook and its partners to place ads on and off Facebook. A cookie may also be stored on your computer for these purposes. You can object to the collection of your data by Facebook pixel, or to the use of your data for the purpose of displaying Facebook ads. - -We also use Facebook’s Software Development Kit (SDK) within our apps, in order to link various Facebook services with our apps. For example, this enables users to be able to use the Facebook SDK to share content from our apps within their Facebook timeline or to send messages to other Facebook users. Further information about the Facebook SDK within iOS can be found here: - -https://developers.facebook.com/docs/ios. For Android, please refer to: https://developers.facebook.com/docs/android. - -We use the Facebook App Events service though the Facebook SDK to track how many people our advertising campaigns reach, and the use of the Facebook SDK. Facebook merely provides us with an aggregated analysis of user behavior with our app. We have no influence beyond that on the information that will be processed through App Events by Facebook. In our app settings, you can opt out of using App Events for these purposes. - -As a guarantee pursuant of Art. 44ff of the General Data Protection Regulation (GDPR), Facebook has signed the EU standard contractual clauses. The legal basis for this processing is Art. 6 paragraph 1 sentence 1 letter f GDPR. - -If you do not wish to be tracked by Facebook in the future, you can opt out at any time by writing an email to service@workouttest.com. -

Facebook Custom Audience

-The product Custom Audiences from Facebook (Facebook Custom Audiences 1601 S. California Avenue, Palo Alto, CA, 94304) is also used on the website as part of the usage-based online advertising. Basically, a non- reversible and non-personal checksum (hash value) is generated from your usage data, which can be transmitted to Facebook for analysis and marketing purposes. This is done either by placing a pixel-code from Facebook on our website or by capturing your usage behavior in our app using the Facebook SDK (see section above for a detailed description of these two Facebook services). Alternatively, we may provide Facebook with a customer list that includes the email address you provided to us when you registered. It collects information about your activities on the website (e.g. surfing habits, sub-pages visited, etc.). This allows Facebook to create a profile about your usage patterns in our app and on our website. Your IP address is stored and used for the geographical control of advertising. - -As a guarantee pursuant of Art. 44ff of the General Data Protection Regulation (GDPR), Facebook has signed the EU standard contractual clauses. The legal basis for our processing is Art. 6 Para. 1 Sentence 1 Letter f GDPR. - -For registrations from June 2020: The legal basis for our processing is Art. 6 Para. 1 Sentence 1 Letter a GDPR. We only actively provide Facebook with customer lists that include your email address or other personal data with your consent. Obviously, you can withdraw your declarations of consent for the future at any time. - -If you no longer agree to us providing your data to Facebook, you can opt-out in our app-settings. - -In this context, please note that Facebook may also use - -the data we provide about your usage behavior and your e-mail address for its own purposes. Here you have the opportunity to object to targeting on Facebook. Alternatively, you can contact us directly by email at service@workouttest.com. - -Further information about the purpose and scope of the data collection and the further processing and use of the data, as well as the privacy settings can be found in the Facebook data protection guidelines. -

-

Firebase by Google

-We use the Firebase service from Google Ireland Limited (Gordon House, Barrow Street, Dublin 4, Ireland) in order to derive application behavioral analytics. We use that information to see how users interact with our website and app. - -Firebase is part of the Google Cloud Platform and offers numerous services for developers. Some Firebase services process personal data. In most cases, the personal data is limited to so-called "instance IDs", which are provided with a time stamp. These "Instance IDs" assigned by Firebase are unique and thus allow the linking of different events or processes. This data does not represent personally identifiable information for us, nor do we make any efforts to personalize it subsequently. We process these aggregated data to analyze and optimize usage behavior, for example by evaluating crash reports. - -Currently, we use the following Firebase services: - -Google Analytics for Firebase: Google Analytics uses the data to provide analytics and attribution information. The precise information collected can vary by the device and environment. Google Analytics retains ID-associated data for 60 days, and retains aggregate reporting and campaign data without automatic expiration, unless the Firebase customer changes their retention preference in their Analytics settings or deletes their project. For Analytics for Firebase, Google uses not only the "Instance ID" described above, but also the advertising ID of the end device. You can restrict the use of the advertising ID in the device settings of your mobile device. For Android: - -Settings > Google > Ads > Reset Ad ID For iOS: Settings > Privacy > Advertising > No ad tracking - -Firebase Remote Config: Remote Config uses Instance IDs to select configuration values to return to end-user devices. Firebase retains Instance IDs until the Firebase customer makes an API call to delete the ID. After the call, data is removed from live and backup systems within 180 days. - -Firebase Dynamic Links: Dynamic Links uses device specs on iOS to open newly-installed apps to a specific page or context. Dynamic Links only stores device specs temporarily, to provide the service. - -Firebase Cloud Messaging: Firebase Cloud Messaging is used to transmit push messages or so-called in-app messages (messages that are only displayed within the respective app). A pseudonymized push reference is assigned to the mobile device, which serves as a target for the push messages or in-app messages. The push messages can be deactivated and reactivated at any time in the settings of the mobile device. Firebase Cloud Messaging uses Instance IDs to determine which devices to deliver messages to. Firebase retains Instance IDs until the Firebase customer makes an API call to delete the ID. After the call, data is removed from live and backup systems within 180 days. - -Firebase will use this information on our behalf for the - -above mentioned reasons. - -The legal basis for the use of this service is Art. 6 paragraph 1 sentence 1 letter f GDPR. As a guarantee pursuant of Art. 44ff of the General Data Protection Regulation (GDPR), Google has signed the EU standard contractual clauses. - -  -

YouTube (extended data protection mode)

-We also use services from YouTube, LLC 901 Cherry Ave., 94066 San Bruno, CA, USA, a company of Google Inc., Amphitheatre Parkway, Mountain View, CA 94043, USA on our website. In so doing we use the option of “extended data protection mode” provided by YouTube. When you access a page containing an embedded YouTube video, a connection to the YouTube servers is established and the contents are displayed on the Internet page through a notification to your browser. Pursuant to YouTube specifications, in the “extended data protection mode” your data is sent to the YouTube servers only when you view the video. If you are simultaneously logged in to YouTube, this information is assigned to your YouTube member account. You may prevent this by logging out of your member account before visiting our website. - -For more information on data protection in connection with YouTube, please refer to this link. -

-

Quality assurance

-When using our website and apps, data is collected and stored which is used to generate information using pseudonymous usage profiles for purposes of web analysis. These usage profiles serve to analyze visitor behaviour and are evaluated to improve and design our services based on demand. In addition, we measure and analyze technical performance data (e.g. response and load times) and application data (hardware and software used) in order to improve the performance of our products. Cookies are used to do so. These are text files saved on your computer that allow us to analyze how you use our website. The pseudonymous usage profiles are not associated with personal data on the bearer of the pseudonym without the concerned party's express consent. You can object to future data collection and storage for the purpose of web analysis at any time by deactivating cookies in your browser settings. You can find the individual privacy notices for the providers here: - -Flurry, Sentry - -  - -  -

Social Plugins

-This website uses social plugins from providers: - -Facebook (Facebook Inc., 1601 S. California Ave, Palo Alto, CA 94304, USA) -Twitter (Twitter Inc., 795 Folsom St., Suite 600, San Francisco, CA 94107, USA) - -These plugins normally collect your data and transmit it to the server of the respective provider. - -After being activated, these plugins also record personal data, such as your IP address, and send this to the server of the respective provider where it is stored. Active social plugins also create a cookie with a unique identifier when accessing the respective website. This allows the provider to create profiles on your usage behavior. This also happens when you are not a member of the social network of the respective provider. If you are a member of the provider's social network, and if you are logged in to the social network while visiting this website, your data and visit information can be associated with your profile on the social network. We cannot influence the exact scope of the data collected on you by the respective provider. Please refer to the privacy policies of the respective social network providers for more detailed information on the scope, manner, and purpose of data processing, and on your rights and setting options to protect your privacy. These can be found in the table above. They are also available at the following addresses: - -Facebook, Twitter -

Social media fan pages

-Workout Test maintains so-called fan pages with social media providers like Instagram, Facebook (both: Facebook Inc. Menlo Park, California) and Twitter (Twitter Inc., 795 Folsom St., Suite 600, San Francisco, CA 94107, USA) in order to communicate with customers, interested parties, and users who are active there, and to inform them about our products, services, and events. In doing so, the users’ data can be processed outside of the EU. The above-mentioned US providers have signed the EU standard contractual clauses and thus guarantee the observance of European data protection laws. - -In the opinion of the European Court of Justice (ECJ), we are responsible, together with Facebook, for the processing of your personal data. You can find the decision of the ECJ dated June 5, 2018 here. - -A Joint Controller Agreement exists with Facebook Inc. pursuant to Art. 26 GDPR. Facebook Ireland pledges to assume the main responsibility in the context of the General Data Protection Regulation (GDPR) for the processing of Insights data and to fulfill all applicable obligations in the context of the GDPR with reference to the processing of Insights data (including, but not limited to Articles 12 and 13 GDPR, Articles 15 to 22 GDPR, and Articles 32 to 34 GDPR). Facebook Ireland will also make available the essential information of this Page Insights Addendum to the affected parties. Please contact Facebook to assume your rights as affected parties. The Data Policy of Facebook can be found here. - -When using the Facebook fan page, the following data will be collected from you for the purpose of user communication and target group advertising: -
    -
  • user interactions (posts, likes, etc.)
  • -
  • Facebook cookies
  • -
  • demographic data (e.g., based on information regarding age, place of residence, language, or gender)
  • -
  • statistical data on user interactions in aggregated form, that is, without the possibility to relate the information to any particular persons (e.g., page activities, page impressions, page previews, likes, recommendations, articles, videos, page subscriptions, incl. source, times of day)
  • -
-The usage of personal data for advertising purposes is of particular importance for Facebook. We use the statistics function to find out more about visitors to our fan page. The use of the function enables us to adapt our content to the respective target group. In this way we also use, for example, the demographic information about the users’ age and location, whereby it is not at all possible for us to relate this information to persons. - -In order to provide the social media service in the form of our Facebook fan page and to use the Insight function, Facebook generally saves cookies on the end device of the user. These include session cookies, which are deleted when the browser is closed, and persistent cookies that remain on the end device until they expire or are deleted by the user. - -We use the Facebook Insights function for statistical - -evaluation purposes. In this connection, we receive anonymized data concerning the users of our Facebook fan page. As a result, it is not possible for us to trace them back to your person. For more information, you can refer to the cookie guideline of Facebook. - -The personal data of users are processed on the basis of our justified interest in effectively providing information to users and maintaining communication with the users, as well as for the purposes of statistical evaluation pursuant to Art. 6(I) (f) GDPR. - -  -

Transfer of data to third parties

-We only pass your personal data on to third parties if: -
    -
  • you have given your explicit consent to this,
  • -
  • forwarding data is necessary for the assertion, exercise or defense of legal claims and there is no reason to assume you have an overriding legitimate interest in your data not being passed on,
  • -
  • in the event that we have a legal obligation to forward data, and
  • -
  • this is legally permissible and required for the performance of the contractual relationship with you.
  • -
-In the case of data transfer outside the European Union, the high European level of data protection essentially does not exist. It may be the case with a transfer that an EU Commission adequacy decision in accordance with Article 45 (1) (3) GDPR is not currently in place. This means the EU Commission has not yet decided that the level of data protection in the respective country corresponds to the level of protection in the European Union based on the GDPR. Consequently, we have put the appropriate guarantees referred to above in place. Potential risks, which cannot be ruled out completely in connection with data transfer, are in particular: -
    -
  • your personal data could be processed over and above the intended purpose.
  • -
  • Moreover, there is a possibility that you may not be able to exercise your rights in relation to data protection, for example your right of access, to rectification, erasure or data portability, on a consistent basis and enforce these.
  • -
  • It may also be highly likely that data is processed incorrectly and in quantitative and qualitative terms, the protection of personal data fails to meet the requirements of the GDPR in full.
  • -
-  -

Your rights

-

Information on the rights of data subjects

-Each data subject has the right of access in accordance with Article 15 GDPR, the right to rectification in accordance with Article 16 GDPR, the right to erasure in accordance with Article 17 GDPR, the right to restriction of processing in accordance with Article 18 GDPR, the right to object in Article 21 GDPR and the right to data portability in Article 20 GDPR. The limitations according to Articles 34 and 35 BDSG apply to the right of access and to the right to erasure. - -  -

-

Information on right the to object in the case of balance of interests

-If we process your personal data based on a balance of interests, you can object to such processing. If you exercise this right to object, please state the reasons why we should not process your data as we have described. If your objection is justified, we will review the situation and either stop or adjust data processing or explain our compelling legitimate reasons for processing to you. - -  - -Information on withdrawal of consent - -You can withdraw your consent with us to process personal data at any time. This also applies to withdrawals of a declaration of consent that were given to us before the General Data Protection Regulation came into effect, i.e. before May 25, 2018. Please note that this withdrawal will only apply prospectively. This does not affect processing that took place prior to a withdrawal. - -  -

Information on right the to object in the case of balance of interests

-If we process your personal data based on a balance of interests, you can object to such processing. If you exercise this right to object, please state the reasons why we should not process your data as we have described. If your objection is justified, we will review the situation and either stop or adjust data processing or explain our compelling legitimate reasons for processing to you. - -"""; - -class _DialogPremiumState extends State with Trans { - bool isStart = true; - @override - Widget build(BuildContext context) { - setContext(context); - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(31), - ), - elevation: 0, - backgroundColor: Colors.transparent, - child: contentBox(context), - ); - } - - contentBox(context) { - return Stack(children: [ - SingleChildScrollView( - padding: EdgeInsets.only(top: 15), - child: Container( - padding: EdgeInsets.only(left: 20, top: 24, right: 20, bottom: 30), - margin: EdgeInsets.only(top: 30), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(24), - boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)], - image: DecorationImage( - image: AssetImage('asset/image/WT_light_background.jpg'), - fit: BoxFit.cover, - alignment: Alignment.center, - ), - ), - child: Html(data: htmlData, - //Optional parameters: - style: { - "html": Style( - backgroundColor: Colors.transparent, - ), - }), - ), - ), - Align( - alignment: Alignment.centerRight, - child: FloatingActionButton( - backgroundColor: Colors.orange, - onPressed: () => Navigator.of(context).pop(), - child: Text("OK"), - )), - GestureDetector( - onTap: () { - Navigator.of(context).pop(); - }, - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: 28, - child: Text( - "X", - style: GoogleFonts.archivoBlack(fontSize: 32, color: Colors.grey[400]), - ), - )), - ]); - } - - @override - void dispose() { - super.dispose(); - } -} diff --git a/lib/widgets/dialog_web_browser.dart b/lib/widgets/dialog_web_browser.dart new file mode 100644 index 0000000..9984a52 --- /dev/null +++ b/lib/widgets/dialog_web_browser.dart @@ -0,0 +1,28 @@ +import 'package:aitrainer_app/util/trans.dart'; +import 'package:flutter/material.dart'; +import 'package:web_browser/web_browser.dart'; + +// ignore: must_be_immutable +class DialogWebBrowser extends StatelessWidget with Trans { + final String url; + final bool javascriptEnabled; + DialogWebBrowser({Key? key, required this.url, required this.javascriptEnabled}) : super(key: key); + + @override + Widget build(BuildContext context) { + setContext(context); + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(31), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: SafeArea( + child: WebBrowser( + initialUrl: url, + javascriptEnabled: javascriptEnabled, + ), + ), + ); + } +} diff --git a/lib/widgets/exercise_save.dart b/lib/widgets/exercise_save.dart index d88c84a..d0d0be3 100644 --- a/lib/widgets/exercise_save.dart +++ b/lib/widgets/exercise_save.dart @@ -1,13 +1,19 @@ +import 'dart:async'; + +import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/time_picker.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions_config.dart'; import 'package:stop_watch_timer/stop_watch_timer.dart'; import 'package:wakelock/wakelock.dart'; +import 'dialog_common.dart'; import 'dialog_html.dart'; // ignore: must_be_immutable @@ -26,6 +32,7 @@ class ExerciseSave extends StatefulWidget { final int? repeats; final int? set; final int? exerciseNr; + final int? originalQuantity; ExerciseSave( {required this.onQuantityChanged, @@ -41,7 +48,8 @@ class ExerciseSave extends StatefulWidget { this.weight, this.repeats, this.set, - this.exerciseNr}); + this.exerciseNr, + this.originalQuantity}); @override _ExerciseSaveState createState() => _ExerciseSaveState(); } @@ -65,7 +73,7 @@ class _ExerciseSaveState extends State with Trans { initState() { super.initState(); _controller1.text = widget.weight == null - ? "30" + ? "0" : widget.weight! % widget.weight!.round() == 0 ? widget.weight!.toStringAsFixed(0) : widget.weight!.toStringAsFixed(1); @@ -81,8 +89,35 @@ class _ExerciseSaveState extends State with Trans { } }); if (widget.unit == "second") { - stopWatchTimer.rawTime.listen((value) => widget.onQuantityChanged((value / 1000))); + stopWatchTimer.rawTime.listen((value) => { + if (value > 0) + { + widget.onQuantityChanged((value / 1000)), + } + }); } + + SchedulerBinding.instance!.addPostFrameCallback((_) { + final TutorialBloc bloc = BlocProvider.of(context); + if (bloc.actualCheck == "directTest") { + Timer( + Duration(milliseconds: 2000), + () => { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return DialogCommon( + title: t("Attention"), + descriptions: t(widget.exerciseTask), + text: "OK", + onTap: () => Navigator.of(context).pop(), + onCancel: () => Navigator.of(context).pop(), + ); + }) + }); + } + }); } @override @@ -137,6 +172,22 @@ class _ExerciseSaveState extends State with Trans { ); } + String getTimeGoal(int? originalQuantity) { + if (originalQuantity == null) { + return ""; + } else if (originalQuantity == -1) { + return t("Goal") + ": Max"; + } else { + int mins = (originalQuantity / 60).floor(); + int secs = originalQuantity % 60; + String seconds = ""; + if (secs > 0) { + seconds = secs.toStringAsFixed(0) + " " + t("secs"); + } + return t("Goal") + ": " + mins.toStringAsFixed(0) + " " + t("mins") + " " + seconds; + } + } + Widget getExerciseWidget() { return KeyboardActions( config: _buildConfig(context), @@ -171,18 +222,9 @@ class _ExerciseSaveState extends State with Trans { SizedBox( height: 15, ), - Padding( - padding: const EdgeInsets.only(top: 10, left: 55, right: 55), - child: Text( - widget.exerciseDescription, - style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]), - maxLines: 1, - overflow: TextOverflow.fade, - softWrap: true, - )), InkWell( child: Text( - t("More »"), + t("Exercise descripton") + " »", style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[200]), ), onTap: () => { @@ -223,6 +265,29 @@ class _ExerciseSaveState extends State with Trans { Divider( color: Colors.transparent, ), + widget.unit == "second" + ? Text( + getTimeGoal(widget.originalQuantity), + style: GoogleFonts.inter( + fontSize: 24, + color: Colors.yellow[400], + fontWeight: FontWeight.bold, + shadows: [ + Shadow( + offset: Offset(2.0, 2.0), + blurRadius: 6.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + ), + textAlign: TextAlign.center, + ) + : Offstage(), columnQuantityUnit(), Divider( color: Colors.transparent, @@ -298,7 +363,6 @@ class _ExerciseSaveState extends State with Trans { return Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Padding( padding: const EdgeInsets.only(top: 10, left: 55, right: 55), - //padding: const EdgeInsets.only(bottom: 0), child: StreamBuilder( stream: stopWatchTimer.rawTime, initialData: stopWatchTimer.rawTime.value, @@ -316,7 +380,6 @@ class _ExerciseSaveState extends State with Trans { ]); })), Padding( - //padding: const EdgeInsets.all(2), padding: const EdgeInsets.only(top: 10, left: 25, right: 25), child: Column( children: [ @@ -372,7 +435,11 @@ class _ExerciseSaveState extends State with Trans { Divider(), Divider(), Text(t("Or type the time manually:"), style: GoogleFonts.inter(color: Colors.white)), - TimePickerWidget(onChange: (value) => widget.onQuantityChanged((value))) + TimePickerWidget( + onChange: (value) => { + widget.onQuantityChanged(value), + }, + ) ]); } Widget row = Container( diff --git a/lib/widgets/home.dart b/lib/widgets/home.dart index 9f649ec..d8ed6ec 100644 --- a/lib/widgets/home.dart +++ b/lib/widgets/home.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:aitrainer_app/bloc/session/session_bloc.dart'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; diff --git a/lib/widgets/menu_page_widget.dart b/lib/widgets/menu_page_widget.dart index f92759b..6401e2b 100644 --- a/lib/widgets/menu_page_widget.dart +++ b/lib/widgets/menu_page_widget.dart @@ -25,8 +25,6 @@ import 'package:flutter/scheduler.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'dialog_html.dart'; - // ignore: must_be_immutable class MenuPageWidget extends StatefulWidget { int? parent; @@ -288,9 +286,9 @@ class _MenuPageWidgetState extends State with Trans, Logging { backgroundColor: Colors.orange, content: Text(AppLocalizations.of(context)!.translate('Please log in'), style: TextStyle(color: Colors.white)))); } else { - Track().track(TrackingEvent.search, eventValue: value.exerciseType!.name); + Track().track(TrackingEvent.search, eventValue: value!.exerciseType!.name); menuBloc.ability = ExerciseAbility.oneRepMax; - Navigator.of(context).popAndPushNamed('exerciseNewPage', arguments: value.exerciseType); + Navigator.of(context).pushNamed('exerciseNewPage', arguments: value.exerciseType); } }, ), diff --git a/lib/widgets/menu_search_bar.dart b/lib/widgets/menu_search_bar.dart index 60893de..c552f19 100644 --- a/lib/widgets/menu_search_bar.dart +++ b/lib/widgets/menu_search_bar.dart @@ -26,7 +26,7 @@ class SearchBarStream { // ignore: must_be_immutable class MenuSearchBar extends StatelessWidget { final List listItems; - final Function(WorkoutMenuTree) onFind; + final Function(WorkoutMenuTree?) onFind; bool showIcon; MenuSearchBar({required this.listItems, required this.onFind, this.showIcon = true}); @@ -43,7 +43,7 @@ class MenuSearchBar extends StatelessWidget { // ignore: must_be_immutable class AnimatedSearch extends StatefulWidget { final List listItems; - final Function(WorkoutMenuTree) onFind; + final Function(WorkoutMenuTree?) onFind; bool showIcon = true; AnimatedSearch({required this.listItems, required this.onFind, required this.showIcon}); @@ -118,7 +118,7 @@ class _AnimatedSearch extends State { // ignore: must_be_immutable class Search extends StatelessWidget with Trans { final List listItems; - final Function(WorkoutMenuTree) onFind; + final Function(WorkoutMenuTree?) onFind; Search({required this.listItems, required this.onFind}); @@ -172,7 +172,7 @@ class Search extends StatelessWidget with Trans { child: ListTile( selected: isSelected, title: Text( - item.name, + item!.name, style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 16), ), subtitle: Text( diff --git a/lib/widgets/tutorial_widget.dart b/lib/widgets/tutorial_widget.dart index 4fda72a..f17e9ea 100644 --- a/lib/widgets/tutorial_widget.dart +++ b/lib/widgets/tutorial_widget.dart @@ -1,6 +1,9 @@ import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart'; +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; @@ -28,6 +31,12 @@ class TutorialWidget with Trans, Logging { print("Action is null"); return; } + if (bloc.actualCheck == "directTest") { + print("DirectTest"); + tooltip!.close(); + directTest(bloc); + return; + } setContext(context); if (tooltip != null && tooltip!.isOpen) { tooltip!.rebuild(); @@ -161,4 +170,66 @@ class TutorialWidget with Trans, Logging { tooltip!.show(context); } + + void directTest(TutorialBloc bloc) { + ExerciseType? exerciseType; + showCupertinoDialog( + useRootNavigator: true, + context: context, + builder: (_) => CupertinoAlertDialog( + title: Html(data: bloc.actualText!, + //Optional parameters: + style: { + "p": Style( + color: Colors.indigo, + fontSize: FontSize(16), + padding: const EdgeInsets.all(4), + ), + }), + content: Column(children: [ + Divider(), + ]), + actions: [ + TextButton( + child: Text(t("Chest Press")), + onPressed: () { + Navigator.pop(context); + exerciseType = Cache().getExerciseTypeById(37); + if (exerciseType != null) { + Navigator.of(context).popAndPushNamed('exerciseNewPage', arguments: exerciseType); + } + }), + TextButton( + child: Text(t("Olympic Squat")), + onPressed: () { + Navigator.pop(context); + exerciseType = Cache().getExerciseTypeById(145); + if (exerciseType != null) { + Navigator.of(context).popAndPushNamed('exerciseNewPage', arguments: exerciseType); + } + }, + ), + TextButton( + child: Text(t("Pushups")), + onPressed: () { + Navigator.pop(context); + exerciseType = Cache().getExerciseTypeById(33); + if (exerciseType != null) { + Navigator.of(context).popAndPushNamed('exerciseNewPage', arguments: exerciseType); + } + }, + ), + TextButton( + child: Text(t("Plank")), + onPressed: () { + Navigator.pop(context); + exerciseType = Cache().getExerciseTypeById(53); + if (exerciseType != null) { + Navigator.of(context).popAndPushNamed('exerciseNewPage', arguments: exerciseType); + } + }, + ) + ], + )); + } } diff --git a/lib/widgets/weight_control.dart b/lib/widgets/weight_control.dart new file mode 100644 index 0000000..2820ec2 --- /dev/null +++ b/lib/widgets/weight_control.dart @@ -0,0 +1,112 @@ +import 'package:aitrainer_app/util/trans.dart'; +import 'package:aitrainer_app/widgets/number_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +class WeightControl extends StatefulWidget { + final Function(double) onTap; + final double initialValue; + const WeightControl({required this.onTap, required this.initialValue}); + @override + _UnitQuantityControlState createState() => _UnitQuantityControlState(); +} + +class _UnitQuantityControlState extends State with Trans { + double? changedValue; + @override + Widget build(BuildContext context) { + setContext(context); + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(31), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: contentBox(context), + ); + } + + contentBox(context) { + return Stack(alignment: AlignmentDirectional.topStart, children: [ + Container( + padding: EdgeInsets.only(left: 20, top: 24, right: 20, bottom: 30), + margin: EdgeInsets.only(top: 30), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)], + image: DecorationImage( + image: AssetImage('asset/image/WT_results_background.jpg'), + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + child: Column(mainAxisSize: MainAxisSize.min, children: [ + Text( + t("Change the weight to"), + textAlign: TextAlign.center, + style: GoogleFonts.archivoBlack( + fontSize: 24, + color: Colors.yellow[100], + shadows: [ + Shadow( + offset: Offset(5.0, 5.0), + blurRadius: 12.0, + color: Colors.black54, + ), + Shadow( + offset: Offset(-3.0, 3.0), + blurRadius: 12.0, + color: Colors.black54, + ), + ], + ), + ), + SizedBox( + height: 20, + ), + NumberPickerWidget( + minValue: (widget.initialValue - 30).round(), + maxValue: (widget.initialValue + 30).round(), + initalValue: widget.initialValue.round(), + unit: t("kg"), + color: Colors.yellow[50]!, + onChange: (value) => { + setState(() { + changedValue = value; + }) + }), + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: () => { + if (changedValue == null) + { + changedValue = widget.initialValue, + }, + Navigator.of(context).pop(), + widget.onTap(changedValue!), + }, + child: Stack( + alignment: Alignment.center, + children: [ + Image.asset('asset/icon/gomb_orange_c.png', width: 100, height: 45), + Text( + t("OK"), + style: TextStyle(fontSize: 16, color: Colors.white), + ), + ], + ))), + ])), + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: CircleAvatar( + backgroundColor: Colors.transparent, + radius: 28, + child: Text( + "X", + style: GoogleFonts.archivoBlack(fontSize: 32, color: Colors.white54), + ), + )), + ]); + } +} diff --git a/pubspec.lock b/pubspec.lock index f5d8b68..401fb23 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -239,6 +239,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" + csp: + dependency: transitive + description: + name: csp + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" csslib: dependency: transitive description: @@ -679,6 +686,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.4.0" + kind: + dependency: transitive + description: + name: kind + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.2" logging: dependency: transitive description: @@ -903,6 +917,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.1" + protobuf: + dependency: transitive + description: + name: protobuf + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" provider: dependency: transitive description: @@ -980,6 +1001,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.1.0-beta.1" + share: + dependency: transitive + description: + name: share + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" shared_preferences: dependency: "direct dev" description: @@ -1237,6 +1265,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + universal_html: + dependency: transitive + description: + name: universal_html + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + universal_io: + dependency: transitive + description: + name: universal_io + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" upgrader: dependency: "direct main" description: @@ -1245,7 +1287,7 @@ packages: source: hosted version: "3.3.0" url_launcher: - dependency: "direct main" + dependency: transitive description: name: url_launcher url: "https://pub.dartlang.org" @@ -1370,6 +1412,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + web_browser: + dependency: "direct main" + description: + name: web_browser + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" + web_node: + dependency: transitive + description: + name: web_node + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1" web_socket_channel: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 4b7c322..c88c000 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.1.19+90 +version: 1.1.20+91 environment: sdk: ">=2.12.0 <3.0.0" @@ -55,9 +55,9 @@ dependencies: carousel_slider: ^4.0.0-nullsafety.0 convex_bottom_bar: ^3.0.0 flutter_app_badger: ^1.2.0 - url_launcher: ^6.0.3 extended_tabs: ^2.2.0 upgrader: ^3.3.0 + web_browser: ^0.5.0 firebase_core: ^1.2.0 firebase_analytics: ^8.1.0 @@ -159,6 +159,7 @@ flutter: - asset/image/button_apple.png - asset/image/button_google.png - asset/image/continue.png + - asset/image/drop_set.png - asset/image/lock.png - asset/image/add_test.png - asset/image/testemfejl400x400.jpg @@ -185,7 +186,8 @@ flutter: - asset/image/kupa.png - asset/image/test_picto_m.png - asset/image/test_picto_w.png - + - asset/image/pict_1rm.png + - asset/image/pict_history.png - asset/image/pict_calorie.png - asset/image/pict_development_by_bodypart_percent.png - asset/image/pict_distance_m.png