WT 1.1.7+2 SearchBar, Timer for ExerciseControl

This commit is contained in:
bossanyit 2021-02-28 17:03:47 +01:00
parent cf348cebb0
commit 6bea5e70e1
77 changed files with 1581 additions and 1008 deletions

1
android/.gitignore vendored
View File

@ -4,4 +4,5 @@ gradle-wrapper.jar
/gradlew /gradlew
/gradlew.bat /gradlew.bat
/local.properties /local.properties
key.properties
GeneratedPluginRegistrant.java GeneratedPluginRegistrant.java

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 54 KiB

BIN
asset/menu/2.1.4.squats.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
asset/menu/row_machine.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
asset/wine-glass.mp3 Normal file

Binary file not shown.

View File

@ -361,33 +361,36 @@
"Body Type Analyser":"Body Type Analyser", "Body Type Analyser":"Body Type Analyser",
"How likely is it true about you?":"How likely is it true about you?", "How likely is it true about you?":"How likely is it true about you?",
"Very unlikely":"Very unlikely", "Very unlikely":"Not True",
"Maybe":"Maybe", "Maybe":"Maybe",
"Very likely":"Very likely", "Very likely":"True",
"« Back":"« Back", "« Back":"« Back",
"1. Basicly I am skinny and bonny":"1. Basicly I am skinny and bonny", "1. Basicly I am skinny and bonny":"1. I have basically a thin and bony physique",
"2. question":"2. question", "2. question":"2. Long limbs and narrow shoulders are typical of me",
"3. question":"3. question", "3. question":"3. It is difficult for me to build muscle",
"4. question":"4. question", "4. question":"4. My chest and waist are nearly the same width",
"5. question":"5. question", "5. question":"5. Chopstick was my nickname in the kindergarten",
"6. question":"6. question", "6. question":"6. I easily lose the muscle I built up",
"7. question":"7. question", "7. question":"7. To my knowledge, my body fat percentage is low",
"8. question":"8. question", "8. question":"8. Basically, I have a sporty and athletic physique",
"9. question":"9. question", "9. question":"9. I have a wide collarbone and shoulders",
"10. question":"10. question", "10. question":"10. My hips are narrow and my waist is sporty",
"11. question":"11. question", "11. question":"11. I get muscular quickly",
"12. question":"12. question", "12. question":"12. My chest is wider than my waist",
"13. question":"13. question", "13. question":"13. I could be the statue of David",
"14. question":"14. question", "14. question":"14. I have a strong calf and forearm",
"15. question":"15. question", "15. question":"15. I have a wide rib cage",
"16. question":"16. question", "16. question":"16. I have thick and wide joints",
"17. question":"17. question", "17. question":"17. My bones are strong",
"18. question":"18. question", "18. question":"18. My body is muscular but a little fatter",
"19. question":"19. question", "19. question":"19. My hips are wider than my chest",
"20. question":"20. question", "20. question":"20. Tun could be my nickname too",
"21. question":"21. question", "21. question":"21. I lose weight hard and gain weight more easily",
"22. question":"22. question", "22. question":"22. I have a strong and chunky physique",
"Your Bodytype result":"Your Bodytype result", "Your Bodytype result":"Your Bodytype result",
"Change the weight to":"Change the weight to" "Change the weight to":"Change the weight to",
"Search Exercises...":"Search Exercises...",
"No exercise found":"No exercise found"
} }

View File

@ -361,7 +361,7 @@
"Maybe":"Talán", "Maybe":"Talán",
"Very likely":"Biztosan", "Very likely":"Biztosan",
"« Back":"« Vissza", "« Back":"« Vissza",
"1. Basicly I am skinny and bonny":"1. Alapvetően vékony csontos testalkat vagyok", "1. Basicly I am skinny and bonny":"1. Alapvetően vékony, csontos testalkat vagyok",
"2. question":"2. Hosszú végtagok, keskeny vállak jellemzőek rám", "2. question":"2. Hosszú végtagok, keskeny vállak jellemzőek rám",
"3. question":"3. Nehezen tudok izmot növelni", "3. question":"3. Nehezen tudok izmot növelni",
"4. question":"4. Mellkasom, derekam közel egyforma szélességű", "4. question":"4. Mellkasom, derekam közel egyforma szélességű",
@ -374,16 +374,19 @@
"11. question":"11. Gyorsan izmosodok", "11. question":"11. Gyorsan izmosodok",
"12. question":"12. Szélesebb a mellkasom a derekamnál", "12. question":"12. Szélesebb a mellkasom a derekamnál",
"13. question":"13. Akár lehetnék én a Dávid szobor", "13. question":"13. Akár lehetnék én a Dávid szobor",
"14. question":"14. Erős vádli és alkar", "14. question":"14. Erős vádli és alkar jellemez",
"15. question":"15. Széles bordakosaram van", "15. question":"15. Széles bordakosaram van",
"16. question":"16. Vastag széles ízületeim vannak", "16. question":"16. Vastag, széles ízületeim vannak",
"17. question":"17. Erős a csontozatom", "17. question":"17. Erős a csontozatom",
"18. question":"18. Zsírosabb, de izmos vagyok", "18. question":"18. Zsírosabb, de izmos vagyok",
"19. question":"19. Szélesebb a csípőm a mellkasomnál", "19. question":"19. Szélesebb a csípőm a mellkasomnál",
"20. question":"20. Hordó is lehetne a becenevem", "20. question":"20. Hordó is lehetne a becenevem",
"21. question":"21. Nehezen fogyok, könnyebben hízok", "21. question":"21. Nehezen fogyok, könnyebben hízok",
"22. question":"22. Erős vaskos testalkat vagyok", "22. question":"22. Erős, vaskos testalkat vagyok",
"Your Bodytype result":"Testtípus eredményed", "Your Bodytype result":"Testtípus eredményed",
"Change the weight to":"Súly változtatása" "Change the weight to":"Súly változtatása",
"Search Exercises...":"Gyakorlat keresése...",
"No exercise found":"Nincs ilyen gyakorlat"
} }

View File

@ -6,6 +6,8 @@ PODS:
- AppAuth/ExternalUserAgent (1.4.0) - AppAuth/ExternalUserAgent (1.4.0)
- apple_sign_in (0.0.1): - apple_sign_in (0.0.1):
- Flutter - Flutter
- audioplayer (0.0.1):
- Flutter
- devicelocale (0.0.1): - devicelocale (0.0.1):
- Flutter - Flutter
- FBSDKCoreKit (9.0.0): - FBSDKCoreKit (9.0.0):
@ -181,6 +183,7 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- apple_sign_in (from `.symlinks/plugins/apple_sign_in/ios`) - apple_sign_in (from `.symlinks/plugins/apple_sign_in/ios`)
- audioplayer (from `.symlinks/plugins/audioplayer/ios`)
- devicelocale (from `.symlinks/plugins/devicelocale/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`) - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
@ -232,6 +235,8 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
apple_sign_in: apple_sign_in:
:path: ".symlinks/plugins/apple_sign_in/ios" :path: ".symlinks/plugins/apple_sign_in/ios"
audioplayer:
:path: ".symlinks/plugins/audioplayer/ios"
devicelocale: devicelocale:
:path: ".symlinks/plugins/devicelocale/ios" :path: ".symlinks/plugins/devicelocale/ios"
firebase_analytics: firebase_analytics:
@ -274,6 +279,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7 AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4 apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
audioplayer: 0584f31a697e4b0bbad405ae7903d7a93585e784
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
FBSDKCoreKit: ac6cc500b8e104bb9a4dd20b1527b5d199123c2e FBSDKCoreKit: ac6cc500b8e104bb9a4dd20b1527b5d199123c2e
FBSDKLoginKit: e9b6542fdee322333502ab497f628b011dce7d78 FBSDKLoginKit: e9b6542fdee322333502ab497f628b011dce7d78

View File

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

View File

@ -47,8 +47,14 @@
<string>10.0</string> <string>10.0</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
<array> <array>
<string>audio</string>
<string>fetch</string> <string>fetch</string>
<string>remote-notification</string> <string>remote-notification</string>
</array> </array>

View File

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';

View File

@ -0,0 +1,32 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'development_sizes_event.dart';
part 'development_sizes_state.dart';
class DevelopmentSizesBloc extends Bloc<DevelopmentSizesEvent, DevelopmentSizesState> {
final CustomerRepository customerRepository;
DevelopmentSizesBloc({this.customerRepository}) : super(DevelopmentSizesInitial()) {
isMan = Cache().userLoggedIn.sex == "m";
}
bool isMan;
@override
Stream<DevelopmentSizesState> mapEventToState(
DevelopmentSizesEvent event,
) async* {
try {
if (state is DevelopmentSizesLoad) {
yield DevelopmentSizesLoading();
yield DevelopmentSizesReady();
}
} on Exception catch (e) {
yield DevelopmentSizesError(message: e.toString());
}
}
}

View File

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

View File

@ -0,0 +1,28 @@
part of 'development_sizes_bloc.dart';
abstract class DevelopmentSizesState extends Equatable {
const DevelopmentSizesState();
@override
List<Object> get props => [];
}
class DevelopmentSizesInitial extends DevelopmentSizesState {
const DevelopmentSizesInitial();
}
class DevelopmentSizesLoading extends DevelopmentSizesState {
const DevelopmentSizesLoading();
}
class DevelopmentSizesReady extends DevelopmentSizesState {
const DevelopmentSizesReady();
}
class DevelopmentSizesError extends DevelopmentSizesState {
final String message;
const DevelopmentSizesError({this.message});
@override
List<Object> get props => [this.message];
}

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
@ -9,6 +10,7 @@ part 'exercise_control_event.dart';
part 'exercise_control_state.dart'; part 'exercise_control_state.dart';
class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlState> { class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlState> {
final TimerBloc timerBloc;
final ExerciseRepository exerciseRepository; final ExerciseRepository exerciseRepository;
final bool readonly; final bool readonly;
final double percentToCalculate; final double percentToCalculate;
@ -25,7 +27,8 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
double scrollOffset = 0; double scrollOffset = 0;
@override @override
ExerciseControlBloc({this.exerciseRepository, this.readonly, this.percentToCalculate}) : super(ExerciseControlInitial()) { ExerciseControlBloc({this.exerciseRepository, this.readonly, this.percentToCalculate, @required this.timerBloc})
: super(ExerciseControlInitial()) {
initialRM = this.calculate1RM(percent75: false); initialRM = this.calculate1RM(percent75: false);
unitQuantity = this.calculate1RM(percent75: true).roundToDouble(); unitQuantity = this.calculate1RM(percent75: true).roundToDouble();
quantity = percentToCalculate == 0.75 ? 12 : 30; quantity = percentToCalculate == 0.75 ? 12 : 30;
@ -34,6 +37,7 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
print("init quantity: " + quantity.toString()); print("init quantity: " + quantity.toString());
timerBloc.add(TimerStart(duration: 300));
} }
@override @override
@ -78,6 +82,7 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
exerciseRepository.exercise.exerciseId = null; exerciseRepository.exercise.exerciseId = null;
step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd());
} }
yield ExerciseControlReady(); yield ExerciseControlReady();
} }
@ -109,12 +114,7 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
final double weight = exerciseRepository.exercise.unitQuantity; final double weight = exerciseRepository.exercise.unitQuantity;
final double repeatWendler = (rmWendler - weight) / 0.0333 / weight; final double repeatWendler = (rmWendler - weight) / 0.0333 / weight;
final double repeatOconner = (rmOconner / weight - 1) * 40; final double repeatOconner = (rmOconner / weight - 1) * 40;
print("Weight: " + print("Weight: $weight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner");
weight.toString() + return unitQuantity > 100 ? (repeatOconner + repeatWendler) / 2 : repeatWendler;
" repeatWendler: " +
repeatWendler.toStringAsFixed(0) +
" repeat Oconner: " +
repeatOconner.toStringAsFixed(0));
return repeatWendler;
} }
} }

View File

@ -44,14 +44,12 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
String fitnessLevel; String fitnessLevel;
bool changedWeight = false; bool changedWeight = false;
bool changedSizes = false; bool changedSizes = false;
final List<Property> womanSizes = List();
final List<Property> manSizes = List();
final double baseWidth = 312; final double baseWidth = 312;
final double baseHeight = 675.2; final double baseHeight = 675.2;
double mediaWidth = 0; double mediaWidth = 0;
double mediaHeight = 0; double mediaHeight = 0;
bool isMan = true;
String exerciseTask = ""; String exerciseTask = "";
final StopWatchTimer stopWatchTimer = StopWatchTimer( final StopWatchTimer stopWatchTimer = StopWatchTimer(
@ -73,7 +71,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
height = customerRepository.customer.getProperty("Height"); height = customerRepository.customer.getProperty("Height");
birthYear = customerRepository.customer.birthYear; birthYear = customerRepository.customer.birthYear;
fitnessLevel = customerRepository.customer.fitnessLevel; fitnessLevel = customerRepository.customer.fitnessLevel;
this.isMan = (customerRepository.customer.sex == "m");
} }
if (exerciseType.unit == "second") { if (exerciseType.unit == "second") {
stopWatchTimer.rawTime.listen((value) => {timerValue = value, this.setQuantity((value / 1000).toDouble())}); stopWatchTimer.rawTime.listen((value) => {timerValue = value, this.setQuantity((value / 1000).toDouble())});
@ -109,196 +107,6 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
} }
void setMediaDimensions(double width, double height) {
this.mediaHeight = height;
this.mediaWidth = width;
this.addSizes(customerRepository.sex);
}
void addSizes(String sex) {
List<Property> properties = Cache().getProperties();
if (properties == null) {
return;
}
final double distortionWidth = mediaWidth / baseWidth;
final double distortionHeight = mediaHeight / baseHeight;
if (isMan) {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (122 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (68 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (178 * distortionHeight).toInt();
element.left = (208 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (154 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (244 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (308 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (332 * distortionHeight).toInt();
element.left = (165 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (382 * distortionHeight).toInt();
element.left = (100 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (464 * distortionHeight).toInt();
element.left = (97 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (520 * distortionHeight).toInt();
element.left = (97 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (620 * distortionHeight).toInt();
element.left = (150 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (402 * distortionHeight).toInt();
element.left = (240 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Weight");
manSizes.add(element);
}
});
} else {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (122 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (78 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (178 * distortionHeight).toInt();
element.left = (212 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (154 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (230 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (294 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (335 * distortionHeight).toInt();
element.left = (185 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (377 * distortionHeight).toInt();
element.left = (125 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (468 * distortionHeight).toInt();
element.left = (129 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (525 * distortionHeight).toInt();
element.left = (129 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (620 * distortionHeight).toInt();
element.left = (162 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (402 * distortionHeight).toInt();
element.left = (240 * distortionWidth).toInt();
element.value = customerRepository.customer.getProperty("Weight");
manSizes.add(element);
}
});
}
}
int getWeightCoordinate(isMan, {isTop = false, isLeft = false}) {
int value = 0;
this.manSizes.forEach((element) {
if (element.propertyName == "Weight") {
if (isTop == true) {
value = element.top;
} else if (isLeft == true) {
value = element.left;
}
}
});
return value;
}
Property getPropertyByName(String propertyName) {
Property property;
List<Property> sizes;
if (customerRepository.sex == "Man") {
sizes = this.manSizes;
} else {
sizes = this.womanSizes;
}
sizes.forEach((element) {
if (element.propertyName == propertyName) {
property = element;
}
});
return property;
}
void updateSizes(String propertyName, double value) {
List<Property> sizes;
if (customerRepository.sex == "Man") {
sizes = this.manSizes;
} else {
sizes = this.womanSizes;
}
sizes.forEach((element) {
if (element.propertyName == propertyName) {
element.value = value;
}
});
}
@override @override
Stream<ExerciseNewState> mapEventToState(ExerciseNewEvent event) async* { Stream<ExerciseNewState> mapEventToState(ExerciseNewEvent event) async* {
try { try {
@ -358,7 +166,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
} else if (event is ExerciseNewSizeChange) { } else if (event is ExerciseNewSizeChange) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
this.changedSizes = true; this.changedSizes = true;
this.updateSizes(event.propertyName, event.value); this.customerRepository.updateSizes(event.propertyName, event.value);
customerRepository.setCustomerProperty(event.propertyName, event.value); customerRepository.setCustomerProperty(event.propertyName, event.value);
yield ExerciseNewReady(); yield ExerciseNewReady();
} else if (event is ExerciseNewSubmit) { } else if (event is ExerciseNewSubmit) {

View File

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart'; import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/session.dart'; import 'package:aitrainer_app/util/session.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';

View File

@ -1,7 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';

View File

@ -0,0 +1,106 @@
import 'dart:async';
import 'package:audioplayer/audioplayer.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'timer_event.dart';
part 'timer_state.dart';
class Ticker {
Stream<int> tick({int ticks}) {
return Stream.periodic(Duration(seconds: 1), (x) => compute(ticks, x)).take(ticks);
}
int compute(int ticks, int x) {
//print("tcik: " + (ticks - x - 1).toString());
return ticks - x - 1;
}
}
class TimerBloc extends Bloc<TimerEvent, TimerState> {
final Ticker _ticker = Ticker();
int _duration = 0;
final AudioPlayer audioPlayer = AudioPlayer();
int minutes = 0;
int seconds = 0;
StreamSubscription<int> _tickerSubscription;
TimerBloc() : super(TimerReady(300));
@override
void onTransition(Transition<TimerEvent, TimerState> transition) {
super.onTransition(transition);
//print(transition);
}
@override
Stream<TimerState> mapEventToState(
TimerEvent event,
) async* {
if (event is TimerStart) {
yield* _mapStartToState(event);
} else if (event is TimerPause) {
yield* _mapPauseToState(event);
} else if (event is TimerResume) {
yield* _mapResumeToState(event);
} else if (event is TimerReset) {
yield* _mapResetToState(event);
} else if (event is TimerTick) {
yield* _mapTickToState(event);
} else if (event is TimerEnd) {
print("$event");
_tickerSubscription?.cancel();
yield TimerFinished(state.duration);
}
}
@override
Future<void> close() {
_tickerSubscription?.cancel();
return super.close();
}
Stream<TimerState> _mapStartToState(TimerStart start) async* {
//print("$start");
yield TimerRunning(start.duration);
_tickerSubscription?.cancel();
_tickerSubscription = _ticker.tick(ticks: start.duration).listen(
(localDuration) {
//print("local: $localDuration");
add(TimerTick(duration: localDuration));
},
);
}
Stream<TimerState> _mapPauseToState(TimerPause pause) async* {
if (state is TimerRunning) {
_tickerSubscription?.pause();
yield TimerPaused(state.duration);
}
}
Stream<TimerState> _mapResumeToState(TimerResume pause) async* {
if (state is TimerPaused) {
_tickerSubscription?.resume();
yield TimerRunning(state.duration);
}
}
Stream<TimerState> _mapResetToState(TimerReset reset) async* {
this._duration = 0;
yield TimerReady(_duration);
}
Stream<TimerState> _mapTickToState(TimerTick tick) async* {
//print("tick $tick");
yield TickStart(tick.duration);
yield tick.duration >= 0 ? TimerRunning(tick.duration) : TimerFinished(tick.duration);
}
Future _play() async {
await audioPlayer.play('asset/wine-glass.mp3', isLocal: true);
}
}

View File

@ -0,0 +1,41 @@
part of 'timer_bloc.dart';
abstract class TimerEvent extends Equatable {
const TimerEvent();
@override
List<Object> get props => [];
}
class TimerStart extends TimerEvent {
final int duration;
const TimerStart({this.duration});
@override
String toString() => "TimerStart { duration: $duration }";
}
class TimerEnd extends TimerEvent {
final int duration;
const TimerEnd({this.duration});
}
class TimerTick extends TimerEvent {
final int duration;
const TimerTick({this.duration});
@override
String toString() => "Tick { duration: $duration }";
}
class TimerPause extends TimerEvent {
const TimerPause();
}
class TimerResume extends TimerEvent {
const TimerResume();
}
class TimerReset extends TimerEvent {
const TimerReset();
}

View File

@ -0,0 +1,49 @@
part of 'timer_bloc.dart';
abstract class TimerState extends Equatable {
final int duration;
TimerState(this.duration, [List props = const []]);
@override
List<Object> get props => [];
}
class TickStart extends TimerState {
TickStart(int duration) : super(duration);
@override
String toString() => 'Start { duration: $duration }';
}
class TimerRunning extends TimerState {
TimerRunning(int duration) : super(duration);
@override
String toString() => 'Running { duration: $duration }';
}
class TimerReady extends TimerState {
TimerReady(int duration) : super(duration);
@override
String toString() => 'Ready { duration: $duration }';
}
class TimerPaused extends TimerState {
TimerPaused(int duration) : super(duration);
@override
String toString() => 'Paused { duration: $duration }';
}
class TimerFinished extends TimerState {
TimerFinished(int duration) : super(duration);
@override
String toString() => 'Finished { duration: $duration }';
}
class TimerError extends TimerState {
final String message;
TimerError(int duration, {this.message}) : super(duration);
}

161
lib/library/clock.dart Normal file
View File

@ -0,0 +1,161 @@
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'dart:math';
import 'package:google_fonts/google_fonts.dart';
final temperatureColors = [
const Color(0xFFB50DE2), // -20 Celsius , friggin cold
const Color(0xFFAE0DE2),
const Color(0xFF980DE2),
const Color(0xFF8E0DE2),
const Color(0xFF810DE2),
const Color(0xFF7B0DE2),
const Color(0xFF670DE2),
const Color(0xFF570DE2),
const Color(0xFF4A0DE2),
const Color(0xFF410DE2),
const Color(0xFF1D0DE2),
const Color(0xFF0D4AE2),
const Color(0xFF0D57E2),
const Color(0xFF0D74E2),
const Color(0xFF0DB8E2),
const Color(0xFF0DD8E2),
const Color(0xFF0DE2BB),
const Color(0xFF0DE2A1),
const Color(0xFF0DE284),
const Color(0xFF0DE25E),
const Color(0xFF0DE244),
const Color(0xFF84E20D),
const Color(0xFFC2E20D),
const Color(0xFFE2DF0D),
const Color(0xFFE2A10D),
const Color(0xFFE2740D),
const Color(0xFFE2510D),
const Color(0xFFE22D0D),
const Color(0xFFE2100D),
const Color(0xFFE20D17), // 40 Celsius, rather be dead
];
// ignore: must_be_immutable
class Clock extends StatelessWidget {
final TimerBloc bloc;
final List<Color> colors = temperatureColors;
Clock({this.bloc});
// ignore: close_sinks
final Paint paintSeconds = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
final Paint paintMinutes = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
final Paint paintHours = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = 4
..isAntiAlias = true;
@override
Widget build(BuildContext context) {
return BlocBuilder<TimerBloc, TimerState>(builder: (context, state) {
if (state is TimerRunning) {
return getLayout(bloc.state);
} else {
return Offstage();
}
});
}
Widget getLayout(TimerState state) {
int duration = 300 - state.duration;
int seconds = (duration % 60).floor();
int minutes = ((duration / 60) % 60).floor();
String secondStr = seconds.toString().padLeft(2, '0');
String time = minutes == 0 ? "$secondStr" : "$minutes:$secondStr";
return LayoutBuilder(builder: (context, constraints) {
return Stack(
alignment: Alignment.center,
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: 37,
left: (45 - time.length / 2 * 9).toDouble(), //seconds < 10 ? 37 : 30,
child: Text(
"$time",
style: GoogleFonts.kosugi(color: colors[(seconds ~/ 2)], fontSize: 16),
)),
CustomPaint(painter: ArcPainter(minutes, paintMinutes, 5, constraints.maxHeight * 0.40, 0.15, colors)),
CustomPaint(painter: ArcPainter(seconds, paintSeconds, 60, constraints.maxHeight * 0.34, 0.2, colors)),
],
);
});
}
}
class ArcPainter extends CustomPainter {
int _progress;
Paint _paint;
int _units;
double _gap;
List<Color> _gradient;
Offset center;
double _radius;
Paint paintMarkerEmpty;
ArcPainter(
this._progress,
this._paint,
this._units,
this._radius,
this._gap,
this._gradient,
) {
this.paintMarkerEmpty = Paint()
..strokeCap = StrokeCap.butt
..style = PaintingStyle.stroke
..strokeWidth = this._paint.strokeWidth
..isAntiAlias = true;
}
@override
void paint(Canvas canvas, Size size) {
center = Offset(size.width / 2, size.height / 2);
var rect = Rect.fromCircle(center: center, radius: this._radius);
final gradient2 = new SweepGradient(
startAngle: -pi / 2,
endAngle: (-pi / 2) + (pi * 2),
tileMode: TileMode.repeated,
colors: this._gradient,
);
this._paint.shader = gradient2.createShader(rect);
this.paintMarkerEmpty.color = this._gradient[0].withOpacity(0.2);
for (var i = 0; i < this._units; i++) {
final double unit = 2 * pi / this._units;
double start = unit * i;
double to = (((2 * pi) / this._units) + unit);
canvas.drawArc(rect, (-pi / 2 + start), to * 2 * this._gap, false, i < this._progress ? this._paint : this.paintMarkerEmpty);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}

View File

@ -26,6 +26,7 @@ import 'package:aitrainer_app/view/menu_page.dart';
import 'package:aitrainer_app/view/mydevelopment_body_page.dart'; import 'package:aitrainer_app/view/mydevelopment_body_page.dart';
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart'; import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
import 'package:aitrainer_app/view/mydevelopment_page.dart'; import 'package:aitrainer_app/view/mydevelopment_page.dart';
import 'package:aitrainer_app/view/mydevelopment_sizes_page.dart';
import 'package:aitrainer_app/view/myexcercise_plan_page.dart'; import 'package:aitrainer_app/view/myexcercise_plan_page.dart';
import 'package:aitrainer_app/view/registration.dart'; import 'package:aitrainer_app/view/registration.dart';
import 'package:aitrainer_app/view/reset_password.dart'; import 'package:aitrainer_app/view/reset_password.dart';
@ -40,7 +41,7 @@ import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:sentry/sentry.dart'; import 'package:sentry/sentry.dart';
import 'bloc/account/account_bloc.dart'; import 'bloc/account/account_bloc.dart';
@ -51,6 +52,7 @@ import 'bloc/exercise_plan/exercise_plan_bloc.dart';
import 'bloc/menu/menu_bloc.dart'; import 'bloc/menu/menu_bloc.dart';
import 'bloc/session/session_bloc.dart'; import 'bloc/session/session_bloc.dart';
import 'bloc/settings/settings_bloc.dart'; import 'bloc/settings/settings_bloc.dart';
import 'bloc/timer/timer_bloc.dart';
const dsn = 'https://5fac40cbfcfb4c15aa80c7a8638d7310@o418565.ingest.sentry.io/5322520'; const dsn = 'https://5fac40cbfcfb4c15aa80c7a8638d7310@o418565.ingest.sentry.io/5322520';
@ -145,6 +147,9 @@ Future<Null> main() async {
BlocProvider<BodyDevelopmentBloc>( BlocProvider<BodyDevelopmentBloc>(
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository), create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
), ),
BlocProvider<TimerBloc>(
create: (BuildContext context) => TimerBloc(),
),
], ],
child: WorkoutTestApp(), child: WorkoutTestApp(),
)); ));
@ -218,6 +223,7 @@ class WorkoutTestApp extends StatelessWidget {
'exerciseExecuteAddPage': (context) => ExerciseExecutePlanAddPage(), 'exerciseExecuteAddPage': (context) => ExerciseExecutePlanAddPage(),
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(), 'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(), 'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),
'mydevelopmentSizesPage': (context) => SizesDevelopmentPage(),
'evaluationPage': (context) => EvaluationPage(), 'evaluationPage': (context) => EvaluationPage(),
'salesPage': (context) => SalesPage(), 'salesPage': (context) => SalesPage(),
}, },

View File

@ -62,6 +62,7 @@ class Cache with Logging {
static final String serverKey = 'live'; static final String serverKey = 'live';
static final String hardwareKey = 'hardware'; static final String hardwareKey = 'hardware';
static final String loginTypeKey = 'login_type'; static final String loginTypeKey = 'login_type';
static final String timerDisplayKey = 'timer_display';
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/';
@ -421,7 +422,7 @@ class Cache with Logging {
int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt(); int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt();
int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt(); int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt();
int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt(); int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt();
print("endo " + _endo.toString() + " mezo " + _mezo.toString()); //print("endo " + _endo.toString() + " mezo " + _mezo.toString());
if (this.userLoggedIn != null) { if (this.userLoggedIn != null) {
if (this.userLoggedIn.birthYear == null || this.userLoggedIn.birthYear == 0) { if (this.userLoggedIn.birthYear == null || this.userLoggedIn.birthYear == 0) {
setBadge("personalData", true); setBadge("personalData", true);

View File

@ -38,9 +38,26 @@ class WorkoutMenuTree {
bool executed = false; bool executed = false;
String exerciseDetail; String exerciseDetail;
String nameEnglish; String nameEnglish;
String parentName;
String parentNameEnglish;
WorkoutMenuTree(this.id, this.parent, this.name, this.imageName, this.color, this.fontSize, this.child, this.exerciseTypeId, WorkoutMenuTree(
this.exerciseType, this.base, this.is1RM, this.isEndurance, this.isRunning, this.nameEnglish); 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.isRunning,
this.nameEnglish,
this.parentName,
this.parentNameEnglish);
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {

View File

@ -11,6 +11,7 @@ import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/service/product_test_service.dart'; import 'package:aitrainer_app/service/product_test_service.dart';
import 'package:aitrainer_app/service/purchase_service.dart'; import 'package:aitrainer_app/service/purchase_service.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/not_found_exception.dart'; import 'package:aitrainer_app/util/not_found_exception.dart';
class GenderItem { class GenderItem {
@ -25,6 +26,14 @@ class CustomerRepository with Logging {
List<Customer> _trainees; List<Customer> _trainees;
List<CustomerProperty> _allProperties; List<CustomerProperty> _allProperties;
final PropertyRepository propertyRepository = PropertyRepository(); final PropertyRepository propertyRepository = PropertyRepository();
final List<Property> womanSizes = List();
final List<Property> manSizes = List();
final double baseWidth = 312;
final double baseHeight = 675.2;
double mediaWidth = 0;
double mediaHeight = 0;
bool isMan = true;
//List<CustomerRepository> customerList = List<CustomerRepository>(); //List<CustomerRepository> customerList = List<CustomerRepository>();
bool visibleDetails = false; bool visibleDetails = false;
@ -32,10 +41,10 @@ class CustomerRepository with Logging {
CustomerRepository({this.customer}) { CustomerRepository({this.customer}) {
customer = Customer(); customer = Customer();
genders = [
GenderItem("m", "Man"), if (Cache().userLoggedIn != null) {
GenderItem("w", "Woman"), isMan = (Cache().userLoggedIn.sex == "m");
]; }
} }
String getGenderByName(String name) { String getGenderByName(String name) {
@ -297,4 +306,194 @@ class CustomerRepository with Logging {
Future<void> addProductTest(ProductTest productTest) async { Future<void> addProductTest(ProductTest productTest) async {
await ProductTestApi().saveProductTest(productTest); await ProductTestApi().saveProductTest(productTest);
} }
void setMediaDimensions(double width, double height) {
this.mediaHeight = height;
this.mediaWidth = width;
this.addSizes(this.sex);
}
void addSizes(String sex) {
List<Property> properties = Cache().getProperties();
if (properties == null) {
return;
}
final double distortionWidth = mediaWidth / baseWidth;
final double distortionHeight = mediaHeight / baseHeight;
if (isMan) {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (122 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = this.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (68 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = this.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (178 * distortionHeight).toInt();
element.left = (208 * distortionWidth).toInt();
element.value = this.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (154 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = this.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (244 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = this.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (308 * distortionHeight).toInt();
element.left = (130 * distortionWidth).toInt();
element.value = this.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (332 * distortionHeight).toInt();
element.left = (165 * distortionWidth).toInt();
element.value = this.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (382 * distortionHeight).toInt();
element.left = (100 * distortionWidth).toInt();
element.value = this.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (464 * distortionHeight).toInt();
element.left = (97 * distortionWidth).toInt();
element.value = this.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (520 * distortionHeight).toInt();
element.left = (97 * distortionWidth).toInt();
element.value = this.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (620 * distortionHeight).toInt();
element.left = (150 * distortionWidth).toInt();
element.value = this.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (402 * distortionHeight).toInt();
element.left = (240 * distortionWidth).toInt();
element.value = this.customer.getProperty("Weight");
manSizes.add(element);
}
});
} else {
properties.forEach((element) {
if (element.propertyName == "Shoulder") {
element.top = (122 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = this.customer.getProperty("Shoulder");
manSizes.add(element);
} else if (element.propertyName == "Neck") {
element.top = (78 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = this.customer.getProperty("Neck");
manSizes.add(element);
} else if (element.propertyName == "Biceps") {
element.top = (178 * distortionHeight).toInt();
element.left = (212 * distortionWidth).toInt();
element.value = this.customer.getProperty("Biceps");
manSizes.add(element);
} else if (element.propertyName == "Chest") {
element.top = (154 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = this.customer.getProperty("Chest");
manSizes.add(element);
} else if (element.propertyName == "Belly") {
element.top = (230 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = this.customer.getProperty("Belly");
manSizes.add(element);
} else if (element.propertyName == "Hip") {
element.top = (294 * distortionHeight).toInt();
element.left = (151 * distortionWidth).toInt();
element.value = this.customer.getProperty("Hip");
manSizes.add(element);
} else if (element.propertyName == "Thigh Top") {
element.top = (335 * distortionHeight).toInt();
element.left = (185 * distortionWidth).toInt();
element.value = this.customer.getProperty("Thigh Top");
manSizes.add(element);
} else if (element.propertyName == "Thigh Middle") {
element.top = (377 * distortionHeight).toInt();
element.left = (125 * distortionWidth).toInt();
element.value = this.customer.getProperty("Thigh Middle");
manSizes.add(element);
} else if (element.propertyName == "Knee") {
element.top = (468 * distortionHeight).toInt();
element.left = (129 * distortionWidth).toInt();
element.value = this.customer.getProperty("Knee");
manSizes.add(element);
} else if (element.propertyName == "Calf") {
element.top = (525 * distortionHeight).toInt();
element.left = (129 * distortionWidth).toInt();
element.value = this.customer.getProperty("Calf");
manSizes.add(element);
} else if (element.propertyName == "Ankle") {
element.top = (620 * distortionHeight).toInt();
element.left = (162 * distortionWidth).toInt();
element.value = this.customer.getProperty("Ankle");
manSizes.add(element);
} else if (element.propertyName == "Weight") {
element.top = (402 * distortionHeight).toInt();
element.left = (240 * distortionWidth).toInt();
element.value = this.customer.getProperty("Weight");
manSizes.add(element);
}
});
}
}
int getWeightCoordinate(isMan, {isTop = false, isLeft = false}) {
int value = 0;
this.manSizes.forEach((element) {
if (element.propertyName == SizesEnum.Weight.toStr()) {
if (isTop == true) {
value = element.top;
} else if (isLeft == true) {
value = element.left;
}
}
});
return value;
}
Property getPropertyByName(String propertyName) {
Property property;
List<Property> sizes;
if (this.sex == "m") {
sizes = this.manSizes;
} else {
sizes = this.womanSizes;
}
sizes.forEach((element) {
if (element.propertyName == propertyName) {
property = element;
}
});
return property;
}
void updateSizes(String propertyName, double value) {
List<Property> sizes;
if (this.sex == "m") {
sizes = this.manSizes;
} else {
sizes = this.womanSizes;
}
sizes.forEach((element) {
if (element.propertyName == propertyName) {
element.value = value;
}
});
}
} }

View File

@ -1,6 +1,6 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';

View File

@ -1,5 +1,5 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/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_ability.dart';
import 'package:aitrainer_app/model/exercise_tree.dart'; import 'package:aitrainer_app/model/exercise_tree.dart';
@ -35,6 +35,7 @@ class WorkoutTreeRepository with Logging {
SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>(); SplayTreeMap sortedTree = SplayTreeMap<String, List<WorkoutMenuTree>>();
bool isEnglish; bool isEnglish;
WorkoutType workoutType; WorkoutType workoutType;
final List<WorkoutMenuTree> menuAsExercise = List();
final Map<String, int> _antagonist = { final Map<String, int> _antagonist = {
Antagonist.chest: Antagonist.chestNr, Antagonist.chest: Antagonist.chestNr,
@ -85,23 +86,24 @@ class WorkoutTreeRepository with Logging {
if (isRunning == false && treeItem.parentId != 0) { if (isRunning == false && treeItem.parentId != 0) {
isRunning = isParentRunning(treeItem.parentId); isRunning = isParentRunning(treeItem.parentId);
} }
WorkoutMenuTree parent = getParentItem(treeItem.parentId);
WorkoutMenuTree menuItem = WorkoutMenuTree( WorkoutMenuTree menuItem = WorkoutMenuTree(
treeItem.treeId, treeItem.treeId,
treeItem.parentId, treeItem.parentId,
treeName, treeName,
treeItem.imageUrl, treeItem.imageUrl,
Colors.white, Colors.white,
30, 30,
false, false,
0, 0,
null, null,
false, false,
is1RM, is1RM,
isEndurance, isEndurance,
isRunning, isRunning,
treeItem.name, treeItem.name,
); parent != null ? parent.name : "",
parent != null ? parent.nameEnglish : "");
menuItem = this.setWorkoutTypes(menuItem, treeItem); menuItem = this.setWorkoutTypes(menuItem, treeItem);
this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem; this.tree[treeItem.name + "_" + treeItem.parentId.toString()] = menuItem;
//log("WorkoutMenuTree item " + menuItem.toJson().toString()); //log("WorkoutMenuTree item " + menuItem.toJson().toString());
@ -113,6 +115,7 @@ class WorkoutTreeRepository with Logging {
exerciseType.active == true) { exerciseType.active == true) {
String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation; String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation;
//String assetImage = await _buildImage(exerciseType.imageUrl); //'asset/menu/' + exerciseType.imageUrl.substring(7); //String assetImage = await _buildImage(exerciseType.imageUrl); //'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);
@ -121,6 +124,7 @@ class WorkoutTreeRepository with Logging {
if (isEndurance) exerciseType.setAbility(ExerciseAbility.endurance); if (isEndurance) exerciseType.setAbility(ExerciseAbility.endurance);
bool isRunning = this.isParentRunning(parentId); bool isRunning = this.isParentRunning(parentId);
if (isRunning) exerciseType.setAbility(ExerciseAbility.running); if (isRunning) exerciseType.setAbility(ExerciseAbility.running);
WorkoutMenuTree parent = getParentItem(parentId);
WorkoutMenuTree menuItem = WorkoutMenuTree( WorkoutMenuTree menuItem = WorkoutMenuTree(
exerciseType.exerciseTypeId, exerciseType.exerciseTypeId,
parentId, parentId,
@ -135,8 +139,11 @@ class WorkoutTreeRepository with Logging {
is1RM, is1RM,
isEndurance, isEndurance,
isRunning, isRunning,
exerciseType.name); exerciseType.name,
parent != null ? parent.name : "",
parent != null ? parent.nameEnglish : "");
this.tree[exerciseType.name] = menuItem; this.tree[exerciseType.name] = menuItem;
menuAsExercise.add(menuItem);
//log("WorkoutMenuTree item " + menuItem.toJson().toString()); //log("WorkoutMenuTree item " + menuItem.toJson().toString());
/* log("ExerciseType in Menu item " + /* log("ExerciseType in Menu item " +
exerciseType.toJson().toString() + exerciseType.toJson().toString() +
@ -156,6 +163,7 @@ class WorkoutTreeRepository with Logging {
Cache().setWorkoutMenuTree(tree); Cache().setWorkoutMenuTree(tree);
ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseRepository exerciseRepository = ExerciseRepository();
exerciseRepository.getBaseExerciseFinishedPercent(); exerciseRepository.getBaseExerciseFinishedPercent();
menuAsExercise.sort((a, b) => a.name.compareTo(b.name));
} }
WorkoutMenuTree setWorkoutTypes(WorkoutMenuTree menu, ExerciseTree treeItem) { WorkoutMenuTree setWorkoutTypes(WorkoutMenuTree menu, ExerciseTree treeItem) {

View File

@ -1,6 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.dart';

View File

@ -36,7 +36,7 @@ enum TrackingEvent {
my_special_plan, my_special_plan,
my_suggested_plan, my_suggested_plan,
prediction, prediction,
search,
exercise_device, exercise_device,
customer_change, customer_change,
settings_lang, settings_lang,
@ -62,3 +62,11 @@ extension PropertyExt on PropertyEnum {
bool equalsTo(PropertyEnum event) => this.toString() == event.toString(); bool equalsTo(PropertyEnum event) => this.toString() == event.toString();
bool equalsStringTo(String event) => this.toString() == event; bool equalsStringTo(String event) => this.toString() == event;
} }
enum SizesEnum { Weight, Height, Shoulder, Neck, Biceps, Chest, Belly, Hip, ThighTop, ThighMiddle, Knee, Calf, Ankle, Underarm, Lowerarm }
extension SizesExt on SizesEnum {
String toStr() => this.toString().split(".").last;
bool equalsTo(SizesEnum event) => this.toString() == event.toString();
bool equalsStringTo(String event) => this.toString() == event;
}

View File

@ -1,231 +0,0 @@
/*
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/product.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
class PlatformPurchaseApi with Logging {
static final PlatformPurchaseApi _singleton = PlatformPurchaseApi._internal();
bool _kAutoConsume = true;
final String _kConsumableId = 'consumable';
final InAppPurchaseConnection _connection = InAppPurchaseConnection.instance;
bool _isAvailable = false;
List<ProductDetails> _products = [];
List<PurchaseDetails> _purchases = [];
List<String> _notFoundIds = [];
List<String> _consumables = [];
bool _purchasePending = false;
String _queryProductError;
StreamSubscription<List<PurchaseDetails>> _subscription;
final List<String> _productList = List();
List getProductList() => _productList;
factory PlatformPurchaseApi() {
return _singleton;
}
PlatformPurchaseApi._internal();
Future<void> close() async {
_subscription.cancel();
}
Future<void> initStoreInfo() async {
final bool isAvailable = await _connection.isAvailable();
if (!isAvailable) {
_isAvailable = isAvailable;
_products = [];
_purchases = [];
_notFoundIds = [];
_consumables = [];
_purchasePending = false;
log("Payment processor not available");
return;
}
getSubscriptions();
ProductDetailsResponse productDetailResponse = await _connection.queryProductDetails(_productList.toSet());
log("ProductDetailsResponse " + productDetailResponse.toString());
if (productDetailResponse.error != null) {
_queryProductError = productDetailResponse.error.message;
_isAvailable = isAvailable;
_products = productDetailResponse.productDetails;
_purchases = [];
_notFoundIds = productDetailResponse.notFoundIDs;
_consumables = [];
_purchasePending = false;
log("Payment processor not available");
return;
}
if (productDetailResponse.productDetails.isEmpty) {
_queryProductError = null;
_isAvailable = isAvailable;
_products = productDetailResponse.productDetails;
_purchases = [];
_notFoundIds = productDetailResponse.notFoundIDs;
_consumables = [];
_purchasePending = false;
return;
}
_products = productDetailResponse.productDetails;
_products.forEach((element) {
ProductDetails product = element as ProductDetails;
log("Product " + product.id + " " + product.price + " " + product.skuDetail.toString());
});
final QueryPurchaseDetailsResponse purchaseResponse = await _connection.queryPastPurchases();
if (purchaseResponse.error != null) {
// handle query past purchase error..
}
final List<PurchaseDetails> verifiedPurchases = [];
for (PurchaseDetails purchase in purchaseResponse.pastPurchases) {
if (await _verifyPurchase(purchase)) {
verifiedPurchases.add(purchase);
}
}
//TODO List<String> consumables = await ConsumableStore.load();
_isAvailable = isAvailable;
_products = productDetailResponse.productDetails;
_purchases = verifiedPurchases;
_notFoundIds = productDetailResponse.notFoundIDs;
//_consumables = consumables;
_purchasePending = false;
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPurchasePlatform() async {
if (_productList.length > 0) {
return;
}
log(' --- InappPurchase connection: $_connection');
log(" --- Init PurchasePlatform");
await this.initStoreInfo();
Stream purchaseUpdated = InAppPurchaseConnection.instance.purchaseUpdatedStream;
_subscription = purchaseUpdated.listen((purchaseDetailsList) {
_listenToPurchaseUpdated(purchaseDetailsList);
}, onDone: () {
_subscription.cancel();
}, onError: (error) {
// handle error here.
log("Error listen purchase updated " + error.toString());
});
}
void deliverProduct(PurchaseDetails purchaseDetails) async {
log("DeliverProduct");
// IMPORTANT!! Always verify a purchase purchase details before delivering the product.
if (purchaseDetails.productID == _kConsumableId) {
//TODO
//await ConsumableStore.save(purchaseDetails.purchaseID);
//List<String> consumables = await ConsumableStore.load();
_purchasePending = false;
//_consumables = consumables;
} else {
_purchases.add(purchaseDetails);
_purchasePending = false;
}
}
Future<bool> _verifyPurchase(PurchaseDetails purchaseDetails) {
log("verifyPurchase");
// IMPORTANT!! Always verify a purchase before delivering the product.
// For the purpose of an example, we directly return true.
log("Verifying Purchase" + purchaseDetails.toString());
return Future<bool>.value(true);
}
void _handleInvalidPurchase(PurchaseDetails purchaseDetails) {
// handle invalid purchase here if _verifyPurchase` failed.
log("Invalid Purchase" + purchaseDetails.toString());
}
void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async {
if (purchaseDetails.status == PurchaseStatus.pending) {
//showPendingUI();
log("Purchase pending");
} else {
if (purchaseDetails.status == PurchaseStatus.error) {
//handleError(purchaseDetails.error);
} else if (purchaseDetails.status == PurchaseStatus.purchased) {
bool valid = await _verifyPurchase(purchaseDetails);
if (valid) {
deliverProduct(purchaseDetails);
} else {
_handleInvalidPurchase(purchaseDetails);
return;
}
}
if (Platform.isAndroid) {
if (!_kAutoConsume && purchaseDetails.productID == _kConsumableId) {
await InAppPurchaseConnection.instance.consumePurchase(purchaseDetails);
}
}
if (purchaseDetails.pendingCompletePurchase) {
await InAppPurchaseConnection.instance.completePurchase(purchaseDetails);
}
}
});
}
void getSubscriptions() {
Cache().products.forEach((element) {
Product product = element as Product;
if (Platform.isAndroid) {
if (product.productIdAndroid != null && product.productIdAndroid.isNotEmpty) {
_productList.add(product.productIdAndroid);
}
} else {
if (product.productIdIos != null && product.productIdIos.isNotEmpty) {
_productList.add(product.productIdIos);
}
}
});
_productList.forEach((element) {
print(element);
});
}
void purchase(Product product) {
if (product == null) {
throw Exception("No product to purchase");
}
String productId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos;
ProductDetails productDetails;
_products.forEach((element) {
if (element.id == productId) {
productDetails = element;
log("product to purchase: " +
productDetails.id +
" title " +
productDetails.title +
" price " +
productDetails.price +
" period " +
productDetails.skuDetail.subscriptionPeriod);
}
});
final PurchaseParam purchaseParam = PurchaseParam(productDetails: productDetails);
/* if (_isConsumable(productDetails)) {
InAppPurchaseConnection.instance.buyConsumable(purchaseParam: purchaseParam);
} else { */
InAppPurchaseConnection.instance.buyNonConsumable(purchaseParam: purchaseParam);
//}
// From here the purchase flow will be handled by the underlying storefront.
// Updates will be delivered to the `InAppPurchaseConnection.instance.purchaseUpdatedStream`.
}
}
*/

View File

@ -34,7 +34,8 @@ class RevenueCatPurchases with Logging {
Future<void> restore() async { Future<void> restore() async {
if (appUserId != null) { if (appUserId != null) {
try { try {
PurchaserInfo purchaserInfo = await Purchases.restoreTransactions(); //PurchaserInfo purchaserInfo = await Purchases.restoreTransactions();
PurchaserInfo purchaserInfo = await Purchases.getPurchaserInfo();
if (purchaserInfo != null && if (purchaserInfo != null &&
purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"] != null &&
purchaserInfo.entitlements.all["wt_subscription"].isActive) { purchaserInfo.entitlements.all["wt_subscription"].isActive) {

View File

@ -1,15 +1,11 @@
import 'dart:io'; import 'dart:io';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/service/api.dart'; import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/service/package_service.dart'; import 'package:aitrainer_app/service/package_service.dart';
import 'package:aitrainer_app/service/product_service.dart';
import 'package:aitrainer_app/service/property_service.dart';
import 'package:aitrainer_app/util/purchases.dart'; import 'package:aitrainer_app/util/purchases.dart';
import 'package:aitrainer_app/util/track.dart';
import 'package:devicelocale/devicelocale.dart'; import 'package:devicelocale/devicelocale.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:package_info/package_info.dart'; import 'package:package_info/package_info.dart';

View File

@ -1,4 +1,4 @@
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
mixin Trans { mixin Trans {

View File

@ -2,12 +2,10 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart'; import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.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:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';

View File

@ -1,7 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart'; import 'package:aitrainer_app/bloc/custom_exercise_form_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';

View File

@ -2,7 +2,7 @@ import 'dart:collection';
import 'dart:ui'; import 'dart:ui';
import 'package:aitrainer_app/bloc/body_type/bodytype_bloc.dart'; import 'package:aitrainer_app/bloc/body_type/bodytype_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
@ -44,7 +44,7 @@ class _CustomerBodyTypeAnimationPageState extends State<CustomerBodyTypeAnimatio
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('asset/image/WT_black_G_background.jpg'), image: AssetImage('asset/image/WT_plainblack_background.jpg'),
fit: BoxFit.cover, fit: BoxFit.cover,
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
), ),
@ -445,8 +445,8 @@ class _QuestionState extends State<Question> with TickerProviderStateMixin {
} }
void buildAnimation() { void buildAnimation() {
_controller = AnimationController(duration: const Duration(milliseconds: 1000), vsync: this); _controller = AnimationController(duration: const Duration(milliseconds: 2000), vsync: this);
_animation = CurvedAnimation(parent: _controller, curve: Curves.slowMiddle); _animation = CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn);
_controller.forward(); _controller.forward();
} }

View File

@ -1,220 +0,0 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class CustomerBodyTypePage extends StatefulWidget {
_CustomerBodyTypePageState _state;
_CustomerBodyTypePageState createState() {
_state = _CustomerBodyTypePageState();
return _state;
}
}
class BodyTypeItem {
static String endomorph = "endomorph";
static String ectomorph = "ectomorph";
static String mesomorph = "mesomorph";
}
class _CustomerBodyTypePageState extends State<CustomerBodyTypePage> with Trans {
String selected;
bool fulldata = false;
@override
Widget build(BuildContext context) {
CustomerRepository customerRepository;
dynamic args = ModalRoute.of(context).settings.arguments;
if (args is HashMap && args['personal_data'] != null) {
fulldata = args['personal_data'];
customerRepository = args['bloc'];
} else {
customerRepository = ModalRoute.of(context).settings.arguments;
}
final double cWidth = MediaQuery.of(context).size.width * 0.75;
setContext(context);
return Scaffold(
appBar: fulldata
? AppBarMin(
back: true,
)
: AppBarProgress(min: 76, max: 100),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: BlocProvider(
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
child: Builder(builder: (context) {
// ignore: close_sinks
CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Divider(),
Wrap(
//runAlignment: WrapAlignment.center,
alignment: WrapAlignment.center,
children: [
Text(
t("Your Body Type"),
textAlign: TextAlign.center,
style: TextStyle(color: Colors.orange, fontSize: 42, fontFamily: 'Arial', fontWeight: FontWeight.w900),
)
]),
Divider(),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.ectomorph ? Colors.orange[200] : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Ectomorph"),
htmlData: t("Ectomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded),
),
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
t("Ectomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.ectomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.ectomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.endomorph ? Colors.orange : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Endomorph"),
htmlData: t("Endomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded)),
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
Text(t("Endomorph"),
textWidthBasis: TextWidthBasis.longestLine,
style:
TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
],
)),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.endomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.endomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
Badge(
badgeColor: customerRepository.bodyType == BodyTypeItem.mesomorph ? Colors.orange[200] : Colors.blue[50],
badgeContent: GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Mesomorph"),
htmlData: t("Mesomorph_desc"),
);
})
},
child: Icon(Icons.info_outline_rounded),
),
child: FlatButton(
child: Container(
width: cWidth,
child: Column(
children: [
InkWell(
child: Text(
t("Mesomorph"),
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
),
highlightColor: Colors.white,
),
],
),
),
padding: EdgeInsets.all(10.0),
shape: getShape(customerRepository, BodyTypeItem.mesomorph),
onPressed: () => {
setState(() {
selected = BodyTypeItem.mesomorph;
changeBloc.add(CustomerBodyTypeChange(bodyType: selected));
}),
})),
Divider(),
RaisedButton(
color: Colors.orange,
textColor: Colors.white,
child: Text(fulldata ? t("Save") : t("Next")),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
if (fulldata == false) {Navigator.of(context).pushNamed("customerWelcomePage", arguments: customerRepository)}
},
)
],
);
})),
));
}
dynamic getShape(CustomerRepository customerRepository, String fitnessLevel) {
String selected = customerRepository.bodyType;
dynamic returnCode = (selected == fitnessLevel)
? RoundedRectangleBorder(
side: BorderSide(width: 4, color: Colors.orange),
)
: RoundedRectangleBorder(
side: BorderSide(width: 1, color: Colors.blue),
);
//return
return returnCode;
}
}

View File

@ -1,5 +1,5 @@
import 'package:aitrainer_app/bloc/customer_exercise_device/customer_exercise_device_bloc.dart'; import 'package:aitrainer_app/bloc/customer_exercise_device/customer_exercise_device_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_device.dart'; import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart'; import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart';

View File

@ -1,7 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart'; import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/model/fitness_state.dart'; import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';

View File

@ -1,7 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart'; import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart'; import 'package:aitrainer_app/repository/customer_repository.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';

View File

@ -1,4 +1,4 @@
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@ -2,7 +2,7 @@ import 'dart:collection';
import 'dart:ui'; import 'dart:ui';
import 'package:aitrainer_app/bloc/result/result_bloc.dart'; import 'package:aitrainer_app/bloc/result/result_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/exercise_ability.dart'; import 'package:aitrainer_app/model/exercise_ability.dart';

View File

@ -1,15 +1,16 @@
import 'dart:collection'; 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/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.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/dialog_html.dart'; import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:aitrainer_app/widgets/number_picker.dart'; import 'package:aitrainer_app/widgets/number_picker.dart';
import 'package:aitrainer_app/widgets/timer_widget.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';
@ -38,9 +39,12 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
final double percent = arguments['percent']; final double percent = arguments['percent'];
final bool readonly = arguments['readonly']; final bool readonly = arguments['readonly'];
setContext(context); setContext(context);
// ignore: close_sinks
TimerBloc timerBloc = BlocProvider.of<TimerBloc>(context);
return BlocProvider( return BlocProvider(
create: (context) => ExerciseControlBloc(exerciseRepository: exerciseRepository, percentToCalculate: percent, readonly: readonly) create: (context) => ExerciseControlBloc(
exerciseRepository: exerciseRepository, percentToCalculate: percent, readonly: readonly, timerBloc: timerBloc)
..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) {
@ -53,7 +57,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
_controller.animateTo(exerciseBloc.scrollOffset, duration: Duration(milliseconds: 300), curve: Curves.easeIn); _controller.animateTo(exerciseBloc.scrollOffset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
} }
return ModalProgressHUD( return ModalProgressHUD(
child: getControlForm(exerciseBloc), child: getControlForm(exerciseBloc, timerBloc),
inAsyncCall: state is ExerciseControlLoading, inAsyncCall: state is ExerciseControlLoading,
opacity: 0.5, opacity: 0.5,
color: Colors.black54, color: Colors.black54,
@ -62,7 +66,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
})); }));
} }
Form getControlForm(ExerciseControlBloc exerciseBloc) { Form getControlForm(ExerciseControlBloc exerciseBloc, TimerBloc timerBloc) {
this.offset = exerciseBloc.scrollOffset; this.offset = exerciseBloc.scrollOffset;
String exerciseName = AppLanguage().appLocal == Locale("en") String exerciseName = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.name ? exerciseBloc.exerciseRepository.exerciseType.name
@ -84,120 +88,63 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
), ),
), ),
child: Container( child: Stack(children: [
padding: const EdgeInsets.only(top: 10, left: 25, right: 25), Container(
child: SingleChildScrollView( padding: const EdgeInsets.only(top: 10, left: 25, right: 25),
scrollDirection: Axis.vertical, child: SingleChildScrollView(
controller: _controller, scrollDirection: Axis.vertical,
child: Column( controller: _controller,
mainAxisAlignment: MainAxisAlignment.spaceAround, child: Column(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ crossAxisAlignment: CrossAxisAlignment.start,
Text( children: <Widget>[
exerciseName, Text(
style: GoogleFonts.archivoBlack( exerciseName,
fontWeight: FontWeight.bold, style: GoogleFonts.archivoBlack(
fontSize: 24, fontWeight: FontWeight.bold,
color: Colors.white, fontSize: 24,
shadows: <Shadow>[ color: Colors.white,
Shadow( shadows: <Shadow>[
offset: Offset(2.0, 2.0), Shadow(
blurRadius: 6.0, offset: Offset(2.0, 2.0),
color: Colors.black54, blurRadius: 6.0,
), color: Colors.black54,
Shadow( ),
offset: Offset(-3.0, 3.0), Shadow(
blurRadius: 12.0, offset: Offset(-3.0, 3.0),
color: Colors.black54, blurRadius: 12.0,
), color: Colors.black54,
], ),
), ],
overflow: TextOverflow.fade,
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(t("Your 1RM:"),
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
shadows: <Shadow>[
Shadow(
offset: Offset(-2.0, -2.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
Text(
" " +
exerciseBloc.initialRM.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
fontWeight: FontWeight.bold,
shadows: <Shadow>[
Shadow(
offset: Offset(-2.0, -2.0),
blurRadius: 6.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 6.0,
color: Colors.black54,
),
],
),
), ),
SizedBox(width: 10), overflow: TextOverflow.fade,
GestureDetector( textAlign: TextAlign.center,
onTap: () => { maxLines: 2,
showDialog( softWrap: true,
context: context, ),
builder: (BuildContext context) { Divider(
return DialogHTML( color: Colors.transparent,
title: t("OneRepMax"), ),
htmlData: t("OneRepMax_desc"), Divider(
); color: Colors.transparent,
}) ),
}, Divider(
child: Icon(CustomIcon.question, color: Colors.yellow[300])) color: Colors.transparent,
], ),
), Divider(
Divider(), color: Colors.transparent,
Row(mainAxisAlignment: MainAxisAlignment.start, children: [ ),
Flexible( Row(
child: Text(t("Why do you need Exercise Control?"), mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(t("Your 1RM:"),
style: GoogleFonts.inter( style: GoogleFonts.inter(
color: Colors.yellow[300], color: Colors.yellow[300],
fontSize: 18, fontSize: 18,
shadows: <Shadow>[ shadows: <Shadow>[
Shadow( Shadow(
offset: Offset(2.0, 2.0), offset: Offset(-2.0, -2.0),
blurRadius: 6.0, blurRadius: 12.0,
color: Colors.black54, color: Colors.black54,
), ),
Shadow( Shadow(
@ -206,29 +153,91 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
color: Colors.black54, color: Colors.black54,
), ),
], ],
))), )),
SizedBox(width: 10), Text(
GestureDetector( " " +
onTap: () => { exerciseBloc.initialRM.toStringAsFixed(0) +
showDialog( " " +
context: context, exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit,
builder: (BuildContext context) { style: GoogleFonts.inter(
return DialogHTML( color: Colors.yellow[300],
title: t("Control Exercise:"), fontSize: 18,
htmlData: t("controlexercise_desc"), fontWeight: FontWeight.bold,
); shadows: <Shadow>[
}) Shadow(
}, offset: Offset(-2.0, -2.0),
child: Icon(CustomIcon.question, color: Colors.yellow[300])) blurRadius: 6.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 6.0,
color: Colors.black54,
),
],
),
),
SizedBox(width: 10),
GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("OneRepMax"),
htmlData: t("OneRepMax_desc"),
);
})
},
child: Icon(CustomIcon.question, color: Colors.yellow[300]))
],
),
Divider(),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Flexible(
child: Text(t("Why do you need Exercise Control?"),
style: GoogleFonts.inter(
color: Colors.yellow[300],
fontSize: 18,
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,
),
],
))),
SizedBox(width: 10),
GestureDetector(
onTap: () => {
showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: t("Control Exercise:"),
htmlData: t("controlexercise_desc"),
);
})
},
child: Icon(CustomIcon.question, color: Colors.yellow[300]))
]),
Divider(),
numberPickForm(exerciseBloc, 1),
Divider(),
numberPickForm(exerciseBloc, 2),
Divider(),
numberPickForm(exerciseBloc, 3),
]), ]),
Divider(), )),
numberPickForm(exerciseBloc, 1), TimerWidget(
Divider(), bloc: timerBloc,
numberPickForm(exerciseBloc, 2), ),
Divider(), ])),
numberPickForm(exerciseBloc, 3),
]),
))),
//bottomNavigationBar: BottomNavigator(bottomNavIndex: 1), //bottomNavigationBar: BottomNavigator(bottomNavIndex: 1),
), ),
); );

View File

@ -3,7 +3,7 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_execute_plan/exercise_execute_plan_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_execute_plan/exercise_execute_plan_bloc.dart';
import 'package:aitrainer_app/bloc/exercise_execute_plan_add/exercise_execute_plan_add_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_execute_plan_add/exercise_execute_plan_add_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';

View File

@ -7,7 +7,7 @@ import 'package:aitrainer_app/widgets/dialog_premium.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';

View File

@ -3,7 +3,7 @@ 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/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/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_ability.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';

View File

@ -2,7 +2,7 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
import 'package:aitrainer_app/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_plan_custom_add/exercise_plan_custom_add_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart'; import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';

View File

@ -1,4 +1,4 @@
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart'; import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View File

@ -2,7 +2,6 @@ import 'dart:io';
import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/login/login_bloc.dart'; import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.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';
@ -183,17 +182,17 @@ class LoginPage extends StatelessWidget with Trans {
), ),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
InkWell( InkWell(
child: Text(AppLocalizations.of(context).translate('SignUpLink')), child: Text(t('SignUpLink')),
onTap: () => Navigator.of(context).pushNamed('registration'), onTap: () => Navigator.of(context).pushNamed('registration'),
), ),
Spacer(flex: 2), Spacer(flex: 2),
InkWell( InkWell(
child: Text(AppLocalizations.of(context).translate('I forgot the password')), child: Text(t('I forgot the password')),
onTap: () => Navigator.of(context).pushNamed('resetPassword'), onTap: () => Navigator.of(context).pushNamed('resetPassword'),
), ),
Spacer(flex: 2), Spacer(flex: 2),
InkWell( InkWell(
child: Text(AppLocalizations.of(context).translate('Privacy')), child: Text(t('Privacy')),
onTap: () => { onTap: () => {
showDialog( showDialog(
context: context, context: context,

View File

@ -83,15 +83,12 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
), ),
backgroundColor: Colors.orange, backgroundColor: Colors.orange,
)); ));
} else if (state is DevelopmentByMuscleLoadingState) {
//LoadingDialog.show(context);
} }
}, },
builder: (context, state) { builder: (context, state) {
if (state is DevelopmentByMuscleStateInitial) { if (state is DevelopmentByMuscleStateInitial) {
return Container(); return Container();
} else { } else {
//LoadingDialog.hide(context);
return TreeView( return TreeView(
startExpanded: false, startExpanded: false,
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc), children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),

View File

@ -77,6 +77,25 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
}, },
isLocked: true, isLocked: true,
), ),
/* ImageButton(
width: imageWidth,
textAlignment: Alignment.topLeft,
text: t("My Sizes Development"),
style: GoogleFonts.robotoMono(
textStyle: TextStyle(
fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4)),
),
image: "asset/image/testemfejl400x400.jpg",
left: 5,
onTap: () => {
if (Cache().userLoggedIn != null)
{
args['customerId'] = Cache().userLoggedIn.customerId,
Navigator.of(context).pushNamed('mydevelopmentSizesPage', arguments: args)
}
},
isLocked: true,
), */
ImageButton( ImageButton(
width: imageWidth, width: imageWidth,
textAlignment: Alignment.topLeft, textAlignment: Alignment.topLeft,

View File

@ -0,0 +1,196 @@
import 'package:aitrainer_app/bloc/development_sizes/development_sizes_bloc.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import '../widgets/app_bar.dart';
import '../widgets/input_dialog_widget.dart';
class SizesDevelopmentPage extends StatefulWidget {
const SizesDevelopmentPage();
@override
_SizeState createState() => _SizeState();
}
class _SizeState extends State<SizesDevelopmentPage> with Trans {
@override
Widget build(BuildContext context) {
setContext(context);
return BlocProvider(
create: (context) => DevelopmentSizesBloc(customerRepository: CustomerRepository())..add(DevelopmentSizesLoad()),
child: BlocConsumer<DevelopmentSizesBloc, DevelopmentSizesState>(listener: (context, state) {
if (state is DevelopmentSizesError) {
Scaffold.of(context)
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
}, builder: (context, state) {
final bloc = BlocProvider.of<DevelopmentSizesBloc>(context);
return ModalProgressHUD(
child: getForm(bloc),
inAsyncCall: state is DevelopmentSizesLoad,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}),
);
}
Widget getForm(DevelopmentSizesBloc bloc) {
return Form(
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: SafeArea(
child: Container(
padding: EdgeInsets.only(top: 10),
child: Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
Stack(
alignment: Alignment.center,
children: getSizeFigure(bloc),
)
]))),
)));
}
List<Widget> getSizeFigure(DevelopmentSizesBloc bloc) {
double mediaWidth = MediaQuery.of(context).size.width * .8;
double mediaHeight = MediaQuery.of(context).size.height * .8;
bloc.customerRepository.setMediaDimensions(mediaWidth, mediaHeight);
List<Widget> list = List();
list.add(
bloc.isMan
? Image.asset(
"asset/image/man_sizes.png",
height: mediaHeight,
width: mediaWidth,
)
: Image.asset(
"asset/image/woman_sizes.png",
height: mediaHeight,
width: mediaWidth,
),
);
list.add(Positioned(
top: bloc.customerRepository.getWeightCoordinate(bloc.isMan, isTop: true).toDouble(),
left: bloc.customerRepository.getWeightCoordinate(bloc.isMan, isTop: false, isLeft: true).toDouble() - 45,
child: GestureDetector(
//onTap: () => onPressed(bloc.customerRepository.getPropertyByName("Weight")),
child: Image.asset(
"asset/image/merleg.png",
height: 120,
width: 120,
color: Colors.blue,
)),
));
list.addAll(getSizeElements(bloc));
list.add(
Positioned(
top: mediaHeight * .07,
left: bloc.isMan ? mediaWidth * .62 : mediaWidth * .65,
child: Stack(
alignment: Alignment.topLeft,
children: [
SizedBox(height: 80, width: 100),
Text(t("Your Size Diagrams"),
maxLines: 2,
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 3.0,
color: Colors.black54,
),
],
fontSize: 20,
color: Colors.orange[500],
)),
],
)),
);
return list;
}
List<Widget> getSizeElements(DevelopmentSizesBloc bloc) {
List<Widget> list = List();
bloc.customerRepository.manSizes.forEach((element) {
list.add(
Positioned(
top: element.top.toDouble(),
left: element.left.toDouble(),
child: element.value != 0
? Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: bloc.isMan ? Colors.green[800] : Color(0xFFEA776C),
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
padding: EdgeInsets.zero,
child: IconButton(
icon: Icon(Icons.trending_up, color: Colors.green),
padding: EdgeInsets.zero,
color: Colors.red[800],
splashColor: Colors.amber,
onPressed: () => onPressed(element),
))
: Container(
width: 23,
height: 23,
padding: EdgeInsets.zero,
decoration: BoxDecoration(
color: bloc.isMan ? Colors.white10 : Color(0xFFEA776C),
borderRadius: BorderRadius.all(
Radius.circular(23),
),
),
child: IconButton(
icon: Icon(Icons.trending_up, color: Colors.red),
padding: EdgeInsets.zero,
color: Colors.red[800],
splashColor: Colors.amber,
onPressed: () => onPressed(element),
))),
);
});
return list;
}
void onPressed(Property element) {
print(element.propertyName);
showDialog(
context: context,
builder: (context) => InputDialog(
title: t("Size Of Your"),
subtitle: element.propertyNameTranslation,
initialValue: element.value,
onChanged: (value) {
//widget.exerciseBloc.add(ExerciseNewSizeChange(propertyName: element.propertyName, value: value));
},
));
}
}

View File

@ -2,7 +2,6 @@ import 'dart:io';
import 'package:aitrainer_app/bloc/account/account_bloc.dart'; import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/login/login_bloc.dart'; import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.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';
@ -208,12 +207,12 @@ class RegistrationPage extends StatelessWidget with Trans {
), ),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
InkWell( InkWell(
child: Text(AppLocalizations.of(context).translate('Login')), child: Text(t('Login')),
onTap: () => Navigator.of(context).pushNamed('login'), onTap: () => Navigator.of(context).pushNamed('login'),
), ),
Spacer(flex: 2), Spacer(flex: 2),
InkWell( InkWell(
child: Text(AppLocalizations.of(context).translate('Privacy')), child: Text(t('Privacy')),
onTap: () => { onTap: () => {
showDialog( showDialog(
context: context, context: context,

View File

@ -1,5 +1,4 @@
import 'package:aitrainer_app/bloc/reset_password_bloc.dart'; import 'package:aitrainer_app/bloc/reset_password_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.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';
@ -77,8 +76,7 @@ class ResetPasswordPage extends StatelessWidget with Trans {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
new InkWell( new InkWell(
child: new Text(AppLocalizations.of(context).translate('I forgot the password'), child: new Text(t('I forgot the password'), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
), ),
], ],
), ),
@ -119,7 +117,7 @@ class ResetPasswordPage extends StatelessWidget with Trans {
), ),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[ Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
new InkWell( new InkWell(
child: new Text(AppLocalizations.of(context).translate('Login')), child: new Text(t('Login')),
onTap: () => Navigator.of(context).pushNamed('login'), onTap: () => Navigator.of(context).pushNamed('login'),
), ),
Spacer(flex: 1), Spacer(flex: 1),

View File

@ -1,7 +1,7 @@
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/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';

View File

@ -1,7 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/cache.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/common.dart'; import 'package:aitrainer_app/util/common.dart';
@ -69,6 +70,8 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
menuBloc = BlocProvider.of<MenuBloc>(context); menuBloc = BlocProvider.of<MenuBloc>(context);
// ignore: close_sinks
final TimerBloc timerBloc = BlocProvider.of<TimerBloc>(context);
return AppBar( return AppBar(
backgroundColor: Colors.black, backgroundColor: Colors.black,
@ -91,6 +94,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white), icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => { onPressed: () => {
timerBloc.add(TimerEnd()),
if (widget.isMenu != null) if (widget.isMenu != null)
{ {
if (menuBloc.workoutItem != null) if (menuBloc.workoutItem != null)

View File

@ -1,7 +1,9 @@
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
// ignore: must_be_immutable // ignore: must_be_immutable
@ -24,6 +26,8 @@ class _AppBarNav extends State<AppBarMin> with Common {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// ignore: close_sinks
final TimerBloc timerBloc = BlocProvider.of<TimerBloc>(context);
return AppBar( return AppBar(
backgroundColor: Colors.black, backgroundColor: Colors.black,
title: Row( title: Row(
@ -44,6 +48,7 @@ class _AppBarNav extends State<AppBarMin> with Common {
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: widget.back ? Colors.white : Colors.black), icon: Icon(Icons.arrow_back, color: widget.back ? Colors.white : Colors.black),
onPressed: () => { onPressed: () => {
timerBloc.add(TimerEnd()),
if (widget.back) {Navigator.of(context).pop()} if (widget.back) {Navigator.of(context).pop()}
}, },
)); ));

View File

@ -1,6 +1,8 @@
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:liquid_progress_indicator/liquid_progress_indicator.dart'; import 'package:liquid_progress_indicator/liquid_progress_indicator.dart';
class AppBarProgress extends StatefulWidget implements PreferredSizeWidget { class AppBarProgress extends StatefulWidget implements PreferredSizeWidget {
@ -23,14 +25,12 @@ class _AppBarNav extends State<AppBarProgress> with SingleTickerProviderStateMix
_animationController = AnimationController( _animationController = AnimationController(
lowerBound: (widget.min).toDouble(), lowerBound: (widget.min).toDouble(),
upperBound: (widget.max).toDouble(), upperBound: (widget.max).toDouble(),
//upperBound: (widget.value / 100).toDouble(),
vsync: this, vsync: this,
duration: Duration(seconds: 3), duration: Duration(seconds: 3),
); );
_animationController.addListener(() => setState(() {})); _animationController.addListener(() => setState(() {}));
_animationController.forward(); _animationController.forward();
//Future.delayed(Duration(seconds: 3)).then((value) => _animationController.repeat());
super.initState(); super.initState();
} }
@ -42,12 +42,15 @@ class _AppBarNav extends State<AppBarProgress> with SingleTickerProviderStateMix
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// ignore: close_sinks
final TimerBloc timerBloc = BlocProvider.of<TimerBloc>(context);
return AppBar( return AppBar(
backgroundColor: Colors.black, backgroundColor: Colors.black,
title: getAnimatedWidget(), title: getAnimatedWidget(),
leading: IconButton( leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white), icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => {Navigator.of(context).pop()}, onPressed: () => {timerBloc.add(TimerEnd()), Navigator.of(context).pop()},
)); ));
} }

View File

@ -1,5 +1,5 @@
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/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:animated_widgets/widgets/rotation_animated.dart'; import 'package:animated_widgets/widgets/rotation_animated.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -73,7 +73,7 @@ class _BMIState extends State<BMI> with Trans {
double mediaWidth = MediaQuery.of(context).size.width * .8; double mediaWidth = MediaQuery.of(context).size.width * .8;
double mediaHeight = MediaQuery.of(context).size.height * .8; double mediaHeight = MediaQuery.of(context).size.height * .8;
//print("w " + mediaWidth.toString() + "h " + mediaHeight.toString()); //print("w " + mediaWidth.toString() + "h " + mediaHeight.toString());
widget.exerciseBloc.setMediaDimensions(mediaWidth, mediaHeight); widget.exerciseBloc.customerRepository.setMediaDimensions(mediaWidth, mediaHeight);
widget.exerciseBloc.getBMI(); widget.exerciseBloc.getBMI();
return Form( return Form(
child: Scaffold( child: Scaffold(

View File

@ -1,5 +1,5 @@
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/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/fitness_state.dart'; import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View File

@ -1,4 +1,4 @@
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';
@ -94,7 +94,12 @@ class _NawDrawerWidget extends State<BottomNavigator> with Trans, Logging {
backgroundColor: bgrColor, backgroundColor: bgrColor,
icon: Icon(Icons.settings, color: inactive), icon: Icon(Icons.settings, color: inactive),
activeIcon: Icon(Icons.settings, color: active), activeIcon: Icon(Icons.settings, color: active),
title: Text(t("Settings"), style: TextStyle(fontSize: 12))) title: Text(t("Settings"), style: TextStyle(fontSize: 12))),
/* BottomNavigationBarItem(
backgroundColor: bgrColor,
icon: Icon(Icons.multiple_stop, color: inactive),
activeIcon: Icon(Icons.multiple_stop, color: active),
title: Text(t("Multi test"), style: TextStyle(fontSize: 12))) */
], ],
onTap: (index) { onTap: (index) {
setState(() { setState(() {

View File

@ -3,8 +3,11 @@ import 'dart:ui';
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/library/custom_icon_icons.dart';
import 'package:aitrainer_app/localization/app_language.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/track.dart';
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart'; import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
@ -233,86 +236,50 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
return sliverList; return sliverList;
} }
SliverList getInfoWidget(BuildContext context, MenuBloc menuBloc) { SliverAppBar getInfoWidget(BuildContext context, MenuBloc menuBloc) {
List<Widget> widgets = List(); menuBloc.setContext(context);
menuBloc.setMenuInfo();
if (context != null) { SliverAppBar sliverAppBar = SliverAppBar(
menuBloc.setContext(context); backgroundColor: Colors.transparent,
menuBloc.setMenuInfo(); title: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
widgets.add(SizedBox( SizedBox(
height: 10, width: 10,
)); ),
GestureDetector(
widgets.add( onTap: () => {
GestureDetector( showDialog(
onTap: () => { context: context,
showDialog( barrierDismissible: false,
context: context, builder: (BuildContext context) {
barrierDismissible: false, return DialogCommon(
builder: (BuildContext context) { title: menuBloc.infoTitle,
return DialogCommon( descriptions: menuBloc.infoText,
title: menuBloc.infoTitle, description2: menuBloc.infoText2,
descriptions: menuBloc.infoText, description3: menuBloc.infoText3,
description2: menuBloc.infoText2, text: "OK",
description3: menuBloc.infoText3, onTap: () => {Navigator.of(context).pop()},
text: "OK", onCancel: () => {Navigator.of(context).pop()},
onTap: () => {Navigator.of(context).pop()}, );
onCancel: () => {Navigator.of(context).pop()}, })
); },
}) child: Icon(
}, CustomIcon.question_circle,
child: Align( color: Colors.orange[400],
alignment: Alignment.center, size: 40,
child: SizedBox( )),
height: 35, MenuSearchBar(
child: AnimatedSwitcher( listItems: menuBloc.menuTreeRepository.menuAsExercise,
duration: Duration(milliseconds: 800), onFind: (value) => {
transitionBuilder: (Widget child, Animation<double> animation) { Track().track(TrackingEvent.search, eventValue: value.exerciseType.name),
return ScaleTransition(child: child, scale: animation); Navigator.of(context).pushNamed('exerciseNewPage', arguments: value.exerciseType)
}, },
child: isFirst && !wait ),
? Icon( SizedBox(
CustomIcon.question_circle, width: 10,
color: Colors.yellow[300], ),
size: 40, ]));
) return sliverAppBar;
: Offstage())))),
);
}
SliverList sliverList = SliverList(delegate: SliverChildListDelegate(widgets));
return sliverList;
}
SliverGrid getInfoWidget2(BuildContext context, MenuBloc menuBloc) {
final List<Widget> _columnChildren = List();
if (context != null) {
menuBloc.setContext(context);
menuBloc.setMenuInfo();
Widget info = MenuInfoWidget(
title: menuBloc.infoTitle,
titleSize: 18,
titleWeight: FontWeight.bold,
titleColor: Colors.orangeAccent,
text: menuBloc.infoText,
textSize: 13,
textColor: Colors.yellowAccent,
text2: menuBloc.infoText2,
text3: menuBloc.infoText3,
link: menuBloc.infoLink,
bloc: menuBloc,
);
_columnChildren.add(info);
}
SliverGrid sliverList = SliverGrid(
delegate: SliverChildListDelegate(_columnChildren),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 5.0,
crossAxisSpacing: 5.0,
childAspectRatio: 2,
));
return sliverList;
} }
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) { void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {

View File

@ -0,0 +1,277 @@
import 'dart:async';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class SearchBarStream {
static final SearchBarStream _singleton = SearchBarStream._internal();
final StreamController<bool> streamController = StreamController<bool>.broadcast();
bool searching = false;
Stream get stream => streamController.stream;
StreamController getStreamController() => streamController;
factory SearchBarStream() => _singleton;
SearchBarStream._internal();
void dispose() {
streamController.close();
}
}
class MenuSearchBar extends StatelessWidget {
final List listItems;
final Function(WorkoutMenuTree) onFind;
const MenuSearchBar({@required this.listItems, this.onFind});
@override
Widget build(BuildContext context) {
return AnimatedSearch(
listItems: listItems,
onFind: onFind,
);
}
}
class AnimatedSearch extends StatefulWidget {
final List listItems;
final Function(WorkoutMenuTree) onFind;
AnimatedSearch({this.listItems, this.onFind});
@override
_AnimatedSearch createState() => _AnimatedSearch();
}
class _AnimatedSearch extends State<AnimatedSearch> {
bool isSearching = false;
final Stream stream = SearchBarStream().stream;
var subscription;
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() {
subscription = stream.listen((value) {
setState(() {
isSearching = SearchBarStream().searching;
});
});
super.didChangeDependencies();
}
@override
void dispose() {
subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 0),
child: Stack(
alignment: Alignment.center,
children: [
AnimateExpansion(
animate: !isSearching,
axisAlignment: 1.0,
child: IconButton(
onPressed: () => {
setState(() {
isSearching = !isSearching;
SearchBarStream().searching = isSearching;
SearchBarStream().getStreamController().add(true);
})
},
icon: Icon(
Icons.search,
color: Color(0xffb4f500),
size: 40,
),
)),
AnimateExpansion(
animate: isSearching,
axisAlignment: -1.0,
child: Search(
listItems: widget.listItems,
onFind: widget.onFind,
),
),
],
));
}
}
// ignore: must_be_immutable
class Search extends StatelessWidget with Trans {
final List listItems;
final Function(WorkoutMenuTree) onFind;
Search({this.listItems, this.onFind});
@override
Widget build(BuildContext context) {
setContext(context);
return SizedBox(
width: MediaQuery.of(context).size.width * .6,
child: DropdownSearch<WorkoutMenuTree>(
onPopupDismissed: () => {SearchBarStream().searching = false, SearchBarStream().getStreamController().add(false)},
showAsSuffixIcons: false,
showSearchBox: true,
mode: Mode.DIALOG,
showSelectedItem: false,
items: listItems,
onChanged: (value) => onFind(value),
dropdownSearchDecoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 0, bottom: 5),
labelStyle: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[50]),
fillColor: Colors.black38,
filled: true,
border: OutlineInputBorder(
gapPadding: 8.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
searchBoxController: TextEditingController(),
searchBoxDecoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: t("Search Exercises..."),
labelStyle: GoogleFonts.inter(fontSize: 14, color: Colors.grey[400]),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 8.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.white12, width: 0.4),
),
),
popupBackgroundColor: Colors.grey[700],
popupItemBuilder: (context, item, isSelected) {
return Container(
margin: EdgeInsets.all(3),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_G_background.jpg'),
fit: BoxFit.cover,
),
),
child: ListTile(
selected: isSelected,
title: Text(
item.name,
style: GoogleFonts.inter(color: Colors.yellow[300], fontSize: 16),
),
subtitle: Text(
item.parentName,
maxLines: 1,
style: GoogleFonts.inter(color: Colors.grey[400]),
),
leading: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset(item.imageName),
),
),
);
},
emptyBuilder: (context, searchEntry) => Center(
child: Text(
t("No exercise found"),
textAlign: TextAlign.center,
style: GoogleFonts.inter(color: Colors.yellow[200], fontSize: 16),
)),
dropdownBuilder: (context, WorkoutMenuTree item, itemDesignation) => Container(
child: ListView(scrollDirection: Axis.vertical, shrinkWrap: true, children: [
(item == null)
? Container(
height: 15,
padding: EdgeInsets.all(0),
child: Text(
t("Search Exercises..."),
style: GoogleFonts.inter(color: Colors.grey[400], fontSize: 14),
),
)
: Container(
height: 15,
padding: EdgeInsets.all(0),
child: Text(
item.name,
maxLines: 3,
style: GoogleFonts.inter(color: Colors.yellow[400], fontSize: 14),
),
),
]))),
);
}
}
class AnimateExpansion extends StatefulWidget {
final Widget child;
final bool animate;
final double axisAlignment;
AnimateExpansion({
this.animate = false,
this.axisAlignment,
this.child,
});
@override
_AnimateExpansionState createState() => _AnimateExpansionState();
}
class _AnimateExpansionState extends State<AnimateExpansion> with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animation;
void prepareAnimations() {
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 350),
);
_animation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInCubic,
reverseCurve: Curves.easeOutCubic,
);
}
void _toggle() {
if (widget.animate) {
_animationController.forward();
} else {
_animationController.reverse();
}
}
@override
void initState() {
super.initState();
prepareAnimations();
_toggle();
}
@override
void didUpdateWidget(AnimateExpansion oldWidget) {
super.didUpdateWidget(oldWidget);
_toggle();
}
@override
Widget build(BuildContext context) {
return SizeTransition(axis: Axis.horizontal, axisAlignment: -1.0, sizeFactor: _animation, child: widget.child);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}

View File

@ -53,7 +53,7 @@ class _SizeState extends State<SizeWidget> with Trans {
double mediaWidth = MediaQuery.of(context).size.width * .8; double mediaWidth = MediaQuery.of(context).size.width * .8;
double mediaHeight = MediaQuery.of(context).size.height * .8; double mediaHeight = MediaQuery.of(context).size.height * .8;
//print("w " + mediaWidth.toString() + "h " + mediaHeight.toString()); //print("w " + mediaWidth.toString() + "h " + mediaHeight.toString());
widget.exerciseBloc.setMediaDimensions(mediaWidth, mediaHeight); widget.exerciseBloc.customerRepository.setMediaDimensions(mediaWidth, mediaHeight);
List<Widget> list = List(); List<Widget> list = List();
list.add(GestureDetector( list.add(GestureDetector(
onTap: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())}, onTap: () => {print("Save"), widget.exerciseBloc.add(ExerciseNewSaveWeight())},
@ -63,7 +63,7 @@ class _SizeState extends State<SizeWidget> with Trans {
))); )));
list.add( list.add(
widget.exerciseBloc.isMan widget.exerciseBloc.customerRepository.isMan
? Image.asset( ? Image.asset(
"asset/image/man_sizes.png", "asset/image/man_sizes.png",
height: mediaHeight, height: mediaHeight,
@ -76,10 +76,13 @@ class _SizeState extends State<SizeWidget> with Trans {
), ),
); );
list.add(Positioned( list.add(Positioned(
top: widget.exerciseBloc.getWeightCoordinate(widget.exerciseBloc.isMan, isTop: true).toDouble(), top: widget.exerciseBloc.customerRepository.getWeightCoordinate(widget.exerciseBloc.customerRepository.isMan, isTop: true).toDouble(),
left: widget.exerciseBloc.getWeightCoordinate(widget.exerciseBloc.isMan, isTop: false, isLeft: true).toDouble() - 45, left: widget.exerciseBloc.customerRepository
.getWeightCoordinate(widget.exerciseBloc.customerRepository.isMan, isTop: false, isLeft: true)
.toDouble() -
45,
child: GestureDetector( child: GestureDetector(
onTap: () => onPressed(widget.exerciseBloc.getPropertyByName("Weight")), onTap: () => onPressed(widget.exerciseBloc.customerRepository.getPropertyByName("Weight")),
child: Image.asset( child: Image.asset(
"asset/image/merleg.png", "asset/image/merleg.png",
height: 120, height: 120,
@ -92,7 +95,7 @@ class _SizeState extends State<SizeWidget> with Trans {
list.add( list.add(
Positioned( Positioned(
top: mediaHeight * .07, top: mediaHeight * .07,
left: widget.exerciseBloc.isMan ? mediaWidth * .62 : mediaWidth * .65, left: widget.exerciseBloc.customerRepository.isMan ? mediaWidth * .62 : mediaWidth * .65,
child: Stack( child: Stack(
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
children: [ children: [
@ -129,7 +132,7 @@ class _SizeState extends State<SizeWidget> with Trans {
List<Widget> getSizeElements() { List<Widget> getSizeElements() {
List<Widget> list = List(); List<Widget> list = List();
widget.exerciseBloc.manSizes.forEach((element) { widget.exerciseBloc.customerRepository.manSizes.forEach((element) {
list.add( list.add(
Positioned( Positioned(
top: element.top.toDouble(), top: element.top.toDouble(),
@ -139,7 +142,7 @@ class _SizeState extends State<SizeWidget> with Trans {
width: 20, width: 20,
height: 20, height: 20,
decoration: BoxDecoration( decoration: BoxDecoration(
color: widget.exerciseBloc.isMan ? Colors.green[800] : Color(0xFFEA776C), color: widget.exerciseBloc.customerRepository.isMan ? Colors.green[800] : Color(0xFFEA776C),
borderRadius: BorderRadius.all( borderRadius: BorderRadius.all(
Radius.circular(20), Radius.circular(20),
), ),
@ -156,7 +159,7 @@ class _SizeState extends State<SizeWidget> with Trans {
height: 20, height: 20,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
decoration: BoxDecoration( decoration: BoxDecoration(
color: widget.exerciseBloc.isMan ? Color(0xFF369fb9) : Color(0xFFEA776C), color: widget.exerciseBloc.customerRepository.isMan ? Color(0xFF369fb9) : Color(0xFFEA776C),
borderRadius: BorderRadius.all( borderRadius: BorderRadius.all(
Radius.circular(20), Radius.circular(20),
), ),

View File

@ -0,0 +1,34 @@
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
import 'package:aitrainer_app/library/clock.dart';
import 'package:flutter/material.dart';
class TimerWidget extends StatelessWidget {
final TimerBloc bloc;
const TimerWidget({this.bloc});
@override
Widget build(BuildContext context) {
return Positioned(
left: MediaQuery.of(context).size.width - 95,
top: 28,
child: Stack(alignment: AlignmentDirectional.topEnd, children: [
digitalClock(),
]));
}
Widget digitalClock() {
return ClipRRect(
borderRadius: BorderRadius.circular(45.0),
child: Container(
width: 90,
height: 90,
color: Colors.transparent,
child: Overlay(initialEntries: <OverlayEntry>[
OverlayEntry(
opaque: true,
builder: (BuildContext context) {
return Container(color: Colors.transparent, child: Clock(bloc: bloc));
})
])));
}
}

View File

@ -50,6 +50,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0-nullsafety.1" version: "2.5.0-nullsafety.1"
audioplayer:
dependency: "direct main"
description:
name: audioplayer
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.1"
badges: badges:
dependency: "direct main" dependency: "direct main"
description: description:
@ -259,7 +266,7 @@ packages:
name: dropdown_search name: dropdown_search
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.8" version: "0.4.9"
equatable: equatable:
dependency: "direct main" dependency: "direct main"
description: description:
@ -397,7 +404,7 @@ packages:
name: flutter_bloc name: flutter_bloc
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.1" version: "6.1.2"
flutter_facebook_auth: flutter_facebook_auth:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1005,7 +1012,7 @@ packages:
name: sqflite name: sqflite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.2+2" version: "1.3.2+3"
sqflite_common: sqflite_common:
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.6+55 version: 1.1.7+56
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.7.0 <3.0.0"
@ -28,7 +28,7 @@ dependencies:
google_fonts: ^1.1.1 google_fonts: ^1.1.1
devicelocale: ^0.3.3 devicelocale: ^0.3.3
sentry: ^4.0.3 sentry: ^4.0.3
flutter_bloc: ^6.1.1 flutter_bloc: ^6.1.2
equatable: ^1.2.5 equatable: ^1.2.5
#freezed: ^0.12.2 #freezed: ^0.12.2
flutter_form_bloc: ^0.19.0 flutter_form_bloc: ^0.19.0
@ -40,7 +40,6 @@ dependencies:
infinite_listview: ^1.0.1+1 infinite_listview: ^1.0.1+1
toggle_switch: ^0.1.8 toggle_switch: ^0.1.8
keyboard_actions: ^3.3.1+1 keyboard_actions: ^3.3.1+1
dropdown_search: ^0.4.8
badges: ^1.1.4 badges: ^1.1.4
#health: ^3.0.0 #health: ^3.0.0
stop_watch_timer: ^0.6.0+1 stop_watch_timer: ^0.6.0+1
@ -53,6 +52,8 @@ dependencies:
network_image_to_byte: ^0.0.1 network_image_to_byte: ^0.0.1
package_info: ^0.4.3+4 package_info: ^0.4.3+4
liquid_progress_indicator: ^0.3.2 liquid_progress_indicator: ^0.3.2
dropdown_search: ^0.4.9
audioplayer: ^0.8.1
firebase_core: ^0.5.0 firebase_core: ^0.5.0
@ -71,7 +72,7 @@ dependencies:
animated_widgets: ^1.0.6 animated_widgets: ^1.0.6
mockito: ^4.1.3 mockito: ^4.1.3
sqflite: ^1.3.2+2 sqflite: ^1.3.2+3
flutter_secure_storage: ^3.3.5 flutter_secure_storage: ^3.3.5
flutter_localizations: flutter_localizations:
@ -212,6 +213,7 @@ flutter:
- asset/menu/1.2.anaerob.jpg - asset/menu/1.2.anaerob.jpg
- asset/menu/2.strength.jpg - asset/menu/2.strength.jpg
- asset/menu/2.1.endurance.jpg - asset/menu/2.1.endurance.jpg
- asset/menu/2.1.4.squats.jpg
- asset/menu/2.1.6.core.jpg - asset/menu/2.1.6.core.jpg
- asset/menu/2.1.1.1RM.jpg - asset/menu/2.1.1.1RM.jpg
- asset/menu/2.2.1.1.chest.jpg - asset/menu/2.2.1.1.chest.jpg
@ -234,6 +236,7 @@ flutter:
- asset/menu/bent_arm_barbell_pullovers.jpg - asset/menu/bent_arm_barbell_pullovers.jpg
- asset/menu/bent_knee_situps.jpg - asset/menu/bent_knee_situps.jpg
- asset/menu/bent_over_lateral_raises_with_dumbbells.jpg - asset/menu/bent_over_lateral_raises_with_dumbbells.jpg
- asset/menu/bent_over_rows.jpg
- asset/menu/biceps_machine.jpg - asset/menu/biceps_machine.jpg
- asset/menu/bmi.jpg - asset/menu/bmi.jpg
- asset/menu/bmr.jpg - asset/menu/bmr.jpg
@ -244,14 +247,18 @@ flutter:
- asset/menu/chest_press_machine.jpg - asset/menu/chest_press_machine.jpg
- asset/menu/chest_press.jpg - asset/menu/chest_press.jpg
- asset/menu/chins.jpg - asset/menu/chins.jpg
- asset/menu/close_grip_bench_press.jpg
- asset/menu/close_grip_front_lat_pulldown.jpg - asset/menu/close_grip_front_lat_pulldown.jpg
- asset/menu/close_grip_pull_ups.jpg - asset/menu/close_grip_pull_ups.jpg
- asset/menu/close_reverse_grip_lat_pulldown.jpg
- asset/menu/concentration.jpg - asset/menu/concentration.jpg
- asset/menu/cooper.jpg - asset/menu/cooper.jpg
- asset/menu/crisscross.jpg - asset/menu/crisscross.jpg
- asset/menu/cross_bench_dumbbell_pullover.jpg - asset/menu/cross_bench_dumbbell_pullover.jpg
- asset/menu/deadlift.jpg - asset/menu/deadlift.jpg
- asset/menu/decline_bench_press.jpg
- asset/menu/decline_dumbbell_bench_press.jpg - asset/menu/decline_dumbbell_bench_press.jpg
- asset/menu/decline_flyes.jpg
- asset/menu/decline_cable_flyes.jpg - asset/menu/decline_cable_flyes.jpg
- asset/menu/donkey_calf_raises.jpg - asset/menu/donkey_calf_raises.jpg
- asset/menu/dumbbell_alternate_bicep_curl.jpg - asset/menu/dumbbell_alternate_bicep_curl.jpg
@ -266,6 +273,7 @@ flutter:
- asset/menu/hanging_leg_raises.jpg - asset/menu/hanging_leg_raises.jpg
- asset/menu/head-on-bench_dumbbell_rear_delt_raise.jpg - asset/menu/head-on-bench_dumbbell_rear_delt_raise.jpg
- asset/menu/hyperextension.jpg - asset/menu/hyperextension.jpg
- asset/menu/hyperextension_floor.jpg
- asset/menu/incline_cable_flyes.jpg - asset/menu/incline_cable_flyes.jpg
- asset/menu/incline_curl_with_dumbbels.jpg - asset/menu/incline_curl_with_dumbbels.jpg
- asset/menu/incline_dumbbell_press.jpg - asset/menu/incline_dumbbell_press.jpg
@ -292,10 +300,13 @@ flutter:
- asset/menu/peck_deck_flyes.jpg - asset/menu/peck_deck_flyes.jpg
- asset/menu/plank.jpg - asset/menu/plank.jpg
- asset/menu/pull_up.jpg - asset/menu/pull_up.jpg
- asset/menu/pulldown_machine.jpg
- asset/menu/pullups.jpg - asset/menu/pullups.jpg
- asset/menu/pushups.jpg - asset/menu/pushups.jpg
- asset/menu/pushups_dip.jpg
- asset/menu/reverse_crunches.jpg - asset/menu/reverse_crunches.jpg
- asset/menu/roman_chair_situps.jpg - asset/menu/roman_chair_situps.jpg
- asset/menu/row_machine.jpg
- asset/menu/russian_twist.jpg - asset/menu/russian_twist.jpg
- asset/menu/seated_bar_twist.jpg - asset/menu/seated_bar_twist.jpg
- asset/menu/seated_dumbbell_curl.jpg - asset/menu/seated_dumbbell_curl.jpg
@ -307,7 +318,7 @@ flutter:
- asset/menu/single_arm_bent_over_cable_reverse_fly.jpg - asset/menu/single_arm_bent_over_cable_reverse_fly.jpg
- asset/menu/single_arm_t-bar_rows.jpg - asset/menu/single_arm_t-bar_rows.jpg
- asset/menu/single_hand_lateral_raises.jpg - asset/menu/single_hand_lateral_raises.jpg
- asset/menu/single_hand_lying_triceps_Extension.jpg - asset/menu/single_hand_lying_triceps_extension.jpg
- asset/menu/sitting_knee_ups.jpg - asset/menu/sitting_knee_ups.jpg
- asset/menu/sitting_machine_calf_raises.jpg - asset/menu/sitting_machine_calf_raises.jpg
- asset/menu/situps.jpg - asset/menu/situps.jpg
@ -340,6 +351,7 @@ flutter:
- asset/menu/weighted_bench_dip.jpg - asset/menu/weighted_bench_dip.jpg
- asset/menu/wide_grip_behind_the_neck_pull_ups.jpg - asset/menu/wide_grip_behind_the_neck_pull_ups.jpg
- asset/menu/wide_grip_front_lat_pulldown.jpg - asset/menu/wide_grip_front_lat_pulldown.jpg
- asset/wine-glass.mp3
- i18n/en.json - i18n/en.json

View File

@ -8,7 +8,7 @@
//import 'package:aitrainer_app/bloc/login_form_bloc.dart'; //import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/helper/database.dart'; import 'package:aitrainer_app/helper/database.dart';
import 'package:aitrainer_app/library_keys.dart'; import 'package:aitrainer_app/library_keys.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/user.dart'; import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';

View File

@ -9,7 +9,7 @@
import 'package:aitrainer_app/bloc/login/login_bloc.dart'; import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/helper/database.dart'; import 'package:aitrainer_app/helper/database.dart';
import 'package:aitrainer_app/library_keys.dart'; import 'package:aitrainer_app/library_keys.dart';
import 'package:aitrainer_app/localization/app_localization.dart'; import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/model/user.dart'; import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/repository/user_repository.dart'; import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/common.dart';