Merge ssh://git.aitrainer.app:6622/bossanyit/aitrainer_app

This commit is contained in:
bossanyit 2020-11-29 10:41:13 +01:00
commit ba50018a2b
71 changed files with 1458 additions and 845 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
asset/image/haken.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -223,5 +223,10 @@
"Your Sizes":"Your Sizes",
"Size Of Your":"Size Of Your",
"Please type the following data:":"Please type the following data:",
"Cancel": "Cancel"
"Cancel": "Cancel",
"Available Devices":"Available Devices",
"select your equipments by tapping":"select your equipments by tapping",
"Available Equipments":"Available Equipments",
"select your places by tapping":"select your places by tapping",
"Available Training Places":"Available Training Places"
}

View File

@ -224,5 +224,10 @@
"Your Sizes":"Méreteid",
"Size Of Your":"Testméret:",
"Please type the following data:":"Kérlek írd be a következő adatot:",
"Cancel": "Mégsem"
"Cancel": "Mégsem",
"Available Devices":"Edzés eszközök",
"select your equipments by tapping":"válaszd ki az eszközeidet, kattints a képre",
"Available Equipments":"Elérhető eszközök",
"select your places by tapping":"kattints az edzéshelyszínre",
"Available Training Places":"Elérhető edzéshelyszínek"
}

View File

@ -1,109 +1,91 @@
PODS:
- devicelocale (0.0.1):
- Flutter
- FBSDKCoreKit (7.1.1):
- FBSDKCoreKit/Basics (= 7.1.1)
- FBSDKCoreKit/Core (= 7.1.1)
- FBSDKCoreKit/Basics (7.1.1)
- FBSDKCoreKit/Core (7.1.1):
- FBSDKCoreKit/Basics
- FBSDKLoginKit (7.1.1):
- FBSDKLoginKit/Login (= 7.1.1)
- FBSDKLoginKit/Login (7.1.1):
- FBSDKCoreKit (~> 7.1.1)
- Firebase/Auth (6.26.0):
- Firebase/Auth (6.33.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 6.5.3)
- Firebase/CoreOnly (6.26.0):
- FirebaseCore (= 6.7.2)
- Firebase/Messaging (6.26.0):
- FirebaseAuth (~> 6.9.2)
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Messaging (6.33.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 4.4.1)
- firebase_auth (0.18.1-2):
- Firebase/Auth (~> 6.26.0)
- Firebase/CoreOnly (~> 6.26.0)
- FirebaseMessaging (~> 4.7.0)
- firebase_auth (0.18.3):
- Firebase/Auth (~> 6.33.0)
- Firebase/CoreOnly (~> 6.33.0)
- firebase_core
- Flutter
- firebase_core (0.5.0-1):
- Firebase/CoreOnly (~> 6.26.0)
- firebase_core (0.5.2):
- Firebase/CoreOnly (~> 6.33.0)
- Flutter
- firebase_messaging (7.0.3):
- Firebase/CoreOnly (~> 6.26.0)
- Firebase/Messaging (~> 6.26.0)
- Firebase/CoreOnly (~> 6.33.0)
- Firebase/Messaging (~> 6.33.0)
- firebase_core
- Flutter
- FirebaseAnalyticsInterop (1.5.0)
- FirebaseAuth (6.5.3):
- FirebaseAuthInterop (~> 1.0)
- FirebaseCore (~> 6.6)
- GoogleUtilities/AppDelegateSwizzler (~> 6.5)
- GoogleUtilities/Environment (~> 6.5)
- FirebaseAuth (6.9.2):
- FirebaseCore (~> 6.10)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/Environment (~> 6.7)
- GTMSessionFetcher/Core (~> 1.1)
- FirebaseAuthInterop (1.1.0)
- FirebaseCore (6.7.2):
- FirebaseCoreDiagnostics (~> 1.3)
- FirebaseCoreDiagnosticsInterop (~> 1.2)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- FirebaseCoreDiagnostics (1.4.0):
- GoogleDataTransportCCTSupport (~> 3.1)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Logger (~> 6.5)
- nanopb (~> 1.30905.0)
- FirebaseCoreDiagnosticsInterop (1.2.0)
- FirebaseInstallations (1.3.0):
- FirebaseCore (~> 6.6)
- GoogleUtilities/Environment (~> 6.6)
- GoogleUtilities/UserDefaults (~> 6.6)
- FirebaseCore (6.10.3):
- FirebaseCoreDiagnostics (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- FirebaseCoreDiagnostics (1.7.0):
- GoogleDataTransport (~> 7.4)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- nanopb (~> 1.30906.0)
- FirebaseInstallations (1.7.0):
- FirebaseCore (~> 6.10)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- PromisesObjC (~> 1.2)
- FirebaseInstanceID (4.3.4):
- FirebaseCore (~> 6.6)
- FirebaseInstallations (~> 1.0)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/UserDefaults (~> 6.5)
- FirebaseMessaging (4.4.1):
- FirebaseAnalyticsInterop (~> 1.5)
- FirebaseCore (~> 6.6)
- FirebaseInstanceID (~> 4.3)
- GoogleUtilities/AppDelegateSwizzler (~> 6.5)
- GoogleUtilities/Environment (~> 6.5)
- GoogleUtilities/Reachability (~> 6.5)
- GoogleUtilities/UserDefaults (~> 6.5)
- FirebaseInstanceID (4.8.0):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- FirebaseMessaging (4.7.1):
- FirebaseCore (~> 6.10)
- FirebaseInstanceID (~> 4.7)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Reachability (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- Protobuf (>= 3.9.2, ~> 3.9)
- Flutter (1.0.0)
- flutter_facebook_auth (0.3.1):
- FBSDKCoreKit (~> 7.1.0)
- FBSDKLoginKit (~> 7.1.0)
- flurry (0.0.4):
- Flurry-iOS-SDK/FlurrySDK
- Flutter
- Flurry-iOS-SDK/FlurrySDK (11.1.1)
- Flutter (1.0.0)
- flutter_keyboard_visibility (0.0.1):
- Flutter
- GoogleDataTransport (6.2.1)
- GoogleDataTransportCCTSupport (3.2.0):
- GoogleDataTransport (~> 6.1)
- nanopb (~> 1.30905.0)
- GoogleUtilities/AppDelegateSwizzler (6.6.0):
- GoogleDataTransport (7.5.1):
- nanopb (~> 1.30906.0)
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (6.6.0):
- GoogleUtilities/Environment (6.7.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.6.0):
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Network (6.6.0):
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.6.0)"
- GoogleUtilities/Reachability (6.6.0):
- "GoogleUtilities/NSData+zlib (6.7.2)"
- GoogleUtilities/Reachability (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.6.0):
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
- GTMSessionFetcher/Core (1.4.0)
- nanopb (1.30905.0):
- nanopb/decode (= 1.30905.0)
- nanopb/encode (= 1.30905.0)
- nanopb/decode (1.30905.0)
- nanopb/encode (1.30905.0)
- GTMSessionFetcher/Core (1.5.0)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
- nanopb/decode (1.30906.0)
- nanopb/encode (1.30906.0)
- path_provider (0.0.1):
- Flutter
- PromisesObjC (1.2.11)
@ -116,28 +98,23 @@ DEPENDENCIES:
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- flurry (from `.symlinks/plugins/flurry/ios`)
- Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
SPEC REPOS:
trunk:
- FBSDKCoreKit
- FBSDKLoginKit
- Firebase
- FirebaseAnalyticsInterop
- FirebaseAuth
- FirebaseAuthInterop
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseCoreDiagnosticsInterop
- FirebaseInstallations
- FirebaseInstanceID
- FirebaseMessaging
- Flurry-iOS-SDK
- GoogleDataTransport
- GoogleDataTransportCCTSupport
- GoogleUtilities
- GTMSessionFetcher
- nanopb
@ -153,10 +130,10 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios"
flurry:
:path: ".symlinks/plugins/flurry/ios"
Flutter:
:path: Flutter
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
path_provider:
@ -166,29 +143,24 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
FBSDKCoreKit: b46507dc8b8cefed31d644e74d7cc30e2a715ef8
FBSDKLoginKit: 1a61d79e2b25e2fc0d03dccab1e34b38bbdf2546
Firebase: 7cf5f9c67f03cb3b606d1d6535286e1080e57eb6
firebase_auth: 8ae6798925da84bf8745668a73c936b148c1b04d
firebase_core: 00e54a4744164a6b5a250b96dd1ad5afaba7a342
firebase_messaging: 666d9994651b1ecf8c582b52dd913f3fa58c17ef
FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
FirebaseAuth: 7047aec89c0b17ecd924a550c853f0c27ac6015e
FirebaseAuthInterop: a0f37ae05833af156e72028f648d313f7e7592e9
FirebaseCore: f42e5e5f382cdcf6b617ed737bf6c871a6947b17
FirebaseCoreDiagnostics: 4505e4d4009b1d93f605088ee7d7764d5f0d1c84
FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
FirebaseInstallations: 6f5f680e65dc374397a483c32d1799ba822a395b
FirebaseInstanceID: cef67c4967c7cecb56ea65d8acbb4834825c587b
FirebaseMessaging: 29543feb343b09546ab3aa04d008ee8595b43c44
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_auth: 240419f6b00dea39c60a2a9c4379c16c4a4b02fb
firebase_core: 350ba329d1641211bc6183a3236893cafdacfea7
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75
FirebaseAuth: c92d49ada7948d1a23466e3db17bc4c2039dddc3
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad
Flurry-iOS-SDK: 8f3f7fce27177002f15f145eede88dc1b9ac0cd0
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_facebook_auth: 85c86b1f574faa5eaacd6de0db6b416fa94b326c
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
GoogleDataTransport: 9a8a16f79feffc7f42096743de2a7c4815e84020
GoogleDataTransportCCTSupport: 489c1265d2c85b68187a83a911913d190012158d
GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1
GTMSessionFetcher: 6f5c8abbab8a9bce4bb3f057e317728ec6182b10
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748

View File

@ -362,7 +362,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 32;
CURRENT_PROJECT_VERSION = 33;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -505,7 +505,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 32;
CURRENT_PROJECT_VERSION = 33;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -540,7 +540,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 32;
CURRENT_PROJECT_VERSION = 33;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (

View File

@ -1,9 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:/Users/tiborbossanyi/Development/projects/workouttest/aitrainer_app/ios/ .xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>

View File

@ -1,5 +1,6 @@
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';
@ -77,6 +78,7 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
yield CustomerSaving();
if (validation()) {
await customerRepository.saveCustomer();
Cache().initBadges();
yield CustomerSaveSuccess();
} else {
yield CustomerSaveError(message: "Please provide the necessary information");

View File

@ -0,0 +1,51 @@
import 'dart:async';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'customer_exercise_device_event.dart';
part 'customer_exercise_device_state.dart';
class CustomerExerciseDeviceBloc extends Bloc<CustomerExerciseDeviceEvent, CustomerExerciseDeviceState> {
final CustomerExerciseDeviceRepository repository;
final List<ExerciseDevice> devices;
CustomerExerciseDeviceBloc({this.repository, this.devices}) : super(CustomerExerciseDeviceInitial()) {
if (repository.getDevices().isEmpty) {
repository.setDevices(Cache().getCustomerDevices());
}
}
@override
Stream<CustomerExerciseDeviceState> mapEventToState(
CustomerExerciseDeviceEvent event,
) async* {
try {
if (event is CustomerExerciseDeviceLoad) {
yield CustomerExerciseDeviceLoading();
yield CustomerExerciseDeviceReady();
} else if (event is CustomerExerciseDeviceAdd) {
yield CustomerExerciseDeviceLoading();
print("Add device " + event.device.exerciseDeviceId.toString());
await repository.addDevice(event.device);
Cache().initBadges();
yield CustomerExerciseDeviceReady();
} else if (event is CustomerExerciseDeviceRemove) {
print("Remove device " + event.device.exerciseDeviceId.toString());
yield CustomerExerciseDeviceLoading();
await repository.removeDevice(event.device);
Cache().initBadges();
yield CustomerExerciseDeviceReady();
}
} on Exception catch (ex) {
yield CustomerExerciseDeviceError(message: ex.toString());
}
}
bool hasCustomerDevice(int exerciseDeviceId) {
return repository.hasDevice(exerciseDeviceId);
}
}

View File

@ -0,0 +1,32 @@
part of 'customer_exercise_device_bloc.dart';
abstract class CustomerExerciseDeviceEvent extends Equatable {
const CustomerExerciseDeviceEvent();
@override
List<Object> get props => [];
}
class CustomerExerciseDeviceLoad extends CustomerExerciseDeviceEvent {
const CustomerExerciseDeviceLoad();
}
class CustomerExerciseDeviceAdd extends CustomerExerciseDeviceEvent {
final ExerciseDevice device;
const CustomerExerciseDeviceAdd({this.device});
@override
List<Object> get props => [device];
}
class CustomerExerciseDeviceRemove extends CustomerExerciseDeviceEvent {
final ExerciseDevice device;
const CustomerExerciseDeviceRemove({this.device});
@override
List<Object> get props => [device];
}
class CustomerExerciseDeviceSave extends CustomerExerciseDeviceEvent {
const CustomerExerciseDeviceSave();
}

View File

@ -0,0 +1,28 @@
part of 'customer_exercise_device_bloc.dart';
abstract class CustomerExerciseDeviceState extends Equatable {
const CustomerExerciseDeviceState();
@override
List<Object> get props => [];
}
class CustomerExerciseDeviceInitial extends CustomerExerciseDeviceState {
const CustomerExerciseDeviceInitial();
}
class CustomerExerciseDeviceLoading extends CustomerExerciseDeviceState {
const CustomerExerciseDeviceLoading();
}
class CustomerExerciseDeviceReady extends CustomerExerciseDeviceState {
const CustomerExerciseDeviceReady();
}
class CustomerExerciseDeviceError extends CustomerExerciseDeviceState {
final String message;
const CustomerExerciseDeviceError({this.message});
@override
List<Object> get props => [message];
}

View File

@ -7,6 +7,7 @@ import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flurry/flurry.dart';
import 'package:meta/meta.dart';
part 'exercise_execute_plan_add_event.dart';
@ -30,16 +31,12 @@ class ExerciseExecutePlanAddBloc extends Bloc<ExerciseExecutePlanAddEvent, Exerc
double scrollOffset = 0;
@override
ExerciseExecutePlanAddBloc({
this.exerciseRepository,
this.exercisePlanRepository,
this.customerId,
this.workoutTree,
this.planBloc}): super(ExerciseExecutePlanAddInitial()) {
ExerciseExecutePlanAddBloc({this.exerciseRepository, this.exercisePlanRepository, this.customerId, this.workoutTree, this.planBloc})
: super(ExerciseExecutePlanAddInitial()) {
exerciseRepository.exerciseType = workoutTree.exerciseType;
if ( Cache().userLoggedIn.customerId == customerId) {
if (Cache().userLoggedIn.customerId == customerId) {
customer = Cache().userLoggedIn;
} else if ( Cache().getTrainee().customerId == customerId) {
} else if (Cache().getTrainee().customerId == customerId) {
customer = Cache().getTrainee();
}
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType);
@ -71,12 +68,12 @@ class ExerciseExecutePlanAddBloc extends Bloc<ExerciseExecutePlanAddEvent, Exerc
yield ExerciseExecutePlanAddReady();
} else if (event is ExerciseExecutePlanAddSubmit) {
yield ExerciseExecutePlanAddLoading();
exerciseRepository.exercise.exercisePlanDetailId =
exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId;
exerciseRepository.exercise.exercisePlanDetailId = exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId;
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit;
workoutTree.executed = true;
print("On Submitting Exercise Execute Plan Add " + exerciseRepository.exercise.toJson().toString());
await exerciseRepository.addExercise();
Flurry.logEvent("ExecuteExercisePlan");
step++;
scrollOffset = step * 200.0;
planBloc.add(ExerciseByPlanLoad());

View File

@ -8,6 +8,7 @@ import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
@ -266,6 +267,8 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
customerRepository.saveCustomer();
changedWeight = false;
this.changedSizes = false;
Cache().initBadges();
Flurry.logEvent("Sizes");
yield ExerciseNewReady();
} else if (event is ExerciseNewSizeChange) {
yield ExerciseNewLoading();
@ -277,6 +280,8 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
yield ExerciseNewLoading();
await exerciseRepository.addExercise();
menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges();
Flurry.logEvent("newExercise");
yield ExerciseNewReady();
} else if (event is ExerciseNewBMIAnimate) {
yield ExerciseNewLoading();
@ -288,7 +293,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
}
double getBMI() {
if (height == 0) {
if (height == 0 || weight == 0) {
this.bmi = 0;
return 0;
}
@ -299,6 +304,10 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
double getBMR() {
var date = DateTime.now();
if (height == 0 || weight == 0) {
this.bmi = 0;
return 0;
}
int year = int.parse(DateFormat(DateFormat.YEAR).format(date));
@ -334,14 +343,15 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> {
this.bmiLeft = 72;
bmiAngle = -62;
} else if (bmi < 25 && 18.5 < bmi) {
goalBMI = bmi;
goalBMI = 27;
this.bmiTop = 46;
this.bmiLeft = 130;
bmiAngle = -21;
bmiAngle = -23;
} else if (bmi < 30 && 24.9 < bmi) {
goalBMI = 24;
this.bmiTop = 38.0;
this.bmiLeft = 186.0;
bmiAngle = 7.2;
} else if (bmi < 34.9 && 29.9 < bmi) {
goalBMI = 29;
bmiTop = 48;

View File

@ -1,10 +1,12 @@
import 'dart:async';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flurry/flurry.dart';
import 'package:meta/meta.dart';
part 'exercise_plan_event.dart';
@ -31,7 +33,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
workoutTree.selected = false;
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
ExercisePlanDetail planDetail = exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId);
if (planDetail != null && planDetail.change != ExercisePlanDetailChange.deleted) {
if (planDetail != null && planDetail.change != ModelChange.deleted) {
workoutTree.selected = true;
}
}
@ -39,7 +41,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
});
}
void setExercisePlanRepository(ExercisePlanRepository repo ) => exercisePlanRepository = repo;
void setExercisePlanRepository(ExercisePlanRepository repo) => exercisePlanRepository = repo;
@override
Stream<ExercisePlanState> mapEventToState(ExercisePlanEvent event) async* {
@ -60,9 +62,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
}
yield ExercisePlanReady();
}
else if (event is ExercisePlanAddExercise) {
} else if (event is ExercisePlanAddExercise) {
yield ExercisePlanLoading();
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.actualPlanDetail = planDetail;
@ -74,16 +74,14 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
if (element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = true;
}
});
});
yield ExercisePlanReady();
}
else if (event is ExercisePlanRemoveExercise) {
} else if (event is ExercisePlanRemoveExercise) {
yield ExercisePlanLoading();
ExercisePlanDetail planDetail = event.exercisePlanDetail;
exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(planDetail.exerciseTypeId);
@ -91,7 +89,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) {
if ( element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
if (element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = false;
}
});
@ -99,12 +97,11 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
if (exercisePlanRepository.getExercisePlanDetailSize() != 0) {
exercisePlanRepository.saveExercisePlan();
Flurry.logEvent("SaveExercisePlan");
}
yield ExercisePlanReady();
}
} on Exception catch (e) {
yield ExercisePlanError(message: e.toString());
}

View File

@ -59,6 +59,7 @@ class LoginFormBloc extends FormBloc<String, String> with Common {
}
emitSuccess(canSubmitAgain: false);
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
Cache().initBadges();
}
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());

View File

@ -11,18 +11,13 @@ class RegistrationFormBloc extends FormBloc<String, String> with Common {
FieldBlocValidators.required,
],
);
final passwordField = TextFieldBloc(
validators: [
final passwordField = TextFieldBloc(validators: [
FieldBlocValidators.required,
]
);
]);
final UserRepository userRepository;
RegistrationFormBloc({this.userRepository, this.accountBloc}) {
addFieldBlocs(fieldBlocs: [
emailField,
passwordField
]);
addFieldBlocs(fieldBlocs: [emailField, passwordField]);
emailField.onValueChanges(onData: (previous, current) async* {
userRepository.setEmail(current.value);
@ -31,18 +26,17 @@ class RegistrationFormBloc extends FormBloc<String, String> with Common {
passwordField.onValueChanges(onData: (previous, current) async* {
userRepository.setPassword(current.value);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
if ( ! validateEmail(userRepository)) {
if (!validateEmail(userRepository)) {
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
emitFailure(failureResponse: EMAIL_ERROR);
} else if ( ! validatePassword(userRepository)) {
} else if (!validatePassword(userRepository)) {
passwordField.addFieldError(PASSWORD_ERROR, isPermanent: true);
emitFailure(failureResponse: PASSWORD_ERROR);
} else {
@ -50,12 +44,10 @@ class RegistrationFormBloc extends FormBloc<String, String> with Common {
await userRepository.addUser();
emitSuccess(canSubmitAgain: false);
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
Cache().initBadges();
}
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
}

View File

@ -1,5 +1,4 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/customer_exercise_device/customer_exercise_device_bloc.dart';
import 'package:aitrainer_app/push_notifications.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
@ -31,8 +30,7 @@ import 'package:aitrainer_app/view/registration.dart';
import 'package:aitrainer_app/view/reset_password.dart';
import 'package:aitrainer_app/view/settings.dart';
import 'package:aitrainer_app/widgets/home.dart';
//import 'package:firebase_analytics/firebase_analytics.dart';
//import 'package:firebase_analytics/observer.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
@ -143,18 +141,25 @@ Future<Null> main() async {
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
),
],
child: AitrainerApp(),
child: WorkoutTestApp(),
));
}, (error, stackTrace) async {
await _reportError(error, stackTrace);
});
}
class AitrainerApp extends StatelessWidget {
Future<void> initFlurry() async {
await Flurry.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
//await Flurry.setUserId("userId");
//await Flurry.logEvent("eventName");
}
class WorkoutTestApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
//final FirebaseAnalytics analytics = FirebaseAnalytics();
initFlurry();
PushNotificationsManager().init();
return MaterialApp(
localizationsDelegates: [

View File

@ -4,15 +4,22 @@ import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/customer_exercise_device_service.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/util/env.dart';
import 'package:flurry/flurry.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'customer_exercise_device.dart';
import 'exercise_device.dart';
enum SharePrefsChange {
login,
registration,
@ -64,6 +71,8 @@ class Cache {
List<Exercise> _exercises;
ExercisePlan _myExercisePlan;
List<Property> _properties;
List<ExerciseDevice> _devices;
List<CustomerExerciseDevice> _customerDevices;
LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
@ -75,6 +84,8 @@ class Cache {
ExercisePlan _traineeExercisePlan;
List<ExercisePlanDetail> _traineeExercisesPlanDetail;
LinkedHashMap<String, int> _badges = LinkedHashMap();
List deviceLanguages;
String startPage;
@ -158,7 +169,10 @@ class Cache {
sharedPreferences.setString(Cache.firebaseUidKey, firebaseUid);
await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree();
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
Cache().setCustomerDevices(customerDevices);
await exerciseRepository.getExercisesByCustomer(customerId);
Flurry.setUserId(customerId.toString());
} else if (type == SharePrefsChange.login) {
Cache().startPage = "home";
sharedPreferences.setInt(Cache.customerIdKey, customerId);
@ -166,13 +180,17 @@ class Cache {
sharedPreferences.setBool(Cache.isLoggedInKey, true);
await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree();
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
Cache().setCustomerDevices(customerDevices);
await exerciseRepository.getExercisesByCustomer(customerId);
Flurry.setUserId(customerId.toString());
} else if (type == SharePrefsChange.logout) {
sharedPreferences.setBool(Cache.isLoggedInKey, false);
sharedPreferences.setInt(Cache.customerIdKey, 0);
sharedPreferences.setString(Cache.firebaseUidKey, null);
sharedPreferences.setString(authTokenKey, "");
}
initBadges();
}
void setExerciseTypes(List<ExerciseType> exerciseTypes) {
@ -241,13 +259,85 @@ class Cache {
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
this._myExercisesPlanDetails[detail.exerciseTypeId].change = ExercisePlanDetailChange.deleted;
this._myExercisesPlanDetails[detail.exerciseTypeId].change = ModelChange.deleted;
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
this._myExercisesPlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete;
this._myExercisesPlanDetails[exerciseTypeId].change = ModelChange.delete;
}
void setProperties(List<Property> properties) => this._properties = properties;
List<Property> getProperties() => _properties;
void setDevices(List<ExerciseDevice> devices) => this._devices = devices;
List<ExerciseDevice> getDevices() => this._devices;
void setCustomerDevices(List<CustomerExerciseDevice> devices) => this._customerDevices = devices;
List<CustomerExerciseDevice> getCustomerDevices() => this._customerDevices;
LinkedHashMap getBadges() => _badges;
void setBadge(String key, bool inc) {
if (inc) {
if (_badges[key] != null) {
_badges[key]++;
} else {
_badges[key] = 1;
}
} else {
if (_badges[key] != null) {
if (_badges[key] == 1) {
_badges.remove(key);
} else {
_badges[key]--;
}
}
}
}
void setBadgeNr(String key, int counter) {
if (_badges[key] != null) {
_badges[key] += counter;
} else {
_badges[key] = counter;
}
}
void initBadges() {
CustomerRepository customerRepository = CustomerRepository();
_badges = LinkedHashMap();
customerRepository.setCustomer(userLoggedIn);
if (this.userLoggedIn != null) {
if (this.userLoggedIn.firstname == null || userLoggedIn.firstname.length == 0) {
setBadge("personalData", true);
setBadge("account", true);
}
if (this._customerDevices == null || this._customerDevices.isEmpty) {
setBadge("customerDevice", true);
setBadge("account", true);
}
if (userLoggedIn.properties == null || userLoggedIn.properties.isEmpty) {
setBadge("personalData", true);
setBadge("Sizes", true);
setBadge("BMI", true);
setBadge("BMR", true);
setBadgeNr("Body Compositions", 3);
setBadgeNr("home", 3);
} else if (customerRepository.getWeight() == 0) {
setBadge("BMI", true);
setBadge("BMR", true);
setBadge("Body Compositions", true);
setBadgeNr("home", 1);
}
if (customerRepository.getHeight() == 0) {
setBadge("BMI", true);
setBadge("BMR", true);
setBadge("Body Compositions", true);
setBadgeNr("home", 1);
}
}
print("Badges: " + _badges.toString());
}
}

View File

@ -0,0 +1,42 @@
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomerExerciseDevice {
int customerExerciseDeviceId;
int exerciseDeviceId;
int customerId;
bool favourite;
DateTime dateAdd;
String change;
CustomerExerciseDevice({this.exerciseDeviceId, this.customerId, this.favourite}) {
dateAdd = DateTime.now();
}
CustomerExerciseDevice.fromJson(Map json) {
this.customerExerciseDeviceId = json['customerExerciseDeviceId'];
this.exerciseDeviceId = json['exerciseDeviceId'];
this.customerId = json['customerId'];
this.favourite = json['favourite'] == 1 ? true : false;
this.dateAdd = DateTime.parse(json['dateAdd']);
}
Map<String, dynamic> toJson() {
if (customerExerciseDeviceId == null) {
return {
"exerciseDeviceId": exerciseDeviceId,
"customerId": customerId,
"favourite": favourite == true ? 1 : 0,
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
};
} else {
return {
"customerExerciseDeviceId": customerExerciseDeviceId,
"exerciseDeviceId": exerciseDeviceId,
"customerId": customerId,
"favourite": favourite == true ? 1 : 0,
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd),
};
}
}
}

View File

@ -0,0 +1,19 @@
class ExerciseDevice {
int exerciseDeviceId;
String name;
String description;
String imageUrl;
String nameTranslation;
int sort;
bool place;
ExerciseDevice.fromJson(Map json) {
this.exerciseDeviceId = json['exerciseDeviceId'];
this.name = json['name'];
this.description = json['description'];
this.imageUrl = json['imageUrl'];
this.nameTranslation = json['translations'][0]['name'];
this.sort = json['sort'];
this.place = json['place'] == 1 ? true : false;
}
}

View File

@ -21,19 +21,18 @@ class ExercisePlan {
this.name = json['name'];
this.private = json['private'];
this.description = json['description'];
this.dateAdd = json['dateAdd'] == null ? null : DateTime.parse( json['dateAdd'] );
this.dateUpd = json['dateUpd'] == null ? null : DateTime.parse( json['dateUpd'] );
this.dateAdd = json['dateAdd'] == null ? null : DateTime.parse(json['dateAdd']);
this.dateUpd = json['dateUpd'] == null ? null : DateTime.parse(json['dateUpd']);
}
Map<String, dynamic> toJson() {
String formattedDateAdd;
if ( dateAdd != null) {
if (dateAdd != null) {
formattedDateAdd = DateFormat('yyyy-MM-dd HH:mm').format(dateAdd);
}
String formattedDateUpd = DateFormat('yyyy-MM-dd HH:mm').format(dateUpd);
print("DateAdd $formattedDateAdd");
if ( exercisePlanId == null ) {
if (exercisePlanId == null) {
return {
"customerId": customerId,
"name": name,
@ -54,5 +53,4 @@ class ExercisePlan {
};
}
}
}

View File

@ -1,13 +1,5 @@
import 'exercise_type.dart';
class ExercisePlanDetailChange {
static const String add = "add";
static const String delete = "delete";
static const String update = "update";
static const String deleted = "deleted";
static const String saved = "saved";
}
class ExercisePlanDetail {
int exercisePlanDetailId;
int exercisePlanId;
@ -32,8 +24,7 @@ class ExercisePlanDetail {
this.weightEquation = json['weightEquation'];
}
Map<String, dynamic> toJson() =>
{
Map<String, dynamic> toJson() => {
"exercisePlanId": exercisePlanId,
"exerciseTypeId": exerciseTypeId,
"serie": serie,

View File

@ -1,5 +1,3 @@
import 'package:flutter/semantics.dart';
class FitnessState {
final String value;
final String stateText;

View File

@ -0,0 +1,7 @@
class ModelChange {
static const String add = "add";
static const String delete = "delete";
static const String update = "update";
static const String deleted = "deleted";
static const String saved = "saved";
}

View File

@ -0,0 +1,76 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer_exercise_device.dart';
import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/service/customer_exercise_device_service.dart';
class CustomerExerciseDeviceRepository {
List<CustomerExerciseDevice> _devices = List();
List<CustomerExerciseDevice> getDevices() => this._devices;
void setDevices(List<CustomerExerciseDevice> devices) => this._devices = devices;
Future<List<CustomerExerciseDevice>> getDBDevices() async {
if (Cache().userLoggedIn != null) {
final int customerId = Cache().userLoggedIn.customerId;
this._devices = await CustomerExerciseDeviceApi().getDevices(customerId);
}
return this._devices;
}
Future<void> addDevice(ExerciseDevice device) async {
CustomerExerciseDevice found;
if (_devices != null) {
this._devices.forEach((element) {
if (element.exerciseDeviceId == device.exerciseDeviceId) {
found = element;
}
});
}
if (found == null) {
int customerId;
if (Cache().userLoggedIn != null) {
customerId = Cache().userLoggedIn.customerId;
}
CustomerExerciseDevice newDevice =
CustomerExerciseDevice(customerId: customerId, exerciseDeviceId: device.exerciseDeviceId, favourite: false);
newDevice.change = ModelChange.add;
await CustomerExerciseDeviceApi().addDevice(newDevice);
this._devices.add(newDevice);
Cache().setCustomerDevices(_devices);
}
}
Future<void> removeDevice(ExerciseDevice device) async {
print("Remove " + device.name);
CustomerExerciseDevice found;
if (_devices != null) {
this._devices.forEach((element) {
if (element.exerciseDeviceId == device.exerciseDeviceId) {
found = element;
}
});
}
if (found != null) {
this._devices.remove(found);
if (found.change != ModelChange.add) {
await CustomerExerciseDeviceApi().removeDevice(found.customerExerciseDeviceId);
}
Cache().setCustomerDevices(_devices);
}
}
bool hasDevice(int exerciseDeviceId) {
bool found = false;
if (_devices != null) {
this._devices.forEach((element) {
if (element.exerciseDeviceId == exerciseDeviceId) {
found = true;
}
});
}
return found;
}
}

View File

@ -0,0 +1,15 @@
import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/service/exercise_device_service.dart';
class ExerciseDeviceRepository {
List<ExerciseDevice> _devices = List();
List<ExerciseDevice> getDevices() {
return this._devices;
}
Future<List<ExerciseDevice>> getDBDevices() async {
this._devices = await ExerciseDeviceApi().getDevices();
return this._devices;
}
}

View File

@ -4,17 +4,17 @@ import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/service/exercise_plan_service.dart';
class ExercisePlanRepository {
bool newPlan = true;
ExercisePlan exercisePlan;
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails =
LinkedHashMap<int, ExercisePlanDetail>();
LinkedHashMap<int, ExercisePlanDetail> exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
int customerId = 0;
ExercisePlanDetail actualPlanDetail;
void setCustomerId( int customerId ) {
void setCustomerId(int customerId) {
this.customerId = customerId;
}
@ -24,11 +24,10 @@ class ExercisePlanRepository {
this.exercisePlan = plan;
}
ExercisePlan getExercisePlan() => exercisePlan;
void addDetailToPlan() {
if ( exercisePlan != null ) {
if (exercisePlan != null) {
actualPlanDetail.exercisePlanId = exercisePlan.exercisePlanId;
}
exercisePlanDetails[actualPlanDetail.exerciseTypeId] = actualPlanDetail;
@ -39,7 +38,7 @@ class ExercisePlanRepository {
void setActualPlanDetailByExerciseType(ExerciseType exerciseType) {
ExercisePlanDetail detail = exercisePlanDetails[exerciseType.exerciseTypeId];
if ( detail != null ) {
if (detail != null) {
actualPlanDetail = detail;
} else {
actualPlanDetail = ExercisePlanDetail(exerciseType.exerciseTypeId);
@ -49,7 +48,7 @@ class ExercisePlanRepository {
ExercisePlanDetail getActualPlanDetail() => actualPlanDetail;
void setActualPlanDetail( ExercisePlanDetail detail ) {
void setActualPlanDetail(ExercisePlanDetail detail) {
this.actualPlanDetail = detail;
}
@ -58,10 +57,8 @@ class ExercisePlanRepository {
String getPlanDetail(int exerciseTypeId) {
ExercisePlanDetail detail = exercisePlanDetails[exerciseTypeId];
String detailString = "";
if ( detail != null) {
detailString =
detail.serie.toString() + "x" + detail.repeats.toString() + " " +
detail.weightEquation + "kg";
if (detail != null) {
detailString = detail.serie.toString() + "x" + detail.repeats.toString() + " " + detail.weightEquation + "kg";
}
return detailString;
}
@ -71,14 +68,14 @@ class ExercisePlanRepository {
}
void updateExercisePlanDetail(ExerciseType exerciseType, int serie, int repeat, String weight) {
if ( exercisePlanDetails[exerciseType.exerciseTypeId] == null) {
if (exercisePlanDetails[exerciseType.exerciseTypeId] == null) {
return;
}
ExercisePlanDetail exercisePlanDetail = exercisePlanDetails[exerciseType.exerciseTypeId];
exercisePlanDetail.serie = serie;
exercisePlanDetail.repeats = repeat;
exercisePlanDetail.weightEquation = weight;
exercisePlanDetail.change = ExercisePlanDetailChange.update;
exercisePlanDetail.change = ModelChange.update;
exercisePlanDetails[exerciseType.exerciseTypeId] = exercisePlanDetail;
}
@ -88,19 +85,18 @@ class ExercisePlanRepository {
}
void removeExerciseTypeFromPlanByExerciseTypeId(int exerciseTypeId) {
exercisePlanDetails[exerciseTypeId].change = ExercisePlanDetailChange.delete;
exercisePlanDetails[exerciseTypeId].change = ModelChange.delete;
Cache().deleteMyExercisePlanDetailByExerciseTypeId(exerciseTypeId);
}
Future<void> saveExercisePlan() async {
if ( exercisePlan == null ) {
if ( Cache().userLoggedIn == null ) {
if (exercisePlan == null) {
if (Cache().userLoggedIn == null) {
throw Exception("please log in");
}
String exercisePlanName;
if ( this.customerId == Cache().userLoggedIn.customerId) {
if (this.customerId == Cache().userLoggedIn.customerId) {
exercisePlanName = Cache().userLoggedIn.name + " private";
} else {
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
@ -108,11 +104,10 @@ class ExercisePlanRepository {
exercisePlan = ExercisePlan(exercisePlanName, this.customerId);
}
if ( newPlan ) {
if (newPlan) {
exercisePlan.dateAdd = DateTime.now();
exercisePlan.private = true;
ExercisePlan savedExercisePlan =
await ExercisePlanApi().saveExercisePlan(exercisePlan);
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan);
LinkedHashMap<int, ExercisePlanDetail> savedExercisePlanDetails = LinkedHashMap();
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
@ -123,40 +118,33 @@ class ExercisePlanRepository {
exercisePlan = savedExercisePlan;
exercisePlanDetails = savedExercisePlanDetails;
} else {
//await ExercisePlanApi().updateExercisePlan(exercisePlan, exercisePlan.exercisePlanId);
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
if ( exercisePlanDetail.change == ExercisePlanDetailChange.delete ) {
await ExercisePlanApi()
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
exercisePlanDetail.change = ExercisePlanDetailChange.deleted;
if (exercisePlanDetail.change == ModelChange.delete) {
await ExercisePlanApi().deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
exercisePlanDetail.change = ModelChange.deleted;
Cache().deletedMyExercisePlanDetail(exercisePlanDetail);
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.update ) {
await ExercisePlanApi()
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
} else if (exercisePlanDetail.change == ModelChange.update) {
await ExercisePlanApi().updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
Cache().updateMyExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.change = ExercisePlanDetailChange.saved;
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.add ) {
await ExercisePlanApi()
.saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.change = ModelChange.saved;
} else if (exercisePlanDetail.change == ModelChange.add) {
await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
Cache().addToMyExercisePlanDetails(exercisePlanDetail);
exercisePlanDetail.change = ExercisePlanDetailChange.saved;
exercisePlanDetail.change = ModelChange.saved;
}
});
}
}
Future<ExercisePlan> getLastExercisePlan() async {
if ( customerId == 0) {
if (customerId == 0) {
return null;
}
ExercisePlan myExercisePlan = Cache().getMyExercisePlan();
if ( myExercisePlan != null ) {
if (myExercisePlan != null) {
exercisePlan = myExercisePlan;
return myExercisePlan;
}
@ -171,7 +159,7 @@ class ExercisePlanRepository {
Future<void> getExercisePlanDetails() async {
if (exercisePlan == null) {
ExercisePlan exercisePlan = await this.getLastExercisePlan();
if ( exercisePlan == null ) {
if (exercisePlan == null) {
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
return;
}
@ -179,7 +167,7 @@ class ExercisePlanRepository {
List<ExercisePlanDetail> list = List();
LinkedHashMap<int, ExercisePlanDetail> listCache = Cache().getMyExercisePlanDetails();
if ( listCache.length > 0) {
if (listCache.length > 0) {
exercisePlanDetails = listCache;
return;
} else {
@ -197,5 +185,4 @@ class ExercisePlanRepository {
return;
}
}

View File

@ -1,5 +1,3 @@
import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/service/property_service.dart';

View File

@ -41,9 +41,7 @@ class UserRepository {
String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password);
if (rc == FirebaseApi.SIGN_IN_OK) {
print("Firebase login ok");
await CustomerApi().getUserByEmail(modelUser.email);
print("GetUserBy Email OK");
Cache().afterFirebaseLogin();
} else {
print("Exception: user not found or password is wrong");

View File

@ -0,0 +1,44 @@
import 'package:aitrainer_app/model/customer_exercise_device.dart';
import 'package:aitrainer_app/util/not_found_exception.dart';
import 'dart:convert';
import 'api.dart';
class CustomerExerciseDeviceApi {
final APIClient _client = new APIClient();
Future<List<CustomerExerciseDevice>> getDevices(int customerId) async {
List<CustomerExerciseDevice> devices;
try {
final body = await _client.get("customer_exercise_device/customer/" + customerId.toString(), "");
final Iterable json = jsonDecode(body);
devices = json.map((device) => CustomerExerciseDevice.fromJson(device)).toList();
} on NotFoundException catch (e) {
print("No devices found");
}
return devices;
}
Future<CustomerExerciseDevice> addDevice(CustomerExerciseDevice device) async {
CustomerExerciseDevice savedDevice;
try {
final String body = JsonEncoder().convert(device.toJson());
print(" --- add customer_exercise_device: " + body);
final String responseBody = await _client.post("customer_exercise_device", body);
savedDevice = CustomerExerciseDevice.fromJson(jsonDecode(responseBody));
} on Exception catch (e) {
throw new Exception(e.toString());
}
return savedDevice;
}
Future<void> removeDevice(int id) async {
try {
print(" --- delete customer_exercise_device: " + id.toString());
await _client.post("customer_exercise_device/delete/" + id.toString(), "");
} on Exception catch (e) {
throw new Exception(e.toString());
}
return;
}
}

View File

@ -6,7 +6,6 @@ import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/not_found_exception.dart';
class CustomerApi {
final APIClient _client = new APIClient();

View File

@ -0,0 +1,17 @@
import 'package:aitrainer_app/model/cache.dart';
import 'dart:convert';
import 'package:aitrainer_app/model/exercise_device.dart';
import 'api.dart';
class ExerciseDeviceApi {
final APIClient _client = new APIClient();
Future<List<ExerciseDevice>> getDevices() async {
final body = await _client.get("exercise_device/", "");
final Iterable json = jsonDecode(body);
final List<ExerciseDevice> devices = json.map((device) => ExerciseDevice.fromJson(device)).toList();
Cache().setDevices(devices);
return devices;
}
}

View File

@ -2,30 +2,27 @@ import 'dart:convert';
import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/service/api.dart';
class ExerciseApi {
final APIClient _client=new APIClient();
final APIClient _client = new APIClient();
Future<List<Exercise>> getExerciseTypes(String param) async {
final body = await _client.get("exercises", param);
final Iterable json = jsonDecode(body);
final List<Exercise> exerciseTypes = json.map( (exerciseType) => Exercise.fromJson(exerciseType) ).toList();
final List<Exercise> exerciseTypes = json.map((exerciseType) => Exercise.fromJson(exerciseType)).toList();
return exerciseTypes;
}
Future<void> saveExercise(Exercise exercise) async {
String body = JsonEncoder().convert(exercise.toJson());
print(" ===== saving exercise id: " + exercise.exerciseId.toString() + ":" + body );
await _client.post(
"exercises/"+exercise.exerciseId.toString(),
body);
print(" ===== saving exercise id: " + exercise.exerciseId.toString() + ":" + body);
await _client.post("exercises/" + exercise.exerciseId.toString(), body);
}
Future<List<Exercise>> getExercisesByCustomer(int customerId ) async {
final body = await _client.get("exercises/customer/", customerId.toString() );
Future<List<Exercise>> getExercisesByCustomer(int customerId) async {
final body = await _client.get("exercises/customer/", customerId.toString());
final Iterable json = jsonDecode(body);
final List<Exercise> exercises = json.map( (exercise) {
final List<Exercise> exercises = json.map((exercise) {
Exercise item = Exercise.fromJson(exercise);
return item;
}).toList();
@ -36,19 +33,16 @@ class ExerciseApi {
Future<Exercise> addExercise(Exercise exercise) async {
String body = JsonEncoder().convert(exercise.toJson());
print(" ===== add new exercise: " + body );
final String response = await _client.post(
"exercises",
body);
print(" ===== add new exercise: " + body);
final String response = await _client.post("exercises", body);
final Exercise savedExercise = Exercise.fromJson(jsonDecode(response));
return savedExercise;
}
Future<void> deleteExercise(Exercise exercise) async {
int exerciseId = exercise.exerciseId;
print(" ===== delete exercise: " + exerciseId.toString() );
final String response = await _client.post("exercises/" + exerciseId.toString(), "");
print(" ===== delete exercise: " + exerciseId.toString());
await _client.post("exercises/" + exerciseId.toString(), "");
return;
}
}

View File

@ -1,7 +1,7 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
//import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
class FirebaseApi {
static FirebaseApi _instance;
@ -66,10 +66,6 @@ class FirebaseApi {
print('The account already exists for that email.');
rc = REGISTER_EMAIL_IN_USE;
throw Exception("The email address has been registered already");
/* userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
if (rc != null) {
rc = SIGN_IN_OK;
} */
}
} catch (e) {
print(e);
@ -78,7 +74,7 @@ class FirebaseApi {
return rc;
}
Future<UserCredential> signInWithFacebook() async {
/*Future<UserCredential> signInWithFacebook() async {
// Trigger the sign-in flow
final LoginResult result = await FacebookAuth.instance.login();
@ -87,7 +83,7 @@ class FirebaseApi {
// Once signed in, return the UserCredential
return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
}*/
Future<void> signOut() async {
await FirebaseAuth.instance.signOut();

View File

@ -1,19 +1,20 @@
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/customer_exercise_device.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/service/customer_exercise_device_service.dart';
import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/exercise_device_service.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/service/property_service.dart';
import 'package:devicelocale/devicelocale.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:firebase_core/firebase_core.dart';
//import '../push_notifications.dart';
class Session {
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
@ -36,7 +37,6 @@ class Session {
// Create the initialization Future outside of `build`:
// PushNotificationsManager().init();
}
}
@ -100,15 +100,19 @@ class Session {
customerId = prefs.getInt(Cache.customerIdKey);
await CustomerApi().getCustomer(customerId);
Cache().startPage = "home";
Flurry.setUserId(customerId.toString());
}
}
await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree();
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
Cache().setCustomerDevices(customerDevices);
if (customerId > 0) {
ExerciseRepository exerciseRepository = ExerciseRepository();
await exerciseRepository.getExercisesByCustomer(customerId);
}
await ExerciseDeviceApi().getDevices();
print("--- Session finished");
}
}

View File

@ -4,6 +4,7 @@ import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:badges/badges.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:flutter/material.dart';
@ -57,7 +58,7 @@ class AccountPage extends StatelessWidget with Trans {
ListView accountWidget(BuildContext context, String customerName, AccountBloc accountBloc) {
return ListView(padding: EdgeInsets.only(top: 35), children: <Widget>[
ListTile(
leading: Icon(Icons.perm_identity),
leading: badgedIcon(Colors.grey, Icons.perm_identity, "personalData"), //Icon(Icons.perm_identity),
subtitle: Text(t("Profile")),
title: FlatButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
@ -74,11 +75,33 @@ class AccountPage extends StatelessWidget with Trans {
},
),
),
devices(context, accountBloc),
loginOut(context, accountBloc),
getMyTrainees(context, accountBloc),
]);
}
ListTile devices(BuildContext context, AccountBloc accountBloc) {
ListTile element = ListTile();
element = ListTile(
leading: badgedIcon(Colors.grey, Icons.device_hub, "customerDevice"),
title: FlatButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Text(t("Available Devices"), style: TextStyle(color: Colors.orange)), Icon(Icons.arrow_forward_ios)]),
textColor: Colors.orange,
color: Colors.white,
onPressed: () => {
if (accountBloc.customerRepository.customer != null && Cache().userLoggedIn != null)
{
Navigator.of(context).pushNamed('customerExerciseDevicePage'),
}
},
),
);
return element;
}
ListTile loginOut(BuildContext context, AccountBloc accountBloc) {
ListTile element = ListTile();
@ -203,4 +226,24 @@ class AccountPage extends StatelessWidget with Trans {
],
));
}
Widget badgedIcon(Color color, IconData icon, String badgeKey) {
bool show = Cache().getBadges()[badgeKey] != null;
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
return Badge(
position: BadgePosition.topEnd(top: -10, end: -10),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.red,
showBadge: show,
badgeContent: Text(
counter.toString(),
style: TextStyle(color: Colors.white),
),
child: Icon(
icon,
color: color,
),
);
}
}

View File

@ -0,0 +1,246 @@
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/model/cache.dart';
import 'package:aitrainer_app/model/exercise_device.dart';
import 'package:aitrainer_app/repository/customer_exercise_device_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/image_button.dart';
import 'package:aitrainer_app/widgets/splash.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
// ignore: must_be_immutable
class CustomerExerciseDevicePage extends StatelessWidget with Trans {
List<Widget> listDevice;
@override
Widget build(BuildContext context) {
setContext(context);
double cWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBarNav(depth: 0),
body: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.png'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: BlocProvider(
create: (context) =>
CustomerExerciseDeviceBloc(repository: CustomerExerciseDeviceRepository(), devices: Cache().getDevices())
..add(CustomerExerciseDeviceLoad()),
child: BlocConsumer<CustomerExerciseDeviceBloc, CustomerExerciseDeviceState>(
listener: (context, state) {
if (state is CustomerExerciseDeviceLoading) {
return LoadingDialog();
} else if (state is CustomerExerciseDeviceError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
},
builder: (context, state) {
final bloc = BlocProvider.of<CustomerExerciseDeviceBloc>(context);
return getPage(bloc, cWidth);
},
))));
}
Widget getPage(CustomerExerciseDeviceBloc bloc, double cWidth) {
print("width" + cWidth.toString());
return CustomScrollView(scrollDirection: Axis.vertical, slivers: [
SliverGrid(
delegate: SliverChildListDelegate([
Text(t("Available Training Places"),
textAlign: TextAlign.center,
maxLines: 2,
softWrap: true,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
Text(t("select your places by tapping"),
textAlign: TextAlign.center,
softWrap: true,
maxLines: 2,
style: GoogleFonts.archivoBlack(
fontSize: 14,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
]),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
childAspectRatio: cWidth > 375 ? 9.1 : 4.1,
),
),
SliverGrid(
delegate: SliverChildListDelegate(getDevicesPlace(bloc, cWidth)),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 15.0,
crossAxisSpacing: 10.0,
childAspectRatio: 3.0,
),
),
SliverGrid(
delegate: SliverChildListDelegate([
SizedBox(
height: 1,
),
Text(t("Available Equipments"),
textAlign: TextAlign.center,
maxLines: 2,
style: GoogleFonts.archivoBlack(
fontSize: 24,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
Text(t("select your equipments by tapping"),
textAlign: TextAlign.center,
maxLines: 2,
style: GoogleFonts.archivoBlack(
fontSize: 14,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
]),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 2.0,
crossAxisSpacing: 5.0,
childAspectRatio: cWidth > 375 ? 9.1 : 6.1,
),
),
SliverGrid(
delegate: SliverChildListDelegate(getDevices(bloc)),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 15.0,
crossAxisSpacing: 15.0,
childAspectRatio: 1.0,
),
),
]);
}
List<Widget> getDevices(CustomerExerciseDeviceBloc bloc) {
final bool isEnglish = AppLanguage().appLocal.languageCode == "en";
this.listDevice = List();
final devices = bloc.devices;
devices.sort((a, b) => a.sort.compareTo(b.sort));
if (devices != null) {
devices.forEach((element) {
if (element.place == false) {
final String url = "asset/image/" + element.imageUrl.substring(7);
ImageButton button = ImageButton(
width: 178,
height: 175,
textAlignment: Alignment.topCenter,
text: isEnglish ? element.name : element.nameTranslation,
style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.white, backgroundColor: Colors.black54.withOpacity(0.4)),
image: url,
left: 5,
onTap: () => changeButtonShape(element, bloc),
isLocked: false,
isMarked: bloc.hasCustomerDevice(element.exerciseDeviceId),
buttonIndex: element.exerciseDeviceId,
isShape: false,
);
listDevice.add(button);
}
});
}
return listDevice;
}
List<Widget> getDevicesPlace(CustomerExerciseDeviceBloc bloc, double cWidth) {
final bool isEnglish = AppLanguage().appLocal.languageCode == "en";
this.listDevice = List();
final devices = bloc.devices;
if (devices != null) {
devices.sort((a, b) => a.sort.compareTo(b.sort));
devices.forEach((element) {
if (element.place) {
ImageButton button = ImageButton(
width: cWidth - 80,
height: 125,
top: 10,
textAlignment: Alignment.topCenter,
text: isEnglish ? element.name : element.nameTranslation,
style: GoogleFonts.archivoBlack(fontSize: 14, color: Colors.white, backgroundColor: Colors.black54.withOpacity(0.4)),
image: element.imageUrl,
left: 35,
onTap: () => changeButtonShape(element, bloc),
isLocked: false,
buttonIndex: element.exerciseDeviceId,
isShape: false,
isMarked: bloc.hasCustomerDevice(element.exerciseDeviceId),
);
listDevice.add(button);
}
});
}
return listDevice;
}
void changeButtonShape(ExerciseDevice device, CustomerExerciseDeviceBloc bloc) {
print("Device clicked: " + device.name);
if (bloc.hasCustomerDevice(device.exerciseDeviceId)) {
bloc.add(CustomerExerciseDeviceRemove(device: device));
} else {
bloc.add(CustomerExerciseDeviceAdd(device: device));
}
}
}

View File

@ -27,43 +27,31 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
setContext(context);
return BlocProvider(
create: (context) => ExerciseControlBloc(
exerciseRepository: exerciseRepository, percentToCalculate: percent, readonly: readonly)..
add(ExerciseControlLoad()),
child:
BlocConsumer<ExerciseControlBloc, ExerciseControlState>(
listener: (context, state) {
create: (context) => ExerciseControlBloc(exerciseRepository: exerciseRepository, percentToCalculate: percent, readonly: readonly)
..add(ExerciseControlLoad()),
child: BlocConsumer<ExerciseControlBloc, ExerciseControlState>(listener: (context, state) {
if (state is ExerciseControlError) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content:
Text(state.message, style: TextStyle(color: Colors.white))));
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is ExerciseControlLoading) {
return LoadingDialog();
}
},
builder: (context, state) {
}, builder: (context, state) {
final exerciseBloc = BlocProvider.of<ExerciseControlBloc>(context);
if (state is ExerciseControlReady) {
return getControlForm(exerciseBloc);
} else {
return getControlForm(exerciseBloc);
}
})
);
}));
}
Form getControlForm(ExerciseControlBloc exerciseBloc) {
String exerciseName = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.name
: exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
return Form(
autovalidate: true,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1),
@ -97,8 +85,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
Icon(Icons.info),
Flexible(
child: Text(t("Why do you need Exercise Control?"),
style:
TextStyle(color: Colors.blueAccent, fontWeight: FontWeight.normal, fontSize: 14)),
style: TextStyle(color: Colors.blueAccent, fontWeight: FontWeight.normal, fontSize: 14)),
),
Icon(Icons.arrow_forward_ios),
]),
@ -137,19 +124,20 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
}
Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) {
String strTimes = step == 2 ? exerciseBloc.origQuantity.toString() : "max.";
String textInstruction = "";
textInstruction = t("Please repeat with ") +
exerciseBloc.unitQuantity.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit +
t("hu_with") + " " +
strTimes + " " + t("times!");
t("hu_with") +
" " +
strTimes +
" " +
t("times!");
String title = step.toString() + ". " + t("Control Exercise:");
List<Widget> listWidgets = [
Text(
title,
@ -168,9 +156,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
minValue: 0,
maxValue: 200,
step: 1,
onChanged: (value) => {
exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))
},
onChanged: (value) => {exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))},
listViewHeight: 80,
//decoration: _decoration,
),
@ -181,9 +167,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
focusColor: Colors.blueAccent,
onPressed: () => {
exerciseBloc.add(ExerciseControlSubmit(step: step)),
if ( step == 3 ) {
confirmationDialog(exerciseBloc)
}
if (step == 3) {confirmationDialog(exerciseBloc)}
},
child: Text(
t("Save"),
@ -191,52 +175,48 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
)),
],
),
];
return
Column(
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: listWidgets,
);
}
void confirmationDialog( ExerciseControlBloc bloc ) {
void confirmationDialog(ExerciseControlBloc bloc) {
String unit = t(bloc.exerciseRepository.exerciseType.unit);
showCupertinoDialog(
useRootNavigator: true,
context: context,
//barrierDismissible: false,
builder:(_) => CupertinoAlertDialog(
builder: (_) => CupertinoAlertDialog(
title: Text(t("Summary of your test")),
content: Column(
children: [
Text(t("Test") + ": " + bloc.repeats[1].toStringAsFixed(0) + "x" + bloc.repeats[0].toStringAsFixed(0) + " " + unit ,
style: (TextStyle(color: Colors.blue)),),
content: Column(children: [
Text(
t("Test") + ": " + bloc.repeats[1].toStringAsFixed(0) + "x" + bloc.repeats[0].toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Divider(),
Text(t("1st Control") + ": " + bloc.repeats[2].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit ,
style: (TextStyle(color: Colors.blue)),),
Text(t("2nd Control") + ": " + bloc.repeats[3].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit ,
style: (TextStyle(color: Colors.blue)),),
Text(t("3rd Control") + ": " + bloc.repeats [4].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit ,
style: (TextStyle(color: Colors.blue)),),
Text(
t("1st Control") + ": " + bloc.repeats[2].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Text(
t("2nd Control") + ": " + bloc.repeats[3].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
Text(
t("3rd Control") + ": " + bloc.repeats[4].toStringAsFixed(0) + "x" + bloc.unitQuantity.toStringAsFixed(0) + " " + unit,
style: (TextStyle(color: Colors.blue)),
),
]),
actions: [
FlatButton(
child: Text(t("OK")),
onPressed: () => {
Navigator.of(context).pop(),
Navigator.of(context).pop()
},
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pop()},
)
],
)
);
));
}
}

View File

@ -14,12 +14,11 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ExerciseExecutePlanAddPage extends StatefulWidget{
class ExerciseExecutePlanAddPage extends StatefulWidget {
_ExerciseExecuteAddPage createState() => _ExerciseExecuteAddPage();
}
class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Trans {
@override
Widget build(BuildContext context) {
LinkedHashMap arguments = ModalRoute.of(context).settings.arguments;
@ -31,57 +30,44 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
setContext(context);
return BlocProvider(
create: (context) =>
ExerciseExecutePlanAddBloc(
create: (context) => ExerciseExecutePlanAddBloc(
exerciseRepository: exerciseRepository,
exercisePlanRepository: planBloc.exercisePlanRepository,
customerId: customerId,
workoutTree: workoutTree,
planBloc: planBloc),
child: BlocConsumer<ExerciseExecutePlanAddBloc, ExerciseExecutePlanAddState>(
listener: (context, state) {
child: BlocConsumer<ExerciseExecutePlanAddBloc, ExerciseExecutePlanAddState>(listener: (context, state) {
if (state is ExerciseExecutePlanAddError) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content:
Text(state.message, style: TextStyle(color: Colors.white))));
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is ExerciseExecutePlanAddLoading) {
return LoadingDialog();
}
},
builder: (context, state) {
}, builder: (context, state) {
// ignore: close_sinks
final exerciseBloc = BlocProvider.of<ExerciseExecutePlanAddBloc>(context);
if ( state is ExerciseExecutePlanAddLoading ) {
if (state is ExerciseExecutePlanAddLoading) {
return LoadingDialog();
} else if ( state is ExerciseExecutePlanAddReady) {
} else if (state is ExerciseExecutePlanAddReady) {
return getControlForm(exerciseBloc);
} else {
return getControlForm(exerciseBloc);
}
}
));
}));
}
Form getControlForm( ExerciseExecutePlanAddBloc exerciseBloc) {
String exerciseName = AppLanguage().appLocal == Locale("en") ?
exerciseBloc.exerciseRepository.exerciseType.name :
exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
Form getControlForm(ExerciseExecutePlanAddBloc exerciseBloc) {
String exerciseName = AppLanguage().appLocal == Locale("en")
? exerciseBloc.exerciseRepository.exerciseType.name
: exerciseBloc.exerciseRepository.exerciseType.nameTranslation;
return Form(
autovalidate: true,
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarNav(depth: 1),
body: Container(
width: MediaQuery
.of(context)
.size
.width,
height: MediaQuery
.of(context)
.size
.height,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_light_background.png'),
@ -90,68 +76,76 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
),
),
child: Container(
padding: const EdgeInsets.only (top: 25, left: 25, right: 25),
padding: const EdgeInsets.only(top: 25, left: 25, right: 25),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
controller: ScrollController(
initialScrollOffset: exerciseBloc.scrollOffset,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
Text(t("Save Exercise")),
Text(exerciseName,
style: TextStyle(fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.deepOrange),
Text(
exerciseName,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange),
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: true,
),
Divider(color: Colors.transparent,),
Divider(
color: Colors.transparent,
),
Divider(),
Column(
children: repeatExercises(exerciseBloc),
),
Divider(),
]),
)
)
),
))),
),
);
}
List<Column> repeatExercises(ExerciseExecutePlanAddBloc exerciseBloc) {
List<Column> listColumns = List<Column>();
for ( int i = 0; i < exerciseBloc.countSteps; i++) {
for (int i = 0; i < exerciseBloc.countSteps; i++) {
Column col = Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(color: Colors.transparent,),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: [
Text(t("Execute the") + " ",style: TextStyle(fontWeight: FontWeight.bold),),
Text((i+1).toString() + ". ",style: TextStyle(fontSize:24, fontWeight: FontWeight.bold),),
Text(t("set!"),style: TextStyle(fontWeight: FontWeight.bold),),
Text(
t("Execute the") + " ",
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
(i + 1).toString() + ". ",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Text(
t("set!"),
style: TextStyle(fontWeight: FontWeight.bold),
),
],
),
Divider(color: Colors.transparent,),
Text(t("Please repeat with") + " "+ exerciseBloc.unitQuantity.toStringAsFixed(0) + " " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " +
exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() + " " + t("times!")),
Row(
children: [
Divider(
color: Colors.transparent,
),
Text(t("Please repeat with") +
" " +
exerciseBloc.unitQuantity.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit +
" " +
exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() +
" " +
t("times!")),
Row(children: [
NumberPicker.horizontal(
highlightSelectedValue: (i + 1) == exerciseBloc.step,
initialValue: exerciseBloc.unitQuantity.toInt(),
@ -160,38 +154,27 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 24, color: Colors.indigo, fontWeight: FontWeight.bold),
onChanged: (value) => {
exerciseBloc.add(ExerciseExecutePlanAddChangeUnitQuantity(quantity: value.toDouble()))
},
onChanged: (value) => {exerciseBloc.add(ExerciseExecutePlanAddChangeUnitQuantity(quantity: value.toDouble()))},
listViewHeight: 80,
//decoration: _decoration,
),
Text(exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit),
]
),
Row(
children: [
]),
Row(children: [
NumberPicker.horizontal(
highlightSelectedValue: (i+1) == exerciseBloc.step,
highlightSelectedValue: (i + 1) == exerciseBloc.step,
initialValue: exerciseBloc.quantity.toInt(),
minValue: 0,
maxValue: 200,
step: 1,
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyleHighlighted: TextStyle(fontSize: 24, color: Colors.deepOrange, fontWeight: FontWeight.bold),
onChanged: (value) => {
exerciseBloc.add(ExerciseExecutePlanAddChangeQuantity(quantity: value.toDouble()))
},
onChanged: (value) => {exerciseBloc.add(ExerciseExecutePlanAddChangeQuantity(quantity: value.toDouble()))},
listViewHeight: 80,
//decoration: _decoration,
),
Text(t("repeat")),
]
),
]),
/*TextFieldBlocBuilder(
readOnly: exerciseBloc.step != i+1,
@ -239,25 +222,19 @@ class _ExerciseExecuteAddPage extends State<ExerciseExecutePlanAddPage> with Tra
),
),*/
RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.white,
color: exerciseBloc.step == i+1 ? Colors.blue : Colors.black26,
color: exerciseBloc.step == i + 1 ? Colors.blue : Colors.black26,
focusColor: Colors.blueAccent,
onPressed: () =>
{
print ("Submit step " + exerciseBloc.step.toString() + " (i) " + i.toString()),
if ( exerciseBloc.step == i+1 ) {
exerciseBloc.add(ExerciseExecutePlanAddSubmit())
},
if ( i+1 == exerciseBloc.countSteps) {
Navigator.of(context).pop()
}
onPressed: () => {
print("Submit step " + exerciseBloc.step.toString() + " (i) " + i.toString()),
if (exerciseBloc.step == i + 1) {exerciseBloc.add(ExerciseExecutePlanAddSubmit())},
if (i + 1 == exerciseBloc.countSteps) {Navigator.of(context).pop()}
},
child: Text(
t("Save"),
style: TextStyle(fontSize: 12),)
),
style: TextStyle(fontSize: 12),
)),
Divider(),
],
);

View File

@ -1,10 +1,6 @@
import 'package:aitrainer_app/bloc/login_form_bloc.dart';
import 'package:aitrainer_app/bloc/account/account_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/service/firebase_api.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/splash.dart';
@ -69,20 +65,14 @@ class ResetPasswordPage extends StatelessWidget with Trans {
key: _formKey,
child: Container(
padding: const EdgeInsets.only(left: 25, right: 50),
child: ListView(
shrinkWrap: false,
padding: EdgeInsets.only(top: 150.0),
children: <Widget>[
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0), children: <Widget>[
Divider(),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new InkWell(
child: new Text(
AppLocalizations.of(context)
.translate('I forgot the password'),
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 24)),
child: new Text(AppLocalizations.of(context).translate('I forgot the password'),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
),
],
),
@ -102,24 +92,18 @@ class ResetPasswordPage extends StatelessWidget with Trans {
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[
new FlatButton(
key: LibraryKeys.loginOKButton,
child: Image.asset('asset/image/WT_OK.png',
width: 100, height: 100),
child: Image.asset('asset/image/WT_OK.png', width: 100, height: 100),
onPressed: () => {formBloc.add(SubmitFormBloc())}),
]),
Divider(
color: Colors.transparent,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
new InkWell(
child: new Text(
AppLocalizations.of(context).translate('Login')),
child: new Text(AppLocalizations.of(context).translate('Login')),
onTap: () => Navigator.of(context).pushNamed('login'),
),
Spacer(flex: 1),
@ -129,8 +113,7 @@ class ResetPasswordPage extends StatelessWidget with Trans {
}
void showInSnackBar(String error) {
_scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(error, style: TextStyle(color: Colors.white))));
_scaffoldKey.currentState
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(error, style: TextStyle(color: Colors.white))));
}
}

View File

@ -1,21 +1,11 @@
import 'dart:async';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:rainbow_color/rainbow_color.dart';
// ignore: must_be_immutable
class AppBarMin extends StatefulWidget implements PreferredSizeWidget {
bool back = false;
AppBarMin({this.back = false });
AppBarMin({this.back = false});
@override
_AppBarNav createState() => _AppBarNav();
@ -32,7 +22,6 @@ class _AppBarNav extends State<AppBarMin> with Common {
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.black,
title: Row(
@ -47,19 +36,14 @@ class _AppBarNav extends State<AppBarMin> with Common {
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: widget.back ? Colors.white : Colors.black),
onPressed: () =>
{
if ( widget.back ) {
Navigator.of(context).pop()
}
onPressed: () => {
if (widget.back) {Navigator.of(context).pop()}
},
)
);
));
}
@override
void dispose() {
super.dispose();
}
}

View File

@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:animated_widgets/widgets/rotation_animated.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@ -70,6 +71,7 @@ class _BMIState extends State<BMI> with Trans {
@override
Widget build(BuildContext context) {
setContext(context);
Flurry.logEvent("BMI");
widget.exerciseBloc.getBMI();
return Form(
child: Scaffold(
@ -91,7 +93,7 @@ class _BMIState extends State<BMI> with Trans {
child:
Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
getWeightInput(),
Text(AppLocalizations.of(context).translate("Body Mass Index"),
Text(t("Body Mass Index"),
style: GoogleFonts.archivoBlack(
shadows: <Shadow>[
Shadow(

View File

@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/exercise_new/exercise_new_bloc.dart';
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@ -74,6 +75,7 @@ class _BMRState extends State<BMR> with Trans {
@override
Widget build(BuildContext context) {
setContext(context);
Flurry.logEvent("BMR");
return Form(
child: Scaffold(
resizeToAvoidBottomInset: true,

View File

@ -1,4 +1,8 @@
import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:badges/badges.dart';
import 'package:flurry/flurry.dart';
import 'package:flutter/material.dart';
import 'package:gradient_bottom_navigation_bar/gradient_bottom_navigation_bar.dart';
@ -13,7 +17,7 @@ class BottomNavigator extends StatefulWidget {
_NawDrawerWidget createState() => _NawDrawerWidget();
}
class _NawDrawerWidget extends State<BottomNavigator> {
class _NawDrawerWidget extends State<BottomNavigator> with Trans {
@override
void initState() {
super.initState();
@ -25,32 +29,19 @@ class _NawDrawerWidget extends State<BottomNavigator> {
final Color bgrColorEnd = Colors.blue;
final Color active = Colors.black;
final Color inactive = Colors.black26;
/*final Color bgrColor = Colors.black;
final Color active = Colors.yellowAccent;
final Color inactive = Colors.white60;*/
//
setContext(context);
return GradientBottomNavigationBar(
currentIndex:
widget.bottomNavIndex, // this will be set when a new tab is tapped
currentIndex: widget.bottomNavIndex, // this will be set when a new tab is tapped
backgroundColorStart: bgrColorEnd,
backgroundColorEnd: bgrColor,
fixedColor: active,
//selectedItemColor: active,
//unselectedItemColor: inactive,
//showSelectedLabels: true,
//showUnselectedLabels: true,
items: [
BottomNavigationBarItem(
backgroundColor: bgrColor,
icon: new Icon(Icons.home, color: inactive),
activeIcon: new Icon(
Icons.home,
color: active,
),
title: new Text(AppLocalizations.of(context).translate("Home"),
style: TextStyle(fontSize: 9)),
icon: badgedIcon(inactive, Icons.home, "home"),
activeIcon: badgedIcon(active, Icons.home, "home"),
title: new Text(t("Home"), style: TextStyle(fontSize: 12)),
),
BottomNavigationBarItem(
backgroundColor: bgrColor,
@ -60,8 +51,8 @@ class _NawDrawerWidget extends State<BottomNavigator> {
color: active,
),
title: new Text(
AppLocalizations.of(context).translate("My Development"),
style: TextStyle(fontSize: 9),
t("My Development"),
style: TextStyle(fontSize: 12),
),
),
BottomNavigationBarItem(
@ -72,23 +63,17 @@ class _NawDrawerWidget extends State<BottomNavigator> {
color: active,
),
title: new Text(
AppLocalizations.of(context).translate("My Training Plan"),
style: TextStyle(fontSize: 9),
t("My Training Plan"),
style: TextStyle(fontSize: 12),
),
),
BottomNavigationBarItem(
backgroundColor: bgrColor,
icon: Icon(
Icons.person,
color: inactive,
),
activeIcon: new Icon(
Icons.person,
color: active,
),
icon: badgedIcon(inactive, Icons.person, "account"),
activeIcon: badgedIcon(active, Icons.person, "account"),
title: Text(
AppLocalizations.of(context).translate("Account"),
style: TextStyle(fontSize: 9),
style: TextStyle(fontSize: 12),
)),
BottomNavigationBarItem(
backgroundColor: bgrColor,
@ -97,8 +82,7 @@ class _NawDrawerWidget extends State<BottomNavigator> {
Icons.settings,
color: active,
),
title: Text(AppLocalizations.of(context).translate("Settings"),
style: TextStyle(fontSize: 9)))
title: Text(t("Settings"), style: TextStyle(fontSize: 12)))
],
onTap: (index) {
setState(() {
@ -106,25 +90,30 @@ class _NawDrawerWidget extends State<BottomNavigator> {
switch (index) {
case 0:
Navigator.of(context).pop();
Flurry.logEvent("Home");
Navigator.of(context).pushNamed('home');
break;
case 1:
Navigator.of(context).pop();
Flurry.logEvent("myDevelopment");
Navigator.of(context).pushNamed('myDevelopment');
break;
case 2:
Navigator.of(context).pop();
Flurry.logEvent("myExercisePlan");
Navigator.of(context).pushNamed('myExercisePlan');
break;
case 3:
Navigator.of(context).pop();
Flurry.logEvent("Account");
Navigator.of(context).pushNamed('account');
break;
case 4:
Navigator.of(context).pop();
Flurry.logEvent("Settings");
Navigator.of(context).pushNamed('settings');
break;
@ -132,4 +121,24 @@ class _NawDrawerWidget extends State<BottomNavigator> {
});
});
}
Widget badgedIcon(Color color, IconData icon, String badgeKey) {
bool show = Cache().getBadges()[badgeKey] != null;
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
return Badge(
position: BadgePosition.topEnd(top: -10, end: -10),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.red,
showBadge: show,
badgeContent: Text(
counter.toString(),
style: TextStyle(color: Colors.white),
),
child: Icon(
icon,
color: color,
),
);
}
}

View File

@ -1,7 +1,10 @@
import 'dart:ui';
import 'package:aitrainer_app/model/cache.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:bloc/bloc.dart';
import 'package:google_fonts/google_fonts.dart';
// ignore: must_be_immutable
class ImageButton extends StatelessWidget {
@ -10,13 +13,15 @@ class ImageButton extends StatelessWidget {
final String image;
final double top;
final double left;
final double height;
double width = 180;
final bool isShape;
double height;
double width;
bool isShape;
final Bloc bloc;
final Alignment textAlignment;
final VoidCallback onTap;
bool isLocked;
bool isMarked;
int buttonIndex;
ImageButton(
{this.text,
@ -30,20 +35,23 @@ class ImageButton extends StatelessWidget {
this.isShape,
this.textAlignment,
this.onTap,
this.buttonIndex,
this.isMarked,
@required this.isLocked}) {
width = width ?? 180;
style = style ?? TextStyle(fontSize: 14, fontFamily: "Roboto Mono");
height = height ?? 180;
isMarked = isMarked ?? false;
style = style ??
GoogleFonts.archivoBlack(
fontSize: 14,
);
}
@override
Widget build(BuildContext context) {
double top = width - (style.fontSize - 5) * text.length - 2 * left < 0
? width - 2 * style.fontSize - 10
: width - style.fontSize - 10;
print("Top: " +
top.toStringAsFixed(0) +
" length: " +
((style.fontSize - 5) * text.length).toString());
double top =
height - (style.fontSize - 5) * text.length - 2 * left < 0 ? height - 2 * style.fontSize - 22 : height - style.fontSize - 17;
//print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString());
return Stack(
//alignment: textAlignment,
fit: StackFit.passthrough,
@ -52,24 +60,27 @@ class ImageButton extends StatelessWidget {
FlatButton(
child: image == null
? _getButtonImage("asset/image/WT_menu_dark.png")
: isMarked
? Stack(
children: [
_getButtonImage(image),
Container(
width: width,
height: height,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 1, sigmaY: 1),
child: Container(
color: Colors.black.withOpacity(0.3),
),
),
)
],
)
: _getButtonImage(image),
padding: EdgeInsets.only(left: 0.0, bottom: 0),
shape: getShape(isShape),
onPressed: onTap ?? onTap,
),
Stack(alignment: Alignment.topLeft, children: [
Positioned(
top: 50,
left: 50,
child: this.isLocked
? Image.asset(
'asset/image/lock.png',
height: 60,
width: 60,
)
: Container(),
)
]),
Positioned(
top: top,
left: left,
@ -87,6 +98,31 @@ class ImageButton extends StatelessWidget {
color: Colors.transparent,
),
),
Stack(alignment: Alignment.topLeft, children: [
Positioned(
top: height / 2 - 30,
left: width / 2 - 30,
child: this.isLocked
? GestureDetector(
child: Image.asset(
'asset/image/lock.png',
height: 60,
width: 60,
),
onTap: onTap ?? onTap,
)
: isMarked
? GestureDetector(
child: Image.asset(
'asset/image/haken.png',
height: 70,
width: 70,
),
onTap: onTap ?? onTap,
)
: Container(),
)
]),
]
//)
// )
@ -110,12 +146,8 @@ class ImageButton extends StatelessWidget {
fit: BoxFit.fitWidth,
alignment: Alignment.center,
errorBuilder: (context, error, stackTrace) {
String url = Cache.mediaUrl + 'images/' + imageName.substring(11);
Widget image = FadeInImage.assetNetwork(
placeholder: 'asset/image/dots.gif',
image: url,
height: 180,
);
String url = Cache.mediaUrl + '/' + imageName; //.substring(11);
Widget image = FadeInImage.assetNetwork(placeholder: 'asset/image/dots.gif', image: url, height: this.height);
return image;
},
);
@ -124,7 +156,7 @@ class ImageButton extends StatelessWidget {
image = FadeInImage.assetNetwork(
placeholder: 'asset/image/dots.gif',
image: url,
height: 180,
height: 50,
);
}

View File

@ -5,6 +5,7 @@ import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:badges/badges.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
@ -24,15 +25,13 @@ class MenuPageWidget extends StatelessWidget with Trans {
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
setContext(context);
return CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[buildMenuColumn(parent, context, menuBloc)]);
return CustomScrollView(scrollDirection: Axis.vertical, slivers: <Widget>[buildMenuColumn(parent, context, menuBloc)]);
}
SliverList buildMenuColumn(int parent, BuildContext context, MenuBloc menuBloc) {
final List<Widget> _columnChildren = List();
if ( context != null ) {
if (context != null) {
menuBloc.setContext(context);
menuBloc.setMenuInfo();
@ -52,20 +51,16 @@ class MenuPageWidget extends StatelessWidget with Trans {
_columnChildren.add(info);
}
menuBloc.menuTreeRepository
.getBranch(menuBloc.parent)
.forEach((treeName, value) {
menuBloc.menuTreeRepository.getBranch(menuBloc.parent).forEach((treeName, value) {
WorkoutMenuTree workoutTree = value as WorkoutMenuTree;
_columnChildren.add(Container(
padding: EdgeInsets.only(top: 16.0),
child: Center(
child: Stack(
alignment: Alignment.bottomLeft,
child: Stack(alignment: Alignment.bottomLeft,
//clipBehavior: Clip.antiAliasWithSaveLayer,
children: [
FlatButton(
child: _getButtonImage(workoutTree),
child: badgedIcon(workoutTree),
padding: EdgeInsets.only(left: 0.0, bottom: 0),
shape: getShape(workoutTree),
onPressed: () => menuClick(workoutTree, menuBloc, context),
@ -77,7 +72,7 @@ class MenuPageWidget extends StatelessWidget with Trans {
height: 300,
width: 280,
child: InkWell(
onTap:() => menuClick(workoutTree, menuBloc, context),
onTap: () => menuClick(workoutTree, menuBloc, context),
child: Text(
" " + workoutTree.name,
maxLines: 2,
@ -86,28 +81,20 @@ class MenuPageWidget extends StatelessWidget with Trans {
fontSize: workoutTree.fontSize,
),
),
highlightColor: workoutTree.color,
),
color: Colors.transparent,
),
),
]
)
)
)
);
]))));
});
SliverList sliverList =
SliverList(delegate: SliverChildListDelegate(_columnChildren));
SliverList sliverList = SliverList(delegate: SliverChildListDelegate(_columnChildren));
return sliverList;
}
void menuClick(
WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc, BuildContext context) {
print("Hi!, Menu clicked " + workoutTree.id.toString());
if (workoutTree.child == false) {
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
@ -116,16 +103,12 @@ class MenuPageWidget extends StatelessWidget with Trans {
if (Cache().userLoggedIn == null) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(
AppLocalizations.of(context).translate('Please log in'),
style: TextStyle(color: Colors.white))));
content: Text(AppLocalizations.of(context).translate('Please log in'), style: TextStyle(color: Colors.white))));
} else {
if (workoutTree.exerciseType.name == "Custom" && Cache().userLoggedIn.admin == 1) {
Navigator.of(context).pushNamed('exerciseCustomPage',
arguments: workoutTree.exerciseType);
Navigator.of(context).pushNamed('exerciseCustomPage', arguments: workoutTree.exerciseType);
} else {
Navigator.of(context).pushNamed('exerciseNewPage',
arguments: workoutTree.exerciseType);
Navigator.of(context).pushNamed('exerciseNewPage', arguments: workoutTree.exerciseType);
}
}
}
@ -148,8 +131,7 @@ class MenuPageWidget extends StatelessWidget with Trans {
workoutTree.imageName,
height: 180,
errorBuilder: (context, error, stackTrace) {
String url =
Cache.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
String url = Cache.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
Widget image = FadeInImage.assetNetwork(
placeholder: 'asset/image/dots.gif',
image: url,
@ -169,4 +151,24 @@ class MenuPageWidget extends StatelessWidget with Trans {
return image;
}
Widget badgedIcon(WorkoutMenuTree workoutMenuTree) {
String badgeKey = workoutMenuTree.nameEnglish;
bool show = Cache().getBadges()[badgeKey] != null;
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
return Badge(
padding: EdgeInsets.all(8),
position: BadgePosition.topEnd(top: 3, end: 3),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.red,
showBadge: show,
badgeContent: Text(counter.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 16,
)),
child: _getButtonImage(workoutMenuTree),
);
}
}

View File

@ -52,7 +52,7 @@ class _SizeState extends State<SizeWidget> with Trans {
List<Widget> getSizeFigure() {
double mediaWidth = MediaQuery.of(context).size.width * .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);
List<Widget> list = List();
list.add(GestureDetector(

View File

@ -43,6 +43,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.1"
badges:
dependency: "direct main"
description:
name: badges
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.4"
bloc:
dependency: transitive
description:
@ -70,14 +77,14 @@ packages:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
version: "1.5.1"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
version: "0.4.3"
build_daemon:
dependency: transitive
description:
@ -98,14 +105,14 @@ packages:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.4"
version: "1.10.6"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.3"
version: "6.1.1"
built_collection:
dependency: transitive
description:
@ -203,7 +210,7 @@ packages:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.9"
version: "1.3.10"
devicelocale:
dependency: "direct main"
description:
@ -217,7 +224,7 @@ packages:
name: dropdown_search
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.6"
version: "0.4.8"
equatable:
dependency: "direct main"
description:
@ -246,41 +253,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0-nullsafety.2"
firebase:
dependency: transitive
description:
name: firebase
url: "https://pub.dartlang.org"
source: hosted
version: "7.3.2"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
url: "https://pub.dartlang.org"
source: hosted
version: "0.18.1+2"
version: "0.18.3"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.3"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.1+1"
version: "0.3.2"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0+1"
version: "0.5.2"
firebase_core_platform_interface:
dependency: transitive
description:
@ -316,6 +316,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0"
flurry:
dependency: "direct main"
description:
name: flurry
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.7"
flutter:
dependency: "direct main"
description: flutter
@ -333,13 +340,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_facebook_auth:
dependency: "direct main"
description:
name: flutter_facebook_auth
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.3"
flutter_form_bloc:
dependency: "direct main"
description:
@ -492,7 +492,7 @@ packages:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
version: "3.1.1"
json_rpc_2:
dependency: transitive
description:
@ -1001,7 +1001,7 @@ packages:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.3"
version: "1.7.4"
xdg_directories:
dependency: transitive
description:

View File

@ -15,10 +15,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.2+2
version: 1.1.2+34
environment:
sdk: ">=2.7.0 <3.1.0"
sdk: ">=2.10.0 <3.0.0"
dependencies:
flutter:
@ -28,9 +28,9 @@ dependencies:
google_fonts: ^1.1.1
devicelocale: ^0.3.3
sentry: ^3.0.1
flutter_bloc: ^6.1.0
flutter_bloc: ^6.1.1
equatable: ^1.2.5
freezed: ^0.12.1
freezed: ^0.12.2
flutter_form_bloc: ^0.19.0
spider_chart: ^0.1.5
rainbow_color: ^0.1.1
@ -40,16 +40,19 @@ dependencies:
infinite_listview: ^1.0.1+1
toggle_switch: ^0.1.8
keyboard_actions: ^3.3.1+1
dropdown_search: ^0.4.6
dropdown_search: ^0.4.8
badges: ^1.1.4
firebase_core: 0.5.0+1
#firebase_analytics: ^6.0.2
firebase_core: ^0.5.2
#firebase_analytics: ^6.2.0
firebase_messaging: ^7.0.3
firebase_auth: ^0.18.1+2
flutter_facebook_auth: ^0.3.3
firebase_auth: ^0.18.3
#flutter_facebook_auth: ^1.0.1
flurry: ^0.0.7
animated_widgets: ^1.0.6
mockito: ^4.1.1
mockito: ^4.1.3
flutter_localizations:
sdk: flutter
@ -63,9 +66,9 @@ dev_dependencies:
build_runner:
http: 0.12.1
intl: 0.16.1
shared_preferences: ^0.5.12+2
http: ^0.12.1
intl: ^0.16.1
shared_preferences: ^0.5.12+4
flutter_launcher_icons: ^0.8.1
@ -126,6 +129,27 @@ flutter:
- asset/image/BMI_diagram_b.png
- asset/image/BMI_graph_c.png
- asset/image/BMI_mutato.png
- asset/image/equipment_specialshome.jpg
- asset/image/equipment_none.jpg
- asset/image/equipment_cables.jpg
- asset/image/equipment_weightplates.jpg
- asset/image/equipment_kettlebells.jpg
- asset/image/equipment_bands.jpg
- asset/image/equipment_ez-baar_.jpg
- asset/image/equipment_exerciseball.jpg
- asset/image/equipment_strap.jpg
- asset/image/equipment_roll.jpg
- asset/image/equipment_instabils.jpg
- asset/image/equipment_medicine.jpg
- asset/image/equipment_rope.jpg
- asset/image/equipment_home.jpg
- asset/image/equipment_baar.jpg
- asset/image/equipment_others.jpg
- asset/image/equipment_barbells.jpg
- asset/image/equipment_machine.jpg
- asset/image/equipment_street.jpg
- asset/image/equipment_dumbbells.jpg
- asset/image/haken.png
- asset/menu/1.cardio.png
- asset/menu/1.1.aerob.png
- asset/menu/1.2.anaerob.png

View File

@ -2,6 +2,7 @@ import 'package:aitrainer_app/bloc/exercise_plan/exercise_plan_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:test/test.dart';
@ -65,17 +66,14 @@ main() {
bloc.customerId = 101;
bloc.add(ExercisePlanLoad());
final expectedResponse = [
ExercisePlanLoading(),
ExercisePlanReady()
];
final expectedResponse = [ExercisePlanLoading(), ExercisePlanReady()];
expectLater(
bloc,
emitsInOrder(expectedResponse),
).then((_) {
expect(bloc.exercisePlanRepository.newPlan, false);
expect(bloc.exercisePlanRepository.exercisePlan.name, "Test Plan2" );
expect(bloc.exercisePlanRepository.exercisePlan.name, "Test Plan2");
expect(bloc.exercisePlanRepository.exercisePlanDetails[4].weightEquation, "95");
expect(Cache().getMyExercisePlan().name, "Test Plan2");
expect(Cache().getMyExercisePlanDetails()[4].weightEquation, "95");
@ -93,14 +91,9 @@ main() {
detail4.weightEquation = "55";
detail4.serie = 3;
bloc.add(ExercisePlanAddExercise(exercisePlanDetail: detail4));
final expectedResponse2 = [
ExercisePlanLoading(),
ExercisePlanReady()
];
final expectedResponse2 = [ExercisePlanLoading(), ExercisePlanReady()];
expectLater(
bloc,
@ -110,10 +103,8 @@ main() {
expect(bloc.exercisePlanRepository.exercisePlan.customerId, 101);
expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 3);
expect(bloc.exercisePlanRepository.exercisePlanDetails[5].repeats, 20);
expect(bloc.exercisePlanRepository.exercisePlanDetails[5].change, ExercisePlanDetailChange.add);
expect(Cache()
.getMyExercisePlan()
.name, "Test Plan2");
expect(bloc.exercisePlanRepository.exercisePlanDetails[5].change, ModelChange.add);
expect(Cache().getMyExercisePlan().name, "Test Plan2");
expect(Cache().getMyExercisePlanDetails()[5].weightEquation, "55");
expect(Cache().getMyExercisePlanDetails()[5].repeats, 20);
});
@ -127,10 +118,7 @@ main() {
bloc.add(ExercisePlanAddExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));
final expectedResponse2 = [
ExercisePlanLoading(),
ExercisePlanReady()
];
final expectedResponse2 = [ExercisePlanLoading(), ExercisePlanReady()];
expectLater(
bloc,
@ -140,7 +128,6 @@ main() {
expect(bloc.exercisePlanRepository.exercisePlanDetails[3].repeats, 25);
expect(Cache().getMyExercisePlanDetails()[3].repeats, 25);
});
});
test('Delete bloc', () async {
bloc.customerId = 101;
@ -148,10 +135,7 @@ main() {
bloc.exercisePlanRepository.getExercisePlanDetails();
bloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: bloc.exercisePlanRepository.exercisePlanDetails[3]));
final expectedResponse2 = [
ExercisePlanLoading(),
ExercisePlanReady()
];
final expectedResponse2 = [ExercisePlanLoading(), ExercisePlanReady()];
expectLater(
bloc,
@ -184,7 +168,5 @@ main() {
expect(bloc.exercisePlanRepository.exercisePlanDetails.length, 0);
});*/
});
});
});
}

View File

@ -1,16 +1,15 @@
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:test/test.dart';
import 'mocks.dart';
main() {
SimExercisePlanRepository _exercisePlanRepository;
int _customerId;
Future<void> setUpPlan() async {
final String planName2 = "Test Plan2";
ExercisePlan plan2 = ExercisePlan(planName2, 101);
_exercisePlanRepository.setCustomerId(101);
@ -40,8 +39,6 @@ main() {
await setUpPlan();
});
group('New Plan', () {
test('add new plan and plan details and save', () async {
final String planName = "Boss Test Plan";
@ -69,11 +66,8 @@ main() {
expect(_exercisePlanRepository.getExercisePlan().name, planName);
expect(_exercisePlanRepository.getExercisePlan().exercisePlanId > 0, true);
ExercisePlanDetail detail =
_exercisePlanRepository.getExercisePlanDetailByExerciseId(55);
ExercisePlanDetail detail = _exercisePlanRepository.getExercisePlanDetailByExerciseId(55);
expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan().exercisePlanId);
});
test('save new plan and plan details second', () async {
int customerId = 100;
@ -104,23 +98,21 @@ main() {
ExercisePlanDetail detail = _exercisePlanRepository.getExercisePlanDetailByExerciseId(13);
expect(detail.exercisePlanId, _exercisePlanRepository.getExercisePlan().exercisePlanId);
expect(detail.repeats, 33);
});
});
group('Existing Plan', () {
test('Get Last Plan and Details from DB', () async {
ExercisePlan exercisePlan = await _exercisePlanRepository.getLastExercisePlan();
expect(exercisePlan.customerId,101);
expect(exercisePlan.customerId, 101);
await _exercisePlanRepository.getExercisePlanDetails();
expect(_exercisePlanRepository.exercisePlanDetails[3].repeats,23 );
expect(_exercisePlanRepository.exercisePlanDetails[4].weightEquation,"95" );
expect(_exercisePlanRepository.exercisePlanDetails[3].repeats, 23);
expect(_exercisePlanRepository.exercisePlanDetails[4].weightEquation, "95");
//Test Cache
expect(Cache().getMyExercisePlan().name,"Test Plan2");
expect(Cache().getMyExercisePlanDetails()[3].weightEquation,"60");
expect(Cache().getMyExercisePlan().name, "Test Plan2");
expect(Cache().getMyExercisePlanDetails()[3].weightEquation, "60");
});
test('Add new PlanDetail', () async {
@ -138,20 +130,14 @@ main() {
expect(_exercisePlanRepository.getExercisePlan().name, "Test Plan2");
expect(Cache().getMyExercisePlanDetails()[5].weightEquation, "105");
expect(Cache().getMyExercisePlanDetails()[5].repeats, 6);
});
test('Delete from PlanDetails', () async {
_exercisePlanRepository.removeExerciseTypeFromPlanByExerciseTypeId(4);
_exercisePlanRepository.saveExercisePlan();
expect(_exercisePlanRepository.exercisePlanDetails[4].change, ExercisePlanDetailChange.delete);
expect(_exercisePlanRepository.exercisePlanDetails[4].change, ModelChange.delete);
expect(Cache().getMyExercisePlanDetails()[4], isNull);
});
});
}

View File

@ -3,6 +3,7 @@ import 'dart:collection';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/repository/exercise_plan_repository.dart';
import 'package:aitrainer_app/service/exercise_plan_service.dart';
import 'package:mockito/mockito.dart';
@ -33,7 +34,7 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
Future<ExercisePlanDetail> updateExercisePlanDetail(ExercisePlanDetail detail, int planDetailId) async {
ExercisePlanDetail updated;
memoryExercisePlanDetail.forEach((element) {
if ( element.exercisePlanDetailId == planDetailId ) {
if (element.exercisePlanDetailId == planDetailId) {
element = detail;
}
});
@ -45,12 +46,12 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
int index = -1;
int countIndex = 0;
memoryExercisePlanDetail.forEach((element) {
if ( element.exercisePlanId == exercisePlanId ) {
if (element.exercisePlanId == exercisePlanId) {
index = countIndex;
}
countIndex++;
});
if ( index > -1) {
if (index > -1) {
memoryExercisePlanDetail.removeAt(index);
}
}
@ -58,7 +59,7 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
Future<List<ExercisePlanDetail>> getExercisePlanDetail(int exercisePlanId) async {
List<ExercisePlanDetail> foundList = List();
memoryExercisePlanDetail.forEach((element) {
if ( element.exercisePlanId == exercisePlanId ) {
if (element.exercisePlanId == exercisePlanId) {
foundList.add(element);
}
});
@ -68,7 +69,7 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
Future<ExercisePlan> getLastExercisePlan(int customerId) async {
ExercisePlan found;
memoryExercisePlan.forEach((element) {
if ( element.customerId == customerId ) {
if (element.customerId == customerId) {
found = element;
}
});
@ -77,11 +78,10 @@ class MockExercisePlanApi extends Mock implements ExercisePlanApi {
}
class SimExercisePlanRepository with ExercisePlanRepository {
Future<void> getExercisePlanDetails() async {
if (exercisePlan == null) {
ExercisePlan exercisePlan = await this.getLastExercisePlan();
if ( exercisePlan == null ) {
if (exercisePlan == null) {
exercisePlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
return;
}
@ -89,7 +89,7 @@ class SimExercisePlanRepository with ExercisePlanRepository {
List<ExercisePlanDetail> list = List();
LinkedHashMap<int, ExercisePlanDetail> listCache = Cache().getMyExercisePlanDetails();
if ( listCache.length > 0) {
if (listCache.length > 0) {
exercisePlanDetails = listCache;
return;
} else {
@ -109,11 +109,11 @@ class SimExercisePlanRepository with ExercisePlanRepository {
}
Future<ExercisePlan> getLastExercisePlan() async {
if ( customerId == 0) {
if (customerId == 0) {
return null;
}
ExercisePlan myExercisePlan = Cache().getMyExercisePlan();
if ( myExercisePlan != null ) {
if (myExercisePlan != null) {
newPlan = false;
return myExercisePlan;
}
@ -125,13 +125,13 @@ class SimExercisePlanRepository with ExercisePlanRepository {
}
Future<void> saveExercisePlan() async {
if ( exercisePlan == null ) {
if ( Cache().userLoggedIn == null ) {
if (exercisePlan == null) {
if (Cache().userLoggedIn == null) {
throw Exception("please log in");
}
String exercisePlanName;
if ( this.customerId == Cache().userLoggedIn.customerId) {
if (this.customerId == Cache().userLoggedIn.customerId) {
exercisePlanName = Cache().userLoggedIn.name + " private";
} else {
exercisePlanName = Cache().getTrainee().name + " " + Cache().getTrainee().firstname + " private";
@ -139,13 +139,11 @@ class SimExercisePlanRepository with ExercisePlanRepository {
exercisePlan = ExercisePlan(exercisePlanName, this.customerId);
}
if ( newPlan ) {
if (newPlan) {
exercisePlan.dateAdd = DateTime.now();
exercisePlan.private = true;
ExercisePlan savedExercisePlan
= await MockExercisePlanApi().saveExercisePlan(exercisePlan);
ExercisePlan savedExercisePlan = await MockExercisePlanApi().saveExercisePlan(exercisePlan);
LinkedHashMap<int, ExercisePlanDetail> savedExercisePlanDetails = LinkedHashMap();
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
@ -158,21 +156,17 @@ class SimExercisePlanRepository with ExercisePlanRepository {
exercisePlan = savedExercisePlan;
} else {
await MockExercisePlanApi().updateExercisePlan(exercisePlan, exercisePlan.exercisePlanId);
exercisePlanDetails.forEach((exerciseTypeId, exercisePlanDetail) async {
if ( exercisePlanDetail.change == ExercisePlanDetailChange.delete ) {
await MockExercisePlanApi()
.deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
if (exercisePlanDetail.change == ModelChange.delete) {
await MockExercisePlanApi().deleteExercisePlanDetail(exercisePlanDetail.exercisePlanDetailId);
Cache().deleteMyExercisePlanDetail(exercisePlanDetail);
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.update ) {
await MockExercisePlanApi()
.updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
} else if (exercisePlanDetail.change == ModelChange.update) {
await MockExercisePlanApi().updateExercisePlanDetail(exercisePlanDetail, exercisePlanDetail.exercisePlanDetailId);
Cache().updateMyExercisePlanDetail(exercisePlanDetail);
} else if ( exercisePlanDetail.change == ExercisePlanDetailChange.add ) {
await MockExercisePlanApi()
.saveExercisePlanDetail(exercisePlanDetail);
} else if (exercisePlanDetail.change == ModelChange.add) {
await MockExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
Cache().addToMyExercisePlanDetails(exercisePlanDetail);
}
});