WT 1.1.0+39 evaluation, health data

This commit is contained in:
bossanyit 2020-12-17 22:32:45 +01:00
parent 81f904af2c
commit 5c7a3d67e8
57 changed files with 1702 additions and 225 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
asset/image/pict_steps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
asset/image/pict_time_h.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -235,5 +235,20 @@
"Live-Server":"Live-Server", "Live-Server":"Live-Server",
"Test-Server":"Test-Server", "Test-Server":"Test-Server",
"All Exercises has been filtered out":"All Exercises has been filtered out", "All Exercises has been filtered out":"All Exercises has been filtered out",
"base":"base" "base":"base",
"Hypertrophy":"Hypertrophy",
"Gain Strength":"Gain Strength",
"repeats":"repeats",
"minutes":"minutes",
"Rest time":"Rest time",
"Suggestions based on your test":"Suggestions based on your test",
"Repeats volume":"Repeats volume",
"Weight volume":"Weight volume",
"Calorie":"Calorie",
"Max BPM":"Max BPM",
"Min BPM":"Min BPM",
"Average BPM":"Average BPM",
"Fatburn %":"Fatburn %",
"Health Data Summary":"Health Data Summary"
} }

View File

@ -236,5 +236,20 @@
"Live-Server":"Live-Server", "Live-Server":"Live-Server",
"Test-Server":"Test-Server", "Test-Server":"Test-Server",
"All Exercises has been filtered out":"Az összes gyakorlatot kiszűrted", "All Exercises has been filtered out":"Az összes gyakorlatot kiszűrted",
"base":"alap" "base":"alap",
"Hypertrophy":"Izomnövelés",
"Gain Strength":"Erőnövelés",
"repeats":"ismétlés",
"Rest time":"Pihenőidő",
"minutes":"perc",
"Suggestions based on your test":"Javaslatok a teszted alapján",
"Repeats volume":"Össz. ismétlés",
"Weight volume":"Össztömeg",
"Calorie":"Kalória",
"Max BPM":"Max pulzus",
"Min BPM":"Min pulzus",
"Average BPM":"Átl pulzus",
"Fatburn %":"Zsírégetés %",
"Health Data Summary":"Egészségadatok összefoglalás"
} }

View File

@ -1,4 +1,6 @@
PODS: PODS:
- device_info (0.0.1):
- Flutter
- devicelocale (0.0.1): - devicelocale (0.0.1):
- Flutter - Flutter
- Firebase/Auth (6.33.0): - Firebase/Auth (6.33.0):
@ -84,6 +86,8 @@ PODS:
- GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GTMSessionFetcher/Core (1.5.0) - GTMSessionFetcher/Core (1.5.0)
- health (1.0.1):
- Flutter
- nanopb (1.30906.0): - nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0) - nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0) - nanopb/encode (= 1.30906.0)
@ -100,6 +104,7 @@ PODS:
- FMDB (>= 2.7.5) - FMDB (>= 2.7.5)
DEPENDENCIES: DEPENDENCIES:
- device_info (from `.symlinks/plugins/device_info/ios`)
- devicelocale (from `.symlinks/plugins/devicelocale/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
@ -107,6 +112,7 @@ DEPENDENCIES:
- flurry (from `.symlinks/plugins/flurry/ios`) - flurry (from `.symlinks/plugins/flurry/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/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`) - path_provider (from `.symlinks/plugins/path_provider/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
@ -130,6 +136,8 @@ SPEC REPOS:
- Protobuf - Protobuf
EXTERNAL SOURCES: EXTERNAL SOURCES:
device_info:
:path: ".symlinks/plugins/device_info/ios"
devicelocale: devicelocale:
:path: ".symlinks/plugins/devicelocale/ios" :path: ".symlinks/plugins/devicelocale/ios"
firebase_auth: firebase_auth:
@ -144,6 +152,8 @@ EXTERNAL SOURCES:
:path: Flutter :path: Flutter
flutter_keyboard_visibility: flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios" :path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
health:
:path: ".symlinks/plugins/health/ios"
path_provider: path_provider:
:path: ".symlinks/plugins/path_provider/ios" :path: ".symlinks/plugins/path_provider/ios"
shared_preferences: shared_preferences:
@ -152,6 +162,7 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/sqflite/ios" :path: ".symlinks/plugins/sqflite/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_auth: cb33b01b51904969161403bbcb20036519f0c578 firebase_auth: cb33b01b51904969161403bbcb20036519f0c578
@ -171,6 +182,7 @@ SPEC CHECKSUMS:
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52 GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
health: 44840ad4328aa5586e77bef289898bfed644a81c
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f

View File

@ -15,6 +15,7 @@
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
BB69292B2521AF45001FBA4C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */; }; BB69292B2521AF45001FBA4C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */; };
BB81345024BB4BE10078D9A4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */; }; BB81345024BB4BE10078D9A4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */; };
BBDBEBB825862170006762F6 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBDBEBB725862170006762F6 /* HealthKit.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -48,6 +49,7 @@
BB43773E2540715900D74BFA /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; }; BB43773E2540715900D74BFA /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; }; BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
BBDBEBB725862170006762F6 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; };
D5EDDC52125075FB9E21AD35 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; D5EDDC52125075FB9E21AD35 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
F39E6E227EB942E5663A6086 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; F39E6E227EB942E5663A6086 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -58,6 +60,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
42B6B159AF35AFB6DE777DFB /* Pods_Runner.framework in Frameworks */, 42B6B159AF35AFB6DE777DFB /* Pods_Runner.framework in Frameworks */,
BBDBEBB825862170006762F6 /* HealthKit.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -77,6 +80,7 @@
3ADC50290ED054951FAC1F56 /* Frameworks */ = { 3ADC50290ED054951FAC1F56 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BBDBEBB725862170006762F6 /* HealthKit.framework */,
09BD889296C5C90D989820C8 /* Pods_Runner.framework */, 09BD889296C5C90D989820C8 /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
@ -362,7 +366,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 38; CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -505,7 +509,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 38; CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
@ -540,7 +544,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 38; CURRENT_PROJECT_VERSION = 39;
DEVELOPMENT_TEAM = SFJJBDCU6Z; DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (

View File

@ -46,6 +46,10 @@
<string>10.0</string> <string>10.0</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSHealthShareUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>
<key>NSHealthUpdateUsageDescription</key>
<string>We will sync your data with the Apple Health app to give you better insights</string>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>fetch</string> <string>fetch</string>

View File

@ -4,5 +4,11 @@
<dict> <dict>
<key>aps-environment</key> <key>aps-environment</key>
<string>development</string> <string>development</string>
<key>com.apple.developer.healthkit</key>
<true/>
<key>com.apple.developer.healthkit.access</key>
<array>
<string>health-records</string>
</array>
</dict> </dict>
</plist> </plist>

View File

@ -23,6 +23,8 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
double firstQuantity; // quantity of the first test double firstQuantity; // quantity of the first test
double firstUnitQuantity; // unit quantity of the first test double firstUnitQuantity; // unit quantity of the first test
double scrollOffset = 0;
@override @override
ExerciseControlBloc({this.exerciseRepository, this.readonly, this.percentToCalculate}) : super(ExerciseControlInitial()) { ExerciseControlBloc({this.exerciseRepository, this.readonly, this.percentToCalculate}) : super(ExerciseControlInitial()) {
firstUnitQuantity = exerciseRepository.exercise.unitQuantity; firstUnitQuantity = exerciseRepository.exercise.unitQuantity;
@ -36,7 +38,6 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
origQuantity = quantity; origQuantity = quantity;
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
} }
@override @override
@ -46,23 +47,31 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
yield ExerciseControlLoading(); yield ExerciseControlLoading();
step = 1; step = 1;
yield ExerciseControlReady(); yield ExerciseControlReady();
} else if (event is ExerciseControlQuantityChange ) { } else if (event is ExerciseControlQuantityChange) {
yield ExerciseControlLoading(); yield ExerciseControlLoading();
if ( event.step == step) { if (event.step == step) {
exerciseRepository.setQuantity(event.quantity); exerciseRepository.setQuantity(event.quantity);
quantity = event.quantity; quantity = event.quantity;
} }
yield ExerciseControlReady(); yield ExerciseControlReady();
} else if (event is ExerciseControlSubmit ) { } else if (event is ExerciseControlSubmit) {
yield ExerciseControlLoading(); yield ExerciseControlLoading();
if ( event.step == step) { if (event.step == step) {
step++; step++;
//print("step " + step.toString() + " quantity " + quantity.toString() + " origQ: " + origQuantity.toString()); scrollOffset = step * 200.0;
print("step " +
step.toString() +
" quantity " +
quantity.toString() +
" origQuantity: " +
origQuantity.toString() +
" scrollOffset: " +
scrollOffset.toString());
repeats.add(quantity); repeats.add(quantity);
quantity = origQuantity; quantity = origQuantity;
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
} }
yield ExerciseControlReady(); yield ExerciseControlReady();
@ -78,7 +87,7 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
} }
double weight = exerciseRepository.exercise.unitQuantity; double weight = exerciseRepository.exercise.unitQuantity;
double repeat = exerciseRepository.exercise.quantity; double repeat = exerciseRepository.exercise.quantity;
if ( weight == 0 || repeat == 0) { if (weight == 0 || repeat == 0) {
return 0; return 0;
} }
@ -86,6 +95,6 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
double rmOconner = weight * (1 + repeat / 40); double rmOconner = weight * (1 + repeat / 40);
double average = (rmWendler + rmOconner) / 2; double average = (rmWendler + rmOconner) / 2;
return percent75 ? average * this.percentToCalculate : average; return percent75 ? average * this.percentToCalculate : average;
} }
} }

View File

@ -13,6 +13,7 @@ import 'package:flutter/animation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';
part 'exercise_new_event.dart'; part 'exercise_new_event.dart';
part 'exercise_new_state.dart'; part 'exercise_new_state.dart';
@ -45,6 +46,11 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
double mediaHeight = 0; double mediaHeight = 0;
bool isMan = true; bool isMan = true;
final StopWatchTimer stopWatchTimer = StopWatchTimer(
isLapHours: false,
);
int timerValue;
@override @override
ExerciseNewBloc({this.exerciseRepository, this.menuBloc, this.customerRepository, ExerciseType exerciseType}) ExerciseNewBloc({this.exerciseRepository, this.menuBloc, this.customerRepository, ExerciseType exerciseType})
: super(ExerciseNewInitial()) { : super(ExerciseNewInitial()) {
@ -52,14 +58,15 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.exercise.exercisePlanDetailId = 0; exerciseRepository.exercise.exercisePlanDetailId = 0;
exerciseRepository.start = DateTime.now();
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
customerRepository.customer = Cache().userLoggedIn; customerRepository.customer = Cache().userLoggedIn;
weight = customerRepository.customer.getProperty("Weight"); weight = customerRepository.customer.getProperty("Weight");
height = customerRepository.customer.getProperty("Height"); height = customerRepository.customer.getProperty("Height");
fitnessLevel = customerRepository.customer.fitnessLevel; fitnessLevel = customerRepository.customer.fitnessLevel;
this.isMan = (customerRepository.customer.sex == "m"); this.isMan = (customerRepository.customer.sex == "m");
print("Sex Man? " + isMan.toString() + " " + customerRepository.customer.sex);
} }
stopWatchTimer.rawTime.listen((value) => timerValue = value);
} }
void setMediaDimensions(double width, double height) { void setMediaDimensions(double width, double height) {
@ -75,7 +82,6 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
} }
final double distortionWidth = mediaWidth / baseWidth; final double distortionWidth = mediaWidth / baseWidth;
final double distortionHeight = mediaHeight / baseHeight; final double distortionHeight = mediaHeight / baseHeight;
print("distiortionW " + distortionWidth.toString() + " dH " + distortionHeight.toString());
if (isMan) { if (isMan) {
properties.forEach((element) { properties.forEach((element) {
if (element.propertyName == "Shoulder") { if (element.propertyName == "Shoulder") {
@ -146,12 +152,10 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
element.top = (122 * distortionHeight).toInt(); element.top = (122 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt(); element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Shoulder"); element.value = customerRepository.customer.getProperty("Shoulder");
print("CHEST top: " + element.top.toString() + " left " + element.left.toString());
manSizes.add(element); manSizes.add(element);
} else if (element.propertyName == "Neck") { } else if (element.propertyName == "Neck") {
element.top = (78 * distortionHeight).toInt(); element.top = (78 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt(); element.left = (151 * distortionWidth).toInt();
print("Neck top: " + element.top.toString() + " left " + element.left.toString());
element.value = customerRepository.customer.getProperty("Neck"); element.value = customerRepository.customer.getProperty("Neck");
manSizes.add(element); manSizes.add(element);
} else if (element.propertyName == "Biceps") { } else if (element.propertyName == "Biceps") {
@ -279,6 +283,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if (event is ExerciseNewSubmit) { } else if (event is ExerciseNewSubmit) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
menuBloc.add(MenuTreeDown(parent: 0)); menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges(); Cache().initBadges();
@ -373,4 +378,9 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
return goalBMI; return goalBMI;
} }
@override
void dispose() async {
await stopWatchTimer.dispose();
}
} }

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_device_repository.dart'; import 'package:aitrainer_app/repository/exercise_device_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
@ -15,8 +16,6 @@ import 'package:meta/meta.dart';
part 'menu_event.dart'; part 'menu_event.dart';
part 'menu_state.dart'; part 'menu_state.dart';
enum ExerciseAbility { oneRepMax, endurance, none }
class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans { class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans {
final WorkoutTreeRepository menuTreeRepository; final WorkoutTreeRepository menuTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
@ -106,8 +105,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans {
yield MenuLoading(); yield MenuLoading();
parent = event.parent; parent = event.parent;
workoutItem = event.item; workoutItem = event.item;
setAbility(workoutItem.nameEnglish); if (workoutItem != null) {
//print("menuitem " + workoutItem.id.toString() + " parent "+workoutItem.parent.toString()); setAbility(workoutItem.nameEnglish);
}
menuTreeRepository.getBranch(event.parent); menuTreeRepository.getBranch(event.parent);
yield MenuReady(); yield MenuReady();
} else if (event is MenuTreeUp) { } else if (event is MenuTreeUp) {
@ -117,7 +117,6 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans {
workoutItem = menuTreeRepository.getParentItem(parent); workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) { if (workoutItem != null) {
//print("UP menuitem " + workoutItem.id.toString() + " parent " + workoutItem.parent.toString());
menuTreeRepository.getBranch(workoutItem.parent); menuTreeRepository.getBranch(workoutItem.parent);
setAbility(workoutItem.nameEnglish); setAbility(workoutItem.nameEnglish);
} }
@ -128,7 +127,6 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans {
workoutItem = menuTreeRepository.getParentItem(parent); workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) { if (workoutItem != null) {
//print("JUMP menuitem " + workoutItem.id.toString() + " parent " + workoutItem.parent.toString());
menuTreeRepository.getBranch(workoutItem.parent); menuTreeRepository.getBranch(workoutItem.parent);
setAbility(workoutItem.nameEnglish); setAbility(workoutItem.nameEnglish);
} }

View File

@ -0,0 +1,225 @@
import 'dart:async';
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:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:health/health.dart';
part 'result_event.dart';
part 'result_state.dart';
class ResultBloc extends Bloc<ResultEvent, ResultState> {
final ExerciseResultRepository resultRepository;
final ExerciseRepository exerciseRepository;
List<HealthDataPoint> _healthDataList = List();
DateTime startTime;
DateTime endTime;
final HealthFactory health = HealthFactory();
final List<HealthDataType> types = [
HealthDataType.ACTIVE_ENERGY_BURNED,
HealthDataType.WATER,
HealthDataType.STEPS,
HealthDataType.HEART_RATE,
HealthDataType.BASAL_ENERGY_BURNED,
HealthDataType.BODY_TEMPERATURE,
HealthDataType.HIGH_HEART_RATE_EVENT,
HealthDataType.LOW_HEART_RATE_EVENT,
HealthDataType.RESTING_HEART_RATE
];
ResultBloc({this.resultRepository, this.exerciseRepository}) : super(ResultInitial()) {
this.startTime = exerciseRepository.start;
this.endTime = exerciseRepository.end;
}
@override
Stream<ResultState> mapEventToState(
ResultEvent event,
) async* {
try {
if (event is ResultLoad) {
yield ResultLoading();
await _fetchHealthData();
_matchExerciseData();
yield ResultReady();
}
} on Exception catch (ex) {
yield ResultError(error: ex.toString());
}
}
void _matchExerciseData() {
resultRepository.getResults().forEach((element) {
switch (element.item) {
case ResultItem.bpm_avg:
element.data = _gethHealthDataPointValueAvg(HealthDataType.HEART_RATE).toStringAsFixed(0);
break;
case ResultItem.bpm_min:
element.data = element.data = _gethHealthDataPointValueMin(HealthDataType.HEART_RATE).toStringAsFixed(0);
break;
case ResultItem.bpm_max:
element.data = element.data = _gethHealthDataPointValueMax(HealthDataType.HEART_RATE).toStringAsFixed(0);
break;
case ResultItem.calorie:
element.data = _gethHealthDataPointValueSum(HealthDataType.ACTIVE_ENERGY_BURNED).toStringAsFixed(0);
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);
}
break;
case ResultItem.fatburn_percent:
DateTime today = DateTime.now();
int age = today.year - Cache().userLoggedIn.birthYear;
double minBpm = (200 - age) * 0.6;
double maxBpm = (200 - age) * 0.7;
int counter = 0;
int burnCounter = 0;
_healthDataList.forEach((dataPoint) {
if (dataPoint.type == HealthDataType.ACTIVE_ENERGY_BURNED) {
if (dataPoint.value >= minBpm && dataPoint.value <= maxBpm) {
burnCounter++;
}
counter++;
}
});
if (counter > 0) {
element.data = (burnCounter / counter * 100).toStringAsFixed(2);
} else {
element.data = "0";
}
break;
case ResultItem.speed_max:
// TODO: Handle this case.
break;
case ResultItem.reps_volume:
if (exerciseRepository.exerciseType.unit == "repeat") {
double value = 0;
exerciseRepository.actualExerciseList.forEach((element) {
value += element.quantity;
});
element.data = value.toStringAsFixed(0);
}
break;
case ResultItem.steps:
element.data = _gethHealthDataPointValueSum(HealthDataType.STEPS).toStringAsFixed(0);
break;
/* case ResultItem.time:
final Duration duration = this.endTime.difference(this.startTime);
element.data = _printDuration(duration);
break; */
case ResultItem.weight_volume:
if (exerciseRepository.exerciseType.unitQuantityUnit == "kilogram") {
double value = 0;
exerciseRepository.actualExerciseList.forEach((element) {
value += element.quantity * element.unitQuantity;
});
element.data = value.toStringAsFixed(0);
}
break;
}
});
}
String _printDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes);
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
String twoDigitMilliSeconds = duration.inMilliseconds.remainder(1000).toString();
return "$twoDigitMinutes:$twoDigitSeconds:$twoDigitMilliSeconds" + '"';
}
double _gethHealthDataPointValueAvg(HealthDataType dataType) {
double value = 0;
double counter = 0;
_healthDataList.forEach((dataPoint) {
if (dataPoint.type == dataType) {
value += dataPoint.value;
counter++;
}
});
double avg = 0;
if (counter > 0) {
avg = value / counter;
}
return avg;
}
double _gethHealthDataPointValueSum(HealthDataType dataType) {
double value = 0;
_healthDataList.forEach((dataPoint) {
if (dataPoint.type == dataType) {
value += dataPoint.value;
}
});
return value;
}
double _gethHealthDataPointValueMax(HealthDataType dataType) {
double max = 0;
_healthDataList.forEach((dataPoint) {
if (dataPoint.type == dataType) {
if (max < dataPoint.value) {
max = dataPoint.value;
}
}
});
return max;
}
double _gethHealthDataPointValueMin(HealthDataType dataType) {
double min = 9999999;
_healthDataList.forEach((dataPoint) {
if (dataPoint.type == dataType) {
if (min > dataPoint.value && dataPoint.value != 0) {
min = dataPoint.value;
}
}
});
if (min == 9999999) {
min = 0;
}
return min;
}
Future<void> _fetchHealthData() async {
if (health == null) {
return;
}
try {
print("Get Health data between " + startTime.toString() + " AND " + endTime.toString());
_healthDataList = await health.getHealthDataFromTypes(this.startTime, this.endTime, types);
_healthDataList.forEach((element) {
print(element.toString());
});
} on Exception catch (e) {
print("Caught exception in getHealthDataFromTypes: $e");
throw Exception(e);
}
}
double calculate1RM({double percent}) {
if (exerciseRepository.exercise == null) {
exerciseRepository.getLastExercise();
}
double weight = exerciseRepository.exercise.unitQuantity;
double repeat = exerciseRepository.exercise.quantity;
if (weight == 0 || repeat == 0) {
return 0;
}
double rmWendler = weight * repeat * 0.0333 + weight;
double rmOconner = weight * (1 + repeat / 40);
double average = (rmWendler + rmOconner) / 2;
return average * percent;
}
}

View File

@ -0,0 +1,12 @@
part of 'result_bloc.dart';
abstract class ResultEvent extends Equatable {
const ResultEvent();
@override
List<Object> get props => [];
}
class ResultLoad extends ResultEvent {
const ResultLoad();
}

View File

@ -0,0 +1,28 @@
part of 'result_bloc.dart';
abstract class ResultState extends Equatable {
const ResultState();
@override
List<Object> get props => [];
}
class ResultInitial extends ResultState {
const ResultInitial();
}
class ResultLoading extends ResultState {
const ResultLoading();
}
class ResultReady extends ResultState {
const ResultReady();
}
class ResultError extends ResultState {
final String error;
const ResultError({this.error});
@override
List<Object> get props => [this.error];
}

View File

@ -2,9 +2,11 @@ import 'dart:async';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:health/health.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
part 'settings_event.dart'; part 'settings_event.dart';
@ -31,18 +33,52 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
) async* { ) async* {
if (event is SettingsChangeLanguage) { if (event is SettingsChangeLanguage) {
yield SettingsLoading(); yield SettingsLoading();
await _changeLang( event.language); await _changeLang(event.language);
yield SettingsReady(_locale); yield SettingsReady(_locale);
} else if ( event is SettingsGetLanguage) { } else if (event is SettingsGetLanguage) {
await AppLanguage().fetchLocale(); await AppLanguage().fetchLocale();
_locale = AppLanguage().appLocal; _locale = AppLanguage().appLocal;
yield SettingsReady(_locale); yield SettingsReady(_locale);
} else if (event is SettingsSetServer) {
yield SettingsLoading();
final bool live = event.live;
Cache().setServer(live);
yield SettingsReady(_locale);
} else if (event is SettingsSetHardware) {
yield SettingsLoading();
bool selectedHardwareBefore = await Cache().selectedHardwareBefore();
print("selectedBefore " + selectedHardwareBefore.toString());
if (!selectedHardwareBefore) {
await _accessHealthData();
}
final bool hasHardware = event.hasHardware;
await Cache().setHardware(hasHardware);
yield SettingsReady(_locale);
} }
} }
Future<void> _changeLang( String lang ) async{ Future<void> _accessHealthData() async {
final List<HealthDataType> types = [
HealthDataType.ACTIVE_ENERGY_BURNED,
HealthDataType.WATER,
HealthDataType.STEPS,
HealthDataType.HEART_RATE,
HealthDataType.BASAL_ENERGY_BURNED,
HealthDataType.BODY_TEMPERATURE,
HealthDataType.HIGH_HEART_RATE_EVENT,
HealthDataType.LOW_HEART_RATE_EVENT,
HealthDataType.RESTING_HEART_RATE
];
final HealthFactory health = HealthFactory();
DateTime now = DateTime.now();
List<HealthDataPoint> _healthDataList = await health.getHealthDataFromTypes(now.subtract(Duration(minutes: 5)), now, types);
print(_healthDataList.toString());
}
Future<void> _changeLang(String lang) async {
print("_change to $lang"); print("_change to $lang");
switch ( lang ) { switch (lang) {
case "English": case "English":
case "en": case "en":
case "Angol": case "Angol":
@ -59,8 +95,8 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> {
await loadLang(); await loadLang();
} }
Future<void> loadLang() async{ Future<void> loadLang() async {
if ( _locale != null ) { if (_locale != null) {
print(" -- Loading lang $_locale"); print(" -- Loading lang $_locale");
if (context != null) { if (context != null) {
AppLocalizations.of(context).setLocale(_locale); AppLocalizations.of(context).setLocale(_locale);

View File

@ -15,3 +15,19 @@ class SettingsChangeLanguage extends SettingsEvent {
class SettingsGetLanguage extends SettingsEvent { class SettingsGetLanguage extends SettingsEvent {
const SettingsGetLanguage(); const SettingsGetLanguage();
} }
class SettingsSetServer extends SettingsEvent {
final bool live;
const SettingsSetServer({this.live});
@override
List<Object> get props => [this.live];
}
class SettingsSetHardware extends SettingsEvent {
final bool hasHardware;
const SettingsSetHardware({this.hasHardware});
@override
List<Object> get props => [this.hasHardware];
}

View File

@ -11,6 +11,7 @@ import 'package:aitrainer_app/view/customer_fitness_page.dart';
import 'package:aitrainer_app/view/customer_goal_page.dart'; import 'package:aitrainer_app/view/customer_goal_page.dart';
import 'package:aitrainer_app/view/customer_modify_page.dart'; import 'package:aitrainer_app/view/customer_modify_page.dart';
import 'package:aitrainer_app/view/customer_welcome_page.dart'; import 'package:aitrainer_app/view/customer_welcome_page.dart';
import 'package:aitrainer_app/view/evaluation.dart';
import 'package:aitrainer_app/view/exercise_control_page.dart'; import 'package:aitrainer_app/view/exercise_control_page.dart';
import 'package:aitrainer_app/view/exercise_execute_page.dart'; import 'package:aitrainer_app/view/exercise_execute_page.dart';
import 'package:aitrainer_app/view/exercise_execute_plan_add_page.dart'; import 'package:aitrainer_app/view/exercise_execute_plan_add_page.dart';
@ -216,6 +217,7 @@ class WorkoutTestApp extends StatelessWidget {
'exerciseExecuteAddPage': (context) => ExerciseExecutePlanAddPage(), 'exerciseExecuteAddPage': (context) => ExerciseExecutePlanAddPage(),
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(), 'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(), 'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),
'evaluationPage': (context) => EvaluationPage(),
}, },
initialRoute: 'home', initialRoute: 'home',
title: 'WorkoutTest', title: 'WorkoutTest',

View File

@ -55,6 +55,7 @@ class Cache {
static final String isLoggedInKey = 'is_logged_in'; static final String isLoggedInKey = 'is_logged_in';
static final String langKey = 'lang'; static final String langKey = 'lang';
static final String serverKey = 'live'; static final String serverKey = 'live';
static final String hardwareKey = 'hardware';
static String baseUrl = 'http://aitrainer.info:8888/api/'; static String baseUrl = 'http://aitrainer.info:8888/api/';
static final String mediaUrl = 'https://aitrainer.info:4343/media/'; static final String mediaUrl = 'https://aitrainer.info:4343/media/';
@ -92,6 +93,7 @@ class Cache {
String startPage; String startPage;
String testEnvironment; String testEnvironment;
bool liveServer = true; bool liveServer = true;
bool hasHardware = false;
factory Cache() { factory Cache() {
return _singleton; return _singleton;
@ -114,7 +116,7 @@ class Cache {
return this.authToken; return this.authToken;
} }
void setServer(bool live) async { Future<void> setServer(bool live) async {
if (this.testEnvironment == "1") { if (this.testEnvironment == "1") {
liveServer = false; liveServer = false;
live = false; live = false;
@ -123,10 +125,34 @@ class Cache {
SharedPreferences sharedPreferences; SharedPreferences sharedPreferences;
sharedPreferences = await prefs; sharedPreferences = await prefs;
liveServer = live; liveServer = live;
print("Set Live servier. live? " + live.toString() + " env? " + this.testEnvironment);
sharedPreferences.setBool(Cache.serverKey, live); sharedPreferences.setBool(Cache.serverKey, live);
} }
void getHardware(SharedPreferences prefs) {
final bool hasHardware = prefs.getBool(Cache.hardwareKey);
print("Has Hardware: " + hasHardware.toString());
this.hasHardware = hasHardware;
if (hasHardware == null) {
this.hasHardware = false;
}
}
Future<bool> selectedHardwareBefore() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs;
final bool selectedHardware = sharedPreferences.getBool(Cache.hardwareKey);
return selectedHardware == null;
}
Future<void> setHardware(bool hasHardware) async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences;
sharedPreferences = await prefs;
sharedPreferences.setBool(Cache.hardwareKey, hasHardware);
this.hasHardware = hasHardware;
}
void setServerAddress(SharedPreferences prefs) { void setServerAddress(SharedPreferences prefs) {
if (this.testEnvironment == "1") { if (this.testEnvironment == "1") {
baseUrl = 'http://aitrainer.app:8899/api/'; baseUrl = 'http://aitrainer.app:8899/api/';

View File

@ -0,0 +1,6 @@
enum ExerciseAbility { oneRepMax, endurance, running, none }
extension ExerciseAbilityExt on ExerciseAbility {
bool equalsTo(ExerciseAbility ability) => this.toString() == ability.toString();
bool equalsStringTo(String ability) => this.toString() == ability;
}

View File

@ -0,0 +1,44 @@
import 'package:aitrainer_app/model/result.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseResult {
int exerciseResultId;
int customerId;
int exerciseId;
int exercisePlanId;
String resultType;
double value;
DateTime dateFrom;
DateTime dateTo;
ResultExt resultExtension;
Map<String, dynamic> toJson() {
String formattedDateTo;
if (dateTo != null) {
formattedDateTo = DateFormat('yyyy-MM-dd HH:mm').format(dateTo);
}
return {
"customerId": customerId,
"exerciseId": exerciseId,
"exercisePlanId": exercisePlanId,
"resultType": resultType,
"value": value,
"dateFrom": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateFrom),
"dateTo": formattedDateTo,
};
}
ExerciseResult.fromJson(Map json) {
this.exerciseResultId = json['exerciseResultId'];
this.exerciseId = json['exerciseId'];
this.exercisePlanId = json['exercisePlanId'];
this.customerId = json['customerId'];
this.resultType = json['resultType'];
this.value = json["value"];
this.dateFrom = DateTime.parse(json['dateFrom']);
this.dateTo = DateTime.parse(json['dateTo']);
this.resultExtension = ResultExt(itemString: this.resultType);
}
}

View File

@ -37,6 +37,7 @@ class ExerciseTree {
if (parentId != -1) { if (parentId != -1) {
newTree.parentId = parentId; newTree.parentId = parentId;
} }
newTree.active = this.active;
return newTree; return newTree;
} }

View File

@ -1,3 +1,4 @@
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class ExerciseType { class ExerciseType {
@ -17,8 +18,7 @@ class ExerciseType {
List<int> devices = List(); List<int> devices = List();
List<int> parents = List(); List<int> parents = List();
bool is1RM; ExerciseAbility ability;
bool isEndurance;
ExerciseType({this.name, this.description}); ExerciseType({this.name, this.description});
@ -70,19 +70,19 @@ class ExerciseType {
"parents": this.parents.toString() "parents": this.parents.toString()
}; };
void set1RM(bool is1RM) { void setAbility(ExerciseAbility ability) {
this.is1RM = is1RM; this.ability = ability;
} }
bool get1RM() { ExerciseAbility getAbility() {
return this.is1RM; return this.ability;
} }
void setEndurance(bool isEndurance) { bool isEndurance() {
this.isEndurance = isEndurance; return this.ability.equalsTo(ExerciseAbility.endurance);
} }
bool getEndurance() { bool is1RM() {
return this.isEndurance; return this.ability.equalsTo(ExerciseAbility.oneRepMax);
} }
} }

93
lib/model/result.dart Normal file
View File

@ -0,0 +1,93 @@
enum ResultItem {
calorie,
development_percent_bodypart,
distance,
fatburn_percent,
bpm_avg,
bpm_min,
bpm_max,
speed_max,
reps_volume,
steps,
//time,
weight_volume
}
extension ResultItemExt on ResultItem {
static const ResultItemDesc = {
ResultItem.calorie: "Calorie",
ResultItem.development_percent_bodypart: "Development in %",
ResultItem.distance: "Distance",
ResultItem.bpm_avg: "Average BPM",
ResultItem.bpm_min: "Min BPM",
ResultItem.bpm_max: "Max BPM",
ResultItem.speed_max: "Max speed",
ResultItem.reps_volume: "Repeats volume",
ResultItem.steps: "Steps",
//ResultItem.time: "Time",
ResultItem.weight_volume: "Weight volume",
ResultItem.fatburn_percent: "Fatburn %",
};
static const ResultItemImg = {
ResultItem.calorie: "pict_calorie.png",
ResultItem.development_percent_bodypart: "pic_development_by_bodypart_percent.png",
ResultItem.distance: "pict_distance_m.png",
ResultItem.bpm_avg: "pict_hravg_bpm.png",
ResultItem.bpm_min: "pict_hrmin_bpm.png",
ResultItem.bpm_max: "pict_hrmax_bpm.png",
ResultItem.speed_max: "pict_maxspeed_kmh.png",
ResultItem.reps_volume: "pict_reps_volumen_db.png",
ResultItem.steps: "pict_steps.png",
//ResultItem.time: "pict_time_h.png",
ResultItem.weight_volume: "pict_weight_volumen_tonna.png",
ResultItem.fatburn_percent: "pict_fatburn_percent.png",
};
static const HardwareData = {
ResultItem.calorie: true,
ResultItem.development_percent_bodypart: false,
ResultItem.distance: true,
ResultItem.bpm_avg: true,
ResultItem.bpm_min: true,
ResultItem.bpm_max: true,
ResultItem.speed_max: true,
ResultItem.reps_volume: false,
ResultItem.steps: true,
//ResultItem.time: false,
ResultItem.weight_volume: false,
ResultItem.fatburn_percent: true,
};
bool equals(ResultItem item) => this.toString() == item.toString();
bool equalsString(String item) => this.description == item;
String get description => ResultItemDesc[this];
String get image => ResultItemImg[this];
bool get isHardware => HardwareData[this];
String displayString() => description;
}
class ResultExt {
final String itemString;
ResultItem item;
String data = "0";
ResultExt({this.itemString}) {
ResultItem.values.forEach((element) {
if (element.equalsString(itemString)) {
item = element;
}
});
}
String getDescription() => item.description;
String getImage() => "asset/image/" + item.image;
bool isHardware() {
return item.isHardware;
}
bool equals(ResultItem item) => this.item.equals(item);
bool equalsString(String item) => this.item.equalsString(item);
}

View File

@ -2,6 +2,22 @@ import 'dart:ui';
import 'exercise_type.dart'; import 'exercise_type.dart';
enum WorkoutType { endurance, oneRepMax, cardio, staticExercise }
extension WorkoutTypeExt on WorkoutType {
static const WorkoutTypeMenu = {
WorkoutType.endurance: "Endurance",
WorkoutType.cardio: "Cardio",
WorkoutType.oneRepMax: "One Rep Max",
WorkoutType.staticExercise: "Static"
};
bool equals(WorkoutType type) => this.toString() == type.toString();
bool equalsString(String type) => this.toString() == type;
String get menu => WorkoutTypeMenu[this];
}
class WorkoutMenuTree { class WorkoutMenuTree {
int id; int id;
int parent; int parent;
@ -16,13 +32,15 @@ class WorkoutMenuTree {
bool is1RM; bool is1RM;
bool isEndurance; bool isEndurance;
bool isRunning;
List<WorkoutType> workoutTypes = List();
bool selected = false; bool selected = false;
bool executed = false; bool executed = false;
String exerciseDetail; String exerciseDetail;
String nameEnglish; String nameEnglish;
WorkoutMenuTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, WorkoutMenuTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId,
this.exerciseType, this.base, this.is1RM, this.isEndurance, this.nameEnglish); this.exerciseType, this.base, this.is1RM, this.isEndurance, this.isRunning, this.nameEnglish);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
@ -37,6 +55,7 @@ class WorkoutMenuTree {
"base": base.toString(), "base": base.toString(),
"is1RM": is1RM.toString(), "is1RM": is1RM.toString(),
"isEndurance": isEndurance.toString(), "isEndurance": isEndurance.toString(),
"isRunning": isRunning.toString(),
}; };
} }

View File

@ -12,6 +12,7 @@ class ExerciseRepository {
Customer customer; Customer customer;
ExerciseType exerciseType; ExerciseType exerciseType;
List<Exercise> exerciseList; List<Exercise> exerciseList;
List<Exercise> actualExerciseList = List();
double rmWendler = 0; double rmWendler = 0;
double rmMcglothlin = 0; double rmMcglothlin = 0;
@ -20,28 +21,35 @@ class ExerciseRepository {
double rmOconner = 0; double rmOconner = 0;
double rmWathen = 0; double rmWathen = 0;
DateTime start;
DateTime end;
ExerciseRepository() {
this.createNew();
}
createNew() { createNew() {
this.exercise = Exercise(); this.exercise = Exercise();
exercise.dateAdd = DateTime.now(); exercise.dateAdd = DateTime.now();
} }
setQuantity(double quantity) { setQuantity(double quantity) {
if ( this.exercise == null ) { if (this.exercise == null) {
this.createNew(); this.createNew();
} }
this.exercise.quantity = quantity; this.exercise.quantity = quantity;
} }
setUnitQuantity(double unitQuantity) { setUnitQuantity(double unitQuantity) {
if ( this.exercise == null ) { if (this.exercise == null) {
this.createNew(); this.createNew();
} }
this.exercise.unitQuantity = unitQuantity; this.exercise.unitQuantity = unitQuantity;
} }
setUnit( String unit) { setUnit(String unit) {
if ( this.exercise == null ) { if (this.exercise == null) {
this.createNew(); this.createNew();
} }
@ -49,7 +57,7 @@ class ExerciseRepository {
} }
setDatetimeExercise(DateTime datetimeExercise) { setDatetimeExercise(DateTime datetimeExercise) {
if ( this.exercise == null ) { if (this.exercise == null) {
this.createNew(); this.createNew();
} }
@ -66,11 +74,16 @@ class ExerciseRepository {
final Exercise modelExercise = this.exercise; final Exercise modelExercise = this.exercise;
modelExercise.customerId = this.customer.customerId; modelExercise.customerId = this.customer.customerId;
modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId; modelExercise.exerciseTypeId = this.exerciseType.exerciseTypeId;
if (exerciseType.unitQuantity != "1") {
modelExercise.unitQuantity = null;
}
this.actualExerciseList.add(modelExercise);
Exercise savedExercise = await ExerciseApi().addExercise(modelExercise); Exercise savedExercise = await ExerciseApi().addExercise(modelExercise);
if ( customer.customerId == Cache().userLoggedIn.customerId) {
Cache().addExercise(savedExercise); if (customer.customerId == Cache().userLoggedIn.customerId) {
} else if ( Cache().getTrainee() != null && customer.customerId == Cache().getTrainee().customerId ) { Cache().addExercise(savedExercise);
Cache().addExerciseTrainee(savedExercise); } else if (Cache().getTrainee() != null && customer.customerId == Cache().getTrainee().customerId) {
Cache().addExerciseTrainee(savedExercise);
} }
} }
@ -78,21 +91,17 @@ class ExerciseRepository {
await ExerciseApi().deleteExercise(exercise); await ExerciseApi().deleteExercise(exercise);
} }
setCustomer(Customer customer) => this.customer = customer; setCustomer(Customer customer) => this.customer = customer;
setExerciseType( ExerciseType exerciseType) => this.exerciseType = exerciseType; setExerciseType(ExerciseType exerciseType) => this.exerciseType = exerciseType;
Future<List<Exercise>> getExercisesByCustomer(int customerId) async {
Future<List<Exercise>> getExercisesByCustomer( int customerId ) async { final results = await ExerciseApi().getExercisesByCustomer(customerId);
final results = await ExerciseApi().getExercisesByCustomer(customerId);
this.exerciseList = results; this.exerciseList = results;
if ( Cache().userLoggedIn != null ) { if (Cache().userLoggedIn != null) {
if (customerId == Cache().userLoggedIn.customerId) { if (customerId == Cache().userLoggedIn.customerId) {
Cache().setExercises(exerciseList); Cache().setExercises(exerciseList);
} else if (Cache().getTrainee() != null && customerId == Cache() } else if (Cache().getTrainee() != null && customerId == Cache().getTrainee().customerId) {
.getTrainee()
.customerId) {
Cache().setExercisesTrainee(exerciseList); Cache().setExercisesTrainee(exerciseList);
} }
} }
@ -110,11 +119,11 @@ class ExerciseRepository {
} }
String nextMissingBaseExercise(SplayTreeMap sortedTree) { String nextMissingBaseExercise(SplayTreeMap sortedTree) {
if ( exerciseList == null ) { if (exerciseList == null) {
exerciseList = Cache().getExercises(); exerciseList = Cache().getExercises();
} }
if ( exerciseList == null ) { if (exerciseList == null) {
return ""; return "";
} }
String missingTreeName; String missingTreeName;
@ -127,12 +136,12 @@ class ExerciseRepository {
treeName = treeName.substring(3); treeName = treeName.substring(3);
foundTreeName = null; foundTreeName = null;
listByMuscle.forEach((exercise) { listByMuscle.forEach((exercise) {
if ( missingTreeName == null ) { if (missingTreeName == null) {
missingTreeName = treeName; missingTreeName = treeName;
} }
if ( exercise.base ) { if (exercise.base) {
exerciseList.forEach((element) { exerciseList.forEach((element) {
if ( element.exerciseTypeId == exercise.exerciseTypeId ) { if (element.exerciseTypeId == exercise.exerciseTypeId) {
foundTreeName = treeName; foundTreeName = treeName;
//print("Found " + foundTreeName + " Missing actual: " + missingTreeName); //print("Found " + foundTreeName + " Missing actual: " + missingTreeName);
isBreak = true; isBreak = true;
@ -140,7 +149,7 @@ class ExerciseRepository {
}); });
} }
}); });
if ( foundTreeName == null &&! isBreak ) { if (foundTreeName == null && !isBreak) {
missingTreeName = treeName; missingTreeName = treeName;
isBreak = true; isBreak = true;
} }
@ -156,40 +165,38 @@ class ExerciseRepository {
int count1RMExercises = 0; int count1RMExercises = 0;
LinkedHashMap<String, WorkoutMenuTree> tree = Cache().getWorkoutMenuTree(); LinkedHashMap<String, WorkoutMenuTree> tree = Cache().getWorkoutMenuTree();
if ( tree == null ) { if (tree == null) {
return; return;
} }
tree.forEach((key, value) { tree.forEach((key, value) {
WorkoutMenuTree treeItem = value; WorkoutMenuTree treeItem = value;
if (treeItem.exerciseType != null && if (treeItem.exerciseType != null && treeItem.exerciseType.base == true && !baseTreeItem.contains(treeItem.parent)) {
treeItem.exerciseType.base == true &&
!baseTreeItem.contains(treeItem.parent)) {
baseTreeItem.add(treeItem.parent); baseTreeItem.add(treeItem.parent);
} }
}); });
if ( exerciseList == null ) { if (exerciseList == null) {
exerciseList = Cache().getExercises(); exerciseList = Cache().getExercises();
} }
if ( exerciseList == null ) { if (exerciseList == null) {
return; return;
} }
exerciseList.forEach((element) { exerciseList.forEach((element) {
Exercise exercise = element; Exercise exercise = element;
if ( !checkedExerciseTypeId.contains(exercise.exerciseTypeId )) { if (!checkedExerciseTypeId.contains(exercise.exerciseTypeId)) {
checkedExerciseTypeId.add(exercise.exerciseTypeId); checkedExerciseTypeId.add(exercise.exerciseTypeId);
tree.forEach((key, value) { tree.forEach((key, value) {
WorkoutMenuTree treeItem = value; WorkoutMenuTree treeItem = value;
if (treeItem.exerciseType != null if (treeItem.exerciseType != null &&
&& treeItem.exerciseType.base == true treeItem.exerciseType.base == true &&
&& exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId exercise.exerciseTypeId == treeItem.exerciseType.exerciseTypeId &&
&& !checkedBaseTreeItem.contains(treeItem.parent)) { !checkedBaseTreeItem.contains(treeItem.parent)) {
//print ("id: " + exercise.exerciseTypeId.toString()); //print ("id: " + exercise.exerciseTypeId.toString());
checkedBaseTreeItem.add(treeItem.parent); checkedBaseTreeItem.add(treeItem.parent);
count1RMExercises++; count1RMExercises++;
} }
}); });
} }
@ -207,7 +214,7 @@ class ExerciseRepository {
Exercise lastExercise = exercises[0]; Exercise lastExercise = exercises[0];
exercises.forEach((element) { exercises.forEach((element) {
Exercise actualExercise = element; Exercise actualExercise = element;
if ( actualExercise.dateAdd.compareTo(lastExercise.dateAdd) > 0 ) { if (actualExercise.dateAdd.compareTo(lastExercise.dateAdd) > 0) {
lastExercise = actualExercise; lastExercise = actualExercise;
} }
}); });
@ -221,16 +228,15 @@ class ExerciseRepository {
ExerciseType actualExerciseType; ExerciseType actualExerciseType;
Cache().getExerciseTypes().forEach((element) { Cache().getExerciseTypes().forEach((element) {
ExerciseType exerciseType = element; ExerciseType exerciseType = element;
if ( exerciseType.exerciseTypeId == exerciseTypeId) { if (exerciseType.exerciseTypeId == exerciseTypeId) {
actualExerciseType = exerciseType; actualExerciseType = exerciseType;
} }
}); });
if ( actualExerciseType == null ) { if (actualExerciseType == null) {
throw Exception("Data error, no ExerciseType for exerciseTypeId $exerciseTypeId" ); throw Exception("Data error, no ExerciseType for exerciseTypeId $exerciseTypeId");
} }
return actualExerciseType; return actualExerciseType;
} }
void sortByDate() => exerciseList.sort( (a, b) => b.dateAdd.compareTo(a.dateAdd) ); void sortByDate() => exerciseList.sort((a, b) => b.dateAdd.compareTo(a.dateAdd));
}
}

View File

@ -0,0 +1,40 @@
import 'package:aitrainer_app/model/result.dart';
enum ResultType { running, man, woman, none }
extension ResultTypeExt on ResultType {
bool equals(ResultType type) => this.toString() == type.toString();
}
class ExerciseResultRepository {
final List<ResultExt> _results = List();
ResultType resultType;
ExerciseResultRepository({this.resultType}) {
if (resultType == null) {
resultType = ResultType.man;
}
if (resultType.equals(ResultType.man) || resultType.equals(ResultType.woman)) {
//_results.add(ResultExt(itemString: ResultItem.time.description));
_results.add(ResultExt(itemString: ResultItem.reps_volume.description));
_results.add(ResultExt(itemString: ResultItem.weight_volume.description));
_results.add(ResultExt(itemString: ResultItem.bpm_max.description));
_results.add(ResultExt(itemString: ResultItem.calorie.description));
_results.add(ResultExt(itemString: ResultItem.bpm_avg.description));
_results.add(ResultExt(itemString: ResultItem.fatburn_percent.description));
_results.add(ResultExt(itemString: ResultItem.bpm_min.description));
} else {
//_results.add(ResultExt(itemString: ResultItem.time.description));
_results.add(ResultExt(itemString: ResultItem.distance.description));
_results.add(ResultExt(itemString: ResultItem.bpm_max.description));
_results.add(ResultExt(itemString: ResultItem.calorie.description));
_results.add(ResultExt(itemString: ResultItem.bpm_avg.description));
_results.add(ResultExt(itemString: ResultItem.fatburn_percent.description));
_results.add(ResultExt(itemString: ResultItem.bpm_min.description));
_results.add(ResultExt(itemString: ResultItem.steps.description));
_results.add(ResultExt(itemString: ResultItem.speed_max.description));
}
}
List<ResultExt> getResults() => this._results;
}

View File

@ -1,6 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/exercise_tree.dart'; import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
@ -32,6 +33,7 @@ class WorkoutTreeRepository {
final LinkedHashMap tree = LinkedHashMap<String, WorkoutMenuTree>(); final LinkedHashMap tree = LinkedHashMap<String, WorkoutMenuTree>();
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>(); SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
bool isEnglish; bool isEnglish;
WorkoutType workoutType;
final Map<String, int> _antagonist = { final Map<String, int> _antagonist = {
Antagonist.chest: Antagonist.chestNr, Antagonist.chest: Antagonist.chestNr,
@ -59,60 +61,71 @@ class WorkoutTreeRepository {
} }
exerciseTree.forEach((treeItem) async { exerciseTree.forEach((treeItem) async {
//print(" -- TreeItem " + treeItem.toJson().toString()); //print(" -- 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);
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation; bool is1RM = treeItem.name == 'One Rep Max' ? true : false;
String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7); if (is1RM == false && treeItem.parentId != 0) {
is1RM = isParent1RM(treeItem.parentId);
}
bool is1RM = treeItem.name == 'One Rep Max' ? true : false; bool isEndurance = treeItem.name == 'Endurance' ? true : false;
if (is1RM == false && treeItem.parentId != 0) { if (isEndurance == false && treeItem.parentId != 0) {
is1RM = isParent1RM(treeItem.parentId); isEndurance = isParentEndurance(treeItem.parentId);
}
bool isRunning = treeItem.name == "Cardio" ? true : false;
if (isRunning == false && treeItem.parentId != 0) {
isRunning = isParentRunning(treeItem.parentId);
}
WorkoutMenuTree menuItem = WorkoutMenuTree(
treeItem.treeId,
treeItem.parentId,
treeName,
assetImage,
Colors.white,
30,
false,
0,
null,
false,
is1RM,
isEndurance,
isRunning,
treeItem.name,
);
menuItem = this.setWorkoutTypes(menuItem, treeItem);
this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem;
//print("WorkoutMenuTree item " + menuItem.toJson().toString());
} }
bool isEndurance = treeItem.name == 'Endurance' ? true : false;
if (isEndurance == false && treeItem.parentId != 0) {
isEndurance = isParentEndurance(treeItem.parentId);
}
final WorkoutMenuTree menuItem = WorkoutMenuTree(
treeItem.treeId,
treeItem.parentId,
treeName,
assetImage,
Colors.white,
30,
false,
0,
null,
false,
is1RM,
isEndurance,
treeItem.name,
);
this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem;
//print("WorkoutMenuTree item " + menuItem.toJson().toString());
}); });
exerciseTypes.forEach((exerciseType) { exerciseTypes.forEach((exerciseType) {
if (!(exerciseType.imageUrl.isEmpty || exerciseType.name.isEmpty || exerciseType.nameTranslation.isEmpty)) { if (!(exerciseType.imageUrl.isEmpty || exerciseType.name.isEmpty || exerciseType.nameTranslation.isEmpty) &&
exerciseType.active == true) {
String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation; String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation;
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7); String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
if (exerciseType.parents.isNotEmpty) { if (exerciseType.parents.isNotEmpty) {
exerciseType.parents.forEach((parentId) { exerciseType.parents.forEach((parentId) {
bool is1RM = this.isParent1RM(parentId); bool is1RM = this.isParent1RM(parentId);
bool isEndurance = this.isParentEndurance(parentId); bool isEndurance = this.isParentEndurance(parentId);
exerciseType.is1RM = is1RM; if (is1RM) exerciseType.setAbility(ExerciseAbility.oneRepMax);
exerciseType.isEndurance = isEndurance; if (isEndurance) exerciseType.setAbility(ExerciseAbility.endurance);
bool isRunning = this.isParentRunning(parentId);
if (isRunning) exerciseType.setAbility(ExerciseAbility.running);
WorkoutMenuTree menuItem = WorkoutMenuTree(exerciseType.exerciseTypeId, parentId, exerciseTypeName, assetImage, Colors.white, WorkoutMenuTree menuItem = WorkoutMenuTree(exerciseType.exerciseTypeId, parentId, exerciseTypeName, assetImage, Colors.white,
24, true, exerciseType.exerciseTypeId, exerciseType, exerciseType.base, is1RM, isEndurance, exerciseType.name); 24, true, exerciseType.exerciseTypeId, exerciseType, exerciseType.base, is1RM, isEndurance, isRunning, exerciseType.name);
this.tree[exerciseType.name] = menuItem; this.tree[exerciseType.name] = menuItem;
//print("WorkoutMenuTree item " + menuItem.toJson().toString()); print("WorkoutMenuTree item " + menuItem.toJson().toString());
/*print("ExerciseType in Menu item " + print("ExerciseType in Menu item " +
exerciseType.toJson().toString() + exerciseType.toJson().toString() +
" is1RM: " + " is1RM: " +
is1RM.toString() + is1RM.toString() +
" isEndurance: " + " isEndurance: " +
isEndurance.toString());*/ isEndurance.toString());
}); });
} else { } else {
//print("No Parents " + exerciseType.toJson().toString()); //print("No Parents " + exerciseType.toJson().toString());
@ -127,6 +140,39 @@ class WorkoutTreeRepository {
exerciseRepository.getBaseExerciseFinishedPercent(); exerciseRepository.getBaseExerciseFinishedPercent();
} }
WorkoutMenuTree setWorkoutTypes(WorkoutMenuTree menu, ExerciseTree treeItem) {
WorkoutType.values.forEach((workoutType) {
if (workoutType.equalsString(treeItem.name) || existWorkoutTypeInTree(workoutType)) {
menu.workoutTypes.add(workoutType);
}
});
return menu;
}
bool existWorkoutTypeInTree(WorkoutType workoutType) {
bool exists = false;
this.tree.forEach((key, treeItem) {
if (workoutType.equalsString(treeItem.name)) {
exists = true;
}
});
return exists;
}
bool isParentRunning(int treeId) {
bool isTreeItemRunning = false;
this.tree.forEach((key, value) {
WorkoutMenuTree treeItem = value as WorkoutMenuTree;
if (treeItem.id == treeId) {
isTreeItemRunning = isTreeItemRunning || treeItem.isRunning;
//print (treeItem.name + " 1RM " + treeItem.is1RM.toString() );
}
});
return isTreeItemRunning;
}
bool isParent1RM(int treeId) { bool isParent1RM(int treeId) {
bool isTreeItem1RM = false; bool isTreeItem1RM = false;

View File

@ -35,7 +35,7 @@ class ExerciseTreeApi {
if (index > 0) { if (index > 0) {
ExerciseTree newElement = element.copy(parent.exerciseTreeParentId); ExerciseTree newElement = element.copy(parent.exerciseTreeParentId);
exerciseTree.add(newElement); exerciseTree.add(newElement);
print("ExerciseTree " + newElement.toJson().toString()); //print("ExerciseTree " + newElement.toJson().toString());
} else { } else {
element.parentId = parent.exerciseTreeParentId; element.parentId = parent.exerciseTreeParentId;
exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId; exerciseTree[treeIndex].parentId = parent.exerciseTreeParentId;

View File

@ -31,6 +31,7 @@ class Session {
await AppLocalizations.delegate.load(AppLanguage().appLocal); await AppLocalizations.delegate.load(AppLanguage().appLocal);
print(" -- Session: fetch token.."); print(" -- Session: fetch token..");
Cache().setServerAddress(_sharedPreferences); Cache().setServerAddress(_sharedPreferences);
Cache().getHardware(_sharedPreferences);
await _fetchToken(_sharedPreferences); await _fetchToken(_sharedPreferences);
print(" -- FireBase init.."); print(" -- FireBase init..");
await FirebaseApi().initializeFlutterFire(); await FirebaseApi().initializeFlutterFire();

View File

@ -3,7 +3,6 @@ import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart'; import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';

503
lib/view/evaluation.dart Normal file
View File

@ -0,0 +1,503 @@
import 'dart:collection';
import 'dart:ui';
import 'package:aitrainer_app/bloc/result/result_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/repository/exercise_result_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/model/result.dart';
// ignore: must_be_immutable
class EvaluationPage extends StatelessWidget with Trans {
@override
Widget build(BuildContext context) {
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
ExerciseRepository exerciseRepository;
// ignore: close_sinks
if (arguments != null) {
exerciseRepository = arguments['exerciseRepository'];
} else {
exerciseRepository = ExerciseRepository();
}
ResultType resultType = ResultType.none;
String imageUrl = "";
if (Cache().userLoggedIn.sex == "m") {
resultType = ResultType.man;
imageUrl = 'asset/image/WT_Results_for_men.png';
} else {
resultType = ResultType.man;
imageUrl = 'asset/image/WT_Results_for_female.png';
}
if (exerciseRepository.exerciseType.getAbility().equalsTo(ExerciseAbility.running)) {
resultType = ResultType.running;
imageUrl = 'asset/image/WT_Results_for_runners.png';
}
print("ResultType: " + resultType.toString());
setContext(context);
return Scaffold(
appBar: AppBarMin(
back: true,
),
body: Container(
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(imageUrl),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
child: BlocProvider(
create: (context) =>
ResultBloc(resultRepository: ExerciseResultRepository(resultType: resultType), exerciseRepository: exerciseRepository)
..add(ResultLoad()),
child: BlocConsumer<ResultBloc, ResultState>(listener: (context, state) {
if (state is ResultError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.error, style: TextStyle(color: Colors.white))));
} else if (state is ResultLoading) {
Scaffold.of(context).showSnackBar(SnackBar(
duration: Duration(milliseconds: 100),
backgroundColor: Colors.transparent,
content: Container(child: Center(child: CircularProgressIndicator()))));
}
}, builder: (context, state) {
final resultBloc = BlocProvider.of<ResultBloc>(context);
return getEvaluationWidgets(resultBloc);
}))),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 0));
}
Widget getEvaluationWidgets(ResultBloc resultBloc) {
String exerciseName = AppLanguage().appLocal == Locale("en")
? resultBloc.exerciseRepository.exerciseType.name
: resultBloc.exerciseRepository.exerciseType.nameTranslation;
return Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
SliverAppBar(
pinned: true,
backgroundColor: Colors.transparent,
expandedHeight: 50.0,
automaticallyImplyLeading: false,
flexibleSpace: FlexibleSpaceBar(
title: Text(exerciseName,
textAlign: TextAlign.center,
maxLines: 3,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
),
),
SliverList(
delegate: SliverChildListDelegate([
Text(DateFormat('y-M-d HH:mm', AppLanguage().appLocal.toString()).format(resultBloc.exerciseRepository.start),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
Divider(color: Colors.transparent),
Divider(color: Colors.transparent),
Text(t("Summary of your test"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.yellow[300],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
]),
),
getResultSummary(resultBloc),
getSuggestionTitle(resultBloc),
getSuggestion(resultBloc),
emptySliver(),
getResultTitle(resultBloc),
getResults(resultBloc),
]));
}
Widget getSuggestionTitle(ResultBloc resultBloc) {
if (resultBloc.exerciseRepository.exerciseType.unitQuantityUnit != null) {
return SliverList(
delegate: SliverChildListDelegate(
[
Divider(color: Colors.transparent),
Divider(color: Colors.transparent),
Text(t("Suggestions based on your test"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.yellow[300],
shadows: <Shadow>[
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,
),
],
)),
],
),
);
} else
return emptySliver();
}
Widget getResultTitle(ResultBloc resultBloc) {
return SliverList(
delegate: SliverChildListDelegate(
[
Divider(color: Colors.transparent),
Divider(color: Colors.transparent),
Text(t("Health Data Summary"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.yellow[300],
shadows: <Shadow>[
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(),
],
),
);
}
Widget getSuggestion(ResultBloc resultBloc) {
if (resultBloc.exerciseRepository.exerciseType.unitQuantityUnit != null) {
return SliverList(
delegate: SliverChildListDelegate(
[
getSuggestionWidget(resultBloc, "Hypertrophy", "asset/image/pict_hypertrophy.png", "3x10-12", 0.9, "2"),
Divider(color: Colors.transparent),
getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x10-12", 0.75, "3-5"),
Divider(color: Colors.transparent),
getSuggestionWidget(resultBloc, "Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"),
],
),
);
} else
return emptySliver();
}
Widget emptySliver({int count = 1}) {
return SliverList(
delegate: SliverChildListDelegate(
[
Container(),
Divider(color: Colors.transparent),
],
),
);
}
Widget getSuggestionWidget(ResultBloc resultBloc, String title, String picture, String repeats, double percent, String restTime) {
String unitQuantityUnit = resultBloc.exerciseRepository.exerciseType.unitQuantityUnit == null
? ""
: resultBloc.exerciseRepository.exerciseType.unitQuantityUnit;
return Column(
children: [
Text(t(title),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 30,
color: Colors.white,
shadows: <Shadow>[
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,
),
],
)),
Row(children: [
Image.asset(
picture,
height: 80,
),
SizedBox(
width: 10,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(repeats + " " + t("repeats"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 18,
color: Colors.orange,
shadows: <Shadow>[
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,
),
],
))
],
),
Row(
children: [
Text(t("Weight") + ": " + resultBloc.calculate1RM(percent: percent).toStringAsFixed(0) + " " + unitQuantityUnit,
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 18,
color: Colors.orange,
shadows: <Shadow>[
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,
),
],
)),
],
),
Row(
children: [
Text(t("Rest time") + ": " + restTime + " " + t("minutes"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 18,
color: Colors.orange,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
],
),
],
)
]),
],
);
}
Widget getSummary(ResultBloc bloc) {
int index = 0;
List<Text> resultList = List();
bloc.exerciseRepository.actualExerciseList.forEach((exercise) {
final String unit = t(bloc.exerciseRepository.exerciseType.unit);
String exerciseElement = "";
final String exerciseRepeats = exercise.quantity.toStringAsFixed(0);
final String exerciseUnitQuantity = exercise.unitQuantity != null ? "x" + exercise.unitQuantity.toStringAsFixed(0) : "";
if (index == 0) {
exerciseElement = t("Test") + ": ";
} else if (index == 1) {
exerciseElement = t("1st Control") + ": ";
} else if (index == 2) {
exerciseElement = t("2nd Control") + ": ";
} else if (index == 3) {
exerciseElement = t("3rd Control") + ": ";
}
index++;
resultList.add(
Text(exerciseElement + exerciseRepeats + exerciseUnitQuantity + " " + unit,
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.inter(
fontSize: 18,
color: Colors.white,
shadows: <Shadow>[
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,
),
],
)),
);
});
return Column(children: resultList);
}
Widget getResultSummary(ResultBloc resultBloc) {
return SliverList(
delegate: SliverChildListDelegate(
[Divider(color: Colors.transparent), getSummary(resultBloc)],
),
);
}
Widget getResults(ResultBloc resultBloc) {
return SliverGrid(
delegate: SliverChildListDelegate(
getResultData(resultBloc),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0,
childAspectRatio: 1.1,
),
);
}
List<Widget> getResultData(ResultBloc resultBloc) {
List<Widget> data = List();
resultBloc.resultRepository.getResults().forEach((element) {
data.add(getResultWidget(element));
});
return data;
}
Widget getResultWidget(ResultExt element) {
bool hasHardware = Cache().hasHardware;
bool blur = (!hasHardware && element.isHardware());
/* print("Blur: " +
element.getDescription() +
": " +
blur.toString() +
" hasHardware:" +
hasHardware.toString() +
" isHw: " +
element.isHardware().toString()); */
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
blur
? Stack(children: [
Image.asset(
element.getImage(),
height: 80,
//color: Colors.white12,
),
Image.asset(
element.getImage(),
height: 80,
color: Colors.black54,
),
])
: Image.asset(
element.getImage(),
height: 80,
),
SizedBox(
width: 10,
),
Text(
element.data,
style: GoogleFonts.archivoBlack(fontSize: 28, color: blur ? Colors.white30 : Colors.white),
),
Text(
t(element.getDescription()),
style: GoogleFonts.archivoBlack(fontSize: 14, color: blur ? Colors.white30 : Colors.white),
textAlign: TextAlign.left,
),
],
);
}
}

View File

@ -2,16 +2,17 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_control/exercise_control_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_control/exercise_control_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/number_picker.dart';
import 'package:aitrainer_app/widgets/splash.dart'; import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:aitrainer_app/library/numberpicker.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
class ExerciseControlPage extends StatefulWidget { class ExerciseControlPage extends StatefulWidget {
@ -32,16 +33,16 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
..add(ExerciseControlLoad()), ..add(ExerciseControlLoad()),
child: BlocConsumer<ExerciseControlBloc, ExerciseControlState>(listener: (context, state) { child: BlocConsumer<ExerciseControlBloc, ExerciseControlState>(listener: (context, state) {
if (state is ExerciseControlError) { if (state is ExerciseControlError) {
//LoadingDialog.hide(context);
Scaffold.of(context).showSnackBar( Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is ExerciseControlLoading) { } else if (state is ExerciseControlLoading) {
//LoadingDialog.show(context); return LoadingDialog();
} }
}, builder: (context, state) { }, builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseControlBloc>(context); final exerciseBloc = BlocProvider.of<ExerciseControlBloc>(context);
if (state is ExerciseControlReady) { if (state is ExerciseControlLoading) {
//LoadingDialog.hide(context); return LoadingDialog();
} else if (state is ExerciseControlReady) {
return getControlForm(exerciseBloc); return getControlForm(exerciseBloc);
} else { } else {
return getControlForm(exerciseBloc); return getControlForm(exerciseBloc);
@ -53,49 +54,80 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
String exerciseName = AppLanguage().appLocal == Locale("en") String exerciseName = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.name ? exerciseBloc.exerciseRepository.exerciseType.name
: exerciseBloc.exerciseRepository.exerciseType.nameTranslation; : exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
return Form( return Form(
child: Scaffold( child: Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1), appBar: AppBarNav(depth: 1),
body: Container( body: Container(
width: MediaQuery.of(context).size.width, height: double.infinity,
height: MediaQuery.of(context).size.height, width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'), image: Cache().userLoggedIn.sex == "m"
fit: BoxFit.fill, ? AssetImage("asset/image/WT_Results_for_men.png")
alignment: Alignment.center, : AssetImage("asset/image/WT_Results_for_female.png"),
fit: BoxFit.cover,
alignment: Alignment.topCenter,
), ),
), ),
child: Container( child: Container(
padding: const EdgeInsets.only(top: 25, left: 25, right: 25), padding: const EdgeInsets.only(top: 10, left: 25, right: 25),
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
controller: ScrollController(
initialScrollOffset: exerciseBloc.scrollOffset,
),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Text(
exerciseName, exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.orange), style: GoogleFonts.archivoBlack(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 6.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
),
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, textAlign: TextAlign.center,
maxLines: 2,
softWrap: true, softWrap: true,
), ),
FlatButton( Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
/* FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Icon( Icon(
Icons.info, Icons.info,
color: Colors.yellow[300], color: Colors.yellow[50],
), ),
Flexible( Flexible(
child: Text(t("Why do you need Exercise Control?"), child: Text(t("Why do you need Exercise Control?"),
style: TextStyle(color: Colors.yellow[300], fontWeight: FontWeight.normal, fontSize: 14)), style: TextStyle(color: Colors.yellow[50], fontWeight: FontWeight.normal, fontSize: 14)),
), ),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.yellow[300], color: Colors.yellow[50],
), ),
]), ]),
textColor: Colors.blueAccent, textColor: Colors.blueAccent,
@ -103,20 +135,21 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
onPressed: () => { onPressed: () => {
//Navigator.of(context).pushNamed('exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository), //Navigator.of(context).pushNamed('exerciseTypeDescription', arguments: exerciseBloc.exerciseRepository),
}, },
), ), */
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text(t("Your 1RM:"), Text(t("Your 1RM:"),
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Colors.yellow[300], color: Colors.yellow[300],
fontSize: 18,
)), )),
Text( Text(
" " + " " +
exerciseBloc.initialRM.toStringAsFixed(0) + exerciseBloc.initialRM.toStringAsFixed(0) +
" " + " " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit, exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
style: GoogleFonts.inter(color: Colors.yellow[300], fontWeight: FontWeight.bold), style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 18, fontWeight: FontWeight.bold),
), ),
], ],
), ),
@ -134,7 +167,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
} }
Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) { Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) {
String strTimes = step == 2 ? exerciseBloc.origQuantity.toString() : "max."; String strTimes = step == 2 ? exerciseBloc.origQuantity.toStringAsFixed(0) : "max.";
String textInstruction = ""; String textInstruction = "";
textInstruction = t("Please repeat with ") + textInstruction = t("Please repeat with ") +
exerciseBloc.unitQuantity.toStringAsFixed(0) + exerciseBloc.unitQuantity.toStringAsFixed(0) +
@ -149,44 +182,46 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
); );
String title = step.toString() + ". " + t("Control Exercise:"); String title = step.toString() + ". " + t("Control Exercise:");
LinkedHashMap args = LinkedHashMap();
List<Widget> listWidgets = [ List<Widget> listWidgets = [
Text( Text(
title, title,
style: GoogleFonts.inter(color: Colors.yellow[300], fontWeight: FontWeight.bold), style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 18, fontWeight: FontWeight.bold),
), ),
Text( Text(
textInstruction, textInstruction,
style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 12), style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 16),
), ),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
NumberPicker.horizontal( NumberPickerWidget(
highlightSelectedValue: step == exerciseBloc.step, minValue: 0,
initialValue: exerciseBloc.quantity.toInt(), maxValue: 200,
minValue: 0, initalValue: exerciseBloc.quantity.toInt(),
maxValue: 200, unit: t("reps"),
step: 1, color: Colors.yellow[50],
onChanged: (value) => {exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))}, onChange: (value) => {exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))}),
listViewHeight: 80,
textStyleHighlighted: GoogleFonts.archivoBlack(color: Colors.orange[300], fontSize: 24),
//decoration: _decoration,
),
FlatButton( FlatButton(
padding: EdgeInsets.all(0), padding: EdgeInsets.all(0),
textColor: Colors.white, textColor: Colors.white,
//color: step == exerciseBloc.step ? Colors.orange : Colors.black26,
focusColor: Colors.blueAccent, focusColor: Colors.blueAccent,
onPressed: () => { onPressed: () => {
exerciseBloc.add(ExerciseControlSubmit(step: step)), exerciseBloc.add(ExerciseControlSubmit(step: step)),
if (step == 3) {confirmationDialog(exerciseBloc)} if (step == 3)
{
//confirmationDialog(exerciseBloc)
Navigator.of(context).pop(),
args['exerciseRepository'] = exerciseBloc.exerciseRepository,
Navigator.of(context).pushNamed('evaluationPage', arguments: args)
}
}, },
child: step == exerciseBloc.step child: step == exerciseBloc.step
? Stack( ? Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 60),
Text( Text(
t("Save"), t("Save"),
style: TextStyle(fontSize: 16, color: Colors.white), style: TextStyle(fontSize: 16, color: Colors.white),
@ -206,6 +241,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
void confirmationDialog(ExerciseControlBloc bloc) { void confirmationDialog(ExerciseControlBloc bloc) {
String unit = t(bloc.exerciseRepository.exerciseType.unit); String unit = t(bloc.exerciseRepository.exerciseType.unit);
LinkedHashMap args = LinkedHashMap();
showCupertinoDialog( showCupertinoDialog(
useRootNavigator: true, useRootNavigator: true,
@ -235,7 +271,11 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
actions: [ actions: [
FlatButton( FlatButton(
child: Text(t("OK")), child: Text(t("OK")),
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pop()}, onPressed: () => {
Navigator.of(context).pop(),
args['exerciseRepository'] = bloc.exerciseRepository,
Navigator.of(context).pushNamed('evaluationPage', arguments: args)
},
) )
], ],
)); ));

View File

@ -241,11 +241,11 @@ class _ExerciseLogPage extends State<ExerciseLogPage> with Trans, Common {
style: (TextStyle(color: Colors.blue)), style: (TextStyle(color: Colors.blue)),
), ),
Text( Text(
exercise.quantity.toStringAsFixed(0) + exercise.quantity.toStringAsFixed(0) + "x" + exercise.unitQuantity.toStringAsFixed(0) + " ",
"x" + //+
exercise.unitQuantity.toStringAsFixed(0) + //exerciseType.unitQuantityUnit == null
" " + // ? ""
exerciseType.unitQuantityUnit, // : exerciseType.unitQuantityUnit,
style: (TextStyle(color: Colors.deepOrange)), style: (TextStyle(color: Colors.deepOrange)),
), ),
Text( Text(

View File

@ -2,8 +2,10 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
@ -19,6 +21,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart';
class ExerciseNewPage extends StatefulWidget { class ExerciseNewPage extends StatefulWidget {
_ExerciseNewPageState createState() => _ExerciseNewPageState(); _ExerciseNewPageState createState() => _ExerciseNewPageState();
@ -132,14 +135,19 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
return SizeWidget(exerciseBloc: exerciseBloc); return SizeWidget(exerciseBloc: exerciseBloc);
} }
bool isSecond = false;
String exerciseTask = ""; String exerciseTask = "";
if (exerciseBloc.exerciseRepository.exerciseType.is1RM && menuBloc.ability.toString() == ExerciseAbility.oneRepMax.toString()) { if (exerciseBloc.exerciseRepository.exerciseType.unit != "second") {
exerciseTask = "Please take a relative bigger weight and repeat 12-20 times"; if (exerciseBloc.exerciseRepository.exerciseType.is1RM() && menuBloc.ability.toString() == ExerciseAbility.oneRepMax.toString()) {
exerciseBloc.quantity = 12; exerciseTask = "Please take a relative bigger weight and repeat 12-20 times";
} else if (exerciseBloc.exerciseRepository.exerciseType.isEndurance && exerciseBloc.quantity = 12;
menuBloc.ability.toString() == ExerciseAbility.endurance.toString()) { } else if (exerciseBloc.exerciseRepository.exerciseType.isEndurance() &&
exerciseTask = "Please take a medium weight and repeat 20-30 times"; menuBloc.ability.toString() == ExerciseAbility.endurance.toString()) {
exerciseBloc.quantity = 20; exerciseTask = "Please take a medium weight and repeat 20-30 times";
exerciseBloc.quantity = 20;
}
} else {
isSecond = true;
} }
return Form( return Form(
@ -159,20 +167,34 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
child: KeyboardActions( child: KeyboardActions(
config: _buildConfig(context), config: _buildConfig(context),
child: Container( child: Container(
padding: const EdgeInsets.only(top: 5, left: 55, right: 55), padding: const EdgeInsets.only(top: 25, left: 55, right: 55),
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text(t('Save Exercise'), style: TextStyle(fontSize: 14, color: Colors.blue[200])),
Divider(),
Text( Text(
exerciseName, exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.orange), style: GoogleFonts.archivoBlack(
fontWeight: FontWeight.bold,
fontSize: 24,
color: Colors.white,
shadows: <Shadow>[
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,
),
],
),
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 2, maxLines: 4,
softWrap: true, softWrap: true,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@ -235,7 +257,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 60), Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 60),
Text( Text(
t("Save"), t("Save"),
style: TextStyle(fontSize: 16, color: Colors.white), style: TextStyle(fontSize: 16, color: Colors.white),
@ -280,6 +302,80 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
Column columnQuantity(ExerciseNewBloc bloc) { Column columnQuantity(ExerciseNewBloc bloc) {
if (bloc.exerciseRepository.exerciseType.unit == "second") { if (bloc.exerciseRepository.exerciseType.unit == "second") {
return Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ return Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
Padding(
padding: const EdgeInsets.only(bottom: 0),
child: StreamBuilder<int>(
stream: bloc.stopWatchTimer.rawTime,
initialData: bloc.stopWatchTimer.rawTime.value,
builder: (context, snap) {
final value = snap.data;
final displayTime = StopWatchTimer.getDisplayTime(value, hours: false);
return Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(8),
child: Text(
displayTime,
style: const TextStyle(fontSize: 40, fontFamily: 'Helvetica', fontWeight: FontWeight.bold, color: Colors.white),
),
),
]);
})),
Padding(
padding: const EdgeInsets.all(2),
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: IconButton(
padding: const EdgeInsets.all(2),
color: Colors.white70,
//shape: const StadiumBorder(),
onPressed: () async {
bloc.stopWatchTimer.onExecute.add(StopWatchExecute.start);
},
icon: Icon(CustomIcon.play_1),
iconSize: 40,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: IconButton(
padding: const EdgeInsets.all(2),
iconSize: 40,
color: Colors.white70,
//shape: const StadiumBorder(),
onPressed: () async {
bloc.stopWatchTimer.onExecute.add(StopWatchExecute.stop);
},
icon: Icon(CustomIcon.stop),
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: IconButton(
padding: const EdgeInsets.all(2),
iconSize: 40,
color: Colors.white70,
onPressed: () async {
bloc.stopWatchTimer.onExecute.add(StopWatchExecute.reset);
},
icon: Icon(CustomIcon.creative_commons_zero),
),
),
],
),
),
],
),
),
Divider(),
Divider(),
Text("Or type the time manually:", style: GoogleFonts.inter(color: Colors.white)),
TimePickerWidget( TimePickerWidget(
onChange: (value) => {bloc.add(ExerciseNewQuantityChange(quantity: value))}, onChange: (value) => {bloc.add(ExerciseNewQuantityChange(quantity: value))},
) )
@ -360,18 +456,26 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans {
child: Text(t("Yes")), child: Text(t("Yes")),
onPressed: () => { onPressed: () => {
bloc.exerciseRepository.setCustomer(Cache().userLoggedIn), bloc.exerciseRepository.setCustomer(Cache().userLoggedIn),
bloc.exerciseRepository.addExercise(), bloc.add(ExerciseNewSubmit()),
Navigator.pop(context), Navigator.pop(context),
Navigator.pop(context), Navigator.pop(context),
if (bloc.exerciseRepository.exerciseType.is1RM && menuBloc.ability.toString() == ExerciseAbility.oneRepMax.toString()) print("Ability " +
menuBloc.ability.toString() +
" exerciseType 1rm " +
bloc.exerciseRepository.exerciseType.is1RM().toString()),
if (bloc.exerciseRepository.exerciseType.unitQuantityUnit == null)
{
args['exerciseRepository'] = bloc.exerciseRepository,
Navigator.of(context).pushNamed('evaluationPage', arguments: args)
}
else if (menuBloc.ability.equalsTo(ExerciseAbility.oneRepMax))
{ {
args['exerciseRepository'] = bloc.exerciseRepository, args['exerciseRepository'] = bloc.exerciseRepository,
args['percent'] = 0.75, args['percent'] = 0.75,
args['readonly'] = false, args['readonly'] = false,
Navigator.of(context).pushNamed('exerciseControlPage', arguments: args) Navigator.of(context).pushNamed('exerciseControlPage', arguments: args)
} }
else if (bloc.exerciseRepository.exerciseType.isEndurance && else if (menuBloc.ability.equalsTo(ExerciseAbility.endurance))
menuBloc.ability.toString() == ExerciseAbility.endurance.toString())
{ {
args['exerciseRepository'] = bloc.exerciseRepository, args['exerciseRepository'] = bloc.exerciseRepository,
args['percent'] = 0.50, args['percent'] = 0.50,

View File

@ -7,7 +7,6 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart'; import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -161,7 +160,7 @@ class _ExercisePlanDetailAddPage extends State<ExercisePlanDetailAddPage> with T
Text( Text(
exerciseName, exerciseName,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(fontSize: 18, color: Colors.deepOrange), style: GoogleFonts.archivoBlack(fontSize: 18, color: Colors.yellow[200]),
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 3, maxLines: 3,
softWrap: true, softWrap: true,

View File

@ -9,7 +9,6 @@ import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart'; import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';

View File

@ -1,5 +1,6 @@
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
@ -36,20 +37,16 @@ class SettingsPage extends StatelessWidget with Trans {
if (state is SettingsError) { if (state is SettingsError) {
} else if (state is SettingsReady) { } else if (state is SettingsReady) {
menuBloc.add(MenuRecreateTree()); menuBloc.add(MenuRecreateTree());
} else if (state is SettingsLoading) {
Scaffold.of(context).showSnackBar(SnackBar(
duration: Duration(milliseconds: 100),
backgroundColor: Colors.transparent,
content: Container(child: Center(child: CircularProgressIndicator()))));
} }
}, },
// ignore: missing_return // ignore: missing_return
builder: (context, state) { builder: (context, state) {
if (state is SettingsLoading) { return settingsUI(context, settingsBloc, menuBloc);
//LoadingDialog.show(context);
} else if (state is SettingsInitial) {
return settingsUI(context, settingsBloc, menuBloc);
} else if (state is SettingsReady) {
//LoadingDialog.hide(context);
return settingsUI(context, settingsBloc, menuBloc);
} else {
return Container();
}
}), }),
), ),
), ),
@ -72,11 +69,12 @@ class SettingsPage extends StatelessWidget with Trans {
onChanged: (String lang) => { onChanged: (String lang) => {
settingsBloc.add(SettingsChangeLanguage(language: lang)), settingsBloc.add(SettingsChangeLanguage(language: lang)),
})), })),
getServer(), getServer(settingsBloc),
getDevice(settingsBloc),
]); ]);
} }
ListTile getServer() { ListTile getServer(SettingsBloc settingsBloc) {
if (Cache().userLoggedIn.admin != 1) { if (Cache().userLoggedIn.admin != 1) {
return ListTile( return ListTile(
title: Container(), title: Container(),
@ -100,7 +98,29 @@ class SettingsPage extends StatelessWidget with Trans {
inactiveFgColor: Colors.grey[900], inactiveFgColor: Colors.grey[900],
labels: [t('Live-Server'), t('Test-Server')], labels: [t('Live-Server'), t('Test-Server')],
onToggle: (index) { onToggle: (index) {
Cache().setServer(index == 0); //Cache().setServer(index == 0);
settingsBloc.add(SettingsSetServer(live: index == 0));
},
),
);
}
ListTile getDevice(SettingsBloc settingsBloc) {
return ListTile(
leading: Icon(CustomIcon.cog),
subtitle: Text("Do you have Smart watch, or any device which collects the fit/health data?"),
title: ToggleSwitch(
minWidth: 120.0,
minHeight: 30.0,
fontSize: 14.0,
initialLabelIndex: Cache().hasHardware ? 0 : 1,
activeBgColor: Colors.indigo,
activeFgColor: Colors.white,
inactiveBgColor: Colors.white60,
inactiveFgColor: Colors.grey[900],
labels: [t('Yes'), t('No')],
onToggle: (index) {
settingsBloc.add(SettingsSetHardware(hasHardware: index == 0));
}, },
), ),
); );

View File

@ -5,7 +5,8 @@ import 'package:flutter/material.dart';
class LoadingScreenMain extends StatelessWidget { class LoadingScreenMain extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Image _backgroundImage = Image.asset('asset/image/WT01_loading_layers.png', final Image _backgroundImage = Image.asset(
'asset/image/WT01_loading_layers.png',
fit: BoxFit.cover, fit: BoxFit.cover,
height: double.infinity, height: double.infinity,
width: double.infinity, width: double.infinity,
@ -23,13 +24,14 @@ class LoadingScreenMain extends StatelessWidget {
new Container( new Container(
decoration: BoxDecoration(color: Colors.white), decoration: BoxDecoration(color: Colors.white),
), ),
/// Render the background image /// Render the background image
new Container( new Container(
child: SafeArea( child: SafeArea(
bottom: false, bottom: false,
child: _backgroundImage, child: _backgroundImage,
) )),
),
/// Render the Title widget, loader and messages below each other /// Render the Title widget, loader and messages below each other
new Column( new Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -37,15 +39,14 @@ class LoadingScreenMain extends StatelessWidget {
new Expanded( new Expanded(
flex: 3, flex: 3,
child: new Container( child: new Container(
child: new Column( child: new Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
new Padding( new Padding(
padding: const EdgeInsets.only(top: 30.0), padding: const EdgeInsets.only(top: 30.0),
), ),
],
], )),
)),
), ),
Expanded( Expanded(
flex: 1, flex: 1,
@ -54,8 +55,7 @@ class LoadingScreenMain extends StatelessWidget {
children: <Widget>[ children: <Widget>[
/// Loader Animation Widget /// Loader Animation Widget
CircularProgressIndicator( CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>( valueColor: new AlwaysStoppedAnimation<Color>(Colors.lightGreenAccent),
Colors.lightGreenAccent),
), ),
Padding( Padding(
padding: const EdgeInsets.only(top: 20.0), padding: const EdgeInsets.only(top: 20.0),

View File

@ -0,0 +1,71 @@
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class NumberPickerWidget extends StatefulWidget {
final Function(double) onChange;
final int minValue;
final int maxValue;
final int initalValue;
final String unit;
final Color color;
const NumberPickerWidget({Key key, this.minValue, this.maxValue, this.initalValue, this.unit, this.color, this.onChange})
: super(key: key);
@override
_NumberPickerWidgetState createState() => _NumberPickerWidgetState();
}
class _NumberPickerWidgetState extends State<NumberPickerWidget> with Trans {
Widget durationPicker({bool inSeconds = false, bool inHundredths = false}) {
double value = 0;
return CupertinoPicker(
scrollController: FixedExtentScrollController(initialItem: widget.initalValue),
backgroundColor: Colors.transparent,
onSelectedItemChanged: (x) {
currentData = x.toDouble();
value = x.toDouble();
//print("sec" + seconds.toStringAsFixed(2));
setState(() {});
widget.onChange(value);
},
children: List.generate(widget.maxValue, (index) => Text('$index ' + widget.unit, style: TextStyle(color: widget.color))),
itemExtent: 40,
);
}
double currentData = 0;
@override
Widget build(BuildContext context) {
setContext(context);
return Container(
//color: Colors.white24,
width: MediaQuery.of(context).size.width * .45,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.transparent,
width: MediaQuery.of(context).size.width * .3,
child: Center(
child: Container(
color: Colors.transparent,
width: MediaQuery.of(context).size.width * 0.95,
height: MediaQuery.of(context).size.height * 0.25,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: durationPicker()),
],
)),
),
),
],
),
),
);
}
}

View File

@ -211,6 +211,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.10" version: "1.3.10"
device_info:
dependency: transitive
description:
name: device_info
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2+10"
device_info_platform_interface:
dependency: transitive
description:
name: device_info_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
devicelocale: devicelocale:
dependency: "direct main" dependency: "direct main"
description: description:
@ -430,6 +444,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.0"
health:
dependency: "direct main"
description:
name: health
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
http: http:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -869,6 +890,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0-nullsafety.1" version: "1.10.0-nullsafety.1"
stop_watch_timer:
dependency: "direct main"
description:
name: stop_watch_timer
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0+1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.2+36 version: 1.1.2+39
environment: environment:
sdk: ">=2.10.0 <3.0.0" sdk: ">=2.10.0 <3.0.0"
@ -42,7 +42,9 @@ dependencies:
keyboard_actions: ^3.3.1+1 keyboard_actions: ^3.3.1+1
dropdown_search: ^0.4.8 dropdown_search: ^0.4.8
badges: ^1.1.4 badges: ^1.1.4
#health: ^2.0.9 health: ^2.0.9
stop_watch_timer: ^0.6.0+1
#geolocator: ^6.1.13
firebase_core: ^0.5.2 firebase_core: ^0.5.2
@ -97,6 +99,7 @@ flutter:
assets: assets:
- asset/icon/gomb_kek_a-2.png - asset/icon/gomb_kek_a-2.png
- asset/icon/gomb_orange_a.png - asset/icon/gomb_orange_a.png
- asset/icon/gomb_orange_c.png
- asset/icon/gomb_pink_a.png - asset/icon/gomb_pink_a.png
- asset/icon/gomb_pink_b.png - asset/icon/gomb_pink_b.png
- asset/icon/gomb_zold_b-1.png - asset/icon/gomb_zold_b-1.png
@ -116,6 +119,9 @@ flutter:
- asset/image/Gain_muscle.png - asset/image/Gain_muscle.png
- asset/image/WT_weight_loss.png - asset/image/WT_weight_loss.png
- asset/image/WT_welcome.png - asset/image/WT_welcome.png
- asset/image/WT_Results_for_runners.png
- asset/image/WT_Results_for_female.png
- asset/image/WT_Results_for_men.png
- asset/image/login_fb.png - asset/image/login_fb.png
- asset/image/lock.png - asset/image/lock.png
- asset/image/Congrats_N1.jpg - asset/image/Congrats_N1.jpg
@ -157,6 +163,19 @@ flutter:
- asset/image/equipment_gym_place.jpg - asset/image/equipment_gym_place.jpg
- asset/image/equipment_street_place.jpg - asset/image/equipment_street_place.jpg
- asset/image/haken.png - asset/image/haken.png
- asset/image/pict_calorie.png
- asset/image/pict_development_by_bodypart_percent.png
- asset/image/pict_distance_m.png
- asset/image/pict_fatburn_percent.png
- asset/image/pict_hravg_bpm.png
- asset/image/pict_hrmin_bpm.png
- asset/image/pict_hrmax_bpm.png
- asset/image/pict_maxspeed_kmh.png
- asset/image/pict_reps_volumen_db.png
- asset/image/pict_steps.png
- asset/image/pict_time_h.png
- asset/image/pict_hypertrophy.png
- asset/image/pict_weight_volumen_tonna.png
- asset/menu/1.cardio.png - asset/menu/1.cardio.png
- asset/menu/1.1.aerob.png - asset/menu/1.1.aerob.png
- asset/menu/1.2.anaerob.png - asset/menu/1.2.anaerob.png

21
test/result_test.dart Normal file
View File

@ -0,0 +1,21 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/result.dart';
import 'package:test/test.dart';
main() {
setUp(() {
Cache().setTestBaseUrl();
});
group('Result', () {
test('test ResultExt constructor', () async {
final ResultExt resultExt = ResultExt(itemString: "Calorie");
expect(resultExt.getImage(), "asset/image/pic_calorie.png");
expect(resultExt.getDescription(), "Calorie");
expect(resultExt.item.equals(ResultItem.calorie), true);
expect(resultExt.equals(ResultItem.calorie), true);
expect(resultExt.equalsString("Calorie"), true);
});
});
}