diff --git a/asset/image/WT_reg_light_background.png b/asset/image/WT_reg_light_background.png
new file mode 100644
index 0000000..922c546
Binary files /dev/null and b/asset/image/WT_reg_light_background.png differ
diff --git a/asset/image/ankle_weight.png b/asset/image/ankle_weight.png
new file mode 100644
index 0000000..215861f
Binary files /dev/null and b/asset/image/ankle_weight.png differ
diff --git a/asset/image/button_apple.png b/asset/image/button_apple.png
new file mode 100644
index 0000000..78a03a6
Binary files /dev/null and b/asset/image/button_apple.png differ
diff --git a/asset/image/button_fb.png b/asset/image/button_fb.png
new file mode 100644
index 0000000..4c26d3d
Binary files /dev/null and b/asset/image/button_fb.png differ
diff --git a/asset/image/button_google.png b/asset/image/button_google.png
new file mode 100644
index 0000000..e913986
Binary files /dev/null and b/asset/image/button_google.png differ
diff --git a/asset/image/vest_weight.png b/asset/image/vest_weight.png
new file mode 100644
index 0000000..3811b6d
Binary files /dev/null and b/asset/image/vest_weight.png differ
diff --git a/i18n/en.json b/i18n/en.json
index c324114..8a8815c 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -7,13 +7,16 @@
"TRAINING!": "TRAINING!",
"Login": "Login",
"Logout": "Logout",
+ "SignUp with Email": "SignUp with Email",
"Tests": "Tests",
"Change Language": "Change Language",
"Password too short": "Password too short (at least 9 characters)",
"Please type an email address": "Please type an email address",
"Exception: Please accept our data policy":"Please accept our data policy",
- "Please accept our data protection policy. For more information please click on 'Privacy'":"Please accept our data protection policy. For more information please click on 'Privacy'",
- "SignUp": "SignUp",
+ "Please accept our data protection policy.":"Please accept our data protection policy.",
+ "For more information please click on 'Privacy'":"For more information please click on 'Privacy'",
+ "SignUp": "SignUp with Email",
+ "SignUpLink": "SignUp",
"Privacy": "Privacy",
"Change App Language": "Change App Language",
"English": "English",
@@ -26,9 +29,17 @@
"Please log in": "Please log in",
"Exception: Customer does not exist or the password is wrong": "The email does not exist or the password is wrong",
+ "Exception: Facebook signup was not successful. Please try another method": "Facebook signup was not successful. Please try another method",
"Exception: Customer exists": "The email address has been registered already",
+ "Exception: The email address has been registered already":"The email address has been registered already",
"Exception: Please type an email address": "Please type an email address",
"Exception: Password too short": "Password too short (at least 9 characters)",
+ "Exception: Google Sign In failed":"Google Sign In failed",
+ "Exception: Apple Sign-In failed":"Apple Sign-In failed",
+ "Exception: Apple Sign-In cancelled":"Apple Sign-In cancelled",
+ "Exception: Apple Sign In failure: email address is necessary": "Apple Sign In failure: email address is necessary",
+
+
"There is an error: during registration:": "There is an error: during registration:",
"Please select an exercise": "Please select an exercise",
"Cardio": "Cardio",
@@ -199,7 +210,7 @@
"Persistence!": "Persistence!",
"Greetings!": "Greetings!",
- "The purpose is to measure you physical condition": "The purpose is to measure your physical condition.",
+ "The purpose is to measure you physical condition": "The purpose is to measure your physical condition. Your first goal is to test all your muscle regions with a 'base' exercise.",
"The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.": "The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.",
"Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.": "Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.",
"Please continue your tests with a": "Please continue your tests with a",
@@ -286,6 +297,7 @@
"Unleash your potential with WorkoutTest Premium!":"Unleash your potential with WorkoutTest Premium!",
"feature is reachable after you finished":"feature is reachable after you finished",
"100% test circles":"100% test circles",
+ "Keep testing":"Keep Testing",
"Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.":"Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.",
diff --git a/i18n/hu.json b/i18n/hu.json
index 8c82843..7ed0c37 100644
--- a/i18n/hu.json
+++ b/i18n/hu.json
@@ -12,8 +12,11 @@
"Password too short": "A jelszó min. 9 karakterből álljon",
"Please type an email address": "Kérlek írj be egy email címet",
"SignUp": "Regisztráció",
+ "SignUpLink": "Regisztráció",
+ "SignUp with Email": "Email Regisztráció",
"Exception: Please accept our data policy":"Kérlek fogadd el az adatvédelmi szabályzatunkat",
- "Please accept our data protection policy. For more information please click on 'Privacy'":"Kérlek fogadd el az adatvédelmi szabályzatunkat. További információkért kattints az 'Adatkezelés' linkre.",
+ "Please accept our data protection policy.":"Kérlek fogadd el az adatvédelmi szabályzatunkat.",
+ "For more information please click on 'Privacy'":"További információkért kattints az 'Adatkezelés' linkre.",
"Privacy": "Adatkezelés",
"Change App Language": "Nyelvválasztás",
"English": "Angol",
@@ -29,11 +32,17 @@
"Customer does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
"The email does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
"Exception: Facebook login was not successful": "Facebook bejelentkezés sikertelen",
+ "Exception: Facebook signup was not successful. Please try another method": "Facebook regisztráció sikertelen. Kérlek próbálj mással regisztrálni",
"Exception: Please type an email address": "Kérlek írj be egy email címet",
"Exception: Password too short": "A jelszó min. 9 karakterből álljon",
"Exception: You have a previous Facebook login operation in progress":"Az előző bejelentkezés még folyamatban van.",
"Exception: Facebook login cancelled":"Facebook bejelentkezés megszakítva ",
"Exception: Facebook login failed":"Facebook bejelentkezés sikertelen",
+ "Exception: The email address has been registered already":"Ezzel email címmel már regisztráltak",
+ "Exception: Google Sign In failed":"Google bejelentkezés sikertelen",
+ "Exception: Apple Sign-In failed":"Apple bejelentkezés sikertelen",
+ "Exception: Apple Sign-In cancelled":"Apple bejelentkezés megszakítva",
+ "Exception: Apple Sign In failure: email address is necessary": "Apple bejelentkezés sikertelen: email cím szükséges.",
"Please select an exercise": "Válassz ki egy gyakorlatot",
"There is an error: during registration:": "Hiba lépett fel a regisztráció során:",
@@ -73,7 +82,7 @@
"Endurance_desc":"
Erőállóképességi teszt lényege, ahogy az 1RM tesztnél is, hogy a Neked megfelelő SÚLY és ISMÉTLÉS számot tudjuk javasolni.
Nagyon fontos, hogy szabályosan és a kért ismétléssel dolgozz!
Ha a célod a hosszabb távú erő fenntartása, netán sportoló vagy, akkor feltétlen teszteld az erőállóképességi modulunkat is.
Miért az erőállóképesség?
Javítja az izmok oxigén és tápanyagellátottságát és ezáltal képes leszel egyre nagyobb súlyok egyre hosszabbtávon való megmozgatására. Például egyre több fekvőtámaszra és húzódzkodásra.
Kevésbé tömegnövelő hatású, ámbár atlétikus és nagyon erős testalkatot kölcsönöz, ha hosszútávon gyakorlod.
",
"OneRepMax_desc":"Az egy ismétléses maximum, vagy más néven 1RM ismerete számodra fontos lehet a Neked megfelelő SÚLY és ISMÉTLÉS kiszámításában.
Végezd el szabályosan(!) a tesztet, hogy a Neked legmegfelelőbb súlyokat és ismétléseket tudjuk javasolni a későbbiekben.
Ha a célod az izom, vagy az erőnövelés, akkor feltétlen csináld meg az 1RM teszteket!
Mi az 1RM?
Az a súly, amit egyetlen egyszer lennél képes szabályosan megmozgatni. Az egyszer szabályosan végrehajtott maximális súlyú gyakorlatból származtatjuk a céloknak megfelelő súly és ismétlésszámokat.
",
- "Name": "Név",
+ "Name": "Vezetkéknév",
"Exercise": "Gyakorlat",
"Quantity": "Mennyiség",
"Unit": "Egység",
@@ -197,7 +206,7 @@
"Persistence!": "Kitartás!",
"Greetings!": "Üdvözöllek!",
- "The purpose is to measure you physical condition": "A cél a jelenlegi fizikai kondíciód felmérése.",
+ "The purpose is to measure you physical condition": "A cél a jelenlegi fizikai kondíciód felmérése. Az első célod az összes izomcsoport tesztelése egy 'base' gyakorlattal.",
"The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.": "A gyakorlatok javasolt végrehajtási sorrendje: mell - bicepsz - tricepsz - hát - váll - has - comb - vádli.",
"Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.": "Menj a menüben az Erő - Max Erő - Mell menüpontba, és válaszd ki a kedvenc gyakorlatod.",
"Please continue your tests with a": "Kérlek folytasd a gyakorlatokat egy",
@@ -284,6 +293,7 @@
"Unleash your potential with WorkoutTest Premium!":"Bontakoztasd ki az erősségeidet WorkoutTest Prémiummal!",
"feature is reachable after you finished":"funkció elérhető számodra, miután teljesítetted",
"100% test circles":"100%-os teszt-köröd",
+ "Keep testing":"Folytasd a tesztelést",
"Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.":"Élvezd ezt a prémium funkciót is, amely megjeleníti a korábbi gyakorlatok teljes kiértékelését",
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index b3106f5..3b8901b 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -1,4 +1,11 @@
PODS:
+ - AppAuth (1.4.0):
+ - AppAuth/Core (= 1.4.0)
+ - AppAuth/ExternalUserAgent (= 1.4.0)
+ - AppAuth/Core (1.4.0)
+ - AppAuth/ExternalUserAgent (1.4.0)
+ - apple_sign_in (0.0.1):
+ - Flutter
- devicelocale (0.0.1):
- Flutter
- FBSDKCoreKit (8.2.0):
@@ -11,14 +18,24 @@ PODS:
- FBSDKLoginKit/Login (= 8.2.0)
- FBSDKLoginKit/Login (8.2.0):
- FBSDKCoreKit (~> 8.2.0)
+ - Firebase/Analytics (6.33.0):
+ - Firebase/Core
- Firebase/Auth (6.33.0):
- Firebase/CoreOnly
- FirebaseAuth (~> 6.9.2)
+ - Firebase/Core (6.33.0):
+ - Firebase/CoreOnly
+ - FirebaseAnalytics (= 6.8.3)
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Messaging (6.33.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 4.7.0)
+ - firebase_analytics (6.3.0):
+ - Firebase/Analytics (~> 6.33.0)
+ - Firebase/CoreOnly (~> 6.33.0)
+ - firebase_core
+ - Flutter
- firebase_auth (0.18.4-1):
- Firebase/Auth (~> 6.33.0)
- Firebase/CoreOnly (~> 6.33.0)
@@ -32,6 +49,15 @@ PODS:
- Firebase/Messaging (~> 6.33.0)
- firebase_core
- Flutter
+ - FirebaseAnalytics (6.8.3):
+ - FirebaseCore (~> 6.10)
+ - FirebaseInstallations (~> 1.6)
+ - GoogleAppMeasurement (= 6.8.3)
+ - GoogleUtilities/AppDelegateSwizzler (~> 6.7)
+ - GoogleUtilities/MethodSwizzler (~> 6.7)
+ - GoogleUtilities/Network (~> 6.7)
+ - "GoogleUtilities/NSData+zlib (~> 6.7)"
+ - nanopb (~> 1.30906.0)
- FirebaseAuth (6.9.2):
- FirebaseCore (~> 6.10)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
@@ -73,15 +99,26 @@ PODS:
- FBSDKCoreKit (~> 8.2.0)
- FBSDKLoginKit (~> 8.2.0)
- Flutter
- - flutter_inapp_purchase (0.0.1):
- - Flutter
- flutter_keyboard_visibility (0.0.1):
- Flutter
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
+ - google_sign_in (0.0.1):
+ - Flutter
+ - GoogleSignIn (~> 5.0)
+ - GoogleAppMeasurement (6.8.3):
+ - GoogleUtilities/AppDelegateSwizzler (~> 6.7)
+ - GoogleUtilities/MethodSwizzler (~> 6.7)
+ - GoogleUtilities/Network (~> 6.7)
+ - "GoogleUtilities/NSData+zlib (~> 6.7)"
+ - nanopb (~> 1.30906.0)
- GoogleDataTransport (7.5.1):
- nanopb (~> 1.30906.0)
+ - GoogleSignIn (5.0.2):
+ - AppAuth (~> 1.2)
+ - GTMAppAuth (~> 1.0)
+ - GTMSessionFetcher/Core (~> 1.1)
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
@@ -90,6 +127,8 @@ PODS:
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
+ - GoogleUtilities/MethodSwizzler (6.7.2):
+ - GoogleUtilities/Logger
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
@@ -99,7 +138,14 @@ PODS:
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
+ - GTMAppAuth (1.1.0):
+ - AppAuth/Core (~> 1.4)
+ - GTMSessionFetcher (~> 1.4)
+ - GTMSessionFetcher (1.5.0):
+ - GTMSessionFetcher/Full (= 1.5.0)
- GTMSessionFetcher/Core (1.5.0)
+ - GTMSessionFetcher/Full (1.5.0):
+ - GTMSessionFetcher/Core (= 1.5.0)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
@@ -122,15 +168,17 @@ PODS:
- Flutter
DEPENDENCIES:
+ - apple_sign_in (from `.symlinks/plugins/apple_sign_in/ios`)
- devicelocale (from `.symlinks/plugins/devicelocale/ios`)
+ - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- 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_inapp_purchase (from `.symlinks/plugins/flutter_inapp_purchase/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
+ - google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
@@ -140,9 +188,11 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
+ - AppAuth
- FBSDKCoreKit
- FBSDKLoginKit
- Firebase
+ - FirebaseAnalytics
- FirebaseAuth
- FirebaseCore
- FirebaseCoreDiagnostics
@@ -151,16 +201,23 @@ SPEC REPOS:
- FirebaseMessaging
- Flurry-iOS-SDK
- FMDB
+ - GoogleAppMeasurement
- GoogleDataTransport
+ - GoogleSignIn
- GoogleUtilities
+ - GTMAppAuth
- GTMSessionFetcher
- nanopb
- PromisesObjC
- Protobuf
EXTERNAL SOURCES:
+ apple_sign_in:
+ :path: ".symlinks/plugins/apple_sign_in/ios"
devicelocale:
:path: ".symlinks/plugins/devicelocale/ios"
+ firebase_analytics:
+ :path: ".symlinks/plugins/firebase_analytics/ios"
firebase_auth:
:path: ".symlinks/plugins/firebase_auth/ios"
firebase_core:
@@ -173,10 +230,10 @@ EXTERNAL SOURCES:
:path: Flutter
flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
- flutter_inapp_purchase:
- :path: ".symlinks/plugins/flutter_inapp_purchase/ios"
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
+ google_sign_in:
+ :path: ".symlinks/plugins/google_sign_in/ios"
path_provider:
:path: ".symlinks/plugins/path_provider/ios"
shared_preferences:
@@ -191,13 +248,17 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/webview_flutter/ios"
SPEC CHECKSUMS:
+ AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
+ apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
FBSDKCoreKit: 4afd6ff53d8133a433dbcda44451c9498f8c6ce4
FBSDKLoginKit: 7181765f2524d7ebf82d9629066c8e6caafc99d0
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
+ firebase_analytics: 36a619088c46224900829f14f4daa71585693a6f
firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a
firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75
+ FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
FirebaseAuth: c92d49ada7948d1a23466e3db17bc4c2039dddc3
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
@@ -208,11 +269,14 @@ SPEC CHECKSUMS:
Flurry-iOS-SDK: 8f3f7fce27177002f15f145eede88dc1b9ac0cd0
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_facebook_auth: bad08a3d465e7b7ba9d8468a9dc7df3f69c136b8
- flutter_inapp_purchase: 5c6a1ac3f11b11d0c8c0321c0c41c1f05805e4c8
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
+ google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
+ GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
+ GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
+ GTMAppAuth: 197a8dabfea5d665224aa00d17f164fc2248dab9
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index b27c0d8..32adb50 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -156,6 +156,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
EB0A62903CC30EC853FC7908 /* [CP] Embed Pods Frameworks */,
+ C1BA2CB9D651F269CCBE06B3 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -265,6 +266,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
+ C1BA2CB9D651F269CCBE06B3 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
EB0A62903CC30EC853FC7908 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -366,7 +384,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -509,7 +527,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@@ -544,7 +562,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 80c67d1..d6084d5 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -24,6 +24,7 @@
CFBundleURLSchemes
fb584181112271127
+ com.googleusercontent.apps.926782702216-2nsi7d9at3pc5ts8gkobt5697v590kb9
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index f166400..98bdd20 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -4,6 +4,10 @@
aps-environment
development
+ com.apple.developer.applesignin
+
+ Default
+
com.apple.developer.authentication-services.autofill-credential-provider
diff --git a/lib/bloc/login/login_bloc.dart b/lib/bloc/login/login_bloc.dart
index be8f5b4..5849559 100644
--- a/lib/bloc/login/login_bloc.dart
+++ b/lib/bloc/login/login_bloc.dart
@@ -21,6 +21,7 @@ class LoginBloc extends Bloc with Trans {
final BuildContext context;
final bool isRegistration;
bool dataPolicyAllowed = false;
+ bool obscure = true;
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial());
@override
@@ -51,6 +52,20 @@ class LoginBloc extends Bloc with Trans {
Flurry.logEvent("Login");
Flurry.logEvent("LoginFB");
yield LoginSuccess();
+ } else if (event is LoginGoogle) {
+ yield LoginLoading();
+ await userRepository.getUserByGoogle();
+ accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
+ Flurry.logEvent("Login");
+ Flurry.logEvent("LoginGoogle");
+ yield LoginSuccess();
+ } else if (event is LoginApple) {
+ yield LoginLoading();
+ await userRepository.getUserByApple();
+ accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
+ Flurry.logEvent("Login");
+ Flurry.logEvent("LoginApple");
+ yield LoginSuccess();
} else if (event is RegistrationSubmit) {
yield LoginLoading();
if (!this.dataPolicyAllowed) {
@@ -75,9 +90,36 @@ class LoginBloc extends Bloc with Trans {
Flurry.logEvent("RegistrationFB");
Flurry.logEvent("Registration");
yield LoginSuccess();
+ } else if (event is RegistrationGoogle) {
+ yield LoginLoading();
+ if (!this.dataPolicyAllowed) {
+ yield LoginError();
+ throw Exception("Please accept our data policy");
+ }
+ await userRepository.addUserGoogle();
+ accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
+ await saveCustomer();
+ Flurry.logEvent("RegistrationGoogle");
+ Flurry.logEvent("Registration");
+ yield LoginSuccess();
+ } else if (event is RegistrationApple) {
+ yield LoginLoading();
+ if (!this.dataPolicyAllowed) {
+ yield LoginError();
+ throw Exception("Please accept our data policy");
+ }
+ await userRepository.addUserApple();
+ accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn));
+ await saveCustomer();
+ Flurry.logEvent("RegistrationApple");
+ Flurry.logEvent("Registration");
+ yield LoginSuccess();
} else if (event is DataProtectionClicked) {
- this.dataPolicyAllowed = event.marked;
+ yield LoginLoading();
+ this.dataPolicyAllowed = !dataPolicyAllowed;
yield LoginReady();
+ } else if (event is LoginPasswordChangeObscure) {
+ this.obscure = !this.obscure;
}
} on Exception catch (e) {
yield LoginError(message: e.toString());
diff --git a/lib/bloc/login/login_event.dart b/lib/bloc/login/login_event.dart
index c51f179..908df30 100644
--- a/lib/bloc/login/login_event.dart
+++ b/lib/bloc/login/login_event.dart
@@ -35,6 +35,14 @@ class LoginFB extends LoginEvent {
const LoginFB();
}
+class LoginGoogle extends LoginEvent {
+ const LoginGoogle();
+}
+
+class LoginApple extends LoginEvent {
+ const LoginApple();
+}
+
class DataProtectionClicked extends LoginEvent {
final bool marked;
const DataProtectionClicked({this.marked});
@@ -47,3 +55,11 @@ class RegistrationSubmit extends LoginEvent {
class RegistrationFB extends LoginEvent {
const RegistrationFB();
}
+
+class RegistrationGoogle extends LoginEvent {
+ const RegistrationGoogle();
+}
+
+class RegistrationApple extends LoginEvent {
+ const RegistrationApple();
+}
diff --git a/lib/bloc/sales/sales_bloc.dart b/lib/bloc/sales/sales_bloc.dart
index b37c91a..df069d8 100644
--- a/lib/bloc/sales/sales_bloc.dart
+++ b/lib/bloc/sales/sales_bloc.dart
@@ -29,14 +29,14 @@ class SalesBloc extends Bloc with Logging {
if (event is SalesLoad) {
yield SalesLoading();
//Flurry.logEvent("SalesPageOpen");
- await PlatformPurchaseApi().initPurchasePlatformState();
- this.getProductSet();
+ // await PlatformPurchaseApi().initPurchasePlatformState();
+ // this.getProductSet();
yield SalesReady();
} else if (event is SalesPurchase) {
final int productId = event.productId;
trace("Requesting purchase for" + productId.toString());
//Flurry.logEvent("PurchaseRequest");
- PlatformPurchaseApi().purchase(getSelectedProduct(productId));
+ // PlatformPurchaseApi().purchase(getSelectedProduct(productId));
}
} on Exception catch (ex) {
yield SalesError(message: ex.toString());
@@ -53,7 +53,7 @@ class SalesBloc extends Bloc with Logging {
return prod;
}
- String getLocalizedPrice(String productId) {
+ /* String getLocalizedPrice(String productId) {
String price = "";
for (var product in PlatformPurchaseApi().getIAPItems()) {
if (Platform.isAndroid) {
@@ -109,5 +109,5 @@ class SalesBloc extends Bloc with Logging {
productTest.dateView = DateTime.now();
//ProductTestApi().saveProductTest(productTest);
//Cache().productTests.add(productTest);
- }
+ } */
}
diff --git a/lib/bloc/session/session_bloc.dart b/lib/bloc/session/session_bloc.dart
index 5f866bf..57bac26 100644
--- a/lib/bloc/session/session_bloc.dart
+++ b/lib/bloc/session/session_bloc.dart
@@ -42,7 +42,7 @@ class SessionBloc extends Bloc with Logging {
@override
Future close() async {
await this.close();
- PlatformPurchaseApi().close();
+ //PlatformPurchaseApi().close();
super.close();
}
}
diff --git a/lib/main.dart b/lib/main.dart
index e57b2dd..43a2c73 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -32,6 +32,8 @@ import 'package:aitrainer_app/view/reset_password.dart';
import 'package:aitrainer_app/view/sales_page.dart';
import 'package:aitrainer_app/view/settings.dart';
import 'package:aitrainer_app/widgets/home.dart';
+import 'package: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';
@@ -163,7 +165,7 @@ class WorkoutTestApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
- //final FirebaseAnalytics analytics = FirebaseAnalytics();
+ final FirebaseAnalytics analytics = FirebaseAnalytics();
initFlurry();
PushNotificationsManager().init();
return MaterialApp(
@@ -233,7 +235,7 @@ class WorkoutTestApp extends StatelessWidget {
bodyText1: GoogleFonts.openSans(textStyle: TextStyle(fontSize: 14.0)),
)),
navigatorObservers: [
- //FirebaseAnalyticsObserver(analytics: analytics),
+ FirebaseAnalyticsObserver(analytics: analytics),
],
home: AitrainerHome(),
);
diff --git a/lib/model/cache.dart b/lib/model/cache.dart
index 7f68fac..6987ce3 100644
--- a/lib/model/cache.dart
+++ b/lib/model/cache.dart
@@ -73,7 +73,6 @@ class Cache with Logging {
AccessToken accessTokenFacebook;
Customer userLoggedIn;
String firebaseUid;
- String facebookUid;
bool hasPurchased = false;
@@ -201,7 +200,7 @@ class Cache with Logging {
Future prefs = SharedPreferences.getInstance();
userLoggedIn = customer;
- final String uid = Cache().firebaseUid == null ? Cache().facebookUid : Cache().firebaseUid;
+ final String uid = Cache().firebaseUid;
await setPreferences(prefs, SharePrefsChange.registration, customer.customerId, uid);
}
@@ -219,7 +218,7 @@ class Cache with Logging {
afterFacebookLogin() async {
Future prefs = SharedPreferences.getInstance();
- await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().facebookUid);
+ await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid);
}
logout() async {
@@ -457,7 +456,4 @@ class Cache with Logging {
AccessToken get getAccessTokenFacebook => accessTokenFacebook;
set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook;
-
- String get getFacebookUid => facebookUid;
- set setFacebookUid(String facebookUid) => this.facebookUid = facebookUid;
}
diff --git a/lib/repository/user_repository.dart b/lib/repository/user_repository.dart
index 3985b32..c54381a 100644
--- a/lib/repository/user_repository.dart
+++ b/lib/repository/user_repository.dart
@@ -2,8 +2,12 @@ import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/service/customer_service.dart';
import 'package:aitrainer_app/service/firebase_api.dart';
+import 'package:aitrainer_app/service/logging.dart';
+import 'package:aitrainer_app/util/not_found_exception.dart';
+import 'package:firebase_auth/firebase_auth.dart' as auth;
+import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
-class UserRepository {
+class UserRepository with Logging {
User user;
UserRepository() {
@@ -31,29 +35,166 @@ class UserRepository {
await CustomerApi().addUser(modelUser);
}
} catch (e) {
- print(e.toString());
+ log(e.toString());
throw new Exception(e);
}
}
Future addUserFB() async {
final User modelUser = this.user;
+ try {
+ Map userData = await FirebaseApi().registerWithFacebook();
+ if (userData != null) {
+ modelUser.email = userData['email'];
+ if (modelUser.email == null) {
+ throw new Exception("Facebook signup was not successful. Please try another method");
+ }
+ modelUser.password = Cache().firebaseUid;
+ modelUser.firebaseUid = Cache().firebaseUid;
+ await CustomerApi().addUser(modelUser);
+ } else {
+ throw new Exception("Facebook signup was not successful. Please try another method");
+ }
+ } on auth.FirebaseAuthException catch (e) {
+ if (e.code == 'email-already-in-use') {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on WorkoutTestException catch (ex) {
+ if (ex.code == WorkoutTestException.CUSTOMER_EXISTS) {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on Exception catch (ex) {
+ log("Google exception: " + ex.toString());
+ throw Exception("Google Sign In failed");
+ }
+ }
- Map userData = await FirebaseApi().signInWithFacebook();
- if (userData != null) {
- modelUser.email = userData['email'];
- modelUser.password = "1234567";
- modelUser.firebaseUid = Cache().facebookUid;
- await CustomerApi().addUser(modelUser);
+ Future addUserGoogle() async {
+ final User modelUser = this.user;
+ try {
+ Map userData = await FirebaseApi().registerWithGoogle();
+ if (userData != null) {
+ modelUser.email = userData['email'];
+ if (modelUser.email == null) {
+ throw new Exception("Google signup was not successful. Please try another method");
+ }
+ modelUser.password = Cache().firebaseUid;
+ modelUser.firebaseUid = Cache().firebaseUid;
+ await CustomerApi().addUser(modelUser);
+ } else {
+ throw new Exception("Google signup was not successful. Please try another method");
+ }
+ } on auth.FirebaseAuthException catch (e) {
+ if (e.code == 'email-already-in-use') {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on WorkoutTestException catch (ex) {
+ if (ex.code == WorkoutTestException.CUSTOMER_EXISTS) {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on Exception catch (ex) {
+ log("Google exception: " + ex.toString());
+ throw Exception("Google Sign In failed");
+ }
+ }
+
+ Future addUserApple() async {
+ final User modelUser = this.user;
+ try {
+ Map userData = await FirebaseApi().registerWithApple();
+ if (userData != null) {
+ modelUser.email = userData['email'];
+ if (modelUser.email == null) {
+ throw new Exception("Apple signup was not successful. Please try another method");
+ }
+ modelUser.password = Cache().firebaseUid;
+ modelUser.firebaseUid = Cache().firebaseUid;
+ await CustomerApi().addUser(modelUser);
+ } else {
+ throw new Exception("Apple signup was not successful. Please try another method");
+ }
+ } on auth.FirebaseAuthException catch (e) {
+ if (e.code == 'email-already-in-use') {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on WorkoutTestException catch (ex) {
+ if (ex.code == WorkoutTestException.CUSTOMER_EXISTS) {
+ log('The account already exists for that email.');
+ throw Exception("The email address has been registered already");
+ }
+ } on Exception catch (ex) {
+ log("Apple exception: " + ex.toString());
+ throw Exception(ex);
}
}
Future getUserByFB() async {
final User modelUser = this.user;
- Map userData = await FirebaseApi().signInWithFacebook();
+ try {
+ Map userData = await FirebaseApi().signInWithFacebook();
+ if (userData == null) {
+ throw new Exception("Facebook login was not successful");
+ }
+ modelUser.email = userData['email'];
+
+ await CustomerApi().getUserByEmail(modelUser.email);
+ await Cache().afterFirebaseLogin();
+ } on FacebookAuthException catch (e) {
+ switch (e.errorCode) {
+ case FacebookAuthErrorCode.OPERATION_IN_PROGRESS:
+ throw Exception("You have a previous Facebook login operation in progress");
+ break;
+ case FacebookAuthErrorCode.CANCELLED:
+ throw Exception("Facebook login cancelled");
+ break;
+ case FacebookAuthErrorCode.FAILED:
+ throw Exception("Facebook login failed");
+ break;
+ }
+ } on NotFoundException catch (ex) {
+ log("FB exception: " + ex.toString());
+ throw Exception("Customer does not exist or the password is wrong");
+ } on Exception catch (e) {
+ log(e.toString());
+ throw new Exception(e);
+ }
+ }
+
+ Future getUserByGoogle() async {
+ final User modelUser = this.user;
+ Map userData = await FirebaseApi().signInWithGoogle();
+ if (userData == null || userData['email'] == null) {
+ throw new Exception("Google login was not successful");
+ }
modelUser.email = userData['email'];
- await CustomerApi().getUserByEmail(modelUser.email);
- await Cache().afterFacebookLogin();
+ try {
+ await CustomerApi().getUserByEmail(modelUser.email);
+ await Cache().afterFirebaseLogin();
+ } on Exception catch (ex) {
+ log("Google exception: " + ex.toString());
+ throw Exception("Customer does not exist or the password is wrong");
+ }
+ }
+
+ Future getUserByApple() async {
+ final User modelUser = this.user;
+ Map userData = await FirebaseApi().signInWithApple();
+ if (userData == null || userData['email'] == null) {
+ throw new Exception("Apple login was not successful");
+ }
+ modelUser.email = userData['email'];
+ try {
+ await CustomerApi().getUserByEmail(modelUser.email);
+ await Cache().afterFirebaseLogin();
+ } on Exception catch (ex) {
+ log("Apple exception: " + ex.toString());
+ throw Exception("Customer does not exist or the password is wrong");
+ }
}
Future getUser() async {
@@ -64,7 +205,7 @@ class UserRepository {
await CustomerApi().getUserByEmail(modelUser.email);
await Cache().afterFirebaseLogin();
} else {
- print("Exception: user not found or password is wrong");
+ log("Exception: user not found or password is wrong");
throw Exception("Customer does not exist or the password is wrong");
}
}
diff --git a/lib/service/customer_service.dart b/lib/service/customer_service.dart
index e5cdb2f..81763e8 100644
--- a/lib/service/customer_service.dart
+++ b/lib/service/customer_service.dart
@@ -7,6 +7,7 @@ import 'package:aitrainer_app/model/user.dart';
import 'package:aitrainer_app/service/api.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/service/logging.dart';
+import 'package:aitrainer_app/util/not_found_exception.dart';
class CustomerApi with Logging {
final APIClient _client = new APIClient();
@@ -44,12 +45,16 @@ class CustomerApi with Logging {
try {
int status = jsonDecode(responseBody)['status'];
if (status != null) {
- throw new Exception(jsonDecode(responseBody)['error']);
+ String error = jsonDecode(responseBody)['error'];
+ throw new Exception(error);
} else {
customer = Customer.fromJson(jsonDecode(responseBody));
await Cache().afterRegistration(customer);
}
} on FormatException {
+ if (responseBody == "Customer exists") {
+ throw WorkoutTestException(code: WorkoutTestException.CUSTOMER_EXISTS, message: responseBody);
+ }
throw new Exception(responseBody);
}
}
diff --git a/lib/service/firebase_api.dart b/lib/service/firebase_api.dart
index a4233dd..42f7466 100644
--- a/lib/service/firebase_api.dart
+++ b/lib/service/firebase_api.dart
@@ -1,10 +1,13 @@
import 'package:aitrainer_app/model/cache.dart';
-import 'package:aitrainer_app/service/logging.dart';
+import 'package:aitrainer_app/service/logging.dart' as logging;
+import 'package:apple_sign_in/apple_sign_in.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:google_sign_in/google_sign_in.dart';
-class FirebaseApi with Logging {
+class FirebaseApi with logging.Logging {
+ bool appleSignInAvailable = false;
static FirebaseApi _instance;
static final FirebaseAuth auth = FirebaseAuth.instance;
@@ -28,6 +31,7 @@ class FirebaseApi with Logging {
try {
// Wait for Firebase to initialize and set `_initialized` state to true
await Firebase.initializeApp();
+ this.appleSignInAvailable = await AppleSignIn.isAvailable();
} catch (e) {
// Set `_error` state to true if Firebase initialization fails
log("Error initializing Firebase");
@@ -81,34 +85,200 @@ class FirebaseApi with Logging {
return rc;
}
+ Future