WT1.1.3 build 2 iOS. Apple SignIn, Google SignIn
This commit is contained in:
parent
4bd1950ffd
commit
d44fefe9af
BIN
asset/image/WT_reg_light_background.png
Normal file
BIN
asset/image/WT_reg_light_background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
BIN
asset/image/ankle_weight.png
Normal file
BIN
asset/image/ankle_weight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 903 KiB |
BIN
asset/image/button_apple.png
Normal file
BIN
asset/image/button_apple.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
asset/image/button_fb.png
Normal file
BIN
asset/image/button_fb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
asset/image/button_google.png
Normal file
BIN
asset/image/button_google.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
BIN
asset/image/vest_weight.png
Normal file
BIN
asset/image/vest_weight.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
18
i18n/en.json
18
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.",
|
||||
|
||||
|
16
i18n/hu.json
16
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":"<p>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. </p><p>Nagyon fontos, hogy szabályosan és a kért ismétléssel dolgozz!</p><p> 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.</p><br/><h2>Miért az erőállóképesség?</h2><p>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. </p><p>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.</p>",
|
||||
"OneRepMax_desc":"<p>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. <p>Végezd el szabályosan(!) a tesztet, hogy a Neked legmegfelelőbb súlyokat és ismétléseket tudjuk javasolni a későbbiekben.</p> <p>Ha a célod az izom, vagy az erőnövelés, akkor feltétlen csináld meg az 1RM teszteket!</p><br/><h2>Mi az 1RM?</h2><p>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.</p>",
|
||||
|
||||
"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",
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 = (
|
||||
|
@ -24,6 +24,7 @@
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>fb584181112271127</string>
|
||||
<string>com.googleusercontent.apps.926782702216-2nsi7d9at3pc5ts8gkobt5697v590kb9</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
@ -4,6 +4,10 @@
|
||||
<dict>
|
||||
<key>aps-environment</key>
|
||||
<string>development</string>
|
||||
<key>com.apple.developer.applesignin</key>
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
@ -21,6 +21,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> 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<LoginEvent, LoginState> 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<LoginEvent, LoginState> 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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> 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<SalesEvent, SalesState> 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<SalesEvent, SalesState> with Logging {
|
||||
productTest.dateView = DateTime.now();
|
||||
//ProductTestApi().saveProductTest(productTest);
|
||||
//Cache().productTests.add(productTest);
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await this.close();
|
||||
PlatformPurchaseApi().close();
|
||||
//PlatformPurchaseApi().close();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
);
|
||||
|
@ -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<SharedPreferences> 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<SharedPreferences> 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;
|
||||
}
|
||||
|
@ -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<void> addUserFB() async {
|
||||
final User modelUser = this.user;
|
||||
try {
|
||||
Map<String, dynamic> 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<String, dynamic> userData = await FirebaseApi().signInWithFacebook();
|
||||
if (userData != null) {
|
||||
modelUser.email = userData['email'];
|
||||
modelUser.password = "1234567";
|
||||
modelUser.firebaseUid = Cache().facebookUid;
|
||||
await CustomerApi().addUser(modelUser);
|
||||
Future<void> addUserGoogle() async {
|
||||
final User modelUser = this.user;
|
||||
try {
|
||||
Map<String, dynamic> 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<void> addUserApple() async {
|
||||
final User modelUser = this.user;
|
||||
try {
|
||||
Map<String, dynamic> 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<void> getUserByFB() async {
|
||||
final User modelUser = this.user;
|
||||
Map<String, dynamic> userData = await FirebaseApi().signInWithFacebook();
|
||||
try {
|
||||
Map<String, dynamic> 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<void> getUserByGoogle() async {
|
||||
final User modelUser = this.user;
|
||||
Map<String, dynamic> 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<void> getUserByApple() async {
|
||||
final User modelUser = this.user;
|
||||
Map<String, dynamic> 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<void> 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");
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<Map<String, dynamic>> signInWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
final AuthorizationResult result = await AppleSignIn.performRequests([
|
||||
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
|
||||
]);
|
||||
switch (result.status) {
|
||||
case AuthorizationStatus.authorized:
|
||||
print('User authorized');
|
||||
break;
|
||||
case AuthorizationStatus.error:
|
||||
print('User error');
|
||||
throw Exception("Apple Sign-In failed");
|
||||
break;
|
||||
case AuthorizationStatus.cancelled:
|
||||
print('User cancelled');
|
||||
throw Exception("Apple Sign-In cancelled");
|
||||
break;
|
||||
}
|
||||
|
||||
// Create an `OAuthCredential` from the credential returned by Apple.
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: String.fromCharCodes(result.credential.identityToken),
|
||||
accessToken: String.fromCharCodes(result.credential.authorizationCode));
|
||||
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
|
||||
log("userCredential: " + userCredential.toString());
|
||||
|
||||
log("Apple Credentials: " +
|
||||
result.credential.user.toString() +
|
||||
" state " +
|
||||
result.credential.state.toString() +
|
||||
" email " +
|
||||
userCredential.user.email);
|
||||
userData['email'] = userCredential.user.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
final AuthorizationResult result = await AppleSignIn.performRequests([
|
||||
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
|
||||
]);
|
||||
switch (result.status) {
|
||||
case AuthorizationStatus.authorized:
|
||||
print('Apple User authorized');
|
||||
break;
|
||||
case AuthorizationStatus.error:
|
||||
print('Apple User error');
|
||||
throw Exception("Apple Sign-In failed");
|
||||
break;
|
||||
case AuthorizationStatus.cancelled:
|
||||
print('User cancelled');
|
||||
throw Exception("Apple Sign-In cancelled");
|
||||
break;
|
||||
}
|
||||
|
||||
// Create an `OAuthCredential` from the credential returned by Apple.
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: String.fromCharCodes(result.credential.identityToken),
|
||||
accessToken: String.fromCharCodes(result.credential.authorizationCode));
|
||||
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
|
||||
Cache().firebaseUid = userCredential.user.uid;
|
||||
|
||||
userData['email'] = userCredential.user.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> signInWithGoogle() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
try {
|
||||
// Trigger the authentication flow
|
||||
GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
scopes: [
|
||||
'email',
|
||||
'https://www.googleapis.com/auth/contacts.readonly',
|
||||
],
|
||||
);
|
||||
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
// Obtain the auth details from the request
|
||||
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
||||
|
||||
// Create a new credential
|
||||
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
|
||||
accessToken: googleAuth.accessToken,
|
||||
idToken: googleAuth.idToken,
|
||||
);
|
||||
|
||||
await FirebaseAuth.instance.signInWithCredential(credential);
|
||||
|
||||
if (googleUser != null) {
|
||||
log("GoogleUser: " + googleUser.toString());
|
||||
userData['email'] = googleUser.email;
|
||||
userData['id'] = googleUser.id;
|
||||
userData['name'] = googleUser.displayName;
|
||||
}
|
||||
} on Exception catch (ex) {
|
||||
log("Google exception: " + ex.toString());
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithGoogle() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
// Trigger the authentication flow
|
||||
GoogleSignIn _googleSignIn = GoogleSignIn(
|
||||
scopes: [
|
||||
'email',
|
||||
'https://www.googleapis.com/auth/contacts.readonly',
|
||||
],
|
||||
);
|
||||
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
// Obtain the auth details from the request
|
||||
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
|
||||
|
||||
// Create a new credential
|
||||
final GoogleAuthCredential credential = GoogleAuthProvider.credential(
|
||||
accessToken: googleAuth.accessToken,
|
||||
idToken: googleAuth.idToken,
|
||||
);
|
||||
|
||||
final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
|
||||
|
||||
log("Google credentials: " + credential.toString() + " GoogleUser: " + googleUser.toString());
|
||||
Cache().firebaseUid = userCredential.user.uid;
|
||||
|
||||
userData['email'] = googleUser.email;
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> signInWithFacebook() async {
|
||||
Map<String, dynamic> userData;
|
||||
try {
|
||||
// by default the login method has the next permissions ['email','public_profile']
|
||||
AccessToken accessToken = await FacebookAuth.instance.login();
|
||||
if (accessToken != null) {
|
||||
log(accessToken.toJson().toString());
|
||||
Cache().accessTokenFacebook = accessToken;
|
||||
// get the user data
|
||||
userData = await FacebookAuth.instance.getUserData();
|
||||
Cache().facebookUid = userData['id'];
|
||||
log(userData.toString());
|
||||
} else {
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
|
||||
// by default the login method has the next permissions ['email','public_profile']
|
||||
AccessToken accessToken = await FacebookAuth.instance.login();
|
||||
if (accessToken != null) {
|
||||
log(accessToken.toJson().toString());
|
||||
Cache().accessTokenFacebook = accessToken;
|
||||
// get the user data
|
||||
userData = await FacebookAuth.instance.getUserData();
|
||||
Cache().firebaseUid = userData['id'];
|
||||
log(userData.toString());
|
||||
} else {
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> registerWithFacebook() async {
|
||||
Map<String, dynamic> userData;
|
||||
|
||||
// by default the login method has the next permissions ['email','public_profile']
|
||||
AccessToken accessToken = await FacebookAuth.instance.login();
|
||||
if (accessToken != null) {
|
||||
Cache().accessTokenFacebook = accessToken;
|
||||
// get the user data
|
||||
userData = await FacebookAuth.instance.getUserData();
|
||||
|
||||
// Create a credential from the access token
|
||||
final FacebookAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(accessToken.token);
|
||||
|
||||
// Once signed in, return the UserCredential
|
||||
final userCredential = await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
|
||||
|
||||
Cache().firebaseUid = userCredential.user.uid;
|
||||
log(userData.toString());
|
||||
} else {
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,13 @@
|
||||
class NotFoundException implements Exception {
|
||||
final String message;
|
||||
const NotFoundException({this.message});
|
||||
}
|
||||
}
|
||||
|
||||
class WorkoutTestException implements Exception {
|
||||
static const String CUSTOMER_EXISTS = "customer-exists";
|
||||
static const String LOGIN_CANCELLED = "login-cancelled";
|
||||
|
||||
final String message;
|
||||
final String code;
|
||||
const WorkoutTestException({this.message, this.code});
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
/*
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/product.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
@ -21,15 +21,7 @@ class PlatformPurchaseApi with Logging {
|
||||
|
||||
List getProductList() => _productList;
|
||||
|
||||
/* Platform.isAndroid
|
||||
? [
|
||||
'android.test.purchased',
|
||||
'point_1000',
|
||||
'5000_point',
|
||||
'android.test.canceled',
|
||||
]
|
||||
: ['com.cooni.point1000', 'com.cooni.point5000'];
|
||||
*/
|
||||
|
||||
|
||||
factory PlatformPurchaseApi() {
|
||||
return _singleton;
|
||||
@ -167,3 +159,4 @@ class PlatformPurchaseApi with Logging {
|
||||
this._purchases = items;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud/modal_progress_hud.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerExerciseDevicePage extends StatelessWidget with Trans {
|
||||
@ -37,19 +38,20 @@ class CustomerExerciseDevicePage extends StatelessWidget with Trans {
|
||||
..add(CustomerExerciseDeviceLoad()),
|
||||
child: BlocConsumer<CustomerExerciseDeviceBloc, CustomerExerciseDeviceState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerExerciseDeviceLoading) {
|
||||
Scaffold.of(context).showSnackBar(SnackBar(
|
||||
duration: Duration(milliseconds: 100),
|
||||
backgroundColor: Colors.transparent,
|
||||
content: Container(child: Center(child: CircularProgressIndicator()))));
|
||||
} else if (state is CustomerExerciseDeviceError) {
|
||||
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, cHeight);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(bloc, cWidth, cHeight),
|
||||
inAsyncCall: state is CustomerExerciseDeviceLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
))));
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
@ -68,29 +70,40 @@ class LoginPage extends StatelessWidget with Trans {
|
||||
return Form(
|
||||
key: _scaffoldKey,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 15, right: 50),
|
||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 100.0), children: <Widget>[
|
||||
FlatButton(
|
||||
child: new Image.asset(
|
||||
'asset/image/login_fb.png',
|
||||
width: MediaQuery.of(context).size.width * .85,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(LoginFB())},
|
||||
),
|
||||
Text(AppLocalizations.of(context).translate("OR")),
|
||||
Divider(),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0), children: <Widget>[
|
||||
ListTile(title: Text(t("Login"), style: GoogleFonts.inter())),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
new InkWell(
|
||||
child: new Text(AppLocalizations.of(context).translate('Login'),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
|
||||
FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_fb.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(LoginFB())},
|
||||
),
|
||||
FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_google.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(LoginGoogle())},
|
||||
),
|
||||
Platform.isIOS
|
||||
? FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_apple.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(LoginApple())},
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Divider(),
|
||||
ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
|
||||
Divider(),
|
||||
TextFormField(
|
||||
key: LibraryKeys.loginEmailField,
|
||||
decoration: InputDecoration(
|
||||
@ -118,7 +131,7 @@ class LoginPage extends StatelessWidget with Trans {
|
||||
),
|
||||
TextFormField(
|
||||
key: LibraryKeys.loginPasswordField,
|
||||
obscureText: true,
|
||||
obscureText: loginBloc.obscure,
|
||||
decoration: InputDecoration(
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
@ -168,7 +181,7 @@ class LoginPage extends StatelessWidget with Trans {
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
|
||||
InkWell(
|
||||
child: Text(AppLocalizations.of(context).translate('SignUp')),
|
||||
child: Text(AppLocalizations.of(context).translate('SignUpLink')),
|
||||
onTap: () => Navigator.of(context).pushNamed('registration'),
|
||||
),
|
||||
Spacer(flex: 2),
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
|
||||
import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
@ -11,7 +13,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud/modal_progress_hud.dart';
|
||||
import 'package:toggle_switch/toggle_switch.dart';
|
||||
|
||||
import '../library_keys.dart';
|
||||
|
||||
@ -74,28 +75,48 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
return Form(
|
||||
key: _scaffoldKey,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 15, right: 50),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 150.0), children: <Widget>[
|
||||
FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/fb_registration.png',
|
||||
width: MediaQuery.of(context).size.width * .85,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(RegistrationFB())},
|
||||
),
|
||||
ListTile(title: Text(AppLocalizations.of(context).translate("OR"))),
|
||||
ListTile(title: Text(t("SignUp"), style: GoogleFonts.inter())),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_fb.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(RegistrationFB())},
|
||||
),
|
||||
FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_google.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(RegistrationGoogle())},
|
||||
),
|
||||
Platform.isIOS
|
||||
? FlatButton(
|
||||
child: Image.asset(
|
||||
'asset/image/button_apple.png',
|
||||
width: 60,
|
||||
),
|
||||
onPressed: () => {loginBloc.add(RegistrationApple())},
|
||||
)
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
|
||||
/* Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
InkWell(
|
||||
child:
|
||||
Text(AppLocalizations.of(context).translate('SignUp'), style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
|
||||
child: Text(AppLocalizations.of(context).translate('SignUp with Email'),
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24)),
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
), */
|
||||
|
||||
TextFormField(
|
||||
key: LibraryKeys.loginEmailField,
|
||||
decoration: InputDecoration(
|
||||
@ -123,7 +144,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
),
|
||||
TextFormField(
|
||||
key: LibraryKeys.loginPasswordField,
|
||||
obscureText: true,
|
||||
obscureText: loginBloc.obscure,
|
||||
decoration: InputDecoration(
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
@ -153,6 +174,9 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
color: Colors.transparent,
|
||||
),
|
||||
getDataProtection(loginBloc),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
|
||||
FlatButton(
|
||||
key: LibraryKeys.loginOKButton,
|
||||
@ -196,22 +220,16 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
}
|
||||
|
||||
Widget getDataProtection(LoginBloc loginBloc) {
|
||||
return ListTile(
|
||||
subtitle: Text(t("Please accept our data protection policy. For more information please click on 'Privacy'")),
|
||||
title: ToggleSwitch(
|
||||
minWidth: 100.0,
|
||||
minHeight: 30.0,
|
||||
fontSize: 14.0,
|
||||
initialLabelIndex: loginBloc.dataPolicyAllowed ? 0 : 1,
|
||||
activeBgColor: Colors.indigo,
|
||||
activeFgColor: Colors.white,
|
||||
inactiveBgColor: Colors.white30,
|
||||
inactiveFgColor: Colors.black,
|
||||
labels: [t('Yes'), t('No')],
|
||||
onToggle: (index) {
|
||||
loginBloc.add(DataProtectionClicked(marked: index == 0));
|
||||
},
|
||||
),
|
||||
return CheckboxListTile(
|
||||
title: Text(t("Please accept our data protection policy.")),
|
||||
subtitle: Text(t("For more information please click on 'Privacy'")),
|
||||
dense: true,
|
||||
value: loginBloc.dataPolicyAllowed,
|
||||
activeColor: Colors.indigo,
|
||||
onChanged: (value) {
|
||||
loginBloc.add(DataProtectionClicked(marked: value));
|
||||
},
|
||||
controlAffinity: ListTileControlAffinity.leading, // <-- leading Checkbox
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ class DialogPremium extends StatefulWidget {
|
||||
String description, function, unlockedText;
|
||||
final int unlockRound;
|
||||
|
||||
final bool unlocked;
|
||||
bool unlocked;
|
||||
|
||||
DialogPremium(
|
||||
{Key key,
|
||||
@ -27,6 +27,8 @@ class DialogPremium extends StatefulWidget {
|
||||
description = description ?? "";
|
||||
function = function ?? "";
|
||||
unlockedText = unlockedText ?? "";
|
||||
|
||||
unlocked = true;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -88,9 +90,9 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
children: [
|
||||
Text(
|
||||
t("Go Premium") + " ",
|
||||
widget.unlocked ? t("Keep testing") : t("Go Premium") + " ",
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 24,
|
||||
fontSize: widget.unlocked ? 18 : 24,
|
||||
color: Colors.yellow[400],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
@ -106,32 +108,34 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 3,
|
||||
top: 0,
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 900),
|
||||
//reverseDuration: Duration(milliseconds: 200),
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return FadeTransition(child: child, opacity: animation);
|
||||
},
|
||||
child: isStart
|
||||
? Icon(
|
||||
CustomIcon.star_2,
|
||||
color: Colors.yellow[300],
|
||||
)
|
||||
: Offstage() /* Icon(
|
||||
!widget.unlocked
|
||||
? Positioned(
|
||||
right: 3,
|
||||
top: 0,
|
||||
child: AnimatedSwitcher(
|
||||
duration: Duration(milliseconds: 900),
|
||||
//reverseDuration: Duration(milliseconds: 200),
|
||||
transitionBuilder: (Widget child, Animation<double> animation) {
|
||||
return FadeTransition(child: child, opacity: animation);
|
||||
},
|
||||
child: isStart
|
||||
? Icon(
|
||||
CustomIcon.star_2,
|
||||
color: Colors.yellow[300],
|
||||
)
|
||||
: Offstage() /* Icon(
|
||||
CustomIcon.exclamation_circle,
|
||||
color: Colors.yellow[300],
|
||||
) */
|
||||
)),
|
||||
))
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
),
|
||||
Text(
|
||||
t("Unleash your potential with WorkoutTest Premium!"),
|
||||
widget.unlocked ? "" : t("Unleash your potential with WorkoutTest Premium!"),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
@ -160,7 +164,7 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.of(context).pushNamed("salesPage"),
|
||||
onTap: () => widget.unlocked ? Navigator.of(context).pop() : Navigator.of(context).pushNamed("salesPage"),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
@ -222,61 +226,60 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
||||
List<TextSpan> getDescriptionText() {
|
||||
List<TextSpan> list = List();
|
||||
|
||||
if (widget.unlocked) {
|
||||
/* if (widget.unlocked) {
|
||||
list.add(TextSpan(text: widget.unlockedText));
|
||||
} else {
|
||||
list.add(TextSpan(text: t("The")));
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(
|
||||
TextSpan(
|
||||
text: t(widget.function),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.yellow[300],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
} */
|
||||
list.add(TextSpan(text: t("The")));
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(
|
||||
TextSpan(
|
||||
text: t(widget.function),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.yellow[300],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(TextSpan(text: t("feature is reachable after you finished")));
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(
|
||||
TextSpan(
|
||||
text: widget.unlockRound == 1 ? t("the first") : t("the second"),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.yellow[300],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(TextSpan(text: t("feature is reachable after you finished")));
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(
|
||||
TextSpan(
|
||||
text: widget.unlockRound == 1 ? t("the first") : t("the second"),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.yellow[300],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(TextSpan(text: t("100% test circles")));
|
||||
}
|
||||
),
|
||||
);
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(TextSpan(text: t("100% test circles")));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -91,6 +91,6 @@ class _HomePageState extends State<AitrainerHome> with Logging {
|
||||
@override
|
||||
void dispose() async {
|
||||
super.dispose();
|
||||
await PlatformPurchaseApi().close();
|
||||
//await PlatformPurchaseApi().close();
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class ImageButton extends StatelessWidget {
|
||||
//print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString());
|
||||
}
|
||||
final double width = MediaQuery.of(context).size.width;
|
||||
print("Mediawidth: " + width.toStringAsFixed(0));
|
||||
//print("Mediawidth: " + width.toStringAsFixed(0));
|
||||
return Stack(alignment: AlignmentDirectional.bottomStart, children: [
|
||||
FlatButton(
|
||||
child: image == null
|
||||
@ -152,11 +152,11 @@ class ImageButton extends StatelessWidget {
|
||||
imageName,
|
||||
fit: BoxFit.fitWidth,
|
||||
alignment: Alignment.center,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
String url = Cache.mediaUrl + '/' + imageName; //.substring(11);
|
||||
/* errorBuilder: (context, error, stackTrace) {
|
||||
String url = Cache.mediaUrl + imageName; //.substring(11);
|
||||
Widget image = FadeInImage.assetNetwork(placeholder: 'asset/image/dots.gif', image: url, height: this.height);
|
||||
return image;
|
||||
},
|
||||
}, */
|
||||
);
|
||||
} on Exception catch (_) {
|
||||
String url = Cache.mediaUrl + '/images/' + imageName;
|
||||
|
79
pubspec.lock
79
pubspec.lock
@ -22,6 +22,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.6"
|
||||
apple_sign_in:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: apple_sign_in
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -205,7 +212,7 @@ packages:
|
||||
source: hosted
|
||||
version: "0.14.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
@ -281,6 +288,34 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.1"
|
||||
firebase:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.3.3"
|
||||
firebase_analytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_analytics
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.3.0"
|
||||
firebase_analytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
firebase_analytics_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_analytics_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
firebase_auth:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -398,13 +433,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter_inapp_purchase:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_inapp_purchase
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
flutter_keyboard_visibility:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -448,20 +476,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.19.1"
|
||||
freezed:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: freezed
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.6"
|
||||
freezed_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: freezed_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -476,6 +490,27 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
google_sign_in:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_sign_in
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.5.9"
|
||||
google_sign_in_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_sign_in_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
google_sign_in_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_sign_in_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.2"
|
||||
gradient_bottom_navigation_bar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
24
pubspec.yaml
24
pubspec.yaml
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.4+45
|
||||
version: 1.1.4+46
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
@ -30,7 +30,7 @@ dependencies:
|
||||
sentry: ^3.0.1
|
||||
flutter_bloc: ^6.1.1
|
||||
equatable: ^1.2.5
|
||||
freezed: ^0.12.2
|
||||
#freezed: ^0.12.2
|
||||
flutter_form_bloc: ^0.19.0
|
||||
spider_chart: ^0.1.5
|
||||
rainbow_color: ^0.1.1
|
||||
@ -45,17 +45,21 @@ dependencies:
|
||||
#health: ^3.0.0
|
||||
stop_watch_timer: ^0.6.0+1
|
||||
#geolocator: ^6.1.13
|
||||
flutter_inapp_purchase: ^3.0.1
|
||||
#flutter_inapp_purchase: ^3.0.1
|
||||
modal_progress_hud: ^0.1.3
|
||||
flutter_html: ^1.1.1
|
||||
wakelock: ^0.2.1+1
|
||||
|
||||
|
||||
firebase_core: ^0.5.2
|
||||
#firebase_analytics: ^6.2.0
|
||||
firebase_messaging: ^7.0.3
|
||||
firebase_core: ^0.5.0
|
||||
firebase_analytics: ^6.2.0
|
||||
firebase_messaging: ^7.0.0
|
||||
firebase_auth: ^0.18.3
|
||||
flutter_facebook_auth: ^2.0.0+1
|
||||
google_sign_in: ^4.5.9
|
||||
apple_sign_in: ^0.1.0
|
||||
crypto: ^2.1.5
|
||||
|
||||
flurry: ^0.0.7
|
||||
|
||||
animated_widgets: ^1.0.6
|
||||
@ -121,6 +125,7 @@ flutter:
|
||||
- asset/image/WT_black_background.png
|
||||
- asset/image/WT_black_G_background.png
|
||||
- asset/image/WT_plainblack_background.png
|
||||
- asset/image/WT_reg_light_background.png
|
||||
- asset/image/WT_menu.png
|
||||
- asset/image/WT_login.png
|
||||
- asset/image/WT_OK.png
|
||||
@ -136,8 +141,9 @@ flutter:
|
||||
- asset/image/WT_Results_for_runners.png
|
||||
- asset/image/WT_Results_for_female.png
|
||||
- asset/image/WT_Results_for_men.png
|
||||
- asset/image/login_fb.png
|
||||
- asset/image/fb_registration.png
|
||||
- asset/image/button_fb.png
|
||||
- asset/image/button_apple.png
|
||||
- asset/image/button_google.png
|
||||
- asset/image/lock.png
|
||||
- asset/image/Congrats_N1.jpg
|
||||
- asset/image/testemfejl400x400.jpg
|
||||
@ -178,6 +184,8 @@ flutter:
|
||||
- asset/image/equipment_home_place.jpg
|
||||
- asset/image/equipment_gym_place.jpg
|
||||
- asset/image/equipment_street_place.jpg
|
||||
- asset/image/ankle_weight.png
|
||||
- asset/image/vest_weight.png
|
||||
- asset/image/haken.png
|
||||
- asset/image/pict_calorie.png
|
||||
- asset/image/pict_development_by_bodypart_percent.png
|
||||
|
Loading…
Reference in New Issue
Block a user