diff --git a/asset/image/WT_black_G_background.png b/asset/image/WT_black_G_background.png new file mode 100644 index 0000000..29184b2 Binary files /dev/null and b/asset/image/WT_black_G_background.png differ diff --git a/asset/image/WT_plainblack_background.png b/asset/image/WT_plainblack_background.png new file mode 100644 index 0000000..0f5db20 Binary files /dev/null and b/asset/image/WT_plainblack_background.png differ diff --git a/asset/image/WT_sales_background.png b/asset/image/WT_sales_background.png new file mode 100644 index 0000000..82b97fe Binary files /dev/null and b/asset/image/WT_sales_background.png differ diff --git a/asset/image/WT_sales_background_3x5.png b/asset/image/WT_sales_background_3x5.png new file mode 100644 index 0000000..15c5961 Binary files /dev/null and b/asset/image/WT_sales_background_3x5.png differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index b7d775b..b48f0cf 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -11,12 +11,12 @@ PODS: - Firebase/Messaging (6.33.0): - Firebase/CoreOnly - FirebaseMessaging (~> 4.7.0) - - firebase_auth (0.18.3-1): + - firebase_auth (0.18.4-1): - Firebase/Auth (~> 6.33.0) - Firebase/CoreOnly (~> 6.33.0) - firebase_core - Flutter - - firebase_core (0.5.2-1): + - firebase_core (0.5.3): - Firebase/CoreOnly (~> 6.33.0) - Flutter - firebase_messaging (7.0.3): @@ -61,6 +61,8 @@ PODS: - Flutter - Flurry-iOS-SDK/FlurrySDK (11.1.1) - Flutter (1.0.0) + - flutter_inapp_purchase (0.0.1): + - Flutter - flutter_keyboard_visibility (0.0.1): - Flutter - FMDB (2.7.5): @@ -111,6 +113,7 @@ DEPENDENCIES: - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - flurry (from `.symlinks/plugins/flurry/ios`) - Flutter (from `Flutter`) + - flutter_inapp_purchase (from `.symlinks/plugins/flutter_inapp_purchase/ios`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - health (from `.symlinks/plugins/health/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) @@ -150,6 +153,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flurry/ios" Flutter: :path: Flutter + flutter_inapp_purchase: + :path: ".symlinks/plugins/flutter_inapp_purchase/ios" flutter_keyboard_visibility: :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" health: @@ -165,8 +170,8 @@ SPEC CHECKSUMS: device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_auth: cb33b01b51904969161403bbcb20036519f0c578 - firebase_core: 7423d688a1c6f2f2d859d64ae26991be39989781 + firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a + firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseAuth: c92d49ada7948d1a23466e3db17bc4c2039dddc3 FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd @@ -177,6 +182,7 @@ SPEC CHECKSUMS: flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad Flurry-iOS-SDK: 8f3f7fce27177002f15f145eede88dc1b9ac0cd0 Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6c4a57b..7e6a778 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -366,7 +366,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 39; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -509,7 +509,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 39; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -544,7 +544,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 39; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = SFJJBDCU6Z; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/bloc/custom_exercise_form_bloc.dart b/lib/bloc/custom_exercise_form_bloc.dart index 6f4008c..0f2424f 100644 --- a/lib/bloc/custom_exercise_form_bloc.dart +++ b/lib/bloc/custom_exercise_form_bloc.dart @@ -1,5 +1,4 @@ import 'dart:math'; - import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart'; @@ -18,19 +17,21 @@ class CustomExerciseFormBloc extends FormBloc { ); //1RM calculated Fields - final rmWendlerField = TextFieldBloc( initialValue: "0",); - final rmMayhewField = TextFieldBloc( initialValue: "0"); - final rmOconnerField = TextFieldBloc( initialValue: "0"); - final rmWathenField = TextFieldBloc( initialValue: "0"); - final rmAverageField = TextFieldBloc( initialValue: "0"); - final rm90Field = TextFieldBloc( initialValue: "0"); - final rm80Field = TextFieldBloc( initialValue: "0"); - final rm75Field = TextFieldBloc( initialValue: "0"); - final rm75WendlerField = TextFieldBloc( initialValue: "0"); - final rm75OconnorField = TextFieldBloc( initialValue: "0"); - final rm70Field = TextFieldBloc( initialValue: "0"); - final rm60Field = TextFieldBloc( initialValue: "0"); - final rm50Field = TextFieldBloc( initialValue: "0"); + final rmWendlerField = TextFieldBloc( + initialValue: "0", + ); + final rmMayhewField = TextFieldBloc(initialValue: "0"); + final rmOconnerField = TextFieldBloc(initialValue: "0"); + final rmWathenField = TextFieldBloc(initialValue: "0"); + final rmAverageField = TextFieldBloc(initialValue: "0"); + final rm90Field = TextFieldBloc(initialValue: "0"); + final rm80Field = TextFieldBloc(initialValue: "0"); + final rm75Field = TextFieldBloc(initialValue: "0"); + final rm75WendlerField = TextFieldBloc(initialValue: "0"); + final rm75OconnorField = TextFieldBloc(initialValue: "0"); + final rm70Field = TextFieldBloc(initialValue: "0"); + final rm60Field = TextFieldBloc(initialValue: "0"); + final rm50Field = TextFieldBloc(initialValue: "0"); CustomExerciseFormBloc({this.exerciseRepository}) { addFieldBlocs(fieldBlocs: [ @@ -64,7 +65,6 @@ class CustomExerciseFormBloc extends FormBloc { @override void onSubmitting() async { - print("on Submitting Custom form"); try { emitLoading(progress: 30); // Emit either Loaded or Error @@ -78,30 +78,27 @@ class CustomExerciseFormBloc extends FormBloc { void calculate1RM() { double weight = exerciseRepository.exercise.unitQuantity; double repeat = exerciseRepository.exercise.quantity; - if ( weight == 0 || repeat == 0) { + if (weight == 0 || repeat == 0) { return; } - print("Calculating 1RM"); exerciseRepository.rmWendler = weight * repeat * 0.0333 + weight; rmWendlerField.updateValue(exerciseRepository.rmWendler.toStringAsFixed(1)); exerciseRepository.rmOconner = weight * (1 + repeat / 40); rmOconnerField.updateValue(exerciseRepository.rmOconner.toStringAsFixed(1)); - exerciseRepository.rmMayhew = - 100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat)); + exerciseRepository.rmMayhew = 100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat)); rmMayhewField.updateValue(exerciseRepository.rmMayhew.toStringAsFixed(1)); - exerciseRepository.rmWathen = - 100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat)); + exerciseRepository.rmWathen = 100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat)); rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1)); - double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner)/2; + double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner) / 2; rmAverageField.updateValue(average.toStringAsFixed(1)); - rm90Field.updateValue((average*0.9).toStringAsFixed(1)); - rm80Field.updateValue((average*0.8).toStringAsFixed(1)); - rm75Field.updateValue((average*0.75).toStringAsFixed(1)); - rm75OconnorField.updateValue((exerciseRepository.rmOconner*0.75).toStringAsFixed(1)); - rm75WendlerField.updateValue((exerciseRepository.rmWendler*0.75).toStringAsFixed(1)); - rm70Field.updateValue((average*0.7).toStringAsFixed(1)); - rm60Field.updateValue((average*0.6).toStringAsFixed(1)); - rm50Field.updateValue((average*0.5).toStringAsFixed(1)); + rm90Field.updateValue((average * 0.9).toStringAsFixed(1)); + rm80Field.updateValue((average * 0.8).toStringAsFixed(1)); + rm75Field.updateValue((average * 0.75).toStringAsFixed(1)); + rm75OconnorField.updateValue((exerciseRepository.rmOconner * 0.75).toStringAsFixed(1)); + rm75WendlerField.updateValue((exerciseRepository.rmWendler * 0.75).toStringAsFixed(1)); + rm70Field.updateValue((average * 0.7).toStringAsFixed(1)); + rm60Field.updateValue((average * 0.6).toStringAsFixed(1)); + rm50Field.updateValue((average * 0.5).toStringAsFixed(1)); } //@override diff --git a/lib/bloc/customer_change_form_bloc.dart b/lib/bloc/customer_change_form_bloc.dart index 9829849..2e99860 100644 --- a/lib/bloc/customer_change_form_bloc.dart +++ b/lib/bloc/customer_change_form_bloc.dart @@ -104,7 +104,6 @@ class CustomerChangeFormBloc extends FormBloc { @override void onSubmitting() async { - print("on Submitting Customer Change form"); try { emitLoading(progress: 30); // Emit either Loaded or Error diff --git a/lib/bloc/customer_exercise_device/customer_exercise_device_bloc.dart b/lib/bloc/customer_exercise_device/customer_exercise_device_bloc.dart index ac41e0d..151d245 100644 --- a/lib/bloc/customer_exercise_device/customer_exercise_device_bloc.dart +++ b/lib/bloc/customer_exercise_device/customer_exercise_device_bloc.dart @@ -29,13 +29,11 @@ class CustomerExerciseDeviceBloc extends Bloc "2"); await repository.addDevice(event.device); Cache().initBadges(); yield CustomerExerciseDeviceReady(); } else if (event is CustomerExerciseDeviceRemove) { - print("Remove device " + event.device.exerciseDeviceId.toString()); yield CustomerExerciseDeviceLoading(); await repository.removeDevice(event.device); Cache().initBadges(); diff --git a/lib/bloc/development_by_muscle/development_by_muscle_bloc.dart b/lib/bloc/development_by_muscle/development_by_muscle_bloc.dart index 7dd1a73..8d5e463 100644 --- a/lib/bloc/development_by_muscle/development_by_muscle_bloc.dart +++ b/lib/bloc/development_by_muscle/development_by_muscle_bloc.dart @@ -6,6 +6,7 @@ import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/calculate.dart'; import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/group_data.dart'; @@ -48,18 +49,16 @@ class GroupDate extends GroupData with Calculate, Common { GroupDate({this.inputList, this.outputList}); - - double getQuantityByDate(Exercise exercise) { double sum = 0; - if ( this.diagramType == DiagramType.sumMass ) { - if ( exercise.unitQuantity != null ) { + if (this.diagramType == DiagramType.sumMass) { + if (exercise.unitQuantity != null) { sum = exercise.quantity * exercise.unitQuantity; } else { sum = exercise.quantity; } - } else if ( this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent ) { - if ( exercise.unitQuantity != null ) { + } else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) { + if (exercise.unitQuantity != null) { sum = calculate1RM(exercise.quantity, exercise.unitQuantity); } else { sum = exercise.quantity; @@ -93,8 +92,8 @@ class GroupDate extends GroupData with Calculate, Common { Exercise tempExercise; inputList.forEach((element) { tempExercise = element; - if ( this.checkNewType(element)) { - if ( _origDatePart == null ) { + if (this.checkNewType(element)) { + if (_origDatePart == null) { this.addTempData(element); } else { this.temp2Output(_origExercise); @@ -105,7 +104,7 @@ class GroupDate extends GroupData with Calculate, Common { this.addTempData(element); } }); - if ( tempExercise != null) { + if (tempExercise != null) { this.temp2Output(tempExercise); } } @@ -134,7 +133,6 @@ class GroupDate extends GroupData with Calculate, Common { =========== CHART DATA CLASS */ class GroupChart extends GroupData with Calculate { - final List inputList; LinkedHashMap outputList = LinkedHashMap(); @@ -149,7 +147,7 @@ class GroupChart extends GroupData with Calculate { GroupChart({this.inputList, this.outputList}); double getBasePercent(Exercise exercise) { - if ( exercise.unitQuantity != null ) { + if (exercise.unitQuantity != null) { this._basePercent = calculate1RM(exercise.quantity, exercise.unitQuantity); } else { this._basePercent = exercise.quantity; @@ -160,14 +158,14 @@ class GroupChart extends GroupData with Calculate { double getDiagramValue(Exercise exercise) { double value = 0; - if ( diagramType == DiagramType.percent) { - if ( exercise.unitQuantity != null ) { + if (diagramType == DiagramType.percent) { + if (exercise.unitQuantity != null) { double oneRepMax = calculate1RM(exercise.quantity, exercise.unitQuantity); value = (oneRepMax / this._basePercent) * 100; } else { - value = (exercise.quantity / this._basePercent ) * 100; + value = (exercise.quantity / this._basePercent) * 100; } - } else if ( diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) { + } else if (diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) { value = exercise.calculated; } return value; @@ -175,7 +173,6 @@ class GroupChart extends GroupData with Calculate { @override void addTempData(Exercise exercise) { - double diagramValue = this.getDiagramValue(exercise); if (_maxData < diagramValue) { @@ -185,32 +182,27 @@ class GroupChart extends GroupData with Calculate { _minData = diagramValue; } - BarChartGroupData data = BarChartGroupData( - x: exercise.dateAdd.millisecondsSinceEpoch, - barRods: [ - BarChartRodData(y: diagramValue, width: 12, colors: [Colors.lightBlue, Colors.lightBlueAccent]) - ] - ); + BarChartGroupData data = BarChartGroupData(x: exercise.dateAdd.millisecondsSinceEpoch, barRods: [ + BarChartRodData(y: diagramValue, width: 12, colors: [Colors.lightBlue, Colors.lightBlueAccent]) + ]); _chartData.add(data); _origExerciseTypeId = exercise.exerciseTypeId; - } @override bool checkNewType(Exercise exercise) { - return _origExerciseTypeId != exercise.exerciseTypeId; + return _origExerciseTypeId != exercise.exerciseTypeId; } @override void iteration() { - this.resetTemp(); Exercise tempExercise; inputList.forEach((element) { tempExercise = element; - if ( this.checkNewType(element)) { - if ( _origExerciseTypeId == null ) { + if (this.checkNewType(element)) { + if (_origExerciseTypeId == null) { _basePercent = getBasePercent(element); this.addTempData(element); } else { @@ -223,7 +215,7 @@ class GroupChart extends GroupData with Calculate { this.addTempData(element); } }); - if ( tempExercise != null) { + if (tempExercise != null) { this.temp2Output(tempExercise); } } @@ -234,9 +226,8 @@ class GroupChart extends GroupData with Calculate { int gridInterval = (dInterval / 3).floor(); ChartDataExtended extended; - if ( outputList[_origExerciseTypeId] == null ) { - extended = ChartDataExtended( - data: _chartData, interval: dInterval, gridInterval: gridInterval); + if (outputList[_origExerciseTypeId] == null) { + extended = ChartDataExtended(data: _chartData, interval: dInterval, gridInterval: gridInterval); outputList[_origExerciseTypeId] = extended; } else { extended = outputList[_origExerciseTypeId]; @@ -252,7 +243,6 @@ class GroupChart extends GroupData with Calculate { _maxData = 0; _chartData = List(); } - } class ChartDataExtended { @@ -272,7 +262,6 @@ class ChartDataExtended { }; listBarChartData.add(barChartData); }); - }); var chartData = { "data": listBarChartData.toString(), @@ -281,10 +270,9 @@ class ChartDataExtended { }; return chartData; } - } -class DevelopmentByMuscleBloc extends Bloc with Calculate { +class DevelopmentByMuscleBloc extends Bloc with Calculate, Logging { final WorkoutTreeRepository workoutTreeRepository; final ExerciseRepository exerciseRepository = ExerciseRepository(); LinkedHashMap listChartData = LinkedHashMap(); @@ -294,12 +282,9 @@ class DevelopmentByMuscleBloc extends Bloc getData() async { - workoutTreeRepository.sortedTree = null; workoutTreeRepository.sortByMuscleType(); @@ -311,7 +296,6 @@ class DevelopmentByMuscleBloc extends Bloc groupByDate(List exercises) { List groupedExercises = List(); exercises = sort(exercises, false); exercises.forEach((exercise) { - print ("Date exercise " + exercise.toJsonDatePart().toString()); + trace("Date exercise " + exercise.toJsonDatePart().toString()); }); GroupDate groupDate = GroupDate(inputList: exercises, outputList: groupedExercises); @@ -358,12 +339,11 @@ class DevelopmentByMuscleBloc extends Bloc sort(List exercises, bool asc) { - exercises.sort( (a, b) { + exercises.sort((a, b) { var aDateId = a.exerciseTypeId.toString() + "_" + a.datePart.toString(); var bDateId = b.exerciseTypeId.toString() + "_" + b.datePart.toString(); @@ -383,13 +363,13 @@ class DevelopmentByMuscleBloc extends Bloc { } final double distortionWidth = mediaWidth / baseWidth; final double distortionHeight = mediaHeight / baseHeight; - print("W m " + mediaWidth.toString() + " b" + baseWidth.toString() + " d: " + distortionWidth.toString()); - print("H m " + mediaHeight.toString() + " b" + baseHeight.toString() + " d: " + distortionHeight.toString()); this.bmiAngle = (bmi * 90 / 25) - 90; if (bmi < 18.5) { goalBMI = 19; diff --git a/lib/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart b/lib/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart index 06e25a2..c0c6f01 100644 --- a/lib/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart +++ b/lib/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart @@ -25,16 +25,16 @@ class ExercisePlanCustomAddBloc extends Bloc with Common { } else { // Emit either Loaded or Error await PropertyApi().getProperties(); - print("properties OK"); await userRepository.getUser(); - print("get User OK"); await ExerciseTypeApi().getExerciseTypes(); - print("exerciesTypes OK"); await ExerciseTreeApi().getExerciseTree(); if (Cache().userLoggedIn != null && Cache().userLoggedIn.customerId > 0) { ExerciseRepository exerciseRepository = ExerciseRepository(); diff --git a/lib/bloc/menu/menu_bloc.dart b/lib/bloc/menu/menu_bloc.dart index acd78d3..025d2e2 100644 --- a/lib/bloc/menu/menu_bloc.dart +++ b/lib/bloc/menu/menu_bloc.dart @@ -7,6 +7,7 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/exercise_device_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; @@ -16,7 +17,7 @@ import 'package:meta/meta.dart'; part 'menu_event.dart'; part 'menu_state.dart'; -class MenuBloc extends Bloc with Trans { +class MenuBloc extends Bloc with Trans, Logging { final WorkoutTreeRepository menuTreeRepository; final ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository(); @@ -48,7 +49,7 @@ class MenuBloc extends Bloc with Trans { } if (context == null) return; percent = percent * 100; - print("Percent " + percent.toString()); + log("Percent " + percent.toString()); if (percent == -1 || percent == 0) { infoTitle = t("Greetings!"); infoText = t("The purpose is to measure you physical condition") + @@ -69,7 +70,7 @@ class MenuBloc extends Bloc with Trans { menuTreeRepository.sortByMuscleType(); missingTreeName = exerciseRepository.nextMissingBaseExercise(menuTreeRepository.sortedTree); - //print("Missing " + missingTreeName); + //log("Missing " + missingTreeName); if (missingTreeName != null) { if (percent > 0) { infoText = t("Please continue your tests with a") + " '" + missingTreeName + "' " + t("exercise!"); @@ -163,7 +164,7 @@ class MenuBloc extends Bloc with Trans { ability = ExerciseAbility.none; break; } - print("Ability: " + ability.toString() + " name:" + name); + log("Ability: " + ability.toString() + " name:" + name); } bool selectedDevice(int deviceId) { diff --git a/lib/bloc/result/result_bloc.dart b/lib/bloc/result/result_bloc.dart index bcfa78c..b9b93d4 100644 --- a/lib/bloc/result/result_bloc.dart +++ b/lib/bloc/result/result_bloc.dart @@ -4,6 +4,7 @@ import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/result.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_result_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart'; @@ -12,7 +13,7 @@ import 'package:health/health.dart'; part 'result_event.dart'; part 'result_state.dart'; -class ResultBloc extends Bloc { +class ResultBloc extends Bloc with Logging { final ExerciseResultRepository resultRepository; final ExerciseRepository exerciseRepository; List _healthDataList = List(); @@ -46,6 +47,7 @@ class ResultBloc extends Bloc { await _fetchHealthData(); _matchExerciseData(); + await resultRepository.saveExerciseResults(); yield ResultReady(); } } on Exception catch (ex) { @@ -55,25 +57,28 @@ class ResultBloc extends Bloc { void _matchExerciseData() { resultRepository.getResults().forEach((element) { + element.dateFrom = startTime; + element.dateTo = endTime; + element.exerciseId = exerciseRepository.actualExerciseList[0].exerciseId; switch (element.item) { case ResultItem.bpm_avg: - element.data = _gethHealthDataPointValueAvg(HealthDataType.HEART_RATE).toStringAsFixed(0); + element.data = _gethHealthDataPointValueAvg(HealthDataType.HEART_RATE); break; case ResultItem.bpm_min: - element.data = element.data = _gethHealthDataPointValueMin(HealthDataType.HEART_RATE).toStringAsFixed(0); + element.data = element.data = _gethHealthDataPointValueMin(HealthDataType.HEART_RATE); break; case ResultItem.bpm_max: - element.data = element.data = _gethHealthDataPointValueMax(HealthDataType.HEART_RATE).toStringAsFixed(0); + element.data = element.data = _gethHealthDataPointValueMax(HealthDataType.HEART_RATE); break; case ResultItem.calorie: - element.data = _gethHealthDataPointValueSum(HealthDataType.ACTIVE_ENERGY_BURNED).toStringAsFixed(0); + element.data = _gethHealthDataPointValueSum(HealthDataType.ACTIVE_ENERGY_BURNED); break; case ResultItem.development_percent_bodypart: // TODO: Handle this case. break; case ResultItem.distance: if (exerciseRepository.exerciseType.unit == "meter") { - element.data = exerciseRepository.exercise.quantity.toStringAsFixed(0); + element.data = exerciseRepository.exercise.quantity; } break; case ResultItem.fatburn_percent: @@ -92,9 +97,9 @@ class ResultBloc extends Bloc { } }); if (counter > 0) { - element.data = (burnCounter / counter * 100).toStringAsFixed(2); + element.data = (burnCounter / counter * 100); } else { - element.data = "0"; + element.data = 0; } break; case ResultItem.speed_max: @@ -106,11 +111,11 @@ class ResultBloc extends Bloc { exerciseRepository.actualExerciseList.forEach((element) { value += element.quantity; }); - element.data = value.toStringAsFixed(0); + element.data = value; } break; case ResultItem.steps: - element.data = _gethHealthDataPointValueSum(HealthDataType.STEPS).toStringAsFixed(0); + element.data = _gethHealthDataPointValueSum(HealthDataType.STEPS); break; /* case ResultItem.time: final Duration duration = this.endTime.difference(this.startTime); @@ -122,7 +127,7 @@ class ResultBloc extends Bloc { exerciseRepository.actualExerciseList.forEach((element) { value += element.quantity * element.unitQuantity; }); - element.data = value.toStringAsFixed(0); + element.data = value; } break; } @@ -195,13 +200,13 @@ class ResultBloc extends Bloc { return; } try { - print("Get Health data between " + startTime.toString() + " AND " + endTime.toString()); + log("Get Health data between " + startTime.toString() + " AND " + endTime.toString()); _healthDataList = await health.getHealthDataFromTypes(this.startTime, this.endTime, types); _healthDataList.forEach((element) { - print(element.toString()); + log(element.toString()); }); } on Exception catch (e) { - print("Caught exception in getHealthDataFromTypes: $e"); + log("Caught exception in getHealthDataFromTypes: $e"); throw Exception(e); } } diff --git a/lib/bloc/sales/sales_bloc.dart b/lib/bloc/sales/sales_bloc.dart new file mode 100644 index 0000000..eb6a834 --- /dev/null +++ b/lib/bloc/sales/sales_bloc.dart @@ -0,0 +1,79 @@ +import 'dart:async'; +import 'dart:math'; + +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/product.dart'; +import 'package:aitrainer_app/model/product_test.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/service/product_test_service.dart'; +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; + +part 'sales_event.dart'; +part 'sales_state.dart'; + +class SalesBloc extends Bloc with Logging { + List tests = List(); + List product2Display = List(); + int productSet = -1; + SalesBloc() : super(SalesInitial()); + + @override + Stream mapEventToState( + SalesEvent event, + ) async* { + try { + if (event is SalesLoad) { + yield SalesLoading(); + this.getProductSet(); + yield SalesReady(); + } else if (event is SalesPurchase) { + final int productId = event.productId; + trace("Requesting purchase for" + productId.toString()); + //PlatformPurchaseApi().requestPurchase(null); + } + } on Exception catch (ex) { + yield SalesError(message: ex.toString()); + } + } + + void getProductSet() { + int productId = 0; + this.tests = Cache().productTests; + + if (tests.isEmpty) { + var rand = Random.secure(); + productSet = rand.nextInt(5) + 1; + } else { + trace("Previous ProductTest: " + tests[0].toJson().toString()); + productId = tests[0].productId; + for (var elem in Cache().products) { + Product product = elem as Product; + if (product.productId == productId) { + productSet = product.productSet; + break; + } + } + } + + ProductTest productTest = ProductTest(); + trace("ProductSet: " + productSet.toString()); + for (var elem in Cache().products) { + Product product = elem as Product; + if (product.productSet == productSet) { + productId = product.productId; + product2Display.add(product); + } + } + + product2Display.sort((a, b) { + return a.sort < b.sort ? a.sort : b.sort; + }); + + productTest.productId = productId; + productTest.customerId = Cache().userLoggedIn.customerId; + productTest.dateView = DateTime.now(); + ProductTestApi().saveProductTest(productTest); + Cache().productTests.add(productTest); + } +} diff --git a/lib/bloc/sales/sales_event.dart b/lib/bloc/sales/sales_event.dart new file mode 100644 index 0000000..fffce71 --- /dev/null +++ b/lib/bloc/sales/sales_event.dart @@ -0,0 +1,17 @@ +part of 'sales_bloc.dart'; + +abstract class SalesEvent extends Equatable { + const SalesEvent(); + + @override + List get props => []; +} + +class SalesLoad extends SalesEvent { + const SalesLoad(); +} + +class SalesPurchase extends SalesEvent { + final int productId; + const SalesPurchase({this.productId}); +} diff --git a/lib/bloc/sales/sales_state.dart b/lib/bloc/sales/sales_state.dart new file mode 100644 index 0000000..e6391b7 --- /dev/null +++ b/lib/bloc/sales/sales_state.dart @@ -0,0 +1,28 @@ +part of 'sales_bloc.dart'; + +abstract class SalesState extends Equatable { + const SalesState(); + + @override + List get props => []; +} + +class SalesInitial extends SalesState { + const SalesInitial(); +} + +class SalesLoading extends SalesState { + const SalesLoading(); +} + +class SalesReady extends SalesState { + const SalesReady(); +} + +class SalesError extends SalesState { + final String message; + const SalesError({this.message}); + + @override + List get props => [message]; +} diff --git a/lib/bloc/session/session_bloc.dart b/lib/bloc/session/session_bloc.dart index eec31d2..3a910f7 100644 --- a/lib/bloc/session/session_bloc.dart +++ b/lib/bloc/session/session_bloc.dart @@ -2,16 +2,18 @@ import 'dart:async'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/localization/app_language.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/util/platform_purchase.dart'; import 'package:aitrainer_app/util/session.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; -import 'package:meta/meta.dart'; part 'session_event.dart'; part 'session_state.dart'; -class SessionBloc extends Bloc { +class SessionBloc extends Bloc with Logging { final Session session; + SessionBloc({this.session}) : super(SessionInitial()); @override @@ -20,23 +22,26 @@ class SessionBloc extends Bloc { ) async* { try { if (event is SessionStart) { + log(" -------- Session starting..."); yield SessionLoading(); // ignore: close_sinks SettingsBloc settingsBloc = event.settingsBloc; await session.fetchSessionAndNavigate(); + await PlatformPurchaseApi().initPurchasePlatformState(); String lang = AppLanguage().appLocal.languageCode; - print("Change lang to $lang"); + log("Change lang to $lang"); settingsBloc.add(SettingsChangeLanguage(language: lang)); yield SessionReady(); } - } on Exception catch(ex) { + } on Exception catch (ex) { yield SessionFailure(message: ex.toString()); } - } @override Future close() async { - await this.close(); super.close(); + await this.close(); + PlatformPurchaseApi().close(); + super.close(); } } diff --git a/lib/bloc/session/session_event.dart b/lib/bloc/session/session_event.dart index 1af5021..dbfbf8f 100644 --- a/lib/bloc/session/session_event.dart +++ b/lib/bloc/session/session_event.dart @@ -1,6 +1,5 @@ part of 'session_bloc.dart'; -@immutable abstract class SessionEvent extends Equatable { const SessionEvent(); @@ -15,4 +14,3 @@ class SessionStart extends SessionEvent { @override List get props => [settingsBloc]; } - diff --git a/lib/bloc/session/session_state.dart b/lib/bloc/session/session_state.dart index 82822c9..82d1bc0 100644 --- a/lib/bloc/session/session_state.dart +++ b/lib/bloc/session/session_state.dart @@ -1,6 +1,5 @@ part of 'session_bloc.dart'; -@immutable abstract class SessionState extends Equatable { const SessionState(); @@ -26,7 +25,4 @@ class SessionFailure extends SessionState { @override List get props => [message]; - } - - diff --git a/lib/bloc/settings/settings_bloc.dart b/lib/bloc/settings/settings_bloc.dart index 3bba465..f891807 100644 --- a/lib/bloc/settings/settings_bloc.dart +++ b/lib/bloc/settings/settings_bloc.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/cupertino.dart'; @@ -12,7 +13,7 @@ import 'package:meta/meta.dart'; part 'settings_event.dart'; part 'settings_state.dart'; -class SettingsBloc extends Bloc { +class SettingsBloc extends Bloc with Logging { String language; Locale _locale; BuildContext context; @@ -48,7 +49,7 @@ class SettingsBloc extends Bloc { yield SettingsLoading(); bool selectedHardwareBefore = await Cache().selectedHardwareBefore(); - print("selectedBefore " + selectedHardwareBefore.toString()); + log("selectedBefore " + selectedHardwareBefore.toString()); if (!selectedHardwareBefore) { await _accessHealthData(); } @@ -73,11 +74,11 @@ class SettingsBloc extends Bloc { final HealthFactory health = HealthFactory(); DateTime now = DateTime.now(); List _healthDataList = await health.getHealthDataFromTypes(now.subtract(Duration(minutes: 5)), now, types); - print(_healthDataList.toString()); + log(_healthDataList.toString()); } Future _changeLang(String lang) async { - print("_change to $lang"); + log("_change to $lang"); switch (lang) { case "English": case "en": @@ -97,15 +98,15 @@ class SettingsBloc extends Bloc { Future loadLang() async { if (_locale != null) { - print(" -- Loading lang $_locale"); + log(" -- Loading lang $_locale"); if (context != null) { AppLocalizations.of(context).setLocale(_locale); await AppLocalizations.of(context).load(); } else { - print("no context, does not load"); + log("no context, does not load"); } } else { - print("no locale, does not load"); + log("no locale, does not load"); } } } diff --git a/lib/localization/app_language.dart b/lib/localization/app_language.dart index 414cdcb..1fd196b 100644 --- a/lib/localization/app_language.dart +++ b/lib/localization/app_language.dart @@ -1,7 +1,8 @@ +import 'package:aitrainer_app/service/logging.dart'; import 'package:flutter/cupertino.dart'; import 'package:shared_preferences/shared_preferences.dart'; -class AppLanguage{ +class AppLanguage with Logging { static final AppLanguage _singleton = AppLanguage._internal(); Locale _appLocale = Locale('en'); @@ -21,27 +22,25 @@ class AppLanguage{ Future fetchLocale() async { var prefs = await SharedPreferences.getInstance(); String langCode = prefs.getString('language_code'); - print(" ---- lang code $langCode"); - if ( langCode == null) { + log(" ---- lang code $langCode"); + if (langCode == null) { _appLocale = Locale('en'); } else { _appLocale = Locale(langCode); } - print(" ---- Fetched lang: " + _appLocale.toString()); + log(" ---- Fetched lang: " + _appLocale.toString()); } getLocale(SharedPreferences prefs) { String langCode = prefs.getString('language_code'); - if ( langCode == null) { + if (langCode == null) { _appLocale = Locale('en'); langCode = "en"; } _appLocale = Locale(langCode); - print(" ---- Get lang: " + _appLocale.toString() + " lang code $langCode"); - + log(" ---- Get lang: " + _appLocale.toString() + " lang code $langCode"); } - void changeLanguage(Locale type) async { var prefs = await SharedPreferences.getInstance(); if (_appLocale == type) { @@ -56,6 +55,6 @@ class AppLanguage{ await prefs.setString('language_code', 'en'); await prefs.setString('countryCode', 'US'); } - print(" ---- Stored lang: " + _appLocale.toString()); + log(" ---- Stored lang: " + _appLocale.toString()); } } diff --git a/lib/localization/app_localization.dart b/lib/localization/app_localization.dart index 308a3fc..8cd5866 100644 --- a/lib/localization/app_localization.dart +++ b/lib/localization/app_localization.dart @@ -1,10 +1,11 @@ import 'dart:convert'; import 'dart:ui'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/services.dart'; -class AppLocalizations { +class AppLocalizations with Logging { Locale locale; bool isTest; @@ -27,7 +28,7 @@ class AppLocalizations { Future load() async { // Load the language JSON file from the "lang" folder - print(" -- load language pieces " + locale.languageCode); + log(" -- load language pieces " + locale.languageCode); String jsonString = await rootBundle.loadString('i18n/${locale.languageCode}.json'); Map jsonMap = json.decode(jsonString); diff --git a/lib/main.dart b/lib/main.dart index 16a3cc7..f7e42d8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:aitrainer_app/bloc/sales/sales_bloc.dart'; import 'package:aitrainer_app/push_notifications.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/workout_tree_repository.dart'; @@ -29,6 +30,7 @@ import 'package:aitrainer_app/view/mydevelopment_page.dart'; import 'package:aitrainer_app/view/myexcercise_plan_page.dart'; import 'package:aitrainer_app/view/registration.dart'; import 'package:aitrainer_app/view/reset_password.dart'; +import 'package:aitrainer_app/view/sales_page.dart'; import 'package:aitrainer_app/view/settings.dart'; import 'package:aitrainer_app/widgets/home.dart'; import 'package:flurry/flurry.dart'; @@ -218,6 +220,7 @@ class WorkoutTestApp extends StatelessWidget { 'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(), 'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(), 'evaluationPage': (context) => EvaluationPage(), + 'salesPage': (context) => SalesPage(), }, initialRoute: 'home', title: 'WorkoutTest', diff --git a/lib/model/cache.dart b/lib/model/cache.dart index 4e5604c..493aaa6 100644 --- a/lib/model/cache.dart +++ b/lib/model/cache.dart @@ -5,14 +5,19 @@ import 'package:aitrainer_app/model/exercise_plan_detail.dart'; import 'package:aitrainer_app/model/exercise_tree.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/model_change.dart'; +import 'package:aitrainer_app/model/product.dart'; +import 'package:aitrainer_app/model/product_test.dart'; import 'package:aitrainer_app/model/property.dart'; +import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/service/customer_exercise_device_service.dart'; +import 'package:aitrainer_app/service/customer_service.dart'; import 'package:aitrainer_app/service/exercise_device_service.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/env.dart'; import 'package:flurry/flurry.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -43,7 +48,7 @@ enum SharePrefsChange { - is_logged_in */ -class Cache { +class Cache with Logging { static final Cache _singleton = Cache._internal(); // Keys to store and fetch data from SharedPreferences @@ -65,6 +70,7 @@ class Cache { String authToken = ""; Customer userLoggedIn; String firebaseUid; + Purchase purchased; bool firstLoad = true; @@ -74,6 +80,10 @@ class Cache { List _exercises; ExercisePlan _myExercisePlan; List _properties; + List _products; + List _purchases; + List _productTests; + List _devices; List _customerDevices; @@ -130,7 +140,7 @@ class Cache { void getHardware(SharedPreferences prefs) { final bool hasHardware = prefs.getBool(Cache.hardwareKey); - print("Has Hardware: " + hasHardware.toString()); + //log("Has Hardware: " + hasHardware.toString()); this.hasHardware = hasHardware; if (hasHardware == null) { this.hasHardware = false; @@ -182,11 +192,11 @@ class Cache { return mediaUrl; } - afterRegistration(Customer customer) { + afterRegistration(Customer customer) async { Future prefs = SharedPreferences.getInstance(); userLoggedIn = customer; - setPreferences(prefs, SharePrefsChange.registration, customer.customerId, Cache().firebaseUid); + await setPreferences(prefs, SharePrefsChange.registration, customer.customerId, Cache().firebaseUid); } afterLogin(Customer customer) async { @@ -211,43 +221,28 @@ class Cache { _traineeExercisePlan = null; _exercises = List(); _myExercisesPlanDetails = LinkedHashMap(); - print("Trainees is null? " + (_trainee == null).toString()); + log("Trainees is null? " + (_trainee == null).toString()); Future prefs = SharedPreferences.getInstance(); await setPreferences(prefs, SharePrefsChange.logout, 0, ""); } - setPreferences(Future prefs, SharePrefsChange type, int customerId, String firebaseUid) async { + Future setPreferences(Future prefs, SharePrefsChange type, int customerId, String firebaseUid) async { SharedPreferences sharedPreferences; sharedPreferences = await prefs; DateTime now = DateTime.now(); sharedPreferences.setString(Cache.lastStoreDateKey, now.toString()); - ExerciseRepository exerciseRepository = ExerciseRepository(); if (type == SharePrefsChange.registration) { - Cache().startPage = "home"; - Flurry.setUserId(customerId.toString()); sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setBool(Cache.isRegisteredKey, true); sharedPreferences.setBool(Cache.isLoggedInKey, true); sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid); - await ExerciseTypeApi().getExerciseTypes(); - await ExerciseTreeApi().getExerciseTree(); - await ExerciseDeviceApi().getDevices(); - final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId); - Cache().setCustomerDevices(customerDevices); - await exerciseRepository.getExercisesByCustomer(customerId); + await initCustomer(customerId); } else if (type == SharePrefsChange.login) { - Flurry.setUserId(customerId.toString()); - Cache().startPage = "home"; sharedPreferences.setInt(Cache.customerIdKey, customerId); sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid); sharedPreferences.setBool(Cache.isLoggedInKey, true); - await ExerciseTypeApi().getExerciseTypes(); - await ExerciseTreeApi().getExerciseTree(); - await ExerciseDeviceApi().getDevices(); - final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId); - Cache().setCustomerDevices(customerDevices); - await exerciseRepository.getExercisesByCustomer(customerId); + await initCustomer(customerId); } else if (type == SharePrefsChange.logout) { sharedPreferences.setBool(Cache.isLoggedInKey, false); sharedPreferences.setInt(Cache.customerIdKey, 0); @@ -279,6 +274,16 @@ class Cache { List getExerciseTypes() => this._exerciseTypes; + ExerciseType getExercise(int exerciseTypeId) { + ExerciseType exerciseType; + this._exerciseTypes.forEach((element) { + if (element.exerciseTypeId == exerciseTypeId) { + exerciseType = element; + } + }); + return exerciseType; + } + List getExerciseTree() => this._exerciseTree; List getExercises() => this._exercises; @@ -402,6 +407,34 @@ class Cache { setBadgeNr("home", 1); } } - print("Badges: " + _badges.toString()); + log("Badges: " + _badges.toString()); + } + + List get products => _products; + void setProducts(List value) => _products = value; + + List get purchases => _purchases; + setPurchases(List value) => _purchases = value; + + List get productTests => _productTests; + set productTests(List value) => _productTests = value; + + Future initCustomer(int customerId) async { + log(" *** initCustomer"); + await CustomerApi().getCustomer(customerId); + Cache().startPage = "home"; + Flurry.setUserId(customerId.toString()); + await ExerciseTypeApi().getExerciseTypes(); + await ExerciseTreeApi().getExerciseTree(); + await ExerciseDeviceApi().getDevices(); + final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId); + Cache().setCustomerDevices(customerDevices); + + ExerciseRepository exerciseRepository = ExerciseRepository(); + await exerciseRepository.getExercisesByCustomer(customerId); + + CustomerRepository customerRepository = CustomerRepository(customer: this.userLoggedIn); + await customerRepository.getPurchase(); + await customerRepository.getProductTests(); } } diff --git a/lib/model/exercise.dart b/lib/model/exercise.dart index 9275cbf..654776b 100644 --- a/lib/model/exercise.dart +++ b/lib/model/exercise.dart @@ -12,8 +12,7 @@ class Exercise { String datePart; double calculated; - - + String summary; Exercise({this.exerciseTypeId, this.customerId, this.quantity, this.dateAdd}); @@ -24,13 +23,12 @@ class Exercise { this.quantity = json['quantity']; this.unit = json['unit']; this.unitQuantity = json['unitQuantity']; - this.dateAdd = DateTime.parse( json['dateAdd'] ); + this.dateAdd = DateTime.parse(json['dateAdd']); this.datePart = DateFormat('yyyy-MM-dd').format(this.dateAdd); this.calculated = quantity; } - Map toJson() => - { + Map toJson() => { "exerciseTypeId": exerciseTypeId, "customerId": customerId, "quantity": quantity, @@ -40,17 +38,15 @@ class Exercise { "exercisePlanDetailId": exercisePlanDetailId, }; - Map toJsonDatePart() => - { - "exerciseTypeId": exerciseTypeId, - "customerId": customerId, - "quantity": quantity, - 'calculated': calculated, - "unit": unit, - "unitQuantity": unitQuantity, - "datePart": this.datePart, - }; - + Map toJsonDatePart() => { + "exerciseTypeId": exerciseTypeId, + "customerId": customerId, + "quantity": quantity, + 'calculated': calculated, + "unit": unit, + "unitQuantity": unitQuantity, + "datePart": this.datePart, + }; Exercise copy() { Exercise newExercise = Exercise(); @@ -63,4 +59,4 @@ class Exercise { newExercise.exercisePlanDetailId = this.exercisePlanDetailId; return newExercise; } -} \ No newline at end of file +} diff --git a/lib/model/exercise_result.dart b/lib/model/exercise_result.dart index 3a9d40f..bca666e 100644 --- a/lib/model/exercise_result.dart +++ b/lib/model/exercise_result.dart @@ -13,6 +13,8 @@ class ExerciseResult { ResultExt resultExtension; + ExerciseResult(); + Map toJson() { String formattedDateTo; if (dateTo != null) { diff --git a/lib/model/fitness_state.dart b/lib/model/fitness_state.dart index 8a6d2ee..2c6394d 100644 --- a/lib/model/fitness_state.dart +++ b/lib/model/fitness_state.dart @@ -59,7 +59,6 @@ class FitnessItem { FitnessState selected; elements.forEach((element) { if (element.value == value) { - print("selected " + element.value); selected = element; } }); diff --git a/lib/model/product.dart b/lib/model/product.dart index f8a4778..ab29866 100644 --- a/lib/model/product.dart +++ b/lib/model/product.dart @@ -3,15 +3,49 @@ class Product { String name; String description; String type; + String appVersion; + int sort; + int productSet; DateTime validFrom; DateTime validTo; + String productIdIos; + String productIdAndroid; + double priceIos; + double priceAndroid; Product.fromJson(Map json) { this.productId = json['productId']; this.name = json['name']; this.description = json['description']; this.type = json['type']; - this.validFrom = json['validFrom']; - this.validTo = json['validTo']; + this.appVersion = json['appVersion']; + this.sort = json['sort']; + this.productSet = json['productSet']; + this.validFrom = json['validFrom'] == null ? null : DateTime.parse(json['validFrom']); + this.validTo = json['validTo'] == null ? null : DateTime.parse(json['validTo']); + this.productIdIos = json['productIdIos']; + this.productIdAndroid = json['productIdAndroid']; + this.priceIos = json['priceIos']; + this.priceAndroid = json['priceAndroid']; + } + + @override + String toString() { + Map json = { + 'productId': this.productId, + 'name': this.name, + 'description': this.description, + 'type': this.type, + 'appVersion': this.appVersion, + 'sort': this.sort, + 'productSet': this.productSet, + 'validFrom': this.validFrom, + 'validTo': validTo, + 'productIdIos': this.productIdIos, + 'productIdAndroid': this.productIdAndroid, + 'priceIos': this.priceIos, + 'priceAndroid': this.priceAndroid, + }; + return json.toString(); } } diff --git a/lib/model/product_test.dart b/lib/model/product_test.dart index 7a6d788..8853821 100644 --- a/lib/model/product_test.dart +++ b/lib/model/product_test.dart @@ -1,3 +1,5 @@ +import 'package:intl/intl.dart'; + class ProductTest { int productTestId; int customerId; @@ -6,11 +8,32 @@ class ProductTest { DateTime dateView; bool purchaseClick; + ProductTest(); + ProductTest.fromJson(Map json) { this.productTestId = json['productTestId']; this.customerId = json['customerId']; this.productId = json['productId']; - this.dateView = json['dateView']; + this.dateView = DateTime.parse(json['dateView']); this.purchaseClick = json['purchaseClick']; } + + Map toJson() { + if (productTestId != null) { + return { + "productTestId": productTestId, + "customerId": customerId, + "productId": productId, + "dateView": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateView), + "purchaseClick": purchaseClick + }; + } else { + return { + "customerId": customerId, + "productId": productId, + "dateView": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateView), + "purchaseClick": purchaseClick + }; + } + } } diff --git a/lib/model/purchase.dart b/lib/model/purchase.dart index 57b782a..d68cbbe 100644 --- a/lib/model/purchase.dart +++ b/lib/model/purchase.dart @@ -1,4 +1,4 @@ -import 'package:flutter_form_bloc/flutter_form_bloc.dart'; +import 'package:intl/intl.dart'; class Purchase { int purchaseId; @@ -13,13 +13,12 @@ class Purchase { this.purchaseId = json['purchaseId']; this.customerId = json['customerId']; this.productId = json['productId']; - this.dateAdd = json['dateAdd']; + this.dateAdd = DateTime.parse(json['dateAdd']); this.purchaseSum = json['purchaseSum']; - this.customerId = json['currency']; + this.currency = json['currency']; } - Map toJson() => - { + Map toJson() => { "purchaseId": purchaseId, "customerId": customerId, "productId": productId, diff --git a/lib/model/result.dart b/lib/model/result.dart index fb4442c..576fb47 100644 --- a/lib/model/result.dart +++ b/lib/model/result.dart @@ -72,7 +72,11 @@ extension ResultItemExt on ResultItem { class ResultExt { final String itemString; ResultItem item; - String data = "0"; + double data = 0; + int exerciseId; + DateTime dateFrom; + + DateTime dateTo; ResultExt({this.itemString}) { ResultItem.values.forEach((element) { @@ -84,9 +88,13 @@ class ResultExt { String getDescription() => item.description; String getImage() => "asset/image/" + item.image; - bool isHardware() { - return item.isHardware; - } + bool isHardware() => item.isHardware; + int get getExerciseId => exerciseId; + set setExerciseId(int exerciseId) => this.exerciseId = exerciseId; + set setDateFrom(DateTime dateFrom) => this.dateFrom = dateFrom; + DateTime get getDateFrom => dateFrom; + set setDateTo(DateTime dateTo) => this.dateTo = dateTo; + DateTime get getDateTo => dateTo; bool equals(ResultItem item) => this.item.equals(item); bool equalsString(String item) => this.item.equalsString(item); diff --git a/lib/push_notifications.dart b/lib/push_notifications.dart index 6ef1fb6..c2fb5a9 100644 --- a/lib/push_notifications.dart +++ b/lib/push_notifications.dart @@ -1,6 +1,7 @@ +import 'package:aitrainer_app/service/logging.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -class PushNotificationsManager { +class PushNotificationsManager with Logging { PushNotificationsManager._(); factory PushNotificationsManager() => _instance; @@ -16,9 +17,9 @@ class PushNotificationsManager { _firebaseMessaging.requestNotificationPermissions(); _firebaseMessaging.configure(); - // For testing purposes print the Firebase Messaging token + // For testing purposes log the Firebase Messaging token String token = await _firebaseMessaging.getToken(); - print("FirebaseMessaging token: $token"); + log("FirebaseMessaging token: $token"); _initialized = true; } diff --git a/lib/repository/customer_exercise_device_repository.dart b/lib/repository/customer_exercise_device_repository.dart index a46a047..8c9610e 100644 --- a/lib/repository/customer_exercise_device_repository.dart +++ b/lib/repository/customer_exercise_device_repository.dart @@ -45,8 +45,6 @@ class CustomerExerciseDeviceRepository { } Future removeDevice(ExerciseDevice device) async { - print("Remove " + device.name); - CustomerExerciseDevice found; if (_devices != null) { this._devices.forEach((element) { diff --git a/lib/repository/customer_repository.dart b/lib/repository/customer_repository.dart index 73bfeeb..450e873 100644 --- a/lib/repository/customer_repository.dart +++ b/lib/repository/customer_repository.dart @@ -3,8 +3,14 @@ import 'dart:collection'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer_property.dart'; +import 'package:aitrainer_app/model/product_test.dart'; +import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/repository/property_repository.dart'; import 'package:aitrainer_app/service/customer_service.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/service/product_test_service.dart'; +import 'package:aitrainer_app/service/purchase.dart'; +import 'package:aitrainer_app/util/not_found_exception.dart'; class GenderItem { GenderItem(this.dbValue, this.name); @@ -12,7 +18,7 @@ class GenderItem { String name; } -class CustomerRepository { +class CustomerRepository with Logging { Customer customer; Customer _trainee; List _trainees; @@ -244,4 +250,33 @@ class CustomerRepository { }); return _trainee; } + + Future> getPurchase() async { + int customerId = Cache().userLoggedIn.customerId; + List purchases = await PurchaseApi().getPurchasesByCustomer(customerId); + return purchases; + } + + Future addPurchase(Purchase purchase) async { + await PurchaseApi().savePurchase(purchase); + } + + Future> getProductTests() async { + List tests = List(); + try { + int customerId = Cache().userLoggedIn.customerId; + tests = await ProductTestApi().getProductTestByCustomer(customerId); + } on NotFoundException catch (ex) { + log("Product Tests not found"); + Cache().productTests = tests; + } on Exception catch (ex) { + log(ex.toString()); + Cache().productTests = tests; + } + return tests; + } + + Future addProductTest(ProductTest productTest) async { + await ProductTestApi().saveProductTest(productTest); + } } diff --git a/lib/repository/exercise_plan_repository.dart b/lib/repository/exercise_plan_repository.dart index 88faac4..ca2eba7 100644 --- a/lib/repository/exercise_plan_repository.dart +++ b/lib/repository/exercise_plan_repository.dart @@ -151,7 +151,6 @@ class ExercisePlanRepository { exercisePlan = await ExercisePlanApi().getLastExercisePlan(customerId); newPlan = (exercisePlan == null); - print("New plan: " + newPlan.toString()); Cache().setMyExercisePlan(exercisePlan); return exercisePlan; } diff --git a/lib/repository/exercise_repository.dart b/lib/repository/exercise_repository.dart index ae45356..8246493 100644 --- a/lib/repository/exercise_repository.dart +++ b/lib/repository/exercise_repository.dart @@ -1,17 +1,20 @@ import 'dart:collection'; +import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/service/exercise_service.dart'; +import 'package:flutter_form_bloc/flutter_form_bloc.dart'; class ExerciseRepository { Exercise exercise; Customer customer; ExerciseType exerciseType; List exerciseList; + List exerciseLogList = List(); List actualExerciseList = List(); double rmWendler = 0; @@ -78,8 +81,11 @@ class ExerciseRepository { modelExercise.unitQuantity = null; } this.actualExerciseList.add(modelExercise); + int index = this.actualExerciseList.length - 1; + Exercise savedExercise = await ExerciseApi().addExercise(modelExercise); + this.actualExerciseList[index].exerciseId = savedExercise.exerciseId; if (customer.customerId == Cache().userLoggedIn.customerId) { Cache().addExercise(savedExercise); } else if (Cache().getTrainee() != null && customer.customerId == Cache().getTrainee().customerId) { @@ -238,5 +244,44 @@ class ExerciseRepository { return actualExerciseType; } - void sortByDate() => exerciseList.sort((a, b) => b.dateAdd.compareTo(a.dateAdd)); + void sortByDate() { + exerciseList.sort((a, b) => b.dateAdd.compareTo(a.dateAdd)); + + this.exerciseLogList = List(); + String summary = ""; + + String prevDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exerciseList[0].dateAdd); + int prevExerciseTypeId = exerciseList[0].exerciseTypeId; + Exercise prevExercise = exerciseList[0]; + int prevCount = 0; + for (int i = 0; i < this.exerciseList.length; i++) { + Exercise exercise = exerciseList[i]; + int exerciseTypeId = exercise.exerciseTypeId; + String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd); + //print(" -- $prevExerciseTypeId - $prevDate"); + if (!(exerciseTypeId == prevExerciseTypeId && prevDate == exerciseDate)) { + ExerciseType exerciseType = Cache().getExercise(prevExercise.exerciseTypeId); + String unit = exerciseType.unitQuantityUnit != null ? exerciseType.unitQuantityUnit : prevExercise.unit; + prevExercise.summary = summary + " " + unit; + exerciseLogList.add(prevExercise); + //print("Log add " + exercise.toJson().toString()); + summary = ""; + prevCount = 0; + } + String delimiter = ""; + if (prevCount > 0) delimiter = ", "; + summary += delimiter + exercise.quantity.toStringAsFixed(0); + ExerciseType exerciseType = Cache().getExercise(exercise.exerciseTypeId); + if (exerciseType.unitQuantity == "1") { + summary += "x" + exercise.unitQuantity.toStringAsFixed(0); + } + //print(" --- sum " + exerciseType.name + " $summary"); + + prevExerciseTypeId = exerciseTypeId; + prevDate = exerciseDate; + prevExercise = exercise; + prevCount++; + } + ; + } } diff --git a/lib/repository/exercise_result_repository.dart b/lib/repository/exercise_result_repository.dart index 79acf37..de814a7 100644 --- a/lib/repository/exercise_result_repository.dart +++ b/lib/repository/exercise_result_repository.dart @@ -1,4 +1,7 @@ +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/exercise_result.dart'; import 'package:aitrainer_app/model/result.dart'; +import 'package:aitrainer_app/service/exercise_result_service.dart'; enum ResultType { running, man, woman, none } @@ -37,4 +40,17 @@ class ExerciseResultRepository { } List getResults() => this._results; + + Future saveExerciseResults() async { + this._results.forEach((result) async { + ExerciseResult exerciseResult = ExerciseResult(); + exerciseResult.customerId = Cache().userLoggedIn.customerId; + exerciseResult.exerciseId = result.exerciseId; + exerciseResult.dateFrom = result.dateFrom; + exerciseResult.dateTo = result.dateTo; + exerciseResult.resultType = result.itemString; + exerciseResult.value = result.data; + await ExerciseResultApi().saveExerciseResult(exerciseResult); + }); + } } diff --git a/lib/repository/workout_tree_repository.dart b/lib/repository/workout_tree_repository.dart index c4da015..314ac6c 100644 --- a/lib/repository/workout_tree_repository.dart +++ b/lib/repository/workout_tree_repository.dart @@ -8,6 +8,7 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/service/exercise_tree_service.dart'; import 'package:aitrainer_app/service/exercisetype_service.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:flutter/material.dart'; class Antagonist { @@ -29,7 +30,7 @@ class Antagonist { static int calfNr = 8; } -class WorkoutTreeRepository { +class WorkoutTreeRepository with Logging { final LinkedHashMap tree = LinkedHashMap(); SplayTreeMap sortedTree = SplayTreeMap>(); bool isEnglish; @@ -48,7 +49,7 @@ class WorkoutTreeRepository { Future createTree() async { isEnglish = AppLanguage().appLocal == Locale('en'); - print("** Start creating tree on lang: " + AppLanguage().appLocal.languageCode); + log("** Start creating tree on lang: " + AppLanguage().appLocal.languageCode); List exerciseTree = Cache().getExerciseTree(); if (exerciseTree == null || exerciseTree.length == 0) { @@ -61,7 +62,7 @@ class WorkoutTreeRepository { } exerciseTree.forEach((treeItem) async { - //print(" -- TreeItem " + treeItem.toJson().toString() + " active " + treeItem.active.toString()); + //log(" -- TreeItem " + treeItem.toJson().toString() + " active " + treeItem.active.toString()); if (treeItem.active == true) { String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation; String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7); @@ -99,7 +100,7 @@ class WorkoutTreeRepository { ); menuItem = this.setWorkoutTypes(menuItem, treeItem); this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem; - //print("WorkoutMenuTree item " + menuItem.toJson().toString()); + //log("WorkoutMenuTree item " + menuItem.toJson().toString()); } }); @@ -119,19 +120,19 @@ class WorkoutTreeRepository { WorkoutMenuTree menuItem = WorkoutMenuTree(exerciseType.exerciseTypeId, parentId, exerciseTypeName, assetImage, Colors.white, 24, true, exerciseType.exerciseTypeId, exerciseType, exerciseType.base, is1RM, isEndurance, isRunning, exerciseType.name); this.tree[exerciseType.name] = menuItem; - print("WorkoutMenuTree item " + menuItem.toJson().toString()); - print("ExerciseType in Menu item " + + //log("WorkoutMenuTree item " + menuItem.toJson().toString()); + /* log("ExerciseType in Menu item " + exerciseType.toJson().toString() + " is1RM: " + is1RM.toString() + " isEndurance: " + - isEndurance.toString()); + isEndurance.toString()); */ }); } else { - //print("No Parents " + exerciseType.toJson().toString()); + //log("No Parents " + exerciseType.toJson().toString()); } } else { - //print("ExerciseType missing data: " + exerciseType.exerciseTypeId.toString()); + //log("ExerciseType missing data: " + exerciseType.exerciseTypeId.toString()); } }); @@ -166,7 +167,7 @@ class WorkoutTreeRepository { WorkoutMenuTree treeItem = value as WorkoutMenuTree; if (treeItem.id == treeId) { isTreeItemRunning = isTreeItemRunning || treeItem.isRunning; - //print (treeItem.name + " 1RM " + treeItem.is1RM.toString() ); + //log (treeItem.name + " 1RM " + treeItem.is1RM.toString() ); } }); @@ -180,7 +181,7 @@ class WorkoutTreeRepository { WorkoutMenuTree treeItem = value as WorkoutMenuTree; if (treeItem.id == treeId) { isTreeItem1RM = isTreeItem1RM || treeItem.is1RM; - //print (treeItem.name + " 1RM " + treeItem.is1RM.toString() ); + //log (treeItem.name + " 1RM " + treeItem.is1RM.toString() ); } }); @@ -194,7 +195,7 @@ class WorkoutTreeRepository { WorkoutMenuTree treeItem = value as WorkoutMenuTree; if (treeItem.id == treeId) { isTreeItemEndurance = isTreeItemEndurance || treeItem.isEndurance; - //print(treeItem.id.toString() + " " + treeItem.name + " Endurance? " + treeItem.isEndurance.toString()); + //log(treeItem.id.toString() + " " + treeItem.name + " Endurance? " + treeItem.isEndurance.toString()); } }); @@ -208,7 +209,7 @@ class WorkoutTreeRepository { WorkoutMenuTree workoutTree = value; isChild = isChild && workoutTree.child; }); - //print("Check child " + parentId.toString() + " child: " + isChild.toString()); + //log("Check child " + parentId.toString() + " child: " + isChild.toString()); return isChild; } diff --git a/lib/service/api.dart b/lib/service/api.dart index 10c3ab1..79f3433 100644 --- a/lib/service/api.dart +++ b/lib/service/api.dart @@ -1,20 +1,22 @@ import 'dart:convert'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/not_found_exception.dart'; import 'package:http/http.dart' as http; import 'package:aitrainer_app/model/cache.dart'; -class APIClient with Common { +class APIClient with Common, Logging { Future get(String endPoint, String param) async { final url = Cache.getBaseUrl() + endPoint + param; - print("-------- API get " + url); + trace("-------- API get " + url); String authToken = Cache().getAuthToken(); if (authToken.length == 0) { - var responseJson = await APIClient.authenticateUser(Cache.username, Cache.password); + var responseJson = await this.authenticateUser(Cache.username, Cache.password); authToken = responseJson['token']; + Cache().authToken = authToken; } final response = await http.get(url, headers: {'Content-Type': 'application/json', 'Authorization': "Bearer " + authToken}); - print(" ------------get response code: " + response.statusCode.toString()); + trace(" ------------get response code: " + response.statusCode.toString()); if (response.statusCode == 200) { return utf8.decode(response.bodyBytes); } else if (response.statusCode == 404) { @@ -26,10 +28,10 @@ class APIClient with Common { Future post(String endPoint, String body) async { final url = Cache.getBaseUrl() + endPoint; - print(" ------------ http/post endpoint $endPoint body $body - url: $url "); + trace(" ------------ http/post body $body - url: $url "); String authToken = Cache().getAuthToken(); if (authToken.length == 0) { - var responseJson = await APIClient.authenticateUser(Cache.username, Cache.password); + var responseJson = await this.authenticateUser(Cache.username, Cache.password); authToken = responseJson['token']; } @@ -38,18 +40,18 @@ class APIClient with Common { headers: {'Content-Type': 'application/json; charset=UTF-8', 'Authorization': "Bearer " + authToken}, body: body, ); - print(" ------------post response code: " + response.statusCode.toString()); + trace(" ------------post response code: " + response.statusCode.toString()); final String decodedResponse = utf8convert(response.body); - print(" ------------ response: $decodedResponse"); + trace(" ------------ response: $decodedResponse"); return decodedResponse; } - static dynamic authenticateUser(String email, String password) async { + dynamic authenticateUser(String email, String password) async { var uri = Cache.getBaseUrl() + "authenticate"; try { final body = '{"username":"$email", "password":"$password"}'; - print("authentication with $email"); + trace("authentication with $email"); final response = await http.post(uri, headers: {'Authorization': '1', 'Content-Type': 'application/json'}, body: body); final responseCode = response.statusCode; if (responseCode != 200) { @@ -65,7 +67,7 @@ class APIClient with Common { } } - static fetch(var authToken, var endPoint) async { + Future fetch(var authToken, var endPoint) async { var uri = Cache.getBaseUrl() + endPoint; try { @@ -77,7 +79,7 @@ class APIClient with Common { final responseJson = json.decode(response.body); return responseJson; } catch (exception) { - print(exception); + log(exception); if (exception.toString().contains('SocketException')) { return 'NetworkError'; } else { diff --git a/lib/service/customer_exercise_device_service.dart b/lib/service/customer_exercise_device_service.dart index 34c5f83..d08a84a 100644 --- a/lib/service/customer_exercise_device_service.dart +++ b/lib/service/customer_exercise_device_service.dart @@ -1,10 +1,11 @@ import 'package:aitrainer_app/model/customer_exercise_device.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/not_found_exception.dart'; import 'dart:convert'; import 'api.dart'; -class CustomerExerciseDeviceApi { +class CustomerExerciseDeviceApi with Logging { final APIClient _client = new APIClient(); Future> getDevices(int customerId) async { @@ -14,7 +15,7 @@ class CustomerExerciseDeviceApi { final Iterable json = jsonDecode(body); devices = json.map((device) => CustomerExerciseDevice.fromJson(device)).toList(); } on NotFoundException catch (e) { - print("No devices found"); + log("No devices found"); } return devices; } @@ -23,7 +24,7 @@ class CustomerExerciseDeviceApi { CustomerExerciseDevice savedDevice; try { final String body = JsonEncoder().convert(device.toJson()); - print(" --- add customer_exercise_device: " + body); + log(" --- add customer_exercise_device: " + body); final String responseBody = await _client.post("customer_exercise_device", body); savedDevice = CustomerExerciseDevice.fromJson(jsonDecode(responseBody)); } on Exception catch (e) { @@ -34,7 +35,7 @@ class CustomerExerciseDeviceApi { Future removeDevice(int id) async { try { - print(" --- delete customer_exercise_device: " + id.toString()); + log(" --- delete customer_exercise_device: " + id.toString()); await _client.post("customer_exercise_device/delete/" + id.toString(), ""); } on Exception catch (e) { throw new Exception(e.toString()); diff --git a/lib/service/customer_service.dart b/lib/service/customer_service.dart index da870d3..87a6209 100644 --- a/lib/service/customer_service.dart +++ b/lib/service/customer_service.dart @@ -6,8 +6,9 @@ import 'package:aitrainer_app/model/property.dart'; import 'package:aitrainer_app/model/user.dart'; import 'package:aitrainer_app/service/api.dart'; import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/service/logging.dart'; -class CustomerApi { +class CustomerApi with Logging { final APIClient _client = new APIClient(); Future> getRealCustomers(String param) async { @@ -20,24 +21,24 @@ class CustomerApi { Future saveCustomer(Customer customer) async { String body = JsonEncoder().convert(customer.toJson()); - print(" ===== saving customer id: " + customer.customerId.toString() + ":" + body); + log(" ===== saving customer id: " + customer.customerId.toString() + ":" + body); await _client.post("customers/" + customer.customerId.toString(), body); } Future updateFirebaseUid(int customerId, String uid) async { - print(" ===== update Firebase uid : " + customerId.toString() + ": " + uid); + log(" ===== update Firebase uid : " + customerId.toString() + ": " + uid); await _client.post("customers/update_firebase_uid/" + customerId.toString(), uid); } Future addCustomer(Customer customer) async { String body = JsonEncoder().convert(customer.toJson()); - print(" ===== add new customer: " + body); + log(" ===== add new customer: " + body); await _client.post("customers", body); } Future addUser(User user) async { String body = JsonEncoder().convert(user.toJson()); - print(" ===== add new user: " + body); + log(" ===== add new user: " + body); final String responseBody = await _client.post("registration", body); Customer customer; try { @@ -55,7 +56,7 @@ class CustomerApi { Future getUser(User user) async { String body = JsonEncoder().convert(user.toJson()); - print(" ===== login the user: " + body); + log(" ===== login the user: " + body); final String responseBody = await _client.post("login", body); Customer customer; try { @@ -67,7 +68,7 @@ class CustomerApi { } Future getUserByEmail(String email) async { - print(" ===== User getByEmail : " + email); + log(" ===== User getByEmail : " + email); final String responseBody = await _client.get("customers/find_by_email/" + email, ""); Customer customer; try { @@ -87,20 +88,21 @@ class CustomerApi { Future getCustomer(int customerId) async { String body = ""; - print(" ===== get the customer by id: " + customerId.toString()); + log(" ===== get the customer by id: " + customerId.toString()); try { final String responseBody = await _client.get("customers/" + customerId.toString(), body); Customer customer = Customer.fromJson(jsonDecode(responseBody)); - print(" --- Customer: " + customer.toJson().toString()); + log(" --- Customer: " + customer.toJson().toString()); + Cache().userLoggedIn = customer; final List properties = await this.getActualProperties(customerId); - print(" ---- Props: " + properties.toString()); - Cache().afterRegistration(customer); + //log(" ---- Props: " + properties.toJson().toString()); + //await Cache().initCustomer(customerId); if (properties != null) { this._initProperties(properties); } } on Exception catch (exception) { - print("Exception: " + exception.toString()); - print(" === go to registration "); + log("Exception: " + exception.toString()); + log(" === go to registration "); Cache().logout(); Cache().startPage = "registration"; } @@ -130,13 +132,13 @@ class CustomerApi { Future getTrainee(int customerId) async { String body = ""; Customer customer; - print(" ===== get Trainee customer by id: " + customerId.toString()); + log(" ===== get Trainee customer by id: " + customerId.toString()); try { final String responseBody = await _client.get("customers/" + customerId.toString(), body); customer = Customer.fromJson(jsonDecode(responseBody)); - print(" --- Trainee: " + customer.toJson().toString()); + log(" --- Trainee: " + customer.toJson().toString()); } catch (exception) { - print("Exception: " + exception.toString()); + log("Exception: " + exception.toString()); throw Exception(exception); } return customer; @@ -144,14 +146,14 @@ class CustomerApi { Future> getTrainees(int trainerId) async { List trainees = List(); - print("Get trainees list"); + log("Get trainees list"); try { String body = ""; final String responseBody = await _client.get("customers/trainees/" + trainerId.toString(), body); final Iterable json = jsonDecode(responseBody); trainees = json.map((customer) => Customer.fromJson(customer)).toList(); } catch (exception) { - print("Exception: " + exception.toString()); + log("Exception: " + exception.toString()); throw Exception(exception); } return trainees; @@ -174,18 +176,18 @@ class CustomerApi { if (properties != null) { properties.forEach((element) { - print("Property " + element.toString()); + //log("Property " + element.toString()); }); } } on Exception catch (ex) { - print(ex.toString()); + log(ex.toString()); } return properties; } Future addProperty(CustomerProperty property) async { String body = JsonEncoder().convert(property.toJson()); - print(" ===== add new customer property: " + body); + log(" ===== add new customer property: " + body); final String responseBody = await _client.post("customer_property", body); try { int status = jsonDecode(responseBody)['status']; diff --git a/lib/service/exercise_plan_service.dart b/lib/service/exercise_plan_service.dart index 35db27e..4d891b7 100644 --- a/lib/service/exercise_plan_service.dart +++ b/lib/service/exercise_plan_service.dart @@ -1,41 +1,34 @@ import 'package:aitrainer_app/model/exercise_plan.dart'; import 'package:aitrainer_app/model/exercise_plan_detail.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/not_found_exception.dart'; import 'dart:convert'; import 'api.dart'; -class ExercisePlanApi { +class ExercisePlanApi with Logging { final APIClient _client = new APIClient(); Future saveExercisePlan(ExercisePlan exercisePlan) async { String body = JsonEncoder().convert(exercisePlan.toJson()); - print(" ===== saving exercisePlan $exercisePlan"); + log(" ===== saving exercisePlan $exercisePlan"); ExercisePlan savedExercisePlan; try { - final String responseBody = await _client.post( - "exercise_plan", - body); + final String responseBody = await _client.post("exercise_plan", body); savedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody)); - - } on Exception catch(e) { + } on Exception catch (e) { throw new Exception(e.toString()); } return savedExercisePlan; } - Future updateExercisePlan( - ExercisePlan exercisePlan, - int exercisePlanId) async { + Future updateExercisePlan(ExercisePlan exercisePlan, int exercisePlanId) async { String body = JsonEncoder().convert(exercisePlan.toJson()); - print(" ===== update exercisePlan $exercisePlan"); + log(" ===== update exercisePlan $exercisePlan"); ExercisePlan updatedExercisePlan; try { - final String responseBody = await _client.post( - "exercise_plan/" + exercisePlanId.toString(), - body); + final String responseBody = await _client.post("exercise_plan/" + exercisePlanId.toString(), body); updatedExercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody)); - - } on Exception catch(e) { + } on Exception catch (e) { throw new Exception(e.toString()); } return updatedExercisePlan; @@ -43,44 +36,36 @@ class ExercisePlanApi { Future saveExercisePlanDetail(ExercisePlanDetail exercisePlanDetail) async { String body = JsonEncoder().convert(exercisePlanDetail.toJson()); - print(" ===== save exercisePlanDetail $exercisePlanDetail"); + log(" ===== save exercisePlanDetail $exercisePlanDetail"); ExercisePlanDetail savedExercisePlanDetail; try { - final String responseBody = await _client.post( - "exercise_plan_detail", - body); + final String responseBody = await _client.post("exercise_plan_detail", body); savedExercisePlanDetail = ExercisePlanDetail.fromJson(jsonDecode(responseBody)); - } on Exception catch(e) { + } on Exception catch (e) { throw new Exception(e.toString()); } return savedExercisePlanDetail; } - Future updateExercisePlanDetail(ExercisePlanDetail exercisePlanDetail, - int exercisePlanDetailId) async { + Future updateExercisePlanDetail(ExercisePlanDetail exercisePlanDetail, int exercisePlanDetailId) async { String body = JsonEncoder().convert(exercisePlanDetail.toJson()); - print(" ===== update exercisePlanDetail $exercisePlanDetail"); + log(" ===== update exercisePlanDetail $exercisePlanDetail"); ExercisePlanDetail savedExercisePlanDetail; try { - final String responseBody = await _client.post( - "exercise_plan_detail/" + exercisePlanDetailId.toString(), - body); + final String responseBody = await _client.post("exercise_plan_detail/" + exercisePlanDetailId.toString(), body); savedExercisePlanDetail = ExercisePlanDetail.fromJson(jsonDecode(responseBody)); - } on Exception catch(e) { + } on Exception catch (e) { throw new Exception(e.toString()); } return savedExercisePlanDetail; } Future deleteExercisePlanDetail(int exercisePlanDetailId) async { - print(" ===== delete exercisePlanDetail $exercisePlanDetailId"); + log(" ===== delete exercisePlanDetail $exercisePlanDetailId"); String body = ""; try { - await _client.post( - "exercise_plan_detail/delete/" + exercisePlanDetailId.toString(), - body); - - } on Exception catch(e) { + await _client.post("exercise_plan_detail/delete/" + exercisePlanDetailId.toString(), body); + } on Exception catch (e) { throw new Exception(e.toString()); } return; @@ -88,14 +73,11 @@ class ExercisePlanApi { Future deleteExercisePlan(int exercisePlanId) async { String body = ""; - print(" ===== delete exercisePlan $exercisePlanId"); + log(" ===== delete exercisePlan $exercisePlanId"); try { - await _client.post( - "exercise_plan/delete/" + exercisePlanId.toString(), - body); - - } on Exception catch(e) { + await _client.post("exercise_plan/delete/" + exercisePlanId.toString(), body); + } on Exception catch (e) { throw new Exception(e.toString()); } return; @@ -103,16 +85,14 @@ class ExercisePlanApi { Future getLastExercisePlan(int customerId) async { String body = ""; - print(" ===== get last exercisePlan $customerId"); + log(" ===== get last exercisePlan $customerId"); ExercisePlan exercisePlan; try { - final String responseBody = await _client.get( - "exercise_plan/last/" + customerId.toString(), - body); + final String responseBody = await _client.get("exercise_plan/last/" + customerId.toString(), body); exercisePlan = ExercisePlan.fromJson(jsonDecode(responseBody)); - } on Exception catch(e) { - if ( e is NotFoundException) { - print("ExercisePlan not found for " + customerId.toString()); + } on Exception catch (e) { + if (e is NotFoundException) { + log("ExercisePlan not found for " + customerId.toString()); return exercisePlan; } else { throw new Exception(e.toString()); @@ -123,22 +103,16 @@ class ExercisePlanApi { Future> getExercisePlanDetail(int exercisePlanId) async { String body = ""; - print(" ===== get exercisePlanDetail $exercisePlanId"); + log(" ===== get exercisePlanDetail $exercisePlanId"); List listExercisePlanDetail; try { - final String responseBody = await _client.get( - "exercise_plan_detail/" + exercisePlanId.toString(), - body); - print("response body:" + responseBody); + final String responseBody = await _client.get("exercise_plan_detail/" + exercisePlanId.toString(), body); + log("response body:" + responseBody); final Iterable json = jsonDecode(responseBody); - listExercisePlanDetail = json.map( (planDetail) => ExercisePlanDetail.fromJson(planDetail) ) .toList(); - } on Exception catch(e) { + listExercisePlanDetail = json.map((planDetail) => ExercisePlanDetail.fromJson(planDetail)).toList(); + } on Exception catch (e) { throw new Exception(e.toString()); } return listExercisePlanDetail; } - - - - -} \ No newline at end of file +} diff --git a/lib/service/exercise_result_service.dart b/lib/service/exercise_result_service.dart new file mode 100644 index 0000000..0ff7288 --- /dev/null +++ b/lib/service/exercise_result_service.dart @@ -0,0 +1,28 @@ +import 'dart:convert'; + +import 'package:aitrainer_app/model/exercise_result.dart'; +import 'package:aitrainer_app/service/logging.dart'; + +import 'api.dart'; + +class ExerciseResultApi with Logging { + final APIClient _client = new APIClient(); + + Future saveExerciseResult(ExerciseResult exerciseResult) async { + String body = JsonEncoder().convert(exerciseResult.toJson()); + log(" ===== saving exercise result:" + body); + await _client.post("exercise_result", body); + } + + Future> getExerciseResultsByCustomer(int customerId) async { + final body = await _client.get("exercise_result/", customerId.toString()); + final Iterable json = jsonDecode(body); + final List exerciseResults = json.map((exerciseResult) { + ExerciseResult item = ExerciseResult.fromJson(exerciseResult); + return item; + }).toList(); + //exercises.sort( (a, b) => b.dateAdd.compareTo(a.dateAdd) ); + + return exerciseResults; + } +} diff --git a/lib/service/exercise_service.dart b/lib/service/exercise_service.dart index 0abb9e9..02ec870 100644 --- a/lib/service/exercise_service.dart +++ b/lib/service/exercise_service.dart @@ -1,8 +1,9 @@ import 'dart:convert'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/service/api.dart'; +import 'package:aitrainer_app/service/logging.dart'; -class ExerciseApi { +class ExerciseApi with Logging { final APIClient _client = new APIClient(); Future> getExerciseTypes(String param) async { @@ -15,7 +16,7 @@ class ExerciseApi { Future saveExercise(Exercise exercise) async { String body = JsonEncoder().convert(exercise.toJson()); - print(" ===== saving exercise id: " + exercise.exerciseId.toString() + ":" + body); + log(" ===== saving exercise id: " + exercise.exerciseId.toString() + ":" + body); await _client.post("exercises/" + exercise.exerciseId.toString(), body); } @@ -33,7 +34,7 @@ class ExerciseApi { Future addExercise(Exercise exercise) async { String body = JsonEncoder().convert(exercise.toJson()); - print(" ===== add new exercise: " + body); + log(" ===== add new exercise: " + body); final String response = await _client.post("exercises", body); final Exercise savedExercise = Exercise.fromJson(jsonDecode(response)); return savedExercise; @@ -41,7 +42,7 @@ class ExerciseApi { Future deleteExercise(Exercise exercise) async { int exerciseId = exercise.exerciseId; - print(" ===== delete exercise: " + exerciseId.toString()); + log(" ===== delete exercise: " + exerciseId.toString()); await _client.post("exercises/" + exerciseId.toString(), ""); return; } diff --git a/lib/service/exercise_tree_service.dart b/lib/service/exercise_tree_service.dart index fbf9989..1b83ead 100644 --- a/lib/service/exercise_tree_service.dart +++ b/lib/service/exercise_tree_service.dart @@ -43,7 +43,7 @@ class ExerciseTreeApi { index++; } }); - print("ExerciseTree " + element.toJson().toString()); + //print("ExerciseTree " + element.toJson().toString()); treeIndex++; }); diff --git a/lib/service/exercisetype_service.dart b/lib/service/exercisetype_service.dart index ea24e1b..6afe41b 100644 --- a/lib/service/exercisetype_service.dart +++ b/lib/service/exercisetype_service.dart @@ -2,8 +2,9 @@ import 'dart:convert'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/service/api.dart'; +import 'package:aitrainer_app/service/logging.dart'; -class ExerciseTypeApi { +class ExerciseTypeApi with Logging { final APIClient _client = new APIClient(); Future> getExerciseTypes() async { @@ -16,13 +17,13 @@ class ExerciseTypeApi { Future saveExerciseType(ExerciseType exerciseType) async { String body = JsonEncoder().convert(exerciseType.toJson()); - print(" ===== saving exerciseType id: " + exerciseType.exerciseTypeId.toString() + ":" + body); + log(" ===== saving exerciseType id: " + exerciseType.exerciseTypeId.toString() + ":" + body); await _client.post("exercise_type/" + exerciseType.exerciseTypeId.toString(), body); } Future addExerciseType(ExerciseType exerciseType) async { String body = JsonEncoder().convert(exerciseType.toJson()); - print(" ===== add new exerciseType: " + body); + log(" ===== add new exerciseType: " + body); await _client.post("exercise_type", body); } } diff --git a/lib/service/firebase_api.dart b/lib/service/firebase_api.dart index c3d3c83..e285755 100644 --- a/lib/service/firebase_api.dart +++ b/lib/service/firebase_api.dart @@ -1,9 +1,10 @@ import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; //import 'package:flutter_facebook_auth/flutter_facebook_auth.dart'; -class FirebaseApi { +class FirebaseApi with Logging { static FirebaseApi _instance; static final FirebaseAuth auth = FirebaseAuth.instance; @@ -29,7 +30,7 @@ class FirebaseApi { await Firebase.initializeApp(); } catch (e) { // Set `_error` state to true if Firebase initialization fails - print("Error initializing Firebase"); + log("Error initializing Firebase"); } } @@ -40,10 +41,10 @@ class FirebaseApi { Cache().firebaseUid = userCredential.user.uid; } on FirebaseAuthException catch (e) { if (e.code == 'user-not-found') { - print('No user found for that email.'); + log('No user found for that email.'); rc = SIGN_IN_NOT_FOUND; } else if (e.code == 'wrong-password') { - print('Wrong password provided for that user.'); + log('Wrong password provided for that user.'); rc = SIGN_IN_WRONG_PWD; throw Exception("Customer does not exist or the password is wrong"); } @@ -59,16 +60,16 @@ class FirebaseApi { Cache().firebaseUid = userCredential.user.uid; } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { - print('The password provided is too weak.'); + log('The password provided is too weak.'); rc = REGISTER_WEAK_PWD; throw Exception("Password too short"); } else if (e.code == 'email-already-in-use') { - print('The account already exists for that email.'); + log('The account already exists for that email.'); rc = REGISTER_EMAIL_IN_USE; throw Exception("The email address has been registered already"); } } catch (e) { - print(e); + log(e); throw Exception(e.toString()); } return rc; diff --git a/lib/service/logging.dart b/lib/service/logging.dart new file mode 100644 index 0000000..738dc79 --- /dev/null +++ b/lib/service/logging.dart @@ -0,0 +1,16 @@ +import 'package:aitrainer_app/util/env.dart'; +import 'package:intl/intl.dart'; + +mixin Logging { + void log(String message) { + DateTime time = DateTime.now(); + print(DateFormat('yyyy-MM-dd HH:mm:ss ').format(time) + message); + } + + void trace(String message) { + String testEnv = EnvironmentConfig.test_env; + if (testEnv == "1") { + log(message); + } + } +} diff --git a/lib/service/product_service.dart b/lib/service/product_service.dart new file mode 100644 index 0000000..99b1ccc --- /dev/null +++ b/lib/service/product_service.dart @@ -0,0 +1,17 @@ +import 'dart:convert'; + +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/product.dart'; +import 'package:aitrainer_app/service/api.dart'; + +class ProductApi { + final APIClient _client = new APIClient(); + + Future> getProducts() async { + final body = await _client.get("product/", ""); + final Iterable json = jsonDecode(body); + final List products = json.map((product) => Product.fromJson(product)).toList(); + Cache().setProducts(products); + return products; + } +} diff --git a/lib/service/product_test_service.dart b/lib/service/product_test_service.dart new file mode 100644 index 0000000..a96b524 --- /dev/null +++ b/lib/service/product_test_service.dart @@ -0,0 +1,23 @@ +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/product_test.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'dart:convert'; +import 'api.dart'; + +class ProductTestApi with Logging { + final APIClient _client = new APIClient(); + + Future> getProductTestByCustomer(int customerId) async { + final body = await _client.get("product_test/customer/" + customerId.toString(), ""); + final Iterable json = jsonDecode(body); + final List productTests = json.map((productTest) => ProductTest.fromJson(productTest)).toList(); + Cache().productTests = productTests; + return productTests; + } + + Future saveProductTest(ProductTest productTest) async { + String body = JsonEncoder().convert(productTest.toJson()); + log(" ===== saving productTest:" + body); + await _client.post("product_test/", body); + } +} diff --git a/lib/service/purchase.dart b/lib/service/purchase.dart new file mode 100644 index 0000000..c805a44 --- /dev/null +++ b/lib/service/purchase.dart @@ -0,0 +1,23 @@ +import 'package:aitrainer_app/model/cache.dart'; +import 'package:aitrainer_app/model/purchase.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'dart:convert'; +import 'api.dart'; + +class PurchaseApi with Logging { + final APIClient _client = new APIClient(); + + Future> getPurchasesByCustomer(int customerId) async { + final body = await _client.get("purchase/customer/" + customerId.toString(), ""); + final Iterable json = jsonDecode(body); + final List purchases = json.map((purchase) => Purchase.fromJson(purchase)).toList(); + Cache().setPurchases(purchases); + return purchases; + } + + Future savePurchase(Purchase purchase) async { + String body = JsonEncoder().convert(purchase.toJson()); + log(" ===== saving purchase:" + body); + await _client.post("purchase/", body); + } +} diff --git a/lib/util/common.dart b/lib/util/common.dart index be05f68..3519db6 100644 --- a/lib/util/common.dart +++ b/lib/util/common.dart @@ -4,6 +4,7 @@ import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/repository/user_repository.dart'; +import 'package:aitrainer_app/util/env.dart'; import 'package:flutter/cupertino.dart'; import 'package:intl/intl.dart'; @@ -15,26 +16,23 @@ class DateRate { } mixin Common { - final EMAIL_ERROR = "Please type a right email address here."; final PASSWORD_ERROR = "The password must have at least 8 characters."; - - - String toJson( Map map ) { + String toJson(Map map) { String rc = "{"; map.forEach((key, value) { - rc += "'$key':'$value'"; + rc += "'$key':'$value'"; }); rc += "}"; return rc; } - ExerciseType getExerciseType( int exerciseTypeId ) { + ExerciseType getExerciseType(int exerciseTypeId) { ExerciseType returnElement; List listExerciseType = Cache().getExerciseTypes(); - if ( listExerciseType != null ) { - for ( var element in listExerciseType ) { + if (listExerciseType != null) { + for (var element in listExerciseType) { if (exerciseTypeId == element.exerciseTypeId) { returnElement = element; break; @@ -44,12 +42,12 @@ mixin Common { return returnElement; } - String getDateLocale( DateTime datetime, bool timeDisplay ) { + String getDateLocale(DateTime datetime, bool timeDisplay) { var date = datetime; String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(date.toUtc()); - if ( timeDisplay ) { - dateName += " " +DateFormat(DateFormat.HOUR_MINUTE, AppLanguage().appLocal.toString()).format(date.toUtc()); + if (timeDisplay) { + dateName += " " + DateFormat(DateFormat.HOUR_MINUTE, AppLanguage().appLocal.toString()).format(date.toUtc()); } return dateName; @@ -60,8 +58,8 @@ mixin Common { return utf8.decode(bytes); } - double mediaSizeWidth( BuildContext context ) { - return MediaQuery.of(context).size.width; + double mediaSizeWidth(BuildContext context) { + return MediaQuery.of(context).size.width; } bool validateEmail(UserRepository userRepository) { @@ -74,8 +72,7 @@ mixin Common { bool validatePassword(UserRepository userRepository) { final password = userRepository.user.password; - final RegExp _passwordRegExp = - RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$'); + final RegExp _passwordRegExp = RegExp(r'^(?=.*[A-Za-z0-9])(?=.*\d)[A-Za-z\d]{7,}$'); return _passwordRegExp.hasMatch(password); } @@ -88,16 +85,15 @@ mixin Common { String getDatePart(DateTime date, String dateRate) { String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date); - if ( dateRate == DateRate.weekly ) { + if (dateRate == DateRate.weekly) { datePart = weekNumber(date).toString(); - } else if ( dateRate == DateRate.monthly ) { - datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date); - } else if ( dateRate == DateRate.yearly ) { - datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date); - } else if ( dateRate == DateRate.daily ) { - datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date); + } else if (dateRate == DateRate.monthly) { + datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date); + } else if (dateRate == DateRate.yearly) { + datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date); + } else if (dateRate == DateRate.daily) { + datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date); } return datePart; } - -} \ No newline at end of file +} diff --git a/lib/util/platform_purchase.dart b/lib/util/platform_purchase.dart new file mode 100644 index 0000000..02cbf3d --- /dev/null +++ b/lib/util/platform_purchase.dart @@ -0,0 +1,115 @@ +import 'dart:async'; + +import 'package:aitrainer_app/service/logging.dart'; +import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart'; + +class PlatformPurchaseApi with Logging { + static final PlatformPurchaseApi _singleton = PlatformPurchaseApi._internal(); + + StreamSubscription _purchaseUpdatedSubscription; + StreamSubscription _purchaseErrorSubscription; + StreamSubscription _conectionSubscription; + String _platformVersion = 'Unknown'; + List _items = []; + List _purchases = []; + + final List _productLists = List(); + /* Platform.isAndroid + ? [ + 'android.test.purchased', + 'point_1000', + '5000_point', + 'android.test.canceled', + ] + : ['com.cooni.point1000', 'com.cooni.point5000']; + */ + + factory PlatformPurchaseApi() { + return _singleton; + } + + PlatformPurchaseApi._internal(); + + void close() { + if (_conectionSubscription != null) { + _conectionSubscription.cancel(); + _conectionSubscription = null; + } + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPurchasePlatformState() async { + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + try { + platformVersion = await FlutterInappPurchase.instance.platformVersion; + } on Exception { + platformVersion = 'Failed to get platform version for InAppPurchase.'; + log(platformVersion); + } + + // prepare + var result = await FlutterInappPurchase.instance.initConnection; + log('result: $result'); + + _platformVersion = platformVersion; + + // refresh items for android + try { + String msg = await FlutterInappPurchase.instance.consumeAllItems; + log('consumeAllItems: $msg'); + } catch (err) { + log('consumeAllItems error: $err'); + } + + _conectionSubscription = FlutterInappPurchase.connectionUpdated.listen((connected) { + log('connected: $connected'); + }); + + _purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) { + log('purchase-updated: $productItem'); + }); + + _purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) { + log('purchase-error: $purchaseError'); + }); + } + + void requestPurchase(IAPItem item) { + //FlutterInappPurchase.instance.requestPurchase(item.productId); + FlutterInappPurchase.instance.requestPurchase("WT_monthly"); + } + + Future _getProduct() async { + List items = await FlutterInappPurchase.instance.getProducts(_productLists); + for (var item in items) { + log('${item.toString()}'); + this._items.add(item); + } + + this._items = items; + this._purchases = []; + } + + Future _getPurchases() async { + List items = await FlutterInappPurchase.instance.getAvailablePurchases(); + for (var item in items) { + log('${item.toString()}'); + this._purchases.add(item); + } + + this._items = []; + this._purchases = items; + } + + Future _getPurchaseHistory() async { + List items = await FlutterInappPurchase.instance.getPurchaseHistory(); + for (var item in items) { + log('${item.toString()}'); + this._purchases.add(item); + } + + this._items = []; + this._purchases = items; + } +} diff --git a/lib/util/session.dart b/lib/util/session.dart index b3130ce..b6995e0 100644 --- a/lib/util/session.dart +++ b/lib/util/session.dart @@ -1,39 +1,34 @@ import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_localization.dart'; -import 'package:aitrainer_app/model/customer_exercise_device.dart'; -import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/service/api.dart'; -import 'package:aitrainer_app/service/customer_exercise_device_service.dart'; -import 'package:aitrainer_app/service/customer_service.dart'; -import 'package:aitrainer_app/service/exercise_device_service.dart'; -import 'package:aitrainer_app/service/exercise_tree_service.dart'; -import 'package:aitrainer_app/service/exercisetype_service.dart'; import 'package:aitrainer_app/service/firebase_api.dart'; +import 'package:aitrainer_app/service/logging.dart'; +import 'package:aitrainer_app/service/product_service.dart'; import 'package:aitrainer_app/service/property_service.dart'; import 'package:devicelocale/devicelocale.dart'; -import 'package:flurry/flurry.dart'; import 'package:flutter/services.dart'; +import 'package:mockito/mockito.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:aitrainer_app/model/cache.dart'; -class Session { +class Session with Logging { Future _prefs = SharedPreferences.getInstance(); SharedPreferences _sharedPreferences; fetchSessionAndNavigate() async { - print(" -- Session: await prefs.."); + log(" -- Session: await prefs.."); _sharedPreferences = await _prefs; if (Cache().firstLoad) { - print(" -- Session: fetch locale.."); + log(" -- Session: fetch locale.."); await AppLanguage().getLocale(_sharedPreferences); await AppLocalizations.delegate.load(AppLanguage().appLocal); - print(" -- Session: fetch token.."); + log(" -- Session: fetch token.."); Cache().setServerAddress(_sharedPreferences); Cache().getHardware(_sharedPreferences); await _fetchToken(_sharedPreferences); - print(" -- FireBase init.."); + log(" -- FireBase init.."); await FirebaseApi().initializeFlutterFire(); //initDeviceLocale(); @@ -50,15 +45,15 @@ class Session { try { languages = await Devicelocale.preferredLanguages; Cache().deviceLanguages = languages; - print("device langs " + languages.toString()); + log("device langs " + languages.toString()); } on PlatformException { - print("Error obtaining preferred languages"); + log("Error obtaining preferred languages"); } try { currentLocale = await Devicelocale.currentLocale; - print("Device currentlocale " + currentLocale); + log("Device currentlocale " + currentLocale); } on PlatformException { - print("Error obtaining current locale"); + log("Error obtaining current locale"); } } @@ -66,18 +61,19 @@ class Session { Auth flow of the user, see auth.dart */ _fetchToken(SharedPreferences prefs) async { - var responseJson = await APIClient.authenticateUser(Cache.username, Cache.password); + var responseJson = await APIClient().authenticateUser(Cache.username, Cache.password); int customerId = 0; - print("--- Lang: " + AppLanguage().appLocal.toString()); + log("--- Lang: " + AppLanguage().appLocal.toString()); if (responseJson['error'] != null) { - print("************** Here big error - no authentication"); + log("************** Here big error - no authentication"); } else if (responseJson['token'] != null) { prefs.setString(Cache.authTokenKey, responseJson['token']); Cache().authToken = responseJson['token']; Cache().firebaseUid = prefs.get(Cache.firebaseUidKey); await PropertyApi().getProperties(); + await ProductApi().getProducts(); if (prefs.get(Cache.customerIdKey) == null) { - print("************** Registration"); + log("************** Registration"); // registration prefs.setBool(Cache.isRegisteredKey, true); Cache().startPage = "registration"; @@ -90,31 +86,21 @@ class Session { lastStoreDate.difference(minStoreDate) > Duration(days: 10) || prefs.get(Cache.isLoggedInKey) == null || prefs.get(Cache.isLoggedInKey) == false) { - print("************* Login"); + log("************* Login"); Cache().startPage = "login"; } else { // only if (Cache().firebaseUid == null) { - print("************* firebaseUid is null, Login"); + log("************* firebaseUid is null, Login"); Cache().startPage = "login"; } else { // get API customer customerId = prefs.getInt(Cache.customerIdKey); - await CustomerApi().getCustomer(customerId); Cache().startPage = "home"; - Flurry.setUserId(customerId.toString()); - await ExerciseTypeApi().getExerciseTypes(); - await ExerciseTreeApi().getExerciseTree(); - await ExerciseDeviceApi().getDevices(); - final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId); - Cache().setCustomerDevices(customerDevices); - if (customerId > 0) { - ExerciseRepository exerciseRepository = ExerciseRepository(); - await exerciseRepository.getExercisesByCustomer(customerId); - } + await Cache().initCustomer(customerId); } } - print("--- Session finished"); + log("--- Session finished"); } } } diff --git a/lib/view/custom_exercise_page.dart b/lib/view/custom_exercise_page.dart index 30055c8..0f2624e 100644 --- a/lib/view/custom_exercise_page.dart +++ b/lib/view/custom_exercise_page.dart @@ -4,6 +4,7 @@ import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart'; import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/widgets/splash.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -15,7 +16,7 @@ class CustomExercisePage extends StatefulWidget { _CustomExerciseNewPageState createState() => _CustomExerciseNewPageState(); } -class _CustomExerciseNewPageState extends State { +class _CustomExerciseNewPageState extends State with Logging { final GlobalKey _scaffoldKey = new GlobalKey(); @override @@ -23,8 +24,7 @@ class _CustomExerciseNewPageState extends State { final ExerciseType exerciseType = ModalRoute.of(context).settings.arguments; return BlocProvider( - create: (context) => - CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()), + create: (context) => CustomExerciseFormBloc(exerciseRepository: ExerciseRepository()), child: Builder(builder: (context) { final exerciseBloc = BlocProvider.of(context); exerciseBloc.exerciseRepository.setExerciseType(exerciseType); @@ -59,93 +59,58 @@ class _CustomExerciseNewPageState extends State { onFailure: (context, state) { LoadingDialog.hide(context); Scaffold.of(context).showSnackBar(SnackBar( - backgroundColor: Colors.orange, - content: Text(state.failureResponse, - style: TextStyle(color: Colors.white)))); + backgroundColor: Colors.orange, content: Text(state.failureResponse, style: TextStyle(color: Colors.white)))); }, child: Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( image: DecorationImage( - image: - AssetImage('asset/image/WT_light_background.png'), + image: AssetImage('asset/image/WT_light_background.png'), fit: BoxFit.fill, alignment: Alignment.center, ), ), - child: CustomScrollView( - scrollDirection: Axis.vertical, - slivers: [ - SliverList( - delegate: SliverChildListDelegate( - [ - Container( - padding: EdgeInsets.only(top:20,left:25, right:25), - alignment: Alignment.center, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text("Custom Exercise", - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: Colors.deepOrange)), - columnQuantityUnit(exerciseBloc), - columnQuantity(exerciseBloc), - ] - ) - ), - ] - ), - - ), + child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ + SliverList( + delegate: SliverChildListDelegate([ + Container( + padding: EdgeInsets.only(top: 20, left: 25, right: 25), + alignment: Alignment.center, + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + Text("Custom Exercise", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Colors.deepOrange)), + columnQuantityUnit(exerciseBloc), + columnQuantity(exerciseBloc), + ])), + ]), + ), gridCalculation(exerciseBloc) - ] - ) - ) - ) - ); + ])))); })); } Column columnQuantityUnit(CustomExerciseFormBloc bloc) { Column column = Column(); - if (bloc.exerciseRepository.exerciseType != null && - bloc.exerciseRepository.exerciseType.unitQuantity == "1") { + if (bloc.exerciseRepository.exerciseType != null && bloc.exerciseRepository.exerciseType.unitQuantity == "1") { column = Column(children: [ TextFieldBlocBuilder( textFieldBloc: bloc.unitQuantityField, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - color: Colors.lightBlue, - fontWeight: FontWeight.bold), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) - ], - onChanged: (input) => { - print("UnitQuantity value $input"), - bloc.exerciseRepository.setUnitQuantity(double.parse(input)) - }, + style: TextStyle(fontSize: 16, color: Colors.lightBlue, fontWeight: FontWeight.bold), + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))], + onChanged: (input) => {log("UnitQuantity value $input"), bloc.exerciseRepository.setUnitQuantity(double.parse(input))}, decoration: InputDecoration( fillColor: Colors.white, filled: false, - hintStyle: TextStyle( - fontSize: 12, - color: Colors.black54, - fontWeight: FontWeight.w100), - hintText: AppLocalizations.of(context) - .translate("The number of the exercise done with"), + hintStyle: TextStyle(fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100), + hintText: AppLocalizations.of(context).translate("The number of the exercise done with"), labelStyle: TextStyle(fontSize: 12, color: Colors.lightBlue), - labelText: AppLocalizations.of(context).translate( - bloc.exerciseRepository.exerciseType.unitQuantityUnit), + labelText: AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unitQuantityUnit), ), ), new InkWell( - child: new Text( - AppLocalizations.of(context).translate( - bloc.exerciseRepository.exerciseType.unitQuantityUnit), + child: new Text(AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unitQuantityUnit), style: TextStyle(fontSize: 12)), ), ]); @@ -158,29 +123,20 @@ class _CustomExerciseNewPageState extends State { TextFieldBlocBuilder( textFieldBloc: bloc.quantityField, textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - color: Colors.deepOrange, - fontWeight: FontWeight.bold), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) - ], + style: TextStyle(fontSize: 20, color: Colors.deepOrange, fontWeight: FontWeight.bold), + inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r"[\d.]"))], onChanged: (input) => { - print("Quantity value $input"), + log("Quantity value $input"), bloc.exerciseRepository.setQuantity(double.parse(input)), - bloc.exerciseRepository - .setUnit(bloc.exerciseRepository.exerciseType.unit) + bloc.exerciseRepository.setUnit(bloc.exerciseRepository.exerciseType.unit) }, decoration: InputDecoration( fillColor: Colors.white, filled: false, - hintStyle: TextStyle( - fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100), - hintText: AppLocalizations.of(context) - .translate("The number of the exercise"), + hintStyle: TextStyle(fontSize: 12, color: Colors.black54, fontWeight: FontWeight.w100), + hintText: AppLocalizations.of(context).translate("The number of the exercise"), labelStyle: TextStyle(fontSize: 12, color: Colors.deepOrange), - labelText: AppLocalizations.of(context) - .translate(bloc.exerciseRepository.exerciseType.unit), + labelText: AppLocalizations.of(context).translate(bloc.exerciseRepository.exerciseType.unit), ), ), ]); @@ -191,18 +147,18 @@ class _CustomExerciseNewPageState extends State { SliverGrid gridCalculation(CustomExerciseFormBloc bloc) { LinkedHashMap args = LinkedHashMap(); return SliverGrid( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 3, - mainAxisSpacing: 10.0, - crossAxisSpacing: 10.0, - childAspectRatio: 2.0, - ), - delegate: SliverChildListDelegate( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 10.0, + crossAxisSpacing: 10.0, + childAspectRatio: 2.0, + ), + delegate: SliverChildListDelegate( [ - TextFieldBlocBuilder( + TextFieldBlocBuilder( readOnly: true, textFieldBloc: bloc.rmWendlerField, - padding: EdgeInsets.only(left:10), + padding: EdgeInsets.only(left: 10), style: TextStyle(color: Colors.deepOrange, fontSize: 12), decoration: InputDecoration( border: InputBorder.none, @@ -210,9 +166,9 @@ class _CustomExerciseNewPageState extends State { filled: false, labelText: "1RM by Wendler: ", )), - TextFieldBlocBuilder( + TextFieldBlocBuilder( readOnly: true, - padding: EdgeInsets.only(left:10), + padding: EdgeInsets.only(left: 10), maxLines: 1, textFieldBloc: bloc.rmWathenField, style: TextStyle(color: Colors.deepOrange, fontSize: 12), @@ -222,9 +178,9 @@ class _CustomExerciseNewPageState extends State { filled: false, labelText: "1RM by Wahten: ", )), - TextFieldBlocBuilder( + TextFieldBlocBuilder( readOnly: true, - padding: EdgeInsets.only(left:10), + padding: EdgeInsets.only(left: 10), maxLines: 1, textFieldBloc: bloc.rmOconnerField, style: TextStyle(color: Colors.deepOrange, fontSize: 12), @@ -234,9 +190,9 @@ class _CustomExerciseNewPageState extends State { filled: false, labelText: "1RM by O'Conner: ", )), - TextFieldBlocBuilder( + TextFieldBlocBuilder( readOnly: true, - padding: EdgeInsets.only(left:10), + padding: EdgeInsets.only(left: 10), maxLines: 1, textFieldBloc: bloc.rmMayhewField, style: TextStyle(color: Colors.deepOrange, fontSize: 12), @@ -246,9 +202,9 @@ class _CustomExerciseNewPageState extends State { filled: false, labelText: "1RM by Mayhew: ", )), - TextFieldBlocBuilder( + TextFieldBlocBuilder( readOnly: true, - padding: EdgeInsets.only(left:10), + padding: EdgeInsets.only(left: 10), maxLines: 1, textFieldBloc: bloc.rmAverageField, style: TextStyle(color: Colors.blueAccent, fontSize: 12), @@ -259,138 +215,133 @@ class _CustomExerciseNewPageState extends State { labelText: "1RM Average: ", )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm90Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 90%: ", - )), - + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm90Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 90%: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm75Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 75%: ", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm75Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 75%: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm75OconnorField, - style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 75%: by O'Connor", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm75OconnorField, + style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 75%: by O'Connor", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm75WendlerField, - style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 75% by Wendler: ", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm75WendlerField, + style: TextStyle(color: Colors.deepOrange, fontSize: 12, fontWeight: FontWeight.normal), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 75% by Wendler: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm80Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 80%: ", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm80Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 80%: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm70Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 70%: ", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm70Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 70%: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm60Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 60%: ", - )), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm60Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 60%: ", + )), TextFieldBlocBuilder( - readOnly: true, - padding: EdgeInsets.only(left:10), - maxLines: 1, - textFieldBloc: bloc.rm50Field, - style: TextStyle(color: Colors.deepOrange, fontSize: 12), - decoration: InputDecoration( - border: InputBorder.none, - fillColor: Colors.white, - filled: false, - labelText: "1RM 50%: ", - ) - ), + readOnly: true, + padding: EdgeInsets.only(left: 10), + maxLines: 1, + textFieldBloc: bloc.rm50Field, + style: TextStyle(color: Colors.deepOrange, fontSize: 12), + decoration: InputDecoration( + border: InputBorder.none, + fillColor: Colors.white, + filled: false, + labelText: "1RM 50%: ", + )), RaisedButton( - padding: EdgeInsets.all(0), - textColor: Colors.white, - color: Colors.blue, - focusColor: Colors.blueAccent, - onPressed: () => - { - args['exerciseRepository'] = bloc.exerciseRepository, - args['percent'] = 0.75, - args['readonly'] = true, - Navigator.of(context).pushNamed('exerciseControlPage', - arguments: args) - }, - child: Text("Control with 75%", - style: TextStyle(fontSize: 12),) - ), + padding: EdgeInsets.all(0), + textColor: Colors.white, + color: Colors.blue, + focusColor: Colors.blueAccent, + onPressed: () => { + args['exerciseRepository'] = bloc.exerciseRepository, + args['percent'] = 0.75, + args['readonly'] = true, + Navigator.of(context).pushNamed('exerciseControlPage', arguments: args) + }, + child: Text( + "Control with 75%", + style: TextStyle(fontSize: 12), + )), RaisedButton( - padding: EdgeInsets.all(0), - textColor: Colors.white, - color: Colors.green, - focusColor: Colors.blueAccent, - onPressed: () => - { - args['exerciseRepository'] = bloc.exerciseRepository, - args['percent'] = 0.5, - args['readonly'] = true, - Navigator.of(context).pushNamed('exerciseControlPage', - arguments: args ) - }, - child: Text("Control with 50%", - style: TextStyle(fontSize: 12),) - ), - ], - ) - ); + padding: EdgeInsets.all(0), + textColor: Colors.white, + color: Colors.green, + focusColor: Colors.blueAccent, + onPressed: () => { + args['exerciseRepository'] = bloc.exerciseRepository, + args['percent'] = 0.5, + args['readonly'] = true, + Navigator.of(context).pushNamed('exerciseControlPage', arguments: args) + }, + child: Text( + "Control with 50%", + style: TextStyle(fontSize: 12), + )), + ], + )); } @override diff --git a/lib/view/customer_bodytype_page.dart b/lib/view/customer_bodytype_page.dart index 70c8f0f..7357b4b 100644 --- a/lib/view/customer_bodytype_page.dart +++ b/lib/view/customer_bodytype_page.dart @@ -24,8 +24,7 @@ class _CustomerBodyTypePageState extends State { String selected; @override Widget build(BuildContext context) { - final CustomerRepository customerRepository = - ModalRoute.of(context).settings.arguments; + final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments; final double cWidth = MediaQuery.of(context).size.width * 0.75; return Scaffold( @@ -51,12 +50,10 @@ class _CustomerBodyTypePageState extends State { ), ), child: BlocProvider( - create: (context) => - CustomerChangeBloc(customerRepository: customerRepository), + create: (context) => CustomerChangeBloc(customerRepository: customerRepository), child: Builder(builder: (context) { // ignore: close_sinks - CustomerChangeBloc changeBloc = - BlocProvider.of(context); + CustomerChangeBloc changeBloc = BlocProvider.of(context); return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -67,14 +64,9 @@ class _CustomerBodyTypePageState extends State { alignment: WrapAlignment.center, children: [ Text( - AppLocalizations.of(context) - .translate("Your Body Type"), + AppLocalizations.of(context).translate("Your Body Type"), textAlign: TextAlign.center, - style: TextStyle( - color: Colors.orange, - fontSize: 42, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), + style: TextStyle(color: Colors.orange, fontSize: 42, fontFamily: 'Arial', fontWeight: FontWeight.w900), ) ]), Divider(), @@ -83,25 +75,17 @@ class _CustomerBodyTypePageState extends State { width: cWidth, child: Column( children: [ - Text( - AppLocalizations.of(context) - .translate("Endomorph"), + Text(AppLocalizations.of(context).translate("Endomorph"), textWidthBasis: TextWidthBasis.longestLine, - style: TextStyle( - color: Colors.blue, - fontSize: 32, - fontFamily: 'Arial', - fontWeight: FontWeight.w900)), + style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)), ], )), padding: EdgeInsets.all(10.0), - shape: getShape( - customerRepository, BodyTypeItem.endomorph), + shape: getShape(customerRepository, BodyTypeItem.endomorph), onPressed: () => { setState(() { selected = BodyTypeItem.endomorph; changeBloc.add(CustomerBodyTypeChange(bodyType: selected)); - print(selected); }), }), Divider(), @@ -112,13 +96,8 @@ class _CustomerBodyTypePageState extends State { children: [ InkWell( child: Text( - AppLocalizations.of(context) - .translate("Ectomorph"), - style: TextStyle( - color: Colors.blue, - fontSize: 32, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), + AppLocalizations.of(context).translate("Ectomorph"), + style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900), ), highlightColor: Colors.white, ), @@ -126,13 +105,11 @@ class _CustomerBodyTypePageState extends State { ), ), padding: EdgeInsets.all(10.0), - shape: getShape(customerRepository, BodyTypeItem.ectomorph ), - + shape: getShape(customerRepository, BodyTypeItem.ectomorph), onPressed: () => { setState(() { selected = BodyTypeItem.ectomorph; changeBloc.add(CustomerBodyTypeChange(bodyType: selected)); - print(selected); }), }), Divider(), @@ -143,13 +120,8 @@ class _CustomerBodyTypePageState extends State { children: [ InkWell( child: Text( - AppLocalizations.of(context) - .translate("Mesomorph"), - style: TextStyle( - color: Colors.blue, - fontSize: 32, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), + AppLocalizations.of(context).translate("Mesomorph"), + style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900), ), highlightColor: Colors.white, ), @@ -157,22 +129,18 @@ class _CustomerBodyTypePageState extends State { ), ), padding: EdgeInsets.all(10.0), - shape: getShape(customerRepository, BodyTypeItem.mesomorph ), + shape: getShape(customerRepository, BodyTypeItem.mesomorph), onPressed: () => { setState(() { selected = BodyTypeItem.mesomorph; changeBloc.add(CustomerBodyTypeChange(bodyType: selected)); - - print(selected); }), }), Divider(), RaisedButton( color: Colors.orange, textColor: Colors.white, - child: InkWell( - child: Text( - AppLocalizations.of(context).translate("Next"))), + child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))), onPressed: () => { changeBloc.add(CustomerSave()), Navigator.of(context).pop(), diff --git a/lib/view/customer_exercise_device.dart b/lib/view/customer_exercise_device.dart index 6c451e0..357a0ed 100644 --- a/lib/view/customer_exercise_device.dart +++ b/lib/view/customer_exercise_device.dart @@ -180,7 +180,6 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans { } List getDevices(CustomerExerciseDeviceBloc bloc, double cWidth, double cHeight) { - print("height " + cHeight.toString()); final bool isEnglish = AppLanguage().appLocal.languageCode == "en"; this.listDevice = List(); final devices = bloc.devices; @@ -211,7 +210,6 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans { } List getDevicesPlace(CustomerExerciseDeviceBloc bloc, double cWidth, cHeight) { - print("height " + cHeight.toString() + " width " + cWidth.toString()); final bool isEnglish = AppLanguage().appLocal.languageCode == "en"; this.listDevice = List(); final devices = bloc.devices; @@ -243,7 +241,6 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans { } void changeButtonShape(ExerciseDevice device, CustomerExerciseDeviceBloc bloc) { - print("Device clicked: " + device.name); if (bloc.hasCustomerDevice(device.exerciseDeviceId)) { bloc.add(CustomerExerciseDeviceRemove(device: device)); } else { diff --git a/lib/view/customer_fitness_page.dart b/lib/view/customer_fitness_page.dart index 04c63f7..cb43aa0 100644 --- a/lib/view/customer_fitness_page.dart +++ b/lib/view/customer_fitness_page.dart @@ -101,7 +101,6 @@ class _CustomerFitnessPageState extends State { setState(() { selected = FitnessState.beginner; changeBloc.add(CustomerFitnessChange(fitness: selected)); - print(selected); }), }), Divider(), diff --git a/lib/view/customer_goal_page.dart b/lib/view/customer_goal_page.dart index 6ff4792..f9b523a 100644 --- a/lib/view/customer_goal_page.dart +++ b/lib/view/customer_goal_page.dart @@ -12,19 +12,16 @@ class GoalsItem { // ignore: must_be_immutable class CustomerGoalPage extends StatefulWidget { - @override State createState() => _CustomerGoalPage(); } - class _CustomerGoalPage extends State { String selected; @override Widget build(BuildContext context) { - final CustomerRepository customerRepository = - ModalRoute.of(context).settings.arguments; + final CustomerRepository customerRepository = ModalRoute.of(context).settings.arguments; return Scaffold( appBar: AppBar( @@ -51,111 +48,80 @@ class _CustomerGoalPage extends State { height: double.infinity, width: double.infinity, child: BlocProvider( - create: (context) => - CustomerChangeBloc(customerRepository: customerRepository), + create: (context) => CustomerChangeBloc(customerRepository: customerRepository), child: Builder(builder: (context) { - CustomerChangeBloc changeBloc = - BlocProvider.of(context); - + CustomerChangeBloc changeBloc = BlocProvider.of(context); return SingleChildScrollView( child: Center( - child: Column( - children: [ - Divider(), - InkWell( - child: Text( - AppLocalizations.of(context) - .translate("Set Your Goals"), - style: TextStyle( - color: Colors.orange, - fontSize: 50, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), - ), - highlightColor: Colors.white, + child: Column( + children: [ + Divider(), + InkWell( + child: Text( + AppLocalizations.of(context).translate("Set Your Goals"), + style: TextStyle(color: Colors.orange, fontSize: 50, fontFamily: 'Arial', fontWeight: FontWeight.w900), + ), + highlightColor: Colors.white, + ), + Stack(alignment: Alignment.bottomLeft, overflow: Overflow.visible, children: [ + FlatButton( + child: Image.asset( + "asset/image/Gain_muscle.png", + height: 180, ), - Stack( - alignment: Alignment.bottomLeft, - overflow: Overflow.visible, - children: [ - FlatButton( - child: Image.asset( - "asset/image/Gain_muscle.png", - height: 180, - ), - padding: EdgeInsets.all(0.0), - shape: getShape(changeBloc, GoalsItem.muscle), - onPressed: () => { - print("gain muscle"), - setState((){ - selected = GoalsItem.muscle; - changeBloc.add(CustomerGoalChange(goal: GoalsItem.muscle)); - }), - + padding: EdgeInsets.all(0.0), + shape: getShape(changeBloc, GoalsItem.muscle), + onPressed: () => { + setState(() { + selected = GoalsItem.muscle; + changeBloc.add(CustomerGoalChange(goal: GoalsItem.muscle)); }), - InkWell( - child: Text( - AppLocalizations.of(context) - .translate("Gain Muscle"), - style: TextStyle( - color: Colors.white, - fontSize: 32, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), - ), - highlightColor: Colors.white, - ) - ]), - Divider(), - Stack( - alignment: Alignment.bottomLeft, - overflow: Overflow.visible, - children: [ - FlatButton( - child: Image.asset( - "asset/image/WT_weight_loss.png", - height: 180, - ), - padding: EdgeInsets.all(0.0), - shape: getShape(changeBloc, GoalsItem.weight), - onPressed: () => { - print("weight_loss"), - setState((){ - selected = GoalsItem.muscle; - changeBloc.add(CustomerGoalChange(goal: GoalsItem.weight)); - }), - - }), - InkWell( - child: Text( - AppLocalizations.of(context) - .translate("Loose Weight"), - style: TextStyle( - color: Colors.white, - fontSize: 32, - fontFamily: 'Arial', - fontWeight: FontWeight.w900), - ), - highlightColor: Colors.white, - ) - ]), - Divider(), - RaisedButton( - color: Colors.orange, - textColor: Colors.white, - child: InkWell( - child: Text( - AppLocalizations.of(context).translate("Next"))), - onPressed: () => { - //changingViewModel.saveCustomer(), - changeBloc.add(CustomerSave()), - Navigator.of(context).pop(), - Navigator.of(context).pushNamed("customerFitnessPage", - arguments: changeBloc.customerRepository) - }, - ) - ], + }), + InkWell( + child: Text( + AppLocalizations.of(context).translate("Gain Muscle"), + style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900), + ), + highlightColor: Colors.white, + ) + ]), + Divider(), + Stack(alignment: Alignment.bottomLeft, overflow: Overflow.visible, children: [ + FlatButton( + child: Image.asset( + "asset/image/WT_weight_loss.png", + height: 180, + ), + padding: EdgeInsets.all(0.0), + shape: getShape(changeBloc, GoalsItem.weight), + onPressed: () => { + setState(() { + selected = GoalsItem.muscle; + changeBloc.add(CustomerGoalChange(goal: GoalsItem.weight)); + }), + }), + InkWell( + child: Text( + AppLocalizations.of(context).translate("Loose Weight"), + style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900), + ), + highlightColor: Colors.white, + ) + ]), + Divider(), + RaisedButton( + color: Colors.orange, + textColor: Colors.white, + child: InkWell(child: Text(AppLocalizations.of(context).translate("Next"))), + onPressed: () => { + //changingViewModel.saveCustomer(), + changeBloc.add(CustomerSave()), + Navigator.of(context).pop(), + Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository) + }, + ) + ], ), )); }), diff --git a/lib/view/evaluation.dart b/lib/view/evaluation.dart index 6ee9922..4231138 100644 --- a/lib/view/evaluation.dart +++ b/lib/view/evaluation.dart @@ -41,7 +41,6 @@ class EvaluationPage extends StatelessWidget with Trans { resultType = ResultType.running; imageUrl = 'asset/image/WT_Results_for_runners.png'; } - print("ResultType: " + resultType.toString()); setContext(context); return Scaffold( appBar: AppBarMin( @@ -489,7 +488,7 @@ class EvaluationPage extends StatelessWidget with Trans { width: 10, ), Text( - element.data, + element.data.toStringAsFixed(0), style: GoogleFonts.archivoBlack(fontSize: 28, color: blur ? Colors.white30 : Colors.white), ), Text( diff --git a/lib/view/exercise_execute_plan_add_page.dart b/lib/view/exercise_execute_plan_add_page.dart index 22ba5fa..afb08d0 100644 --- a/lib/view/exercise_execute_plan_add_page.dart +++ b/lib/view/exercise_execute_plan_add_page.dart @@ -175,59 +175,12 @@ class _ExerciseExecuteAddPage extends State with Tra ), Text(t("repeat")), ]), - - /*TextFieldBlocBuilder( - readOnly: exerciseBloc.step != i+1, - textFieldBloc: exerciseBloc.unitQuantity1Field, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - color: Colors.black54, - fontWeight: FontWeight.bold), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) - ], - - decoration: InputDecoration( - fillColor: Colors.white, - filled: false, - hintStyle: TextStyle( - fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100), - labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal), - labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit, - ), - ),*/ - /*TextFieldBlocBuilder( - readOnly: exerciseBloc.step != i+1, - textFieldBloc: exerciseBloc.quantity1Field, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 18, - color: Colors.deepOrange, - fontWeight: FontWeight.bold), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) - ], - - decoration: InputDecoration( - fillColor: Colors.white, - filled: false, - hintStyle: TextStyle( - fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100), - hintText: t("The number of the exercise"), - labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal), - labelText: t("Please repeat with") + " "+ exerciseBloc.unitQuantity1Field.value + " " + - exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " + - exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() + " " + t("times!"), - ), - ),*/ RaisedButton( padding: EdgeInsets.all(0), textColor: Colors.white, color: exerciseBloc.step == i + 1 ? Colors.blue : Colors.black26, focusColor: Colors.blueAccent, onPressed: () => { - print("Submit step " + exerciseBloc.step.toString() + " (i) " + i.toString()), if (exerciseBloc.step == i + 1) {exerciseBloc.add(ExerciseExecutePlanAddSubmit())}, if (i + 1 == exerciseBloc.countSteps) {Navigator.of(context).pop()} }, diff --git a/lib/view/exercise_log_page.dart b/lib/view/exercise_log_page.dart index 9da9909..eb96053 100644 --- a/lib/view/exercise_log_page.dart +++ b/lib/view/exercise_log_page.dart @@ -1,7 +1,9 @@ import 'dart:collection'; import 'package:aitrainer_app/bloc/exercise_log/exercise_log_bloc.dart'; +import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; +import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:aitrainer_app/widgets/splash.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -34,7 +36,7 @@ class _ExerciseLogPage extends State with Trans, Common { create: (context) => ExerciseLogBloc(exerciseRepository: ExerciseRepository())..add(ExerciseLogLoad()), child: BlocConsumer(listener: (context, state) { if (state is ExerciseLogLoading) { - //LoadingDialog.show(context); + return LoadingDialog(); } else if (state is ExerciseLogError) { //LoadingDialog.hide(context); Scaffold.of(context).showSnackBar( @@ -45,7 +47,10 @@ class _ExerciseLogPage extends State with Trans, Common { if (state is ExerciseLogReady) { //LoadingDialog.hide(context); return getExerciseLog(customerId, exerciseBloc); + } else if (state is ExerciseLogLoading) { + return LoadingDialog(); } else { + //LoadingDialog.hide(context); return getExerciseLog(customerId, exerciseBloc); } })); @@ -59,8 +64,8 @@ class _ExerciseLogPage extends State with Trans, Common { decoration: BoxDecoration( image: DecorationImage( image: customerId == Cache().userLoggedIn.customerId - ? AssetImage('asset/image/WT_light_background.png') - : AssetImage('asset/image/WT_menu_dark.png'), + ? AssetImage('asset/image/WT_black_background.png') + : AssetImage('asset/image/WT_light_background.png'), fit: BoxFit.cover, alignment: Alignment.center, ), @@ -123,7 +128,7 @@ class _ExerciseLogPage extends State with Trans, Common { List listExercises = List(); String origDate = ""; - exerciseRepository.exerciseList.forEach((exercise) { + exerciseRepository.exerciseLogList.forEach((exercise) { String exerciseDate = DateFormat("yyyy-MM-dd", AppLanguage().appLocal.toString()).format(exercise.dateAdd); if (origDate != exerciseDate) { @@ -168,25 +173,16 @@ class _ExerciseLogPage extends State with Trans, Common { ExerciseType exerciseType = exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId); String exerciseName = isEnglish ? exerciseType.name : exerciseType.nameTranslation; - String unitQuantity = - exerciseType.unitQuantity == "1" ? exercise.unitQuantity.toStringAsFixed(0) + " " + t(exerciseType.unitQuantityUnit) + " " : ""; - - String labelExercise = unitQuantity + exercise.quantity.toStringAsFixed(0) + " " + t(exercise.unit); - list.add( Card( margin: EdgeInsets.only(left: 10, top: 5), color: Colors.white54, child: Container( - padding: const EdgeInsets.only(left: 5, top: 0, right: 5, bottom: 0), + padding: const EdgeInsets.only(left: 15, top: 0, right: 5, bottom: 0), child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [ - Icon(Icons.accessibility, color: Colors.black12), - SizedBox( - width: 10, - ), Flexible( fit: FlexFit.tight, - flex: 8, + flex: 20, child: Text( exerciseName, style: TextStyle(fontSize: 12, color: Colors.black), @@ -195,17 +191,35 @@ class _ExerciseLogPage extends State with Trans, Common { Flexible( fit: FlexFit.tight, child: SizedBox( - width: 10, + width: 5, )), - Text( - labelExercise, - style: TextStyle(fontSize: 9, color: Colors.blueAccent.shade700), - ), Flexible( fit: FlexFit.tight, - child: SizedBox( - width: 10, + flex: 20, + child: Text( + exercise.summary == null ? "" : exercise.summary, + style: TextStyle(fontSize: 12, color: Colors.blue[800]), )), + Stack( + children: [ + IconButton( + iconSize: 36, + icon: Icon(CustomIcon.heart_1, color: Colors.blue[800]), + onPressed: () { + evaluation(); + }, + ), + GestureDetector( + child: Image.asset( + 'asset/image/lock.png', + height: 25, + width: 25, + ), + onTap: () { + evaluation(); + }), + ], + ), IconButton( icon: Icon(Icons.delete, color: Colors.black12), onPressed: () { @@ -220,6 +234,19 @@ class _ExerciseLogPage extends State with Trans, Common { return list; } + void evaluation() { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.", + text: "OK", + ); + }); + } + void confirmationDialog(ExerciseLogBloc bloc, Exercise exercise) { ExerciseType exerciseType = bloc.exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId); String exerciseName = AppLanguage().appLocal == Locale("en") ? exerciseType.name : exerciseType.nameTranslation; @@ -260,11 +287,7 @@ class _ExerciseLogPage extends State with Trans, Common { ), FlatButton( child: Text(t("Yes")), - onPressed: () => { - print("delete exercise: " + exercise.toJson().toString()), - bloc.add(ExerciseLogDelete(exercise: exercise)), - Navigator.pop(context) - }, + onPressed: () => {bloc.add(ExerciseLogDelete(exercise: exercise)), Navigator.pop(context)}, ) ], )); diff --git a/lib/view/exercise_new_page.dart b/lib/view/exercise_new_page.dart index 22201a0..5e69855 100644 --- a/lib/view/exercise_new_page.dart +++ b/lib/view/exercise_new_page.dart @@ -9,6 +9,7 @@ import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bmi_widget.dart'; @@ -27,7 +28,7 @@ class ExerciseNewPage extends StatefulWidget { _ExerciseNewPageState createState() => _ExerciseNewPageState(); } -class _ExerciseNewPageState extends State with Trans { +class _ExerciseNewPageState extends State with Trans, Logging { final FocusNode _nodeText1 = FocusNode(); final FocusNode _nodeText2 = FocusNode(); @@ -123,7 +124,7 @@ class _ExerciseNewPageState extends State with Trans { exerciseDescription = ""; } - //print(exerciseBloc.exerciseRepository.exerciseType.name); + //log(exerciseBloc.exerciseRepository.exerciseType.name); if (exerciseBloc.exerciseRepository.exerciseType.name == "BMR") { return BMR(exerciseBloc: exerciseBloc); @@ -409,7 +410,6 @@ class _ExerciseNewPageState extends State with Trans { void confirmationDialog(ExerciseNewBloc bloc, MenuBloc menuBloc) { LinkedHashMap args = LinkedHashMap(); - print("exercise validated " + bloc.exerciseRepository.exercise.quantity.toString()); if (bloc.exerciseRepository.exercise.quantity == null) { return; } @@ -459,7 +459,7 @@ class _ExerciseNewPageState extends State with Trans { bloc.add(ExerciseNewSubmit()), Navigator.pop(context), Navigator.pop(context), - print("Ability " + + log("Ability " + menuBloc.ability.toString() + " exerciseType 1rm " + bloc.exerciseRepository.exerciseType.is1RM().toString()), diff --git a/lib/view/mydevelopment_body_page.dart b/lib/view/mydevelopment_body_page.dart index 5998705..7aadbbb 100644 --- a/lib/view/mydevelopment_body_page.dart +++ b/lib/view/mydevelopment_body_page.dart @@ -1,7 +1,9 @@ +import 'dart:async'; import 'dart:collection'; import 'package:aitrainer_app/library/radar_chart.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; +import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:aitrainer_app/widgets/splash.dart'; import 'package:flutter/scheduler.dart'; import 'package:aitrainer_app/model/cache.dart'; @@ -17,12 +19,30 @@ class MyDevelopmentBodyPage extends StatefulWidget { } class _MyDevelopmentBodyPage extends State with Trans, Common { + bool isStart = false; // ignore: close_sinks BodyDevelopmentBloc bloc; @override void initState() { super.initState(); + Timer( + Duration(milliseconds: 2000), + () => { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Body Development feature is reachable if you finished the second 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop(), Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop(), Navigator.of(context).pop()}, + ); + }) + }); /// We require the initializers to run after the loading screen is rendered SchedulerBinding.instance.addPostFrameCallback((_) { @@ -38,13 +58,14 @@ class _MyDevelopmentBodyPage extends State with Trans, Co setContext(context); return Scaffold( - appBar: AppBarNav(depth: 1), - body: Container( + appBar: AppBarNav(depth: 1), + body: Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( image: DecorationImage( - image: customerId == Cache().userLoggedIn.customerId ? AssetImage('asset/image/WT_light_background.png'): - AssetImage('asset/image/WT_menu_dark.png'), + image: customerId == Cache().userLoggedIn.customerId + ? AssetImage('asset/image/WT_light_background.png') + : AssetImage('asset/image/WT_menu_dark.png'), fit: BoxFit.cover, alignment: Alignment.center, ), @@ -56,29 +77,24 @@ class _MyDevelopmentBodyPage extends State with Trans, Co } }, builder: (context, state) { - if ( state is BodyDevelopmentInitial) { + if (state is BodyDevelopmentInitial) { return Container(); } else { return developmentWidget(customerId); } }, - ) - - ), - bottomNavigationBar: BottomNavigator(bottomNavIndex: 1), + )), + bottomNavigationBar: BottomNavigator(bottomNavIndex: 1), ); } Widget developmentWidget(int customerId) { - return Column( - children: [ - explanationWidget(), - Expanded( - child: exerciseWidget(customerId), - ), - - ] - ); + return Column(children: [ + explanationWidget(), + Expanded( + child: exerciseWidget(customerId), + ), + ]); } Widget exerciseWidget(int customerId) { @@ -91,39 +107,33 @@ class _MyDevelopmentBodyPage extends State with Trans, Co Widget explanationWidget() { return Card( - color: Colors.white60, - child: Container( - padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Row( + color: Colors.white60, + child: Container( + padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - Icon( - Icons.info, - color: Colors.orangeAccent, + Row( + children: [ + Icon( + Icons.info, + color: Colors.orangeAccent, + ), + Text(" "), + Text( + t("My Body Development"), + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + ], + ), + Divider( + color: Colors.transparent, ), - Text(" "), Text( - t("My Body Development"), - style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + t("You see here your whole body development by muscle groups."), + style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal), ), ], - ), - Divider( - color: Colors.transparent, - ), - Text( - t("You see here your whole body development by muscle groups."), - style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal), - ), - - ], - ) - ) - ); + ))); } - - - } diff --git a/lib/view/mydevelopment_muscle_page.dart b/lib/view/mydevelopment_muscle_page.dart index 969706f..22a7945 100644 --- a/lib/view/mydevelopment_muscle_page.dart +++ b/lib/view/mydevelopment_muscle_page.dart @@ -1,6 +1,8 @@ +import 'dart:async'; import 'dart:collection'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; +import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:aitrainer_app/widgets/treeview_parent_widget.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:aitrainer_app/util/common.dart'; @@ -8,7 +10,6 @@ import 'package:aitrainer_app/bloc/development_by_muscle/development_by_muscle_b import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/library/tree_view.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; -import 'package:aitrainer_app/widgets/splash.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -29,6 +30,23 @@ class _MyDevelopmentMuscleState extends State with Comm @override void initState() { super.initState(); + Timer( + Duration(milliseconds: 2000), + () => { + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Muscle Development feature is reachable if you finished the first 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop(), Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop(), Navigator.of(context).pop()}, + ); + }) + }); /// We require the initializers to run after the loading screen is rendered SchedulerBinding.instance.addPostFrameCallback((_) { diff --git a/lib/view/mydevelopment_page.dart b/lib/view/mydevelopment_page.dart index 9e50fed..1491375 100644 --- a/lib/view/mydevelopment_page.dart +++ b/lib/view/mydevelopment_page.dart @@ -3,6 +3,7 @@ import 'dart:collection'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; +import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; @@ -25,7 +26,6 @@ class _MyDevelopmentPage extends State with Trans { setContext(context); double mediaWidth = MediaQuery.of(context).size.width; double imageWidth = (mediaWidth - 45) / 2; - print("Media: " + mediaWidth.toString() + " imageWidth: " + imageWidth.toString()); return Scaffold( appBar: AppBarNav(depth: 0), @@ -46,13 +46,11 @@ class _MyDevelopmentPage extends State with Trans { textAlignment: Alignment.topCenter, text: t("My Exercise Logs"), style: GoogleFonts.robotoMono( - textStyle: TextStyle( - fontSize: 14, - color: Colors.orange, - fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4) - ) - ), + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), image: "asset/image/edzesnaplom400400.jpg", left: 5, onTap: () => this.callBackExerciseLog(exerciseRepository, customerRepository), @@ -64,10 +62,10 @@ class _MyDevelopmentPage extends State with Trans { text: t("My Whole Body Development"), style: GoogleFonts.robotoMono( textStyle: TextStyle( - fontSize: 14, - color: Colors.orange, - fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4)), + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4)), ), image: "asset/image/testemfejl400x400.jpg", left: 5, @@ -82,11 +80,11 @@ class _MyDevelopmentPage extends State with Trans { textAlignment: Alignment.topLeft, text: t("Development Of Muscles"), style: GoogleFonts.robotoMono( - textStyle: TextStyle( - fontSize: 14, - color: Colors.orange, - fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), image: "asset/image/izomcsop400400.jpg", left: 5, onTap: () => {Navigator.of(context).pushNamed('mydevelopmentMusclePage', arguments: args)}, @@ -98,13 +96,26 @@ class _MyDevelopmentPage extends State with Trans { textAlignment: Alignment.topLeft, text: t("Predictions"), style: GoogleFonts.robotoMono( - textStyle: TextStyle( - fontSize: 14, - color: Colors.orange, - fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), image: "asset/image/predictions.jpg", - onTap: () => {}, + onTap: () => { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Predictions feature is reachable if you finished the second 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop()}, + ); + }) + }, isLocked: true, ), hiddenWidget(customerRepository, exerciseRepository), diff --git a/lib/view/myexcercise_plan_page.dart b/lib/view/myexcercise_plan_page.dart index 35004a8..c6d6bad 100644 --- a/lib/view/myexcercise_plan_page.dart +++ b/lib/view/myexcercise_plan_page.dart @@ -1,9 +1,11 @@ import 'dart:collection'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; +import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:aitrainer_app/widgets/image_button.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -14,7 +16,7 @@ class MyExercisePlanPage extends StatefulWidget { _MyExercisePlanPage createState() => _MyExercisePlanPage(); } -class _MyExercisePlanPage extends State with Trans { +class _MyExercisePlanPage extends State with Trans, Logging { @override Widget build(BuildContext context) { final ExerciseRepository exerciseRepository = ExerciseRepository(); @@ -23,114 +25,146 @@ class _MyExercisePlanPage extends State with Trans { double mediaWidth = MediaQuery.of(context).size.width; double imageWidth = (mediaWidth - 45) / 2; - print("Media: " + mediaWidth.toString() + " imageWidth: " + imageWidth.toString()); return Scaffold( - appBar: AppBarNav(depth: 0), - body: Container( - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage('asset/image/WT_menu_dark.png'), - fit: BoxFit.cover, - alignment: Alignment.center, - ), - ), - child: CustomScrollView( - scrollDirection: Axis.vertical, - slivers: - [ - SliverGrid( - delegate: SliverChildListDelegate( - [ - ImageButton( - width: imageWidth, - textAlignment: Alignment.topLeft, - text: t("Execute My Selected Training Plan"), - style: GoogleFonts.robotoMono( - textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), - image: "asset/image/exercise_plan_execute.jpg", - top: 130, - left: 5, - onTap:() => { - args['customerId'] = Cache().userLoggedIn.customerId, - Navigator.of(context).pushNamed('exerciseExecutePlanPage', - arguments: args) - }, - isLocked: false, - ), - - ImageButton( - width: imageWidth, - textAlignment: Alignment.topLeft, - text: t("Edit My Custom Plan"), - style: GoogleFonts.robotoMono( - textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), - image: "asset/image/exercise_plan_custom.jpg", - left: 5, - onTap:() => { - args['exerciseRepository'] = exerciseRepository, - args['customerId'] = Cache().userLoggedIn.customerId, - Navigator.of(context).pushNamed('exercisePlanCustomPage', - arguments: args) - }, - isLocked: false, - ), - - ImageButton( - width: imageWidth, - textAlignment: Alignment.topLeft, - text: t("Suggested Training Plan"), - style: GoogleFonts.robotoMono( - textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), - image: "asset/image/exercise_plan_suggested.jpg", - left: 5, - onTap:() => { - - }, - isLocked: true, - ), - - ImageButton( - width: imageWidth, - textAlignment: Alignment.topLeft, - text: t("My Special Plan"), - style: GoogleFonts.robotoMono( - textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), - image: "asset/image/exercise_plan_special.jpg", - left: 5, - onTap:() => { - - }, - isLocked: true, - ), - - ImageButton( - width: imageWidth, - textAlignment: Alignment.topLeft, - text: t("My Arnold's Plan"), - style: GoogleFonts.robotoMono( - textStyle: TextStyle(fontSize: 14, color: Colors.orange, fontWeight: FontWeight.bold, - backgroundColor: Colors.black54.withOpacity(0.4))), - image: "asset/image/exercise_plan_stars.jpg", - left: 5, - onTap:() => { - - }, - isLocked: true, - ), - - - hiddenPlanWidget(exerciseRepository), - hiddenTrainingWidget(), - - - ] + appBar: AppBarNav(depth: 0), + body: Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('asset/image/WT_menu_dark.png'), + fit: BoxFit.cover, + alignment: Alignment.center, ), + ), + child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ + SliverGrid( + delegate: SliverChildListDelegate([ + ImageButton( + width: imageWidth, + textAlignment: Alignment.topLeft, + text: t("Execute My Selected Training Plan"), + style: GoogleFonts.robotoMono( + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), + image: "asset/image/exercise_plan_execute.jpg", + top: 130, + left: 5, + onTap: () => { + args['customerId'] = Cache().userLoggedIn.customerId, + Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args) + }, + isLocked: false, + ), + ImageButton( + width: imageWidth, + textAlignment: Alignment.topLeft, + text: t("Edit My Custom Plan"), + style: GoogleFonts.robotoMono( + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), + image: "asset/image/exercise_plan_custom.jpg", + left: 5, + onTap: () => { + args['exerciseRepository'] = exerciseRepository, + args['customerId'] = Cache().userLoggedIn.customerId, + Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args) + }, + isLocked: false, + ), + ImageButton( + width: imageWidth, + textAlignment: Alignment.topLeft, + text: t("Suggested Training Plan"), + style: GoogleFonts.robotoMono( + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), + image: "asset/image/exercise_plan_suggested.jpg", + left: 5, + onTap: () => { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Suggested Training Plan is reachable if you finished the first 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop()}, + ); + }) + }, + isLocked: true, + ), + ImageButton( + width: imageWidth, + textAlignment: Alignment.topLeft, + text: t("My Special Plan"), + style: GoogleFonts.robotoMono( + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), + image: "asset/image/exercise_plan_special.jpg", + left: 5, + onTap: () => { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Special Plan is reachable if you finished the first 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop()}, + ); + }) + }, + isLocked: true, + ), + ImageButton( + width: imageWidth, + textAlignment: Alignment.topLeft, + text: t("Star's Exercise Plan"), + style: GoogleFonts.robotoMono( + textStyle: TextStyle( + fontSize: 14, + color: Colors.orange, + fontWeight: FontWeight.bold, + backgroundColor: Colors.black54.withOpacity(0.4))), + image: "asset/image/exercise_plan_stars.jpg", + left: 5, + onTap: () => { + showDialog( + context: context, + builder: (BuildContext context) { + return DialogPremium( + title: "Go Premium", + descriptions: "Unleash your potential with WorkoutTest Premium!", + description2: "The Star's Exericise Plan is reachable if you finished the second 100% test-circles", + text: "OK", + onTap: () => {Navigator.of(context).pop()}, + onCancel: () => {Navigator.of(context).pop()}, + ); + }) + }, + isLocked: true, + ), + hiddenPlanWidget(exerciseRepository), + hiddenTrainingWidget(), + ]), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, mainAxisSpacing: 15.0, @@ -138,30 +172,27 @@ class _MyExercisePlanPage extends State with Trans { childAspectRatio: 1.0, ), ) - ] - ) - ), - bottomNavigationBar: BottomNavigator(bottomNavIndex: 2)); + ])), + bottomNavigationBar: BottomNavigator(bottomNavIndex: 2)); } Widget hiddenPlanWidget(ExerciseRepository exerciseRepository) { final LinkedHashMap args = LinkedHashMap(); - if ( Cache().getTrainee() != null ) { + if (Cache().getTrainee() != null) { return FlatButton( - padding: EdgeInsets.all(20), - textColor: Colors.white, - color: Colors.black12, - focusColor: Colors.blueAccent, - onPressed: () => - { - args['exerciseRepository'] = exerciseRepository, - args['customerId'] = Cache().getTrainee().customerId, - Navigator.of(context).pushNamed('exercisePlanCustomPage', - arguments: args) - }, - child: Text(t("My Trainee's Plan"), - style: TextStyle(fontSize: 18),) - ); + padding: EdgeInsets.all(20), + textColor: Colors.white, + color: Colors.black12, + focusColor: Colors.blueAccent, + onPressed: () => { + args['exerciseRepository'] = exerciseRepository, + args['customerId'] = Cache().getTrainee().customerId, + Navigator.of(context).pushNamed('exercisePlanCustomPage', arguments: args) + }, + child: Text( + t("My Trainee's Plan"), + style: TextStyle(fontSize: 18), + )); } else { return Container(); } @@ -169,27 +200,23 @@ class _MyExercisePlanPage extends State with Trans { Widget hiddenTrainingWidget() { final LinkedHashMap args = LinkedHashMap(); - if ( Cache().getTrainee() != null ) { - print ("!!Trainee: " + Cache().getTrainee().firstname + " " + Cache().getTrainee().name); + if (Cache().getTrainee() != null) { + log("!!Trainee: " + Cache().getTrainee().firstname + " " + Cache().getTrainee().name); return FlatButton( - padding: EdgeInsets.all(20), - textColor: Colors.white, - color: Colors.black12, - focusColor: Colors.blueAccent, - onPressed: () => - { - args['customerId'] = Cache().getTrainee().customerId, - Navigator.of(context).pushNamed('exerciseExecutePlanPage', - arguments: args) - }, - child: Text(t("Execute My Trainee's Training Plan"), - style: TextStyle(fontSize: 18),) - ); + padding: EdgeInsets.all(20), + textColor: Colors.white, + color: Colors.black12, + focusColor: Colors.blueAccent, + onPressed: () => { + args['customerId'] = Cache().getTrainee().customerId, + Navigator.of(context).pushNamed('exerciseExecutePlanPage', arguments: args) + }, + child: Text( + t("Execute My Trainee's Training Plan"), + style: TextStyle(fontSize: 18), + )); } else { return Container(); } } - } - - diff --git a/lib/view/sales_page.dart b/lib/view/sales_page.dart new file mode 100644 index 0000000..5a56dd7 --- /dev/null +++ b/lib/view/sales_page.dart @@ -0,0 +1,199 @@ +import 'package:aitrainer_app/bloc/sales/sales_bloc.dart'; +import 'package:aitrainer_app/util/trans.dart'; +import 'package:aitrainer_app/widgets/app_bar_min.dart'; +import 'package:aitrainer_app/widgets/sales_button.dart'; +import 'package:aitrainer_app/widgets/splash.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:google_fonts/google_fonts.dart'; + +// ignore: must_be_immutable +class SalesPage extends StatelessWidget with Trans { + @override + Widget build(BuildContext context) { + setContext(context); + return BlocProvider( + create: (context) => SalesBloc()..add(SalesLoad()), + child: BlocConsumer(listener: (context, state) { + if (state is SalesError) { + Scaffold.of(context).showSnackBar( + SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); + } else if (state is SalesLoading) { + return LoadingDialog(); + } + }, builder: (context, state) { + final salesBloc = BlocProvider.of(context); + return salesWidget(salesBloc); + })); + } + + Widget salesWidget(SalesBloc bloc) { + final double mediaWidth = MediaQuery.of(context).size.width; + final double imageWidth = (mediaWidth - 5) / 2; + return Scaffold( + appBar: AppBarMin( + back: true, + ), + body: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('asset/image/WT_black_background.png'), + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ + SliverList( + delegate: SliverChildListDelegate([ + Divider(), + Container( + padding: EdgeInsets.only(left: 65, right: 65), + child: Text("Unleash Your Development Now!", + textAlign: TextAlign.center, + maxLines: 4, + softWrap: true, + style: GoogleFonts.archivoBlack( + fontSize: 30, + 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(), + Container( + padding: EdgeInsets.only(left: 45, right: 45), + child: Text("Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.", + textAlign: TextAlign.left, + maxLines: 4, + softWrap: true, + style: GoogleFonts.inter( + fontSize: 16, + color: Colors.white, + ))), + SizedBox( + height: 50, + ), + ])), + SliverGrid( + delegate: SliverChildListDelegate(getButtons(bloc) + /* [ + SalesButton( + title: "Annual", + price: "9970 Ft / év", + desc1: "Development programs", + desc2: "Suggestions based on your actual status", + desc3: "Special customized training plans", + descStyle: GoogleFonts.inter(fontSize: 10, color: Colors.blue[800]), + badgeText: "2 months free", + badgeColor: Colors.orange, + style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.blue[800]), + onTap: () { + print("1"); + //bloc.sessionBloc.add(event) + }, + ), + SalesButton( + title: "Annual", + price: "10970 Ft / év", + desc1: "Development programs", + desc2: "Suggestions based on your actual status", + desc3: "Special customized training plans", + desc4: "AI driven predictions", + descStyle: GoogleFonts.inter(fontSize: 10, color: Colors.blue[800]), + badgeText: "one month free", + badgeColor: Colors.orange, + style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.blue[800]), + onTap: () => {print("2")}, + ), + SalesButton( + title: "Monthly", + price: "970 Ft / hó", + desc1: "Development programs", + desc2: "Suggestions based on your actual status", + desc3: "Special customized training plans", + desc4: "AI driven predictions", + descStyle: GoogleFonts.inter(fontSize: 10, color: Colors.blue[800]), + badgeColor: Colors.transparent, + style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.blue[800]), + onTap: () => {print("3")}, + ), + ] */ + ), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 10.0, + crossAxisSpacing: 10.0, + childAspectRatio: 0.55, + ), + ), + SliverList( + delegate: SliverChildListDelegate([ + SizedBox( + height: 30, + ), + Container( + padding: EdgeInsets.only(left: 55, right: 55), + child: Text( + "Subscription Conditions", + style: GoogleFonts.inter(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white), + )), + Divider(), + Container( + padding: EdgeInsets.only(left: 55, right: 55), + child: Text( + "Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hourse before the end of the current period", + style: GoogleFonts.inter(fontSize: 12, color: Colors.white), + )), + Divider(), + Container( + padding: EdgeInsets.only(left: 55, right: 55), + child: Text( + "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), + )), + ])), + ]))); + ; + } + + List getButtons(SalesBloc bloc) { + List buttons = List(); + + bloc.product2Display.forEach((element) { + final String title = element.sort == 3 ? "Montly" : "Annual"; + final String interval = element.sort == 3 ? " / month" : " / year"; + final String desc4 = element.sort == 1 ? "" : "AI driven predictions"; + String badge; + if (element.sort == 2) { + badge = "14% discount"; + } else if (element.sort == 1) { + badge = "2 months free"; + } + Widget button = SalesButton( + title: title, + price: element.description + interval, + desc1: "Development programs", + desc2: "Suggestions based on your actual status", + desc3: "Special customized training plans", + desc4: desc4, + descStyle: GoogleFonts.inter(fontSize: 10, color: Colors.blue[800]), + badgeText: badge, + badgeColor: element.sort == 3 ? Colors.transparent : Colors.orange, + style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.blue[800]), + onTap: () => {bloc.add(SalesPurchase(productId: element.productId))}, + ); + buttons.add(button); + }); + + return buttons; + } +} diff --git a/lib/view/settings.dart b/lib/view/settings.dart index 680a59b..dd8a540 100644 --- a/lib/view/settings.dart +++ b/lib/view/settings.dart @@ -35,6 +35,8 @@ class SettingsPage extends StatelessWidget with Trans { child: Form( child: BlocConsumer(listener: (context, state) { if (state is SettingsError) { + Scaffold.of(context).showSnackBar( + SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); } else if (state is SettingsReady) { menuBloc.add(MenuRecreateTree()); } else if (state is SettingsLoading) { diff --git a/lib/widgets/bmi_widget.dart b/lib/widgets/bmi_widget.dart index ee80ce2..13f90a9 100644 --- a/lib/widgets/bmi_widget.dart +++ b/lib/widgets/bmi_widget.dart @@ -245,7 +245,7 @@ class _BMIState extends State with Trans { icon: Icon(Icons.save), hoverColor: Colors.blueAccent, color: widget.exerciseBloc.changedWeight ? Colors.blue[200] : Colors.black54, - onPressed: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())}) + onPressed: () => {widget.exerciseBloc.add(ExerciseNewSaveWeight())}) ], )); } diff --git a/lib/widgets/bmr_widget.dart b/lib/widgets/bmr_widget.dart index 80f2962..b9a80b2 100644 --- a/lib/widgets/bmr_widget.dart +++ b/lib/widgets/bmr_widget.dart @@ -191,7 +191,6 @@ class _BMRState extends State with Trans { selectedItem: FitnessItem().getItem(fitnessLevel), itemAsString: (data) => t(data.stateText), onChanged: (data) { - print(data); widget.exerciseBloc.add(ExerciseNewFitnessLevelChange(value: data.value)); }, dropdownBuilder: _customDropDownItem, @@ -290,7 +289,7 @@ class _BMRState extends State with Trans { icon: Icon(Icons.save), hoverColor: Colors.blueAccent, color: widget.exerciseBloc.changedWeight ? Colors.blue[200] : Colors.black54, - onPressed: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())}) + onPressed: () => {widget.exerciseBloc.add(ExerciseNewSaveWeight())}) ], )); } diff --git a/lib/widgets/dialog_premium.dart b/lib/widgets/dialog_premium.dart new file mode 100644 index 0000000..b83956d --- /dev/null +++ b/lib/widgets/dialog_premium.dart @@ -0,0 +1,205 @@ +import 'dart:async'; + +import 'package:aitrainer_app/library/custom_icon_icons.dart'; +import 'package:aitrainer_app/util/trans.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +// ignore: must_be_immutable +class DialogPremium extends StatefulWidget { + final String title, descriptions, text; + final VoidCallback onTap; + final VoidCallback onCancel; + String description2; + final Image img; + + DialogPremium({Key key, this.title, this.descriptions, this.description2, this.text, this.img, this.onTap, this.onCancel}) + : super(key: key) { + description2 = description2 ?? ""; + } + + @override + _DialogPremiumState createState() { + return _DialogPremiumState(); + } +} + +class _DialogPremiumState extends State with Trans { + bool isStart = true; + Timer _timer; + @override + Widget build(BuildContext context) { + setContext(context); + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(31), + ), + elevation: 0, + backgroundColor: Colors.transparent, + child: contentBox(context), + ); + } + + @override + void initState() { + isStart = true; + _timer = Timer.periodic( + Duration(milliseconds: 1000), + (Timer timer) => setState(() { + isStart = !isStart; + })); + super.initState(); + } + + contentBox(context) { + return Stack(alignment: AlignmentDirectional.topStart, children: [ + Stack( + 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_black_G_background.png'), + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 5, + ), + Stack( + alignment: AlignmentDirectional.topEnd, + children: [ + Text( + widget.title + " ", + style: GoogleFonts.archivoBlack( + fontSize: 24, + color: Colors.yellow[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, + ), + ], + ), + ), + Positioned( + right: 3, + top: 0, + child: AnimatedSwitcher( + duration: Duration(milliseconds: 900), + //reverseDuration: Duration(milliseconds: 200), + transitionBuilder: (Widget child, Animation animation) { + return FadeTransition(child: child, opacity: animation); + }, + child: isStart + ? Icon( + CustomIcon.star_2, + color: Colors.yellow[300], + ) + : Offstage() /* Icon( + CustomIcon.exclamation_circle, + color: Colors.yellow[300], + ) */ + )), + ], + ), + SizedBox( + height: 35, + ), + Text( + widget.descriptions, + style: GoogleFonts.inter( + fontSize: 14, + 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, + ), + ], + ), + textAlign: TextAlign.center, + ), + SizedBox( + height: 15, + ), + Text( + widget.description2, + style: GoogleFonts.inter( + fontSize: 14, + 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, + ), + ], + ), + textAlign: TextAlign.center, + ), + SizedBox( + height: 62, + ), + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: widget.onTap ?? widget.onTap, + 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: () => widget.onCancel == null ? Navigator.of(context).pop() : widget.onCancel, + child: CircleAvatar( + backgroundColor: Colors.transparent, + radius: 28, + child: Text( + "X", + style: GoogleFonts.archivoBlack(fontSize: 32, color: Colors.white54), + ), + )), + ]); + } + + @override + void dispose() { + _timer.cancel(); + super.dispose(); + } +} diff --git a/lib/widgets/home.dart b/lib/widgets/home.dart index db29605..0a46a95 100644 --- a/lib/widgets/home.dart +++ b/lib/widgets/home.dart @@ -1,6 +1,7 @@ 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'; +import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/view/login.dart'; import 'package:aitrainer_app/view/menu_page.dart'; import 'package:aitrainer_app/view/registration.dart'; @@ -11,7 +12,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'loading.dart'; - // ignore: must_be_immutable class AitrainerHome extends StatefulWidget { _HomePageState _state; @@ -22,7 +22,7 @@ class AitrainerHome extends StatefulWidget { } } -class _HomePageState extends State { +class _HomePageState extends State with Logging { GlobalKey _scaffoldKey = new GlobalKey(); @override @@ -37,7 +37,7 @@ class _HomePageState extends State { Future runDelayedEvent() async { await Future.delayed(Duration(seconds: 2), () async { - if ( context != null) { + if (context != null) { // ignore: close_sinks SessionBloc sessionBloc = BlocProvider.of(context); if (sessionBloc.state != SessionReady()) { @@ -49,45 +49,40 @@ class _HomePageState extends State { } }); } + @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, - body: Container( - child: BlocConsumer( - listener: (context, state) { - if ( state is SessionFailure) { - Scaffold.of(context).showSnackBar(SnackBar( - content: Text( - state.message, - ), - backgroundColor: Colors.orange, - )); - } - }, - builder: (context, state) { - if (state is SessionInitial) { - return LoadingScreenMain(); - } else if (state is SessionLoading) { - print("loading"); - return LoadingScreenMain(); - } else if (state is SessionReady) { - print("ready menu with " + Cache().startPage); - if (Cache().startPage == 'login') { - return LoginPage(); - } else if (Cache().startPage == 'registration') { - return RegistrationPage(); - } else { - return MenuPage(parent: 0); - } - } else { - print("else"); - return MenuPage(parent: 0); - } + body: BlocConsumer(listener: (context, state) { + if (state is SessionFailure) { + Scaffold.of(context).showSnackBar(SnackBar( + content: Text( + state.message, + ), + backgroundColor: Colors.orange, + )); + } + }, builder: (context, state) { + if (state is SessionInitial) { + return LoadingScreenMain(); + } else if (state is SessionLoading) { + log("loading"); + return LoadingScreenMain(); + } else if (state is SessionReady) { + log("ready menu with " + Cache().startPage); + if (Cache().startPage == 'login') { + return LoginPage(); + } else if (Cache().startPage == 'registration') { + return RegistrationPage(); + } else { + return MenuPage(parent: 0); } - ), - ), - //bottomNavigationBar: BottomNavigator(bottomNavIndex: 0), + } else { + log("else"); + return MenuPage(parent: 0); + } + }), ); } } diff --git a/lib/widgets/image_button.dart b/lib/widgets/image_button.dart index db561dd..cd7ad82 100644 --- a/lib/widgets/image_button.dart +++ b/lib/widgets/image_button.dart @@ -11,7 +11,7 @@ class ImageButton extends StatelessWidget { final String text; TextStyle style = TextStyle(fontSize: 14); final String image; - final double top; + double top; final double left; double height; double width; @@ -49,9 +49,10 @@ class ImageButton extends StatelessWidget { @override Widget build(BuildContext context) { - double top = - height - (style.fontSize - 5) * text.length - 2 * left < 0 ? height - 2 * style.fontSize - 22 : height - style.fontSize - 17; - //print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString()); + if (top == null) { + top = height - (style.fontSize - 5) * text.length - 2 * left < 0 ? height - 2 * style.fontSize - 22 : height - style.fontSize - 17; + //print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString()); + } return Stack( //alignment: textAlignment, fit: StackFit.passthrough, diff --git a/lib/widgets/menu_info_widget.dart b/lib/widgets/menu_info_widget.dart index 75a2b76..be96613 100644 --- a/lib/widgets/menu_info_widget.dart +++ b/lib/widgets/menu_info_widget.dart @@ -94,10 +94,7 @@ class MenuInfoWidget extends StatelessWidget with Common { link, style: TextStyle(color: Colors.lightBlueAccent, fontSize: textSize, fontFamily: 'Arial', fontWeight: textWeight), ), - onTap: () => { - missingId = bloc.menuTreeRepository.getMissingTreeIdByName(bloc.missingTreeName), - print("menu " + missingId.toString()), - bloc.add(MenuTreeJump(parent: missingId)) - }); + onTap: () => + {missingId = bloc.menuTreeRepository.getMissingTreeIdByName(bloc.missingTreeName), bloc.add(MenuTreeJump(parent: missingId))}); } } diff --git a/lib/widgets/sales_button.dart b/lib/widgets/sales_button.dart new file mode 100644 index 0000000..722cd6b --- /dev/null +++ b/lib/widgets/sales_button.dart @@ -0,0 +1,98 @@ +import 'package:badges/badges.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +// ignore: must_be_immutable +class SalesButton extends StatelessWidget { + TextStyle style = TextStyle(fontSize: 14); + TextStyle descStyle = TextStyle(fontSize: 14); + final String title; + final String price; + final String desc1; + final String desc2; + final String desc3; + String desc4; + final String badgeText; + final Color badgeColor; + final VoidCallback onTap; + + SalesButton( + {this.title, + this.price, + this.desc1, + this.desc2, + this.desc3, + this.desc4, + this.badgeText, + this.badgeColor, + this.onTap, + this.style, + this.descStyle}) { + style = style ?? + GoogleFonts.archivoBlack( + fontSize: 14, + ); + desc4 = desc4 ?? ""; + } + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage('asset/image/WT_sales_background_3x5.png'), + fit: BoxFit.cover, + alignment: Alignment.center, + ), + ), + child: Badge( + position: BadgePosition.topEnd(end: -3, top: -5), + padding: EdgeInsets.all(5), + badgeColor: badgeColor, + borderRadius: BorderRadius.circular(5), + shape: BadgeShape.square, + badgeContent: badgeText != null + ? Text(badgeText, + style: TextStyle( + color: Colors.white, + backgroundColor: badgeColor, + fontSize: 12, + )) + : Text("", + style: TextStyle( + color: Colors.transparent, + backgroundColor: Colors.transparent, + fontSize: 1, + )), + child: Container( + child: Center( + child: Column( + children: [ + Divider( + color: Colors.transparent, + ), + Divider( + color: Colors.transparent, + ), + Text( + title, + style: GoogleFonts.archivoBlack(color: Colors.black54), + ), + Text( + price, + style: style, + ), + Container( + padding: EdgeInsets.only(top: 5, left: 3, right: 3, bottom: 4), child: Text(desc1, maxLines: 2, style: descStyle)), + Container(padding: EdgeInsets.only(left: 3, right: 3, bottom: 4), child: Text(desc2, maxLines: 2, style: descStyle)), + Container(padding: EdgeInsets.only(left: 3, right: 3, bottom: 4), child: Text(desc3, maxLines: 2, style: descStyle)), + Container( + padding: EdgeInsets.only(left: 3, right: 3), + child: Text(desc4, maxLines: 2, style: GoogleFonts.inter(fontSize: 10, color: Colors.red[800]))) + ], + ), + )), + ))); + } +} diff --git a/pubspec.lock b/pubspec.lock index 5eab3d6..e6a2d46 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,14 +49,14 @@ packages: name: badges url: "https://pub.dartlang.org" source: hosted - version: "1.1.4" + version: "1.1.6" bloc: dependency: transitive description: name: bloc url: "https://pub.dartlang.org" source: hosted - version: "6.1.0" + version: "6.1.1" bloc_test: dependency: "direct dev" description: @@ -77,14 +77,14 @@ packages: name: build url: "https://pub.dartlang.org" source: hosted - version: "1.5.1" + version: "1.6.0" build_config: dependency: transitive description: name: build_config url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.5" build_daemon: dependency: transitive description: @@ -98,21 +98,21 @@ packages: name: build_resolvers url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.5.1" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.10.6" + version: "1.10.11" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.dartlang.org" source: hosted - version: "6.1.1" + version: "6.1.5" built_collection: dependency: transitive description: @@ -147,7 +147,7 @@ packages: name: checked_yaml url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.4" cli_util: dependency: transitive description: @@ -266,35 +266,35 @@ packages: name: file url: "https://pub.dartlang.org" source: hosted - version: "6.0.0-nullsafety.2" + version: "5.2.1" firebase_auth: dependency: "direct main" description: name: firebase_auth url: "https://pub.dartlang.org" source: hosted - version: "0.18.3+1" + version: "0.18.4+1" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4" firebase_auth_web: dependency: transitive description: name: firebase_auth_web url: "https://pub.dartlang.org" source: hosted - version: "0.3.2+1" + version: "0.3.2+3" firebase_core: dependency: "direct main" description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "0.5.2+1" + version: "0.5.3" firebase_core_platform_interface: dependency: transitive description: @@ -329,7 +329,7 @@ packages: name: fl_chart url: "https://pub.dartlang.org" source: hosted - version: "0.12.0" + version: "0.12.1" flurry: dependency: "direct main" description: @@ -349,11 +349,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.1" - flutter_driver: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" flutter_form_bloc: dependency: "direct main" description: @@ -361,6 +356,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.19.0" + flutter_inapp_purchase: + dependency: "direct main" + description: + name: flutter_inapp_purchase + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" flutter_keyboard_visibility: dependency: transitive description: @@ -381,7 +383,7 @@ packages: source: sdk version: "0.0.0" flutter_test: - dependency: transitive + dependency: "direct dev" description: flutter source: sdk version: "0.0.0" @@ -403,7 +405,7 @@ packages: name: freezed url: "https://pub.dartlang.org" source: hosted - version: "0.12.3" + version: "0.12.6" freezed_annotation: dependency: transitive description: @@ -411,11 +413,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.0" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" glob: dependency: transitive description: @@ -514,13 +511,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.1.1" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" keyboard_actions: dependency: "direct main" description: @@ -583,7 +573,7 @@ packages: name: node_io url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.2.0" node_preamble: dependency: transitive description: @@ -667,7 +657,7 @@ packages: name: percent_indicator url: "https://pub.dartlang.org" source: hosted - version: "2.1.8" + version: "2.1.9" petitparser: dependency: transitive description: @@ -681,7 +671,7 @@ packages: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.0-nullsafety.2" + version: "2.2.1" plugin_platform_interface: dependency: transitive description: @@ -702,14 +692,14 @@ packages: name: process url: "https://pub.dartlang.org" source: hosted - version: "4.0.0-nullsafety.2" + version: "3.0.13" provider: dependency: transitive description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.3.2+2" + version: "4.3.2+3" pub_semver: dependency: transitive description: @@ -723,7 +713,7 @@ packages: name: pubspec_parse url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.7" quiver: dependency: transitive description: @@ -821,7 +811,7 @@ packages: name: shelf_static url: "https://pub.dartlang.org" source: hosted - version: "0.2.8" + version: "0.2.9+1" shelf_web_socket: dependency: transitive description: @@ -840,7 +830,7 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "0.9.8" + version: "0.9.10+1" source_map_stack_trace: dependency: transitive description: @@ -918,13 +908,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0-nullsafety.1" - sync_http: - dependency: transitive - description: - name: sync_http - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" synchronized: dependency: transitive description: @@ -966,7 +949,7 @@ packages: name: timing url: "https://pub.dartlang.org" source: hosted - version: "0.1.1+2" + version: "0.1.1+3" toggle_switch: dependency: "direct main" description: @@ -1009,13 +992,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.5.0" - vm_service_client: - dependency: transitive - description: - name: vm_service_client - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.6+2" watcher: dependency: transitive description: @@ -1030,13 +1006,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - webdriver: - dependency: transitive - description: - name: webdriver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" webkit_inspection_protocol: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index cae11d4..4e736bd 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,10 +15,10 @@ 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.2+39 +version: 1.1.2+40 environment: - sdk: ">=2.10.0 <3.0.0" + sdk: ">=2.7.0 <3.0.0" dependencies: flutter: @@ -45,6 +45,7 @@ dependencies: health: ^2.0.9 stop_watch_timer: ^0.6.0+1 #geolocator: ^6.1.13 + flutter_inapp_purchase: ^3.0.1 firebase_core: ^0.5.2 @@ -62,10 +63,13 @@ dependencies: flutter_localizations: sdk: flutter +#dependency_overrides: + # flutter_driver: + dev_dependencies: - flutter_driver: + test: '>=1.0.0 <2.0.0' + flutter_test: sdk: flutter - test: any bloc_test: ^7.1.0 build_runner: @@ -109,12 +113,16 @@ flutter: - asset/image/WT01_loading_layers.png - asset/image/WT_menu_backround.png - asset/image/WT_black_background.png + - asset/image/WT_black_G_background.png + - asset/image/WT_plainblack_background.png - asset/image/WT_menu.png - asset/image/WT_login.png - asset/image/WT_OK.png - asset/image/dots.gif - asset/image/WT_long_logo.png - asset/image/WT_light_background.png + - asset/image/WT_sales_background.png + - asset/image/WT_sales_background_3x5.png - asset/image/WT_menu_dark.png - asset/image/Gain_muscle.png - asset/image/WT_weight_loss.png diff --git a/test_driver/app.dart b/test_driver/app.dart index b3698db..a053e8b 100644 --- a/test_driver/app.dart +++ b/test_driver/app.dart @@ -1,11 +1,11 @@ -import 'package:flutter_driver/driver_extension.dart'; +//import 'package:flutter_driver/driver_extension.dart'; import 'package:aitrainer_app/main.dart' as app; -void main() { +/* void main() { // This line enables the extension. enableFlutterDriverExtension(); // Call the `main()` function of the app, or call `runApp` with // any widget you are interested in testing. app.main(); -} \ No newline at end of file +} */ diff --git a/test_driver/app_test.dart b/test_driver/app_test.dart index 1182791..b2525b5 100644 --- a/test_driver/app_test.dart +++ b/test_driver/app_test.dart @@ -1,9 +1,9 @@ // Imports the Flutter Driver API. -import 'package:flutter_driver/flutter_driver.dart'; +//import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart'; import '../lib/helper/database.dart'; - +/* void main() { FlutterDriver driver; group('Login App', () { @@ -18,3 +18,4 @@ void main() { }); }); } + */