WT 1.1.22 reengineering: Training Plan execution, registration
This commit is contained in:
parent
6b25fdfe0e
commit
cebd83648b
@ -78,5 +78,6 @@ dependencies {
|
||||
implementation 'com.google.firebase:firebase-analytics:18.0.0'
|
||||
implementation 'com.facebook.android:facebook-login:5.15.3'
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'com.google.firebase:firebase-messaging:20.1.0'
|
||||
}
|
||||
sourceCompatibility = '1.8'
|
@ -1,41 +1,23 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.aitrainer.aitrainer_app">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.aitrainer.aitrainer_app">
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="WorkoutTest"
|
||||
android:icon="@mipmap/launcher_icon">
|
||||
<activity
|
||||
android:name="com.aitrainer.aitrainer_app.MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:allowBackup="false"
|
||||
android:fullBackupContent="false">
|
||||
<application android:name="io.flutter.app.FlutterApplication" android:label="WorkoutTest" android:icon="@mipmap/launcher_icon">
|
||||
<activity android:name="com.aitrainer.aitrainer_app.MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:allowBackup="false" android:fullBackupContent="false">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background"
|
||||
/>
|
||||
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
@ -44,27 +26,26 @@
|
||||
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<!-- Deep Links -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
|
||||
<data android:scheme="https" android:host="aitrainer.page.link" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||
android:value="high_importance_channel" />
|
||||
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId"
|
||||
android:value="@string/facebook_app_id"/>
|
||||
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="high_importance_channel" />
|
||||
|
||||
<activity android:name="com.facebook.FacebookActivity"
|
||||
android:configChanges=
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||
android:label="@string/app_name" />
|
||||
<activity
|
||||
android:name="com.facebook.CustomTabActivity"
|
||||
android:exported="true">
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
|
||||
|
||||
<activity android:name="com.facebook.FacebookActivity" android:configChanges=
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" />
|
||||
<activity android:name="com.facebook.CustomTabActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
BIN
asset/image/WT_zold.jpg
Normal file
BIN
asset/image/WT_zold.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
BIN
asset/menu/smith_machine_squats.jpg
Normal file
BIN
asset/menu/smith_machine_squats.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
BIN
asset/menu/training_start.jpg
Normal file
BIN
asset/menu/training_start.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 115 KiB |
@ -15,7 +15,7 @@
|
||||
"Exception: Please accept our data policy": "Please accept our data policy",
|
||||
"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",
|
||||
"SignUp": "We will generate your training plan for you. Please register in order to save and recall your data.",
|
||||
"SignUpLink": "SignUp",
|
||||
"Privacy": "Privacy",
|
||||
"Change App Language": "Change App Language",
|
||||
@ -436,7 +436,7 @@
|
||||
"Do you want to restart, or select a new Training Plan?": "Do you want to restart, or select a new Training Plan?",
|
||||
"New Training Plan": "New Training Plan",
|
||||
"Restart": "Restart",
|
||||
"Training Day": "Day",
|
||||
"Training Day": "Training Day",
|
||||
"No Active Training Plan": "No Active Training Plan",
|
||||
"Please select one in the Training menu, or create your custom plan": "Please select one in the Training menu, or create your custom plan",
|
||||
"Continue your training": "Continue your training",
|
||||
@ -508,5 +508,6 @@
|
||||
"Reach all basic functions, suggestions and": "Reach all basic functions, suggestions and",
|
||||
"optimized training plans, customized to your fitness state and strength:": "optimized training plans, customized to your fitness state and strength:",
|
||||
"Soon! Check back later for the plan details": "Soon! Check back later for the plan details",
|
||||
"mins": "mins"
|
||||
"mins": "mins",
|
||||
"set": "set"
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
"Change Language": "Nyelv",
|
||||
"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ó",
|
||||
"SignUp": "A megadott adatok alapján generáljuk az edzéstervedet. Kérlek regisztrálj, hogy az a tervet el tudd menteni és később betölteni.",
|
||||
"SignUpLink": "Regisztráció",
|
||||
"SignUp with Email": "Email Regisztráció",
|
||||
"Exception: Please accept our data policy": "Kérlek fogadd el az adatvédelmi szabályzatunkat",
|
||||
@ -434,7 +434,7 @@
|
||||
"Do you want to restart, or select a new Training Plan?": "Újra akarod indítani, vagy inkább egy másikat választasz?",
|
||||
"New Training Plan": "Másik edzésterv",
|
||||
"Restart": "Újraindítom",
|
||||
"Training Day": "Nap",
|
||||
"Training Day": "Edzésnap",
|
||||
"No Active Training Plan": "Nincs aktív edzésterv",
|
||||
"Please select one in the Training menu, or create your custom plan": "Kérlek válassz egyet a Tréning menüben, vagy hozd létre a saját egyéni edzésedet",
|
||||
"Continue your training": "Folytasd az edzést",
|
||||
@ -506,5 +506,6 @@
|
||||
"Reach all basic functions, suggestions and": "Kattints a regisztrációra, hogy elérd az alap funkciókat, javaslatokat,",
|
||||
"optimized training plans, customized to your fitness state and strength:": "optiomalizált edzés terveket, amelyeket a te erő- és fitnesz állapododra szabunk:",
|
||||
"Soon! Check back later for the plan details": "Nemsokára! Nézz vissza később, amikor már aktiváltuk az edzésterv részleteit",
|
||||
"mins": "perc"
|
||||
"mins": "perc",
|
||||
"set": "sorozat"
|
||||
}
|
228
ios/Podfile.lock
228
ios/Podfile.lock
@ -4,61 +4,80 @@ PODS:
|
||||
- AppAuth/ExternalUserAgent (= 1.4.0)
|
||||
- AppAuth/Core (1.4.0)
|
||||
- AppAuth/ExternalUserAgent (1.4.0)
|
||||
- awesome_notifications (0.0.2):
|
||||
- Flutter
|
||||
- device_info (0.0.1):
|
||||
- Flutter
|
||||
- devicelocale (0.0.1):
|
||||
- Flutter
|
||||
- FBSDKCoreKit (9.1.0):
|
||||
- FBSDKCoreKit/Basics (= 9.1.0)
|
||||
- FBSDKCoreKit/Core (= 9.1.0)
|
||||
- FBSDKCoreKit/Basics (9.1.0)
|
||||
- FBSDKCoreKit/Core (9.1.0):
|
||||
- FBSDKCoreKit/Basics
|
||||
- FBSDKLoginKit (9.1.0):
|
||||
- FBSDKLoginKit/Login (= 9.1.0)
|
||||
- FBSDKLoginKit/Login (9.1.0):
|
||||
- FBSDKCoreKit (~> 9.1.0)
|
||||
- Firebase/Analytics (8.0.0):
|
||||
- FBAEMKit (11.1.0):
|
||||
- FBAEMKit/AEM (= 11.1.0)
|
||||
- FBAEMKit/AEM (11.1.0):
|
||||
- FBSDKCoreKit_Basics (~> 11.1.0)
|
||||
- FBSDKCoreKit (11.1.0):
|
||||
- FBSDKCoreKit/Core (= 11.1.0)
|
||||
- FBSDKCoreKit/Core (11.1.0):
|
||||
- FBAEMKit (~> 11.1.0)
|
||||
- FBSDKCoreKit_Basics (~> 11.1.0)
|
||||
- FBSDKCoreKit_Basics (11.1.0):
|
||||
- FBSDKCoreKit_Basics/Basics (= 11.1.0)
|
||||
- FBSDKCoreKit_Basics/Basics (11.1.0)
|
||||
- FBSDKLoginKit (11.1.0):
|
||||
- FBSDKLoginKit/Login (= 11.1.0)
|
||||
- FBSDKLoginKit/Login (11.1.0):
|
||||
- FBSDKCoreKit (~> 11.1.0)
|
||||
- FBSDKCoreKit_Basics (~> 11.1.0)
|
||||
- Firebase/Analytics (8.5.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Auth (8.0.0):
|
||||
- Firebase/Auth (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAuth (~> 8.0.0)
|
||||
- Firebase/Core (8.0.0):
|
||||
- FirebaseAuth (~> 8.5.0)
|
||||
- Firebase/Core (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 8.0.0)
|
||||
- Firebase/CoreOnly (8.0.0):
|
||||
- FirebaseCore (= 8.0.0)
|
||||
- Firebase/Messaging (8.0.0):
|
||||
- FirebaseAnalytics (~> 8.5.0)
|
||||
- Firebase/CoreOnly (8.5.0):
|
||||
- FirebaseCore (= 8.5.0)
|
||||
- Firebase/DynamicLinks (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 8.0.0)
|
||||
- Firebase/RemoteConfig (8.0.0):
|
||||
- FirebaseDynamicLinks (~> 8.5.0)
|
||||
- Firebase/InAppMessaging (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseRemoteConfig (~> 8.0.0)
|
||||
- firebase_analytics (8.1.0):
|
||||
- Firebase/Analytics (= 8.0.0)
|
||||
- FirebaseInAppMessaging (~> 8.5.0-beta)
|
||||
- Firebase/Messaging (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 8.5.0)
|
||||
- Firebase/RemoteConfig (8.5.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseRemoteConfig (~> 8.5.0)
|
||||
- firebase_analytics (8.3.0):
|
||||
- Firebase/Analytics (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_auth (1.2.0):
|
||||
- Firebase/Auth (= 8.0.0)
|
||||
- firebase_auth (3.0.2):
|
||||
- Firebase/Auth (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_core (1.2.0):
|
||||
- Firebase/CoreOnly (= 8.0.0)
|
||||
- firebase_core (1.5.0):
|
||||
- Firebase/CoreOnly (= 8.5.0)
|
||||
- Flutter
|
||||
- firebase_messaging (10.0.0):
|
||||
- Firebase/Messaging (= 8.0.0)
|
||||
- firebase_dynamic_links (2.0.8):
|
||||
- Firebase/DynamicLinks (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_remote_config (0.10.0):
|
||||
- Firebase/RemoteConfig (= 8.0.0)
|
||||
- firebase_in_app_messaging (0.5.0-8):
|
||||
- Firebase/InAppMessaging (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseABTesting (8.0.0):
|
||||
- firebase_messaging (10.0.5):
|
||||
- Firebase/Messaging (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_remote_config (0.10.0-4):
|
||||
- Firebase/RemoteConfig (= 8.5.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseABTesting (8.6.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseAnalytics (8.0.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 8.0.0)
|
||||
- FirebaseAnalytics (8.5.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 8.5.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
@ -66,51 +85,50 @@ PODS:
|
||||
- GoogleUtilities/Network (~> 7.4)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (8.0.0):
|
||||
- FirebaseAnalytics/Base (= 8.0.0)
|
||||
- FirebaseAnalytics/AdIdSupport (8.5.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleAppMeasurement (= 8.0.0)
|
||||
- GoogleAppMeasurement (= 8.5.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Network (~> 7.4)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAnalytics/Base (8.0.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Network (~> 7.4)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAuth (8.0.0):
|
||||
- FirebaseAuth (8.5.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- FirebaseCore (8.0.0):
|
||||
- FirebaseCore (8.5.0):
|
||||
- FirebaseCoreDiagnostics (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- GoogleUtilities/Logger (~> 7.4)
|
||||
- FirebaseCoreDiagnostics (8.0.0):
|
||||
- FirebaseCoreDiagnostics (8.6.0):
|
||||
- GoogleDataTransport (~> 9.0)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- GoogleUtilities/Logger (~> 7.4)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseInstallations (8.0.0):
|
||||
- FirebaseDynamicLinks (8.5.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInAppMessaging (8.5.0-beta):
|
||||
- FirebaseABTesting (~> 8.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseInstallations (8.6.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- GoogleUtilities/UserDefaults (~> 7.4)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- FirebaseMessaging (8.0.0):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- FirebaseMessaging (8.5.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Environment (~> 7.4)
|
||||
- GoogleUtilities/Reachability (~> 7.4)
|
||||
- GoogleUtilities/UserDefaults (~> 7.4)
|
||||
- FirebaseRemoteConfig (8.0.0):
|
||||
- FirebaseRemoteConfig (8.5.0):
|
||||
- FirebaseABTesting (~> 8.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
@ -124,12 +142,12 @@ PODS:
|
||||
- flutter_app_badger (0.0.1):
|
||||
- Flutter
|
||||
- flutter_facebook_auth (2.0.0):
|
||||
- FBSDKCoreKit (~> 9.1.0)
|
||||
- FBSDKLoginKit (~> 9.1.0)
|
||||
- FBSDKCoreKit (~> 11.1.0)
|
||||
- FBSDKLoginKit (~> 11.1.0)
|
||||
- Flutter
|
||||
- flutter_secure_storage (3.3.1):
|
||||
- Flutter
|
||||
- flutter_uxcam (2.0.0-beta.1):
|
||||
- flutter_uxcam (2.0.0):
|
||||
- Flutter
|
||||
- UXCam (~> 3.3.4)
|
||||
- FMDB (2.7.5):
|
||||
@ -138,45 +156,45 @@ PODS:
|
||||
- google_sign_in (0.0.1):
|
||||
- Flutter
|
||||
- GoogleSignIn (~> 5.0)
|
||||
- GoogleAppMeasurement (8.0.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 8.0.0)
|
||||
- GoogleAppMeasurement (8.5.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 8.5.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Network (~> 7.4)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (8.0.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (8.5.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||
- GoogleUtilities/Network (~> 7.4)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleDataTransport (9.0.0):
|
||||
- GoogleDataTransport (9.1.0):
|
||||
- GoogleUtilities/Environment (~> 7.2)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleSignIn (5.0.2):
|
||||
- AppAuth (~> 1.2)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.4.1):
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.5.1):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (7.4.1):
|
||||
- PromisesObjC (~> 1.2)
|
||||
- GoogleUtilities/Logger (7.4.1):
|
||||
- GoogleUtilities/Environment (7.5.1):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Logger (7.5.1):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/MethodSwizzler (7.4.1):
|
||||
- GoogleUtilities/MethodSwizzler (7.5.1):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network (7.4.1):
|
||||
- GoogleUtilities/Network (7.5.1):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (7.4.1)"
|
||||
- GoogleUtilities/Reachability (7.4.1):
|
||||
- "GoogleUtilities/NSData+zlib (7.5.1)"
|
||||
- GoogleUtilities/Reachability (7.5.1):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (7.4.1):
|
||||
- GoogleUtilities/UserDefaults (7.5.1):
|
||||
- GoogleUtilities/Logger
|
||||
- GTMAppAuth (1.2.2):
|
||||
- AppAuth/Core (~> 1.4)
|
||||
@ -195,7 +213,7 @@ PODS:
|
||||
- Flutter
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- PromisesObjC (1.2.12)
|
||||
- PromisesObjC (2.0.0)
|
||||
- Purchases (3.11.1):
|
||||
- PurchasesCoreSwift (= 3.11.1)
|
||||
- purchases_flutter (3.2.2):
|
||||
@ -231,12 +249,13 @@ PODS:
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`)
|
||||
- device_info (from `.symlinks/plugins/device_info/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_dynamic_links (from `.symlinks/plugins/firebase_dynamic_links/ios`)
|
||||
- firebase_in_app_messaging (from `.symlinks/plugins/firebase_in_app_messaging/ios`)
|
||||
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||
- firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`)
|
||||
- flurry_data (from `.symlinks/plugins/flurry_data/ios`)
|
||||
@ -264,7 +283,9 @@ DEPENDENCIES:
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- AppAuth
|
||||
- FBAEMKit
|
||||
- FBSDKCoreKit
|
||||
- FBSDKCoreKit_Basics
|
||||
- FBSDKLoginKit
|
||||
- Firebase
|
||||
- FirebaseABTesting
|
||||
@ -272,6 +293,8 @@ SPEC REPOS:
|
||||
- FirebaseAuth
|
||||
- FirebaseCore
|
||||
- FirebaseCoreDiagnostics
|
||||
- FirebaseDynamicLinks
|
||||
- FirebaseInAppMessaging
|
||||
- FirebaseInstallations
|
||||
- FirebaseMessaging
|
||||
- FirebaseRemoteConfig
|
||||
@ -292,8 +315,6 @@ SPEC REPOS:
|
||||
- UXCam
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
awesome_notifications:
|
||||
:path: ".symlinks/plugins/awesome_notifications/ios"
|
||||
device_info:
|
||||
:path: ".symlinks/plugins/device_info/ios"
|
||||
devicelocale:
|
||||
@ -304,6 +325,10 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/firebase_auth/ios"
|
||||
firebase_core:
|
||||
:path: ".symlinks/plugins/firebase_core/ios"
|
||||
firebase_dynamic_links:
|
||||
:path: ".symlinks/plugins/firebase_dynamic_links/ios"
|
||||
firebase_in_app_messaging:
|
||||
:path: ".symlinks/plugins/firebase_in_app_messaging/ios"
|
||||
firebase_messaging:
|
||||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||
firebase_remote_config:
|
||||
@ -353,38 +378,43 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
||||
awesome_notifications: 74462bc8e68b11f8235d78422266886759e9da61
|
||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||
devicelocale: b22617f40038496deffba44747101255cee005b0
|
||||
FBSDKCoreKit: a00fe2efd780c195a5e09201bf51c56106245b40
|
||||
FBSDKLoginKit: d98498c598ec09de657385a9349a1f21119b7f86
|
||||
Firebase: 73c3e3b216ec1ecbc54d2ffdd4670c65c749edb1
|
||||
firebase_analytics: 221d3bc4e8f1b5144a4bd4cc6b33790ee51bd543
|
||||
firebase_auth: f960df4ddd8cb415859dbc01a02d7859925ddef0
|
||||
firebase_core: e4d3efb030a2b2021819f8faa538bb23deb46695
|
||||
firebase_messaging: 3b6e0657b21261a57a1cd041fafa713f2aa6923f
|
||||
firebase_remote_config: 3a6e2db440f0e95baba3dfc3d4118b1a4bc792c4
|
||||
FirebaseABTesting: daebc95ec8829607d07dfe5e92dc3285aca29bc4
|
||||
FirebaseAnalytics: dcb92c7c9ef4fa7ffac276e8f87bd4fc8c97f1b8
|
||||
FirebaseAuth: b8cd992fca5b53dc6eec09e873a3f375f000c5a1
|
||||
FirebaseCore: 3f09591d51292843e2a46f18358d60bf4e996255
|
||||
FirebaseCoreDiagnostics: a31d987ba0fe16d59886a5dbadc2f1de871f88c8
|
||||
FirebaseInstallations: c4aab1005d6547b00a7529777fe52f5d4d45165b
|
||||
FirebaseMessaging: 1a33b4af3c8042ed6ddacb6c031894af2064bfab
|
||||
FirebaseRemoteConfig: 055f6b5ba1751547596ded5032c4d5c6054ca501
|
||||
FBAEMKit: 5c8a8d08e5b2c79628490784883e0fcc75b12615
|
||||
FBSDKCoreKit: 7ccb8b4bb2b5ee2ad94327b774dc23f03509675d
|
||||
FBSDKCoreKit_Basics: 8f978bce195845f609b0ec6b425949d0d24f525b
|
||||
FBSDKLoginKit: d65eb587a9eaa89295338fb0bb3b358bde0b7ae4
|
||||
Firebase: ff8c73105b90e33e1dc6c8e5445d7adc2ccdc7c1
|
||||
firebase_analytics: 3b7d92b8d1a3482f557c201e5e46c2f7fa2644ff
|
||||
firebase_auth: 214ff86facd807bbb0ccff32f4b2d3865e3bc4f3
|
||||
firebase_core: 82d486a6231b636aea229bd471bceca82cbe00a6
|
||||
firebase_dynamic_links: 0768a32e69be5b6f9af258f8e072537dff6b8969
|
||||
firebase_in_app_messaging: 04572963cf1ef212ac23e188cb0324316e948bf9
|
||||
firebase_messaging: 0c5342aa6d92d09429ef67c81a1345189fcb76c9
|
||||
firebase_remote_config: cd43874ff082605023b5913bb1d3206452f1ad48
|
||||
FirebaseABTesting: c3e48ebf5e7e5c674c5a131c68e941d7921d83dc
|
||||
FirebaseAnalytics: 96325c1e0acbd2bb805c6a613028b1fe599d6a37
|
||||
FirebaseAuth: b152ea261b60eeb9419ae7e5bf34761382b33277
|
||||
FirebaseCore: 1c1ca72483b59b17050f5b4cec4fb748425a3901
|
||||
FirebaseCoreDiagnostics: 3721920bde3a9a6d5aa093c1d25e9d3e47f694af
|
||||
FirebaseDynamicLinks: 6e406b3bb669f8c8a63e7254bb63251fa3f88a43
|
||||
FirebaseInAppMessaging: ee6cd4397d1e81d34b14f90ec38697dc4ef9fe93
|
||||
FirebaseInstallations: 0ede6ffcd215b8f93c19d9b06c1c54e2d4107e98
|
||||
FirebaseMessaging: 0705ec705c21705efc51c071fba924c8e25c63e7
|
||||
FirebaseRemoteConfig: 693c1f150408e9a727daf4d8c55c7f9c29ef9ad5
|
||||
Flurry-iOS-SDK: 5831da8fc6bedb31fa1f94aac6fd204d36dd351d
|
||||
flurry_data: 49b7066a283aa41f4306974c1f2d74c61231ad74
|
||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||
flutter_app_badger: 65de4d6f0c34a891df49e6cfb8a1c0496426fa68
|
||||
flutter_facebook_auth: 4b170c07b7fce791497093fcc3f134fb215f3f07
|
||||
flutter_facebook_auth: 528d51ea1324741b366fa87fa5dfd41016422364
|
||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||
flutter_uxcam: ab8e5d3954eb448febd581375e2622e9eecb1066
|
||||
flutter_uxcam: 5b2418884a3bf41284a888c7ecc50317c8a84727
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
|
||||
GoogleAppMeasurement: c6bbc9753d046b5456dd4f940057fbad2c28419e
|
||||
GoogleDataTransport: 11e3a5f2c190327df1a4a5d7e7ae3d4d5b9c9e4c
|
||||
GoogleAppMeasurement: 8d10c1c470fcb0e5143ed74fddd164f0a0384800
|
||||
GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
|
||||
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
|
||||
GoogleUtilities: f8a43108b38a68eebe8b3540e1f4f2d28843ce20
|
||||
GoogleUtilities: 3df19e3c24f7bbc291d8b5809aa6b0d41e642437
|
||||
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
||||
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
|
||||
modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
|
||||
@ -392,7 +422,7 @@ SPEC CHECKSUMS:
|
||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
||||
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
|
||||
Purchases: 6351f9ff6bd514e5ec5aa0f989ea181effa94bf5
|
||||
purchases_flutter: 627527b070d80cdaf486fabe8b3d1dbe8d5cad92
|
||||
PurchasesCoreSwift: ee857e4c21e6254b09d7e303a756fcf2b9164408
|
||||
@ -411,4 +441,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: f10c0438b63bc24e6bbc207956dc27d16c4408f2
|
||||
|
||||
COCOAPODS: 1.10.1
|
||||
COCOAPODS: 1.11.0.beta.2
|
||||
|
@ -396,7 +396,7 @@
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -405,12 +405,12 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.21;
|
||||
MARKETING_VERSION = 1.1.22;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
@ -539,7 +539,7 @@
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -548,13 +548,13 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.21;
|
||||
MARKETING_VERSION = 1.1.22;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
@ -574,7 +574,7 @@
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@ -583,12 +583,12 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.21;
|
||||
MARKETING_VERSION = 1.1.22;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
|
@ -10,6 +10,9 @@ import Firebase
|
||||
) -> Bool {
|
||||
FirebaseApp.configure()
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
if #available(iOS 12.0, *) {
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
}
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
}
|
||||
|
@ -1,75 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WorkoutTest</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>fb584181112271127</string>
|
||||
<string>com.googleusercontent.apps.926782702216-2nsi7d9at3pc5ts8gkobt5697v590kb9</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>FacebookAppID</key>
|
||||
<string>584181112271127</string>
|
||||
<key>FacebookDisplayName</key>
|
||||
<string>Mobile Login</string>
|
||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||
<string>NO</string>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
<string>http</string>
|
||||
</array>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>11.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WorkoutTest</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>aitrainer.page.link</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>wt001</string>
|
||||
<string>fb584181112271127</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>FacebookAdvertiserIDCollectionEnabled</key>
|
||||
<string>TRUE</string>
|
||||
<key>FacebookAppID</key>
|
||||
<string>584181112271127</string>
|
||||
<key>FacebookAutoLogAppEventsEnabled</key>
|
||||
<string>TRUE</string>
|
||||
<key>FacebookDisplayName</key>
|
||||
<string>Workout Test</string>
|
||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||
<string>NO</string>
|
||||
<key>LSApplicationQueriesSchemes</key>
|
||||
<array>
|
||||
<string>https</string>
|
||||
<string>http</string>
|
||||
<string>fbapi</string>
|
||||
<string>fbapi20130214</string>
|
||||
<string>fbapi20130410</string>
|
||||
<string>fbapi20130702</string>
|
||||
<string>fbapi20131010</string>
|
||||
<string>fbapi20131219</string>
|
||||
<string>fbapi20140410</string>
|
||||
<string>fbapi20140116</string>
|
||||
<string>fbapi20150313</string>
|
||||
<string>fbapi20150629</string>
|
||||
<string>fbapi20160328</string>
|
||||
<string>fb-messenger-share-api</string>
|
||||
<string>fbauth2</string>
|
||||
<string>fbshareextension</string>
|
||||
</array>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>11.0.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>Launch Screen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>Launch Screen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -8,6 +8,10 @@
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
<key>com.apple.developer.associated-domains</key>
|
||||
<array>
|
||||
<string>applinks:aitrainer.page.link</string>
|
||||
</array>
|
||||
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
@ -29,8 +29,8 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
weight = this.customerRepository.getWeight() == 0 ? 60 : this.customerRepository.getWeight();
|
||||
height = this.customerRepository.getHeight() == 0 ? 170 : this.customerRepository.getHeight();
|
||||
|
||||
selectedSport = customerRepository.getSport();
|
||||
print("selected: $selectedFitnessItem sport: $selectedSport " + customerRepository.customer!.fitnessLevel.toString());
|
||||
// selectedSport = customerRepository.getSport();
|
||||
//print("selected: $selectedFitnessItem sport: $selectedSport " + customerRepository.customer!.fitnessLevel.toString());
|
||||
}
|
||||
|
||||
Sport? selectedSport;
|
||||
@ -41,6 +41,7 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
CustomerChangeEvent event,
|
||||
) async* {
|
||||
try {
|
||||
print("Event: $event");
|
||||
if (event is CustomerLoad) {
|
||||
yield CustomerChangeLoading();
|
||||
yield CustomerDataChanged();
|
||||
@ -63,7 +64,7 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
year = event.year;
|
||||
yield CustomerDataChanged();
|
||||
} else if (event is CustomerWeightChange) {
|
||||
yield CustomerChangeLoading();
|
||||
//yield CustomerChangeLoading();
|
||||
customerRepository.setWeight(event.weight);
|
||||
weight = event.weight.toDouble();
|
||||
yield CustomerDataChanged();
|
||||
@ -88,12 +89,43 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
customerRepository.setName(event.name);
|
||||
yield CustomerDataChanged();
|
||||
} else if (event is CustomerGenderChange) {
|
||||
yield CustomerChangeLoading();
|
||||
customerRepository.setSex(event.gender == 0 ? "m" : "w");
|
||||
yield CustomerDataChanged();
|
||||
} else if (event is CustomerSportChange) {
|
||||
yield CustomerChangeLoading();
|
||||
selectedSport = event.sport;
|
||||
yield CustomerDataChanged();
|
||||
} else if (event is CustomerSaveFitness) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.fitnessLevel == null) {
|
||||
throw Exception("Please select your fitness level");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveGoal) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.goal == null) {
|
||||
throw Exception("Please select your goal");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveSex) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.sex == null) {
|
||||
throw Exception("Please select your biologial gender");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveWeight) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.getProperty("Weight") == null) {
|
||||
throw Exception("Please select your weight");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveHeight) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.getProperty("Height") == null) {
|
||||
throw Exception("Please select your height");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSave) {
|
||||
yield CustomerSaving();
|
||||
if (validation()) {
|
||||
|
@ -114,3 +114,23 @@ class CustomerLoad extends CustomerChangeEvent {
|
||||
class CustomerSave extends CustomerChangeEvent {
|
||||
const CustomerSave();
|
||||
}
|
||||
|
||||
class CustomerSaveGoal extends CustomerChangeEvent {
|
||||
const CustomerSaveGoal();
|
||||
}
|
||||
|
||||
class CustomerSaveFitness extends CustomerChangeEvent {
|
||||
const CustomerSaveFitness();
|
||||
}
|
||||
|
||||
class CustomerSaveSex extends CustomerChangeEvent {
|
||||
const CustomerSaveSex();
|
||||
}
|
||||
|
||||
class CustomerSaveWeight extends CustomerChangeEvent {
|
||||
const CustomerSaveWeight();
|
||||
}
|
||||
|
||||
class CustomerSaveHeight extends CustomerChangeEvent {
|
||||
const CustomerSaveHeight();
|
||||
}
|
||||
|
@ -1,13 +1,17 @@
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_ability.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_device_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
@ -111,6 +115,22 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
||||
listFilterDevice.remove(deviceId);
|
||||
}
|
||||
yield MenuReady();
|
||||
} else if (event is MenuStartTrial) {
|
||||
yield MenuLoading();
|
||||
final DateTime start = event.start;
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
customerRepository.customer!.trialDate = start;
|
||||
Cache().userLoggedIn!.trialDate = start;
|
||||
|
||||
customerRepository.saveCustomer();
|
||||
|
||||
if (DateTime.now().difference(start).inHours < 1) {
|
||||
Cache().hasPurchased = true;
|
||||
log("Trial mode on!");
|
||||
Track().track(TrackingEvent.trial, eventValue: DateFormat('yyyy-MM-dd HH:mm:ss').format(start));
|
||||
}
|
||||
yield MenuReady();
|
||||
}
|
||||
} on Exception catch (ex) {
|
||||
yield MenuError(message: ex.toString());
|
||||
@ -134,6 +154,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
||||
case "my_body":
|
||||
ability = ExerciseAbility.none;
|
||||
break;
|
||||
case "training_execute":
|
||||
ability = ExerciseAbility.training_execute;
|
||||
break;
|
||||
}
|
||||
log("Ability: " + ability.toString() + " name: " + name);
|
||||
}
|
||||
|
@ -56,4 +56,15 @@ class MenuRecreateTree extends MenuEvent {
|
||||
class MenuFilterExerciseType extends MenuEvent {
|
||||
final int deviceId;
|
||||
const MenuFilterExerciseType({required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId];
|
||||
}
|
||||
|
||||
class MenuStartTrial extends MenuEvent {
|
||||
final DateTime start;
|
||||
const MenuStartTrial({required this.start});
|
||||
|
||||
@override
|
||||
List<Object> get props => [start];
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ part 'session_state.dart';
|
||||
|
||||
class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
||||
final Session session;
|
||||
StreamSubscription? _sub;
|
||||
|
||||
SessionBloc({required this.session}) : super(SessionInitial());
|
||||
|
||||
@ -41,6 +42,7 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await this.close();
|
||||
_sub?.cancel();
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
|
@ -59,10 +59,12 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
|
||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||
//if (!element.state.equalsTo(ExercisePlanDetailState.extra)) {
|
||||
if (!findExerciseInEvaluationList(element.exerciseTypeId!)) {
|
||||
addEvaluationExercise(element);
|
||||
} else {
|
||||
//editEvaluationExercise(element);
|
||||
if (element.exerciseTypeId != null) {
|
||||
if (!findExerciseInEvaluationList(element.exerciseTypeId!)) {
|
||||
addEvaluationExercise(element);
|
||||
} else {
|
||||
//editEvaluationExercise(element);
|
||||
}
|
||||
}
|
||||
//}
|
||||
});
|
||||
@ -93,7 +95,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
||||
this.evaluationList.add(exercise);
|
||||
} else {
|
||||
if (detail.exerciseType!.unitQuantityUnit == null) {
|
||||
if (detail.exerciseType!.unitQuantityUnit == null || detail.weight == null) {
|
||||
exercise.type = TrainingEvaluationExerciseType.repeatBased;
|
||||
exercise.repeats = detail.repeats;
|
||||
exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!);
|
||||
|
@ -46,7 +46,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
try {
|
||||
if (event is TrainingPlanActivate) {
|
||||
yield TrainingPlanLoading();
|
||||
_myPlan = await trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
|
||||
_myPlan = trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
|
||||
_myPlan!.type = CustomerTrainingPlanType.template;
|
||||
|
||||
menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||
@ -72,7 +72,6 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
event.detail.repeats =
|
||||
Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.weight);
|
||||
event.detail.weight = event.weight;
|
||||
print(" weight: ${event.weight} new repeats: ${event.detail.repeats}");
|
||||
|
||||
yield TrainingPlanReady();
|
||||
} else if (event is TrainingPlanRepeatsChange) {
|
||||
@ -102,13 +101,12 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
exercise.unitQuantity = event.detail.weight;
|
||||
exercise.dateAdd = DateTime.now();
|
||||
event.detail.exercises.add(exercise);
|
||||
if (event.detail.exercises.length >= event.detail.set!) {
|
||||
if (this.isAllDetailsSameExerciseFinished(event.detail)) {
|
||||
event.detail.state = ExercisePlanDetailState.finished;
|
||||
} else if (event.detail.exercises.length >= 0) {
|
||||
event.detail.state = ExercisePlanDetailState.inProgress;
|
||||
}
|
||||
// recalculate the weight to the original planned repeats for the next details
|
||||
|
||||
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
|
||||
for (var nextDetail in _myPlan!.details) {
|
||||
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
|
||||
@ -357,6 +355,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
return workoutTree.imageName;
|
||||
}
|
||||
|
||||
int getStep(CustomerTrainingPlanDetails detail) {
|
||||
List<CustomerTrainingPlanDetails> details = getAllDetailsSameExercise(detail);
|
||||
int step = 0;
|
||||
int indexElement = 0;
|
||||
details.forEach((element) {
|
||||
if (indexElement == 0) {
|
||||
step = element.exercises.length;
|
||||
} else {
|
||||
step += element.exercises.length;
|
||||
}
|
||||
indexElement++;
|
||||
});
|
||||
|
||||
//print("STEP: $step ");
|
||||
return step;
|
||||
}
|
||||
|
||||
CustomerTrainingPlanDetails? getNext() {
|
||||
if (_myPlan == null || _myPlan!.details.isEmpty) {
|
||||
return null;
|
||||
@ -373,12 +388,16 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
break;
|
||||
} else {
|
||||
final int step = detail.exercises.length;
|
||||
if (step < minStep && !detail.state.equalsTo(ExercisePlanDetailState.skipped) && day == detail.day) {
|
||||
if (step < minStep &&
|
||||
step < detail.set! &&
|
||||
!isAllDetailsSameExerciseFinished(detail) &&
|
||||
!detail.state.equalsTo(ExercisePlanDetailState.skipped) &&
|
||||
day == detail.day) {
|
||||
next = detail;
|
||||
minStep = step;
|
||||
if (detail.parallel != true) {
|
||||
break;
|
||||
}
|
||||
//if (detail.parallel != true) {
|
||||
break;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -423,18 +442,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
int indexInProgress = 0;
|
||||
int indexInStart = 0;
|
||||
final String day = dayNames[this.activeDayIndex];
|
||||
CustomerTrainingPlanDetails? prev;
|
||||
for (var detail in _myPlan!.days[day]!) {
|
||||
if (detail.state == ExercisePlanDetailState.inProgress) {
|
||||
//print("Offset detail $detail");
|
||||
if (detail.state == ExercisePlanDetailState.inProgress || detail.state == ExercisePlanDetailState.start) {
|
||||
prev = detail;
|
||||
break;
|
||||
}
|
||||
if (detail.state == ExercisePlanDetailState.start) {
|
||||
break;
|
||||
|
||||
if (prev != null && prev.exerciseTypeId != detail.exerciseTypeId && detail.state != ExercisePlanDetailState.extra) {
|
||||
//print(" --- offset + 1");
|
||||
indexInStart++;
|
||||
indexInProgress++;
|
||||
}
|
||||
indexInStart++;
|
||||
indexInProgress++;
|
||||
prev = detail;
|
||||
}
|
||||
int index = indexInStart > indexInProgress ? indexInStart : indexInProgress;
|
||||
offset = index * 80;
|
||||
offset = (index) * 270;
|
||||
print("Offset: $offset day: $day ($indexInStart, $indexInProgress)");
|
||||
return offset;
|
||||
}
|
||||
@ -573,4 +597,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
List<CustomerTrainingPlanDetails> getAllDetailsSameExercise(CustomerTrainingPlanDetails detail) {
|
||||
List<CustomerTrainingPlanDetails> list = [];
|
||||
getMyPlan()!.details.forEach((element) {
|
||||
if (detail.exerciseTypeId == element.exerciseTypeId) {
|
||||
list.add(element);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
bool isAllDetailsSameExerciseFinished(CustomerTrainingPlanDetails detail) {
|
||||
bool allFinished = true;
|
||||
List<CustomerTrainingPlanDetails> list = getAllDetailsSameExercise(detail);
|
||||
for (var listDetail in list) {
|
||||
allFinished = allFinished && listDetail.exercises.length >= listDetail.set!;
|
||||
}
|
||||
return allFinished;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,10 @@ import 'package:aitrainer_app/view/customer_bodytype_animation.dart';
|
||||
import 'package:aitrainer_app/view/customer_exercise_device.dart';
|
||||
import 'package:aitrainer_app/view/customer_fitness_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_goal_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_height_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_modify_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_sex_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_weight_page.dart';
|
||||
import 'package:aitrainer_app/view/customer_welcome_page.dart';
|
||||
import 'package:aitrainer_app/view/evaluation_page.dart';
|
||||
import 'package:aitrainer_app/view/exercise_control_page.dart';
|
||||
@ -23,6 +26,7 @@ import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/exercise_new_page.dart';
|
||||
import 'package:aitrainer_app/view/training_plan_custom.dart';
|
||||
import 'package:aitrainer_app/view/training_plan_custom_add.dart';
|
||||
import 'package:aitrainer_app/view/training_plan_execute.dart';
|
||||
import 'package:aitrainer_app/view/training_plans_page.dart';
|
||||
import 'package:aitrainer_app/view/mydevelopment_body_page.dart';
|
||||
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
|
||||
@ -146,7 +150,6 @@ Future<Null> main() async {
|
||||
}
|
||||
|
||||
print(" -- FireBase init..");
|
||||
await FirebaseApi().initializeFlutterFire();
|
||||
|
||||
runApp(MultiBlocProvider(
|
||||
providers: [
|
||||
@ -177,8 +180,8 @@ Future<Null> main() async {
|
||||
BlocProvider<TestSetExecuteBloc>(
|
||||
create: (BuildContext context) => TestSetExecuteBloc(),
|
||||
),
|
||||
BlocProvider<TutorialBloc>(
|
||||
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
|
||||
/* BlocProvider<TutorialBloc>(
|
||||
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())), */
|
||||
BlocProvider<TrainingPlanBloc>(create: (context) {
|
||||
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
|
||||
@ -196,6 +199,7 @@ Future<void> initThirdParty() async {
|
||||
await FlurryData.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
|
||||
FlutterUxcam.optIntoSchematicRecordings();
|
||||
}
|
||||
await FirebaseApi().initializeFlutterFire();
|
||||
}
|
||||
|
||||
class WorkoutTestApp extends StatelessWidget {
|
||||
@ -217,6 +221,7 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
|
||||
//facebookAppEvents.setAdvertiserTracking(enabled: true);
|
||||
initThirdParty();
|
||||
|
||||
return MaterialApp(
|
||||
localizationsDelegates: [
|
||||
// ... app-specific localization delegate[s] here
|
||||
@ -249,6 +254,9 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
'customerModifyPage': (context) => CustomerModifyPage(),
|
||||
'customerGoalPage': (context) => CustomerGoalPage(),
|
||||
'customerFitnessPage': (context) => CustomerFitnessPage(),
|
||||
'customerSexPage': (context) => CustomerSexPage(),
|
||||
'customerWeightPage': (context) => CustomerWeightPage(),
|
||||
'customerHeightPage': (context) => CustomerHeightPage(),
|
||||
'customerBodyTypePage': (context) => CustomerBodyTypeAnimationPage(),
|
||||
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
||||
'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(),
|
||||
@ -275,7 +283,8 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
'myTrainingPlanCustom': (context) => TrainingPlanCustomPage(),
|
||||
'myTrainingPlanCustomAdd': (context) => TrainingPlanCustomAddPage(),
|
||||
'myTrainingPlanActivate': (context) => TrainingPlanActivatePage(),
|
||||
'myTrainingPlanExecute': (context) => TrainingPlanExecutePage(),
|
||||
'myTrainingPlanExecute2': (context) => TrainingPlanExecutePage(),
|
||||
'myTrainingPlanExecute': (context) => TrainingPlanExecute(),
|
||||
'myTrainingPlanExercise': (context) => TrainingPlanExercise(),
|
||||
'myTrainingEvaluation': (context) => TrainingEvaluationPage(),
|
||||
},
|
||||
|
@ -186,8 +186,8 @@ class Cache with Logging {
|
||||
Cache._internal() {
|
||||
String testEnv = EnvironmentConfig.test_env;
|
||||
this.testEnvironment = testEnv;
|
||||
print("testEnv $testEnv");
|
||||
if (testEnv == "1") {
|
||||
print("testEnv $testEnv");
|
||||
baseUrl = baseUrlTest;
|
||||
liveServer = false;
|
||||
}
|
||||
@ -234,6 +234,17 @@ class Cache with Logging {
|
||||
sharedPreferences.setString(Cache.myTrainingPlanKey, myTrainingPlanJson);
|
||||
}
|
||||
|
||||
Future<void> deleteMyTrainingPlan() async {
|
||||
if (myTrainingPlan == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
SharedPreferences sharedPreferences;
|
||||
sharedPreferences = await prefs;
|
||||
sharedPreferences.remove(Cache.myTrainingPlanKey);
|
||||
}
|
||||
|
||||
Future<void> getMyTrainingPlan() async {
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
SharedPreferences sharedPreferences;
|
||||
@ -744,4 +755,21 @@ class Cache with Logging {
|
||||
|
||||
List<TrainingPlanDay> getTrainingPlanDays() => this._trainingPlanDays;
|
||||
setTrainingPlanDays(value) => this._trainingPlanDays = value;
|
||||
|
||||
bool canTrial() {
|
||||
if (Cache().userLoggedIn == null) {
|
||||
return false;
|
||||
}
|
||||
for (var element in _purchases) {
|
||||
if (element.customerId == Cache().userLoggedIn!.customerId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (userLoggedIn!.trialDate != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ class Customer {
|
||||
DateTime? dateChange;
|
||||
int? emailSubscription;
|
||||
int? sportId;
|
||||
DateTime? trialDate;
|
||||
|
||||
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
|
||||
|
||||
@ -70,6 +71,7 @@ class Customer {
|
||||
this.dataPolicyAllowed = json['dataPolicyAllowed'];
|
||||
this.emailSubscription = json['emailSubscription'];
|
||||
this.sportId = json['sportId'];
|
||||
this.trialDate = json['trialDate'] == null ? null : DateTime.parse(json['trialDate']);
|
||||
|
||||
this.dateAdd = json['dateAdd'] == null ? DateTime.parse("0000-00-00") : DateTime.parse(json['dateAdd']);
|
||||
this.dateChange = json['dateChange'] == null ? DateTime.parse("0000-00-00") : DateTime.parse(json['dateChange']);
|
||||
@ -93,7 +95,8 @@ class Customer {
|
||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd!),
|
||||
"dateChange": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateChange!),
|
||||
"emailSubscription": this.emailSubscription,
|
||||
"sportId": this.sportId
|
||||
"sportId": this.sportId,
|
||||
"trialDate": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.trialDate!),
|
||||
};
|
||||
|
||||
double getProperty(String propertyName) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
enum ExerciseAbility { oneRepMax, endurance, running, mini_test_set, paralell_test, training, none }
|
||||
enum ExerciseAbility { oneRepMax, endurance, running, mini_test_set, paralell_test, training, training_execute, none }
|
||||
|
||||
extension ExerciseAbilityExt on ExerciseAbility {
|
||||
String enumToString() => this.toString().split(".").last;
|
||||
|
@ -75,6 +75,7 @@ class WorkoutMenuTree {
|
||||
"is1RM": is1RM.toString(),
|
||||
"isRunning": isRunning.toString(),
|
||||
"sort": sort,
|
||||
"internalName": internalName,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ class CustomerRepository with Logging {
|
||||
if (this.customer!.properties[propertyName] == null) {
|
||||
this.customer!.properties[propertyName] = CustomerProperty(
|
||||
propertyId: propertyRepository.getPropertyByName("Height")!.propertyId,
|
||||
customerId: this.customer!.customerId!,
|
||||
customerId: this.customer!.customerId == null ? 0 : this.customer!.customerId!,
|
||||
propertyValue: value,
|
||||
dateAdd: DateTime.now());
|
||||
} else {
|
||||
|
@ -4,9 +4,10 @@ import 'package:aitrainer_app/model/customer_training_plan_details.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||
import 'package:aitrainer_app/model/fitness_state.dart';
|
||||
import 'package:aitrainer_app/model/training_plan.dart';
|
||||
import 'package:aitrainer_app/repository/training_plan_day_repository.dart';
|
||||
import 'package:aitrainer_app/service/training_plan_service.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
|
||||
class TrainingPlanRepository {
|
||||
@ -40,14 +41,14 @@ class TrainingPlanRepository {
|
||||
/// 2. calculate customer_training_plan_details weights / repleats
|
||||
/// 3. create new customer_training_plan
|
||||
|
||||
Future<CustomerTrainingPlan?> activateTrainingPlan(int trainingPlanId) async {
|
||||
CustomerTrainingPlan? activateTrainingPlan(int trainingPlanId) {
|
||||
print(" **** Activate Plan: $trainingPlanId");
|
||||
// 1. deactivate
|
||||
if (Cache().getCustomerTrainingPlans() != null) {
|
||||
Cache().getCustomerTrainingPlans()!.forEach((plan) {
|
||||
plan.active = false;
|
||||
if (plan.customerTrainingPlanId != null) {
|
||||
TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
|
||||
//TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -58,7 +59,7 @@ class TrainingPlanRepository {
|
||||
plan.active = true;
|
||||
plan.status = "open";
|
||||
plan.dateAdd = DateTime.now();
|
||||
plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations["hu"];
|
||||
plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations[AppLanguage().appLocal.toString()];
|
||||
|
||||
TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
|
||||
if (trainingPlan == null || trainingPlan.details == null) {
|
||||
@ -138,6 +139,23 @@ class TrainingPlanRepository {
|
||||
return plan;
|
||||
}
|
||||
|
||||
int? getTrainingPlanByInternalName(String internalName) {
|
||||
int? id;
|
||||
if (Cache().getTrainingPlans() == null) {
|
||||
return id;
|
||||
}
|
||||
|
||||
for (var trainingPlan in Cache().getTrainingPlans()!) {
|
||||
print("internal ${trainingPlan.internalName}");
|
||||
if (trainingPlan.internalName == internalName) {
|
||||
id = trainingPlan.trainingPlanId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
CustomerTrainingPlanDetails getCalculatedWeightRepeats(int exerciseTypeId, CustomerTrainingPlanDetails detail) {
|
||||
double weight = -1;
|
||||
if (Cache().getExercises() == null) {
|
||||
@ -247,4 +265,32 @@ class TrainingPlanRepository {
|
||||
|
||||
return recalculatedDetail;
|
||||
}
|
||||
|
||||
void generateTrainingPlan() {
|
||||
int? trainingPlanId;
|
||||
if (Cache().userLoggedIn == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isWoman = Cache().userLoggedIn!.sex == "w";
|
||||
|
||||
if (Cache().userLoggedIn!.fitnessLevel == FitnessState.beginner) {
|
||||
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner") : getTrainingPlanByInternalName("beginner_man");
|
||||
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.intermediate) {
|
||||
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_beginner_split") : getTrainingPlanByInternalName("beginner_split");
|
||||
} else if (Cache().userLoggedIn!.fitnessLevel == FitnessState.advanced) {
|
||||
trainingPlanId = isWoman ? getTrainingPlanByInternalName("woman_advanced") : getTrainingPlanByInternalName("man_routine4");
|
||||
} else {
|
||||
trainingPlanId = isWoman ? getTrainingPlanByInternalName("5day") : getTrainingPlanByInternalName("5day");
|
||||
}
|
||||
|
||||
print("Generated plan $trainingPlanId fitness ${Cache().userLoggedIn!.fitnessLevel} - ${FitnessState.beginner}");
|
||||
|
||||
if (trainingPlanId != null) {
|
||||
CustomerTrainingPlan? customerTrainingPlan = activateTrainingPlan(trainingPlanId);
|
||||
if (customerTrainingPlan != null) {
|
||||
Cache().myTrainingPlan = customerTrainingPlan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ class ExerciseTreeApi with Logging {
|
||||
|
||||
Future<String> buildImage(String imageUrl, int treeId) async {
|
||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||
print("asset image $assetImage");
|
||||
return await rootBundle.load(assetImage).then((value) {
|
||||
return assetImage;
|
||||
}).catchError((_) {
|
||||
|
@ -4,12 +4,10 @@ import 'package:crypto/crypto.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart' as logging;
|
||||
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
|
||||
import 'package:awesome_notifications/awesome_notifications.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:firebase_remote_config/firebase_remote_config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
|
||||
@ -37,7 +35,8 @@ class FirebaseApi with logging.Logging {
|
||||
await Firebase.initializeApp();
|
||||
|
||||
this.appleSignInAvailable = await SignInWithApple.isAvailable();
|
||||
AwesomeNotifications().initialize(
|
||||
|
||||
/* AwesomeNotifications().initialize(
|
||||
// set the icon to null if you want to use the default app icon
|
||||
null,
|
||||
[
|
||||
@ -55,7 +54,7 @@ class FirebaseApi with logging.Logging {
|
||||
// This is very important to not harm the user experience
|
||||
AwesomeNotifications().requestPermissionToSendNotifications();
|
||||
}
|
||||
});
|
||||
}); */
|
||||
|
||||
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
|
||||
alert: true, // Required to display a heads up notification
|
||||
@ -71,32 +70,6 @@ class FirebaseApi with logging.Logging {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
print('Handling a background message: ${message.messageId}');
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(message.notification?.title, considerWhiteSpaceAsEmpty: true) ||
|
||||
!StringUtils.isNullOrEmpty(message.notification?.body, considerWhiteSpaceAsEmpty: true)) {
|
||||
print('message also contained a notification: ${message.notification}');
|
||||
|
||||
String? imageUrl;
|
||||
imageUrl ??= message.notification!.android?.imageUrl;
|
||||
imageUrl ??= message.notification!.apple?.imageUrl;
|
||||
|
||||
Map<String, dynamic> notificationAdapter = {
|
||||
NOTIFICATION_CHANNEL_KEY: 'basic_channel',
|
||||
NOTIFICATION_ID: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_ID] ?? message.messageId ?? math.Random().nextInt(2147483647),
|
||||
NOTIFICATION_TITLE: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_TITLE] ?? message.notification?.title,
|
||||
NOTIFICATION_BODY: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_BODY] ?? message.notification?.body,
|
||||
NOTIFICATION_LAYOUT: StringUtils.isNullOrEmpty(imageUrl) ? 'Default' : 'BigPicture',
|
||||
NOTIFICATION_BIG_PICTURE: imageUrl
|
||||
};
|
||||
|
||||
AwesomeNotifications().createNotificationFromJsonData(notificationAdapter);
|
||||
} else {
|
||||
AwesomeNotifications().createNotificationFromJsonData(message.data);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> signInEmail(String? email, String? password) async {
|
||||
if (email == null) {
|
||||
throw Exception("Please type an email address");
|
||||
@ -395,7 +368,7 @@ class FirebaseApi with logging.Logging {
|
||||
}
|
||||
|
||||
Future<void> setupRemoteConfig() async {
|
||||
initializeFlutterFire();
|
||||
//initializeFlutterFire();
|
||||
RemoteConfig? remoteConfig;
|
||||
try {
|
||||
remoteConfig = RemoteConfig.instance;
|
||||
@ -420,3 +393,35 @@ class FirebaseApi with logging.Logging {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
// If you're going to use other Firebase services in the background, such as Firestore,
|
||||
// make sure you call `initializeApp` before using other Firebase services.
|
||||
print('Handling a background message ${message.messageId}');
|
||||
}
|
||||
|
||||
/* Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
print('Handling a background message: ${message.messageId}');
|
||||
|
||||
if (!StringUtils.isNullOrEmpty(message.notification?.title, considerWhiteSpaceAsEmpty: true) ||
|
||||
!StringUtils.isNullOrEmpty(message.notification?.body, considerWhiteSpaceAsEmpty: true)) {
|
||||
print('message also contained a notification: ${message.notification}');
|
||||
|
||||
String? imageUrl;
|
||||
imageUrl ??= message.notification!.android?.imageUrl;
|
||||
imageUrl ??= message.notification!.apple?.imageUrl;
|
||||
|
||||
Map<String, dynamic> notificationAdapter = {
|
||||
NOTIFICATION_CHANNEL_KEY: 'basic_channel',
|
||||
NOTIFICATION_ID: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_ID] ?? message.messageId ?? math.Random().nextInt(2147483647),
|
||||
NOTIFICATION_TITLE: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_TITLE] ?? message.notification?.title,
|
||||
NOTIFICATION_BODY: message.data[NOTIFICATION_CONTENT]?[NOTIFICATION_BODY] ?? message.notification?.body,
|
||||
NOTIFICATION_LAYOUT: StringUtils.isNullOrEmpty(imageUrl) ? 'Default' : 'BigPicture',
|
||||
NOTIFICATION_BIG_PICTURE: imageUrl
|
||||
};
|
||||
|
||||
AwesomeNotifications().createNotificationFromJsonData(notificationAdapter);
|
||||
} else {
|
||||
AwesomeNotifications().createNotificationFromJsonData(message.data);
|
||||
}
|
||||
} */
|
||||
|
@ -57,6 +57,7 @@ enum TrackingEvent {
|
||||
training_plan_execute,
|
||||
training_plan_finished,
|
||||
training_plan_custom,
|
||||
trial
|
||||
}
|
||||
|
||||
T enumFromString<T>(Iterable<T> values, String value) {
|
||||
|
@ -46,7 +46,9 @@ class RevenueCatPurchases with Logging {
|
||||
log("Purchaserinfo not reachable " + e.toString());
|
||||
}
|
||||
}
|
||||
if (Cache().userLoggedIn!.admin == 1) {
|
||||
bool inTrial = Cache().userLoggedIn!.trialDate != null && DateTime.now().difference(Cache().userLoggedIn!.trialDate!).inDays < 10;
|
||||
log("Trial mode: $inTrial date: ${Cache().userLoggedIn!.trialDate}");
|
||||
if (Cache().userLoggedIn!.admin == 1 || inTrial) {
|
||||
Cache().hasPurchased = true;
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,13 @@ class Track with Logging {
|
||||
Track._internal();
|
||||
|
||||
void track(TrackingEvent event, {String eventValue = ""}) {
|
||||
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
|
||||
if (!isInDebugMode) {
|
||||
FlurryData.logEvent(event.toString());
|
||||
// Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
|
||||
FlutterUxcam.logEventWithProperties(event.enumToString(), {"value": eventValue});
|
||||
model.Tracking tracking = model.Tracking();
|
||||
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
|
||||
//analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
|
||||
tracking.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
|
||||
tracking.event = event.enumToString();
|
||||
if (eventValue.isNotEmpty) {
|
||||
|
@ -12,6 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AccountPage extends StatelessWidget with Trans {
|
||||
@ -151,6 +152,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
),
|
||||
devices(context, accountBloc),
|
||||
loginOut(context, accountBloc),
|
||||
//messaging(),
|
||||
//getMyTrainees(context, accountBloc),
|
||||
]);
|
||||
}
|
||||
@ -180,6 +182,25 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile messaging() {
|
||||
FirebaseInAppMessaging fiam = FirebaseInAppMessaging();
|
||||
ListTile element = ListTile(
|
||||
leading: Icon(Icons.message),
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t("Trigger message"), style: TextStyle(color: Colors.purple)),
|
||||
]),
|
||||
onPressed: () => fiam.triggerEvent("mydevelopment"),
|
||||
),
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile loginOut(BuildContext context, AccountBloc accountBloc) {
|
||||
ListTile element = ListTile();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/sport.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
@ -14,6 +15,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
import '../library/dropdown_search/dropdown_search.dart';
|
||||
@ -31,11 +33,13 @@ class CustomerFitnessPage extends StatefulWidget {
|
||||
class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
final double cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
CustomerRepository customerRepository;
|
||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
@ -49,186 +53,122 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 50, min: 26);
|
||||
_bar = AppBarProgress(max: 30, min: 15);
|
||||
}
|
||||
final double h = 27;
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: BlocProvider(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: Builder(builder: (context) {
|
||||
// ignore: close_sinks
|
||||
CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
selected = changeBloc.selectedFitnessItem;
|
||||
if (selected == null) {
|
||||
selected = FitnessState.beginner;
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: 200),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(
|
||||
//runAlignment: WrapAlignment.center,
|
||||
alignment: WrapAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
t("Your Fitness State"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.beginner),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(t("Beginner"),
|
||||
textWidthBasis: TextWidthBasis.longestLine,
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
|
||||
Text(
|
||||
t("I am beginner"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
],
|
||||
)),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.beginner;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.intermediate),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("Intermediate"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("I am intermediate"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.intermediate;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.advanced),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("Advanced"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
t("I am advanced"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.advanced;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, FitnessState.professional),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate("Professional"),
|
||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate("I am professional"),
|
||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
setState(() {
|
||||
selected = FitnessState.professional;
|
||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
||||
print(selected);
|
||||
}),
|
||||
}),
|
||||
Divider(),
|
||||
Text(
|
||||
t("Your Primary Sport") + ":",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 20,
|
||||
),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerSexPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
if (!fulldata)
|
||||
{
|
||||
changeBloc.add(CustomerSaveFitness()),
|
||||
}
|
||||
else
|
||||
{
|
||||
changeBloc.add(CustomerSave()),
|
||||
}
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Your Fitness State"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
|
||||
getButton("Beginner", "I am beginner", FitnessState.beginner),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Intermediate", "I am intermediate", FitnessState.intermediate),
|
||||
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Advanced", "I am advanced", FitnessState.advanced),
|
||||
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Professional", "I am professional", FitnessState.professional),
|
||||
|
||||
/* Divider(),
|
||||
Text(
|
||||
t("Your Primary Sport") + ":",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 20,
|
||||
),
|
||||
getSport(changeBloc),
|
||||
Divider(),
|
||||
), */
|
||||
//getSport(changeBloc),
|
||||
/* Divider(),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
onPrimary: Colors.white,
|
||||
@ -240,22 +180,58 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||
Navigator.of(context).pop(),
|
||||
if (!fulldata) {Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)}
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
) */
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TextButton getButton(String title, String desc, String state) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, state),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate(title),
|
||||
style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
);
|
||||
})));
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.translate(desc),
|
||||
style: TextStyle(color: Colors.white, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
||||
),
|
||||
highlightColor: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerFitnessChange(fitness: state)),
|
||||
});
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc changeBloc, String fitnessLevel) {
|
||||
String? selected = changeBloc.selectedFitnessItem;
|
||||
|
||||
dynamic returnCode = (selected == fitnessLevel)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.orange),
|
||||
side: BorderSide(
|
||||
width: 4,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: Colors.blue),
|
||||
side: BorderSide(width: 4, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
//return
|
||||
return returnCode;
|
||||
|
@ -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_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
enum Goals { gain_muscle, weight_loss, endurance, muscle_endurance, flexibility, gain_strength, explosiveness, shape_forming }
|
||||
|
||||
@ -69,18 +70,21 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
|
||||
CustomerRepository customerRepository;
|
||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
fulldata = args['personal_data'];
|
||||
customerRepository = args['bloc'];
|
||||
if (args != null) {
|
||||
if (args is HashMap && args['personal_data'] != null) {
|
||||
fulldata = args['personal_data'];
|
||||
customerRepository = args['bloc'];
|
||||
} else {
|
||||
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
}
|
||||
} else {
|
||||
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
customerRepository = CustomerRepository();
|
||||
}
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
back: false,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 50, min: 26);
|
||||
_bar = AppBarProgress(max: 14, min: 0);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
@ -88,7 +92,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
@ -97,75 +101,120 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: Builder(builder: (context) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Set Your Primary Goal"),
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange,
|
||||
fontSize: 30,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 3.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.gain_muscle),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.weight_loss),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.shape_forming),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.endurance),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.gain_strength),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.muscle_endurance),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.flexibility),
|
||||
Divider(),
|
||||
getItem(changeBloc, Goals.explosiveness),
|
||||
Divider(),
|
||||
],
|
||||
),
|
||||
));
|
||||
}),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
//changingViewModel.saveCustomer(),
|
||||
changeBloc.add(CustomerSave()),
|
||||
Navigator.of(context).pop(),
|
||||
if (!fulldata) {Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository)}
|
||||
print("Fulldata: $fulldata bloc $changeBloc"),
|
||||
if (!fulldata)
|
||||
{
|
||||
print("Savegoal"),
|
||||
changeBloc.add(CustomerSaveGoal()),
|
||||
}
|
||||
else
|
||||
{
|
||||
changeBloc.add(CustomerSave()),
|
||||
}
|
||||
},
|
||||
backgroundColor: Colors.orange[800],
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
size: 20,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 12),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("Set Your Primary Goal"),
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 3.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.gain_muscle),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.weight_loss),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.shape_forming),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.endurance),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.gain_strength),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.muscle_endurance),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.flexibility),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getItem(changeBloc, Goals.explosiveness),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget getItem(CustomerChangeBloc changeBloc, Goals goal) {
|
||||
return Stack(alignment: Alignment.bottomLeft, children: [
|
||||
TextButton(
|
||||
@ -188,7 +237,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
child: Text(
|
||||
t(goal.description(goal)),
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.yellow[300],
|
||||
color: Colors.white,
|
||||
fontSize: 28,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
@ -204,13 +253,18 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc customerBloc, String goal) {
|
||||
if (customerBloc.customerRepository.goal == null) return null;
|
||||
dynamic baseCode = RoundedRectangleBorder(
|
||||
side: BorderSide(width: 2, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
if (customerBloc.customerRepository.goal == null) return baseCode;
|
||||
String selectedGoal = customerBloc.customerRepository.goal!;
|
||||
dynamic returnCode = (selectedGoal == goal)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.red),
|
||||
side: BorderSide(width: 6, color: Color(0xffb4f500)),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: null;
|
||||
: baseCode;
|
||||
//return
|
||||
return returnCode;
|
||||
}
|
||||
|
178
lib/view/customer_height_page.dart
Normal file
178
lib/view/customer_height_page.dart
Normal file
@ -0,0 +1,178 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerHeightPage extends StatefulWidget {
|
||||
late _CustomerHeightPageState _state;
|
||||
|
||||
_CustomerHeightPageState createState() {
|
||||
_state = _CustomerHeightPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerHeightPageState extends State<CustomerHeightPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 75, min: 60);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("registration", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return getPage();
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => changeBloc.add(CustomerSaveHeight()),
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Finish"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your height?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getButton() {
|
||||
double mediaWidth = MediaQuery.of(context).size.width * .4;
|
||||
double mediaHeight = MediaQuery.of(context).size.height * .4;
|
||||
return Row(children: [
|
||||
changeBloc.customerRepository.customer!.sex == "m"
|
||||
? Image.asset(
|
||||
"asset/image/test_picto_m.png",
|
||||
height: mediaHeight,
|
||||
width: mediaWidth,
|
||||
)
|
||||
: Image.asset(
|
||||
"asset/image/test_picto_w.png",
|
||||
height: mediaHeight,
|
||||
width: mediaWidth,
|
||||
),
|
||||
SfLinearGauge(
|
||||
minimum: 140,
|
||||
maximum: 220,
|
||||
markerPointers: [
|
||||
LinearWidgetPointer(
|
||||
value: changeBloc.height,
|
||||
offset: 55,
|
||||
position: LinearElementPosition.inside,
|
||||
markerAlignment: LinearMarkerAlignment.center,
|
||||
child: Container(
|
||||
height: 25,
|
||||
width: 55,
|
||||
color: Colors.transparent,
|
||||
child: Text(changeBloc.height.toString(),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xffb4f500),
|
||||
)),
|
||||
),
|
||||
),
|
||||
LinearShapePointer(
|
||||
height: 25,
|
||||
width: 55,
|
||||
color: Color(0xffb4f500),
|
||||
value: changeBloc.height,
|
||||
onValueChanged: (value) => {
|
||||
changeBloc.add(CustomerHeightChange(height: value.toInt())),
|
||||
},
|
||||
),
|
||||
],
|
||||
orientation: LinearGaugeOrientation.vertical,
|
||||
majorTickStyle: LinearTickStyle(length: 20, color: Colors.white),
|
||||
axisLabelStyle: TextStyle(fontSize: 12.0, color: Colors.white),
|
||||
axisTrackStyle:
|
||||
LinearAxisTrackStyle(color: Colors.cyan, edgeStyle: LinearEdgeStyle.bothFlat, thickness: 1.0, borderColor: Colors.white))
|
||||
]);
|
||||
}
|
||||
}
|
185
lib/view/customer_sex_page.dart
Normal file
185
lib/view/customer_sex_page.dart
Normal file
@ -0,0 +1,185 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerSexPage extends StatefulWidget {
|
||||
late _CustomerSexPageState _state;
|
||||
|
||||
_CustomerSexPageState createState() {
|
||||
_state = _CustomerSexPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerSexPageState extends State<CustomerSexPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 45, min: 30);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerWeightPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerSaveSex()),
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your biological sex?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Man", "", "m"),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton("Woman", "", "w"),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TextButton getButton(String title, String desc, String state) {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
shape: getShape(changeBloc, state),
|
||||
),
|
||||
child: Container(
|
||||
width: cWidth,
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
child: ListTile(
|
||||
leading: Icon(
|
||||
state == "m" ? Icons.male_outlined : Icons.female,
|
||||
color: Color(0xffb4f500),
|
||||
size: 60,
|
||||
),
|
||||
title: Text(
|
||||
AppLocalizations.of(context)!.translate(title),
|
||||
style: TextStyle(color: Colors.white, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () => {
|
||||
print("Sex $state"),
|
||||
changeBloc.add(CustomerGenderChange(gender: state == "m" ? 0 : 1)),
|
||||
});
|
||||
}
|
||||
|
||||
dynamic getShape(CustomerChangeBloc changeBloc, String sex) {
|
||||
String? selected = changeBloc.customerRepository.customer!.sex;
|
||||
dynamic returnCode = (selected == sex)
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 4,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
)
|
||||
: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 4, color: Colors.white24),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
);
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
}
|
147
lib/view/customer_weight_page.dart
Normal file
147
lib/view/customer_weight_page.dart
Normal file
@ -0,0 +1,147 @@
|
||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_progress.dart';
|
||||
import 'package:aitrainer_app/widgets/number_picker.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWeightPage extends StatefulWidget {
|
||||
late _CustomerWeightPageState _state;
|
||||
|
||||
_CustomerWeightPageState createState() {
|
||||
_state = _CustomerWeightPageState();
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerWeightPageState extends State<CustomerWeightPage> with Trans {
|
||||
String? selected;
|
||||
bool fulldata = false;
|
||||
late CustomerChangeBloc changeBloc;
|
||||
late double cWidth;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerRepository customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||
|
||||
PreferredSizeWidget _bar = AppBarMin(
|
||||
back: true,
|
||||
);
|
||||
if (!fulldata) {
|
||||
_bar = AppBarProgress(max: 60, min: 45);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: _bar,
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
height: double.infinity,
|
||||
width: double.infinity,
|
||||
child: BlocProvider(
|
||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||
listener: (context, state) {
|
||||
if (state is CustomerSaveError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is CustomerSaveSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed("customerHeightPage", arguments: changeBloc.customerRepository);
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getPage(),
|
||||
inAsyncCall: state is CustomerChangeLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () => {
|
||||
changeBloc.add(CustomerSaveWeight()),
|
||||
},
|
||||
backgroundColor: Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.save,
|
||||
color: Colors.black,
|
||||
size: 26,
|
||||
),
|
||||
label: Text(
|
||||
fulldata ? t("Save") : t("Next"),
|
||||
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getPage() {
|
||||
final double h = 27;
|
||||
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
Wrap(alignment: WrapAlignment.center, children: [
|
||||
Text(
|
||||
t("What is your weight?"),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.white,
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)
|
||||
]),
|
||||
SizedBox(
|
||||
height: h,
|
||||
),
|
||||
getButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getButton() {
|
||||
return NumberPickerWidget(
|
||||
minValue: 40,
|
||||
maxValue: 150,
|
||||
fontSize: 30,
|
||||
diameterRatio: 1.1,
|
||||
itemExtent: 40,
|
||||
fontWeight: FontWeight.w700,
|
||||
initalValue: changeBloc.weight.toInt(),
|
||||
unit: t("kg"),
|
||||
color: Color(0xffb4f500),
|
||||
onChange: (value) => changeBloc.add(CustomerWeightChange(weight: value)));
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/library/button_animations.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_fadein/flutter_fadein.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:percent_indicator/circular_percent_indicator.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWelcomePage extends StatefulWidget {
|
||||
@ -12,11 +16,14 @@ class CustomerWelcomePage extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
||||
class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
return Scaffold(
|
||||
appBar: AppBarMin(),
|
||||
appBar: AppBarMin(
|
||||
back: true,
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
@ -30,17 +37,64 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
SizedBox(
|
||||
height: 200,
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.orange,
|
||||
onSurface: Colors.white,
|
||||
CircularPercentIndicator(
|
||||
radius: 250.0,
|
||||
animation: true,
|
||||
animationDuration: 4800,
|
||||
lineWidth: 20.0,
|
||||
percent: 0.98,
|
||||
curve: Curves.bounceInOut,
|
||||
backgroundWidth: 4,
|
||||
center: Text(
|
||||
t("Training Plan Generation"),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 28.0,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: InkWell(child: Text(AppLocalizations.of(context)!.translate("Next"))),
|
||||
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pushNamed("home")},
|
||||
)
|
||||
circularStrokeCap: CircularStrokeCap.round,
|
||||
progressColor: Color(0xffb4f500),
|
||||
backgroundColor: Colors.black,
|
||||
),
|
||||
SizedBox(
|
||||
height: 90,
|
||||
),
|
||||
FadeIn(
|
||||
child: Container(
|
||||
width: 160,
|
||||
height: 80,
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.of(context).popAndPushNamed("home"),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Image.asset('asset/icon/gomb_orange_a.png', width: 140, height: 80),
|
||||
Text(
|
||||
t("Next"),
|
||||
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.white),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
duration: Duration(seconds: 6),
|
||||
),
|
||||
],
|
||||
),
|
||||
))),
|
||||
|
@ -502,7 +502,7 @@ class EvaluationPage extends StatelessWidget with Trans {
|
||||
Divider(color: Colors.transparent),
|
||||
getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x4-8", 0.95, "3-5"),
|
||||
Divider(color: Colors.transparent),
|
||||
getSuggestionWidget(resultBloc, "Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"),
|
||||
getSuggestionWidget(resultBloc, "Muscle Endurance", "asset/image/pict_reps_volumen_db.png", "4x25-35", 0.50, "3"),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ 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/repository/training_plan_repository.dart';
|
||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||
@ -33,17 +34,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(t(state.message), style: TextStyle(color: Colors.white))));
|
||||
} else if (state is LoginSuccess) {
|
||||
TrainingPlanRepository trainingPlanRepository = TrainingPlanRepository();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: t("Successful Registration"),
|
||||
descriptions: t("Now we would like to know you better to lift the experience of the app."),
|
||||
description2: t("Please go through the pages, it will take couple of minutes!"),
|
||||
descriptions: t("Based on your initial data, we will generate the personalized training plan for you."),
|
||||
text: "OK",
|
||||
onTap: () => {Navigator.of(context).pushNamed('customerModifyPage')},
|
||||
onTap: () => {Navigator.of(context).pushNamed('customerWelcomePage')},
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pushNamed("home"),
|
||||
trainingPlanRepository.generateTrainingPlan(),
|
||||
Navigator.of(context).pushNamed("customerWelcomePage"),
|
||||
},
|
||||
);
|
||||
});
|
||||
@ -83,7 +85,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_login.jpg'),
|
||||
image: AssetImage('asset/image/WT_menu_dark.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
@ -99,17 +101,32 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 10.0), children: <Widget>[
|
||||
GestureDetector(
|
||||
onTap: () => loginBloc.add(LoginSkip()),
|
||||
child: Text(
|
||||
t("I Execute My First Test Now"),
|
||||
textAlign: TextAlign.right,
|
||||
style: GoogleFonts.inter(color: loginBloc.testColor, decoration: TextDecoration.underline, fontWeight: FontWeight.bold),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 120,
|
||||
height: 100,
|
||||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
t("SignUp"),
|
||||
style: GoogleFonts.inter(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
ListTile(title: Text(t("SignUp"), style: GoogleFonts.inter())),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@ -140,7 +157,6 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
: Offstage(),
|
||||
],
|
||||
),
|
||||
//ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
@ -149,6 +165,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
labelText: t('Email'),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
fillColor: Colors.white24,
|
||||
filled: true,
|
||||
border: OutlineInputBorder(
|
||||
@ -165,7 +185,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
},
|
||||
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
||||
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
@ -174,7 +194,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
key: LibraryKeys.loginPasswordField,
|
||||
obscureText: loginBloc.obscure,
|
||||
decoration: InputDecoration(
|
||||
labelStyle: TextStyle(fontSize: 14),
|
||||
labelStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Color(0xffb4f500),
|
||||
),
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||
suffixIcon: IconButton(
|
||||
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
|
||||
@ -197,7 +220,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
},
|
||||
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
||||
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
Divider(
|
||||
color: Colors.transparent,
|
||||
@ -214,7 +237,22 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
),
|
||||
title: Text(
|
||||
t("With the registration I accept the data policy and the terms of use."),
|
||||
style: GoogleFonts.inter(color: Colors.indigo),
|
||||
style: GoogleFonts.inter(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
|
||||
@ -242,7 +280,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Login'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||
),
|
||||
@ -250,7 +304,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Terms Of Use'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => {
|
||||
showDialog(
|
||||
@ -263,7 +333,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
||||
InkWell(
|
||||
child: Text(
|
||||
t('Privacy'),
|
||||
style: GoogleFonts.inter(decoration: TextDecoration.underline),
|
||||
style: GoogleFonts.inter(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
onTap: () => {
|
||||
showDialog(
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
|
||||
@ -17,7 +19,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:toggle_switch/toggle_switch.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'dart:async';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class SettingsPage extends StatelessWidget with Trans {
|
||||
@ -81,7 +84,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
Track().track(TrackingEvent.settings_lang, eventValue: lang)
|
||||
})),
|
||||
getServer(settingsBloc),
|
||||
getTuturialBasic(settingsBloc),
|
||||
//getTuturialBasic(settingsBloc),
|
||||
getTermsOfUse(),
|
||||
getPrivacy(),
|
||||
getFaq(),
|
||||
@ -96,7 +99,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
title: Container(),
|
||||
);
|
||||
}
|
||||
print("Live: ${Cache().liveServer}");
|
||||
|
||||
return ListTile(
|
||||
leading: Icon(Icons.data_usage_sharp),
|
||||
subtitle: Text("For Test purpuses select Test-Server. After that please restart the the App"),
|
||||
@ -260,4 +263,26 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _printAndCopy(String cmd) async {
|
||||
print(cmd);
|
||||
|
||||
await Clipboard.setData(ClipboardData(text: cmd));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Copied to Clipboard')),
|
||||
);
|
||||
}
|
||||
|
||||
void link1() {
|
||||
String? cmd;
|
||||
String cmdSuffix;
|
||||
if (Platform.isIOS) {
|
||||
cmd = '/usr/bin/xcrun simctl openurl booted';
|
||||
} else if (Platform.isAndroid) {
|
||||
cmd = '\$ANDROID_HOME/platform-tools/adb shell \'am start'
|
||||
' -a android.intent.action.VIEW'
|
||||
' -c android.intent.category.BROWSABLE -d';
|
||||
cmdSuffix = "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +128,10 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
child: Text(
|
||||
parentTitle,
|
||||
maxLines: 2,
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
649
lib/view/training_plan_execute.dart
Normal file
649
lib/view/training_plan_execute.dart
Normal file
@ -0,0 +1,649 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_html.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_image.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:extended_tabs/extended_tabs.dart';
|
||||
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_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
class TrainingPlanExecute extends StatefulWidget {
|
||||
const TrainingPlanExecute({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TrainingPlanExecuteState createState() => _TrainingPlanExecuteState();
|
||||
}
|
||||
|
||||
class _TrainingPlanExecuteState extends State<TrainingPlanExecute> with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
|
||||
bloc.activateDays();
|
||||
|
||||
setContext(context);
|
||||
return Scaffold(
|
||||
appBar: AppBarNav(depth: 0),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocConsumer<TrainingPlanBloc, TrainingPlanState>(listener: (context, state) {
|
||||
if (state is TrainingPlanError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is TrainingPlanDayFinished) {
|
||||
bloc.celebrating = false;
|
||||
final HashMap args = HashMap();
|
||||
args["bloc"] = bloc;
|
||||
args["day"] = bloc.dayNames[bloc.activeDayIndex];
|
||||
Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args);
|
||||
} else if (state is TrainingPlanDayReadyToRestart) {
|
||||
if (!bloc.celebrating) {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) => CupertinoAlertDialog(
|
||||
title: Text(t("The training is finished")),
|
||||
content: Column(children: [Divider(), Text(t("Do you want to restart, or select a new Training Plan?"))]),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t("New Training Plan"), textAlign: TextAlign.center),
|
||||
onPressed: () => {
|
||||
Navigator.pop(context),
|
||||
Navigator.of(context).popAndPushNamed('myTrainingPlans'),
|
||||
bloc.restarting = false,
|
||||
}),
|
||||
TextButton(
|
||||
child: Text(t("Restart")),
|
||||
onPressed: () {
|
||||
bloc.restart();
|
||||
Navigator.pop(context);
|
||||
Navigator.of(context).popAndPushNamed('home');
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
return ModalProgressHUD(
|
||||
child: ExerciseTabs(bloc: bloc),
|
||||
inAsyncCall: state is TrainingPlanLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
final HashMap args = HashMap();
|
||||
args["bloc"] = bloc;
|
||||
args["day"] = bloc.dayNames[bloc.activeDayIndex];
|
||||
bloc.getNext() != null
|
||||
? _ExerciseListState.executeExercise(bloc, bloc.getNext()!, context)
|
||||
: Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args);
|
||||
},
|
||||
backgroundColor: Colors.orange[600], //Color(0xffb4f500),
|
||||
icon: Icon(
|
||||
CustomIcon.weight_hanging,
|
||||
color: Colors.black,
|
||||
),
|
||||
label: Text(
|
||||
t("Next Exercise"),
|
||||
style: GoogleFonts.inter(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ExerciseTabs extends StatefulWidget {
|
||||
final TrainingPlanBloc bloc;
|
||||
ExerciseTabs({required this.bloc});
|
||||
@override
|
||||
_ExerciseTabs createState() => _ExerciseTabs();
|
||||
}
|
||||
|
||||
class _ExerciseTabs extends State<ExerciseTabs> with TickerProviderStateMixin {
|
||||
late TabController tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
tabController = TabController(length: widget.bloc.dayNames.length, vsync: this);
|
||||
tabController.animateTo(widget.bloc.activeDayIndex, duration: Duration(milliseconds: 300));
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return getTabs(widget.bloc);
|
||||
}
|
||||
|
||||
Widget getTabs(TrainingPlanBloc bloc) {
|
||||
return Column(children: [
|
||||
Text(
|
||||
bloc.getMyPlan()!.name!,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ExtendedTabBar(
|
||||
indicator: BoxDecoration(
|
||||
color: Colors.black87,
|
||||
border: Border(
|
||||
bottom: BorderSide(width: 4.0, color: Color(0xffb4f500)),
|
||||
// top: BorderSide(width: 4.0, color: Colors.blue),
|
||||
)),
|
||||
labelPadding: EdgeInsets.only(left: 0, right: 0),
|
||||
tabs: getTabNames(),
|
||||
controller: tabController,
|
||||
onTap: (index) => bloc.activeDayIndex = index,
|
||||
),
|
||||
Expanded(
|
||||
child: ExtendedTabBarView(
|
||||
children: getExerciseLists(),
|
||||
controller: tabController,
|
||||
|
||||
/// if link is true and current tabbarview over scroll,
|
||||
/// it will check and scroll ancestor or child tabbarView.
|
||||
link: true,
|
||||
|
||||
/// cache page count
|
||||
/// default is 0.
|
||||
/// if cacheExtent is 1, it has two pages in cache
|
||||
/// null is infinity, it will cache all pages
|
||||
cacheExtent: 0,
|
||||
)),
|
||||
]);
|
||||
}
|
||||
|
||||
List<Tab> getTabNames() {
|
||||
List<Tab> tabs = [];
|
||||
final int tabCount = widget.bloc.dayNames.length;
|
||||
double cWidth = MediaQuery.of(context).size.width;
|
||||
widget.bloc.dayNames.forEach((element) {
|
||||
final Widget widget = Container(
|
||||
//height: 40,
|
||||
padding: EdgeInsets.only(top: 3, left: 10, right: 10, bottom: 3),
|
||||
width: (cWidth / tabCount),
|
||||
color: Colors.white10,
|
||||
child: RichText(
|
||||
textScaleFactor: 0.8,
|
||||
text: TextSpan(
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: AppLocalizations.of(context)!.translate("Training Day") + ": \n",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
)),
|
||||
TextSpan(
|
||||
text: element,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xffb4f500),
|
||||
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,
|
||||
),
|
||||
],
|
||||
)),
|
||||
])));
|
||||
|
||||
tabs.add(Tab(child: widget));
|
||||
});
|
||||
return tabs;
|
||||
}
|
||||
|
||||
List<Widget> getExerciseLists() {
|
||||
List<Widget> list = [];
|
||||
widget.bloc.dayNames.forEach((element) {
|
||||
list.add(ExerciseList(bloc: widget.bloc, dayName: element));
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
class ExerciseList extends StatefulWidget {
|
||||
final TrainingPlanBloc bloc;
|
||||
final String dayName;
|
||||
ExerciseList({required this.bloc, required this.dayName});
|
||||
|
||||
@override
|
||||
_ExerciseListState createState() => _ExerciseListState();
|
||||
}
|
||||
|
||||
class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
final scrollController = ScrollController();
|
||||
double offset = 5;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(ExerciseList page) {
|
||||
super.didUpdateWidget(page);
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
}
|
||||
|
||||
void animate() {
|
||||
offset = widget.bloc.getOffset();
|
||||
if (scrollController.hasClients) {
|
||||
scrollController.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
static void executeExercise(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail, BuildContext context) {
|
||||
CustomerTrainingPlanDetails? next = bloc.getNext();
|
||||
|
||||
if (next != null) {
|
||||
String title = "";
|
||||
String description = "";
|
||||
String description2 = "";
|
||||
if (next.exerciseTypeId != detail.exerciseTypeId) {
|
||||
title = AppLocalizations.of(context)!.translate("Stop!");
|
||||
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") +
|
||||
next.exerciseType!.nameTranslation;
|
||||
} else {
|
||||
final HashMap args = HashMap();
|
||||
args['exerciseType'] = next.exerciseType;
|
||||
args['customerTrainingPlanDetails'] = detail;
|
||||
Navigator.of(context).pushNamed('myTrainingPlanExercise', arguments: args);
|
||||
return;
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: title,
|
||||
descriptions: description,
|
||||
description2: description2,
|
||||
text: "OK",
|
||||
onTap: () => {Navigator.of(context).pop()},
|
||||
onCancel: () => {Navigator.of(context).pop()},
|
||||
);
|
||||
});
|
||||
} else {
|
||||
Navigator.of(context).pushNamed('home');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
return CustomScrollView(controller: scrollController, slivers: [
|
||||
SliverList(delegate: SliverChildListDelegate(getTiles(widget.bloc))),
|
||||
]);
|
||||
}
|
||||
|
||||
List<Widget> getTiles(TrainingPlanBloc bloc) {
|
||||
List<Widget> tiles = [];
|
||||
|
||||
tiles.addAll(getExerciseTiles(bloc, context));
|
||||
|
||||
return tiles;
|
||||
}
|
||||
|
||||
List<Widget> getExerciseTiles(TrainingPlanBloc bloc, BuildContext context) {
|
||||
List<Widget> tiles = [];
|
||||
CustomerTrainingPlanDetails? prev;
|
||||
if (bloc.getMyPlan() != null &&
|
||||
bloc.getMyPlan()!.details.isNotEmpty &&
|
||||
bloc.getMyPlan()!.days[widget.dayName] != null &&
|
||||
bloc.getMyPlan()!.days[widget.dayName]!.isNotEmpty) {
|
||||
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
|
||||
if (prev != null && prev!.exerciseTypeId != element.exerciseTypeId) {
|
||||
tiles.add(GestureDetector(
|
||||
onTap: () =>
|
||||
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
|
||||
child: ExerciseTile(bloc: bloc, detail: element)));
|
||||
}
|
||||
prev = element;
|
||||
});
|
||||
}
|
||||
|
||||
return tiles;
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class ExerciseTile extends StatelessWidget with Trans {
|
||||
final TrainingPlanBloc bloc;
|
||||
final CustomerTrainingPlanDetails detail;
|
||||
|
||||
ExerciseTile({required this.bloc, required this.detail});
|
||||
|
||||
Widget getExerciseQuantities(CustomerTrainingPlanDetails detail, int step, bool noFilter) {
|
||||
bool skipped = detail.state == ExercisePlanDetailState.skipped;
|
||||
String quantities = "";
|
||||
String set = "";
|
||||
List<TextSpan> spans = [];
|
||||
if (detail.exerciseType!.name == "Warming Up") {
|
||||
quantities = t("Min. 10 minutes");
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
} else if (detail.exerciseType!.name == "Stretching") {
|
||||
quantities = t("Recommended");
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
} else {
|
||||
set = detail.set! > 1 ? "${detail.set} " + t("set") : "";
|
||||
List<CustomerTrainingPlanDetails> details = bloc.getAllDetailsSameExercise(detail);
|
||||
int index = 0;
|
||||
bool isWeight = true;
|
||||
|
||||
if (set.length > 0) {
|
||||
spans.add(
|
||||
TextSpan(
|
||||
text: step.toString() + " ",
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange[600],
|
||||
)),
|
||||
);
|
||||
spans.add(
|
||||
TextSpan(text: "/ " + set),
|
||||
);
|
||||
}
|
||||
|
||||
details.forEach((element) {
|
||||
quantities = "";
|
||||
String delimiter = ",";
|
||||
if (index == 0) {
|
||||
delimiter = "";
|
||||
}
|
||||
if (element.repeats == -1) {
|
||||
quantities += delimiter + " MAX ";
|
||||
} else {
|
||||
quantities += delimiter + " ${element.repeats}";
|
||||
}
|
||||
if (element.exerciseType!.unitQuantityUnit != null) {
|
||||
quantities += "x";
|
||||
if (element.weight == -1 || element.weight == -2 || element.weight == -3) {
|
||||
quantities += "? kg";
|
||||
} else {
|
||||
num weight = element.weight! % element.weight!.round() == 0 ? element.weight!.round() : element.weight!;
|
||||
quantities += "$weight kg";
|
||||
}
|
||||
} else {
|
||||
isWeight = false;
|
||||
}
|
||||
if (step == index && noFilter) {
|
||||
spans.add(
|
||||
TextSpan(
|
||||
text: quantities,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: Colors.orange[600],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
spans.add(
|
||||
TextSpan(text: quantities),
|
||||
);
|
||||
}
|
||||
index++;
|
||||
});
|
||||
if (isWeight) {
|
||||
quantities += " kg";
|
||||
}
|
||||
}
|
||||
|
||||
return RichText(
|
||||
text: TextSpan(
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: skipped ? Colors.grey : Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 6.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
children: spans),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
|
||||
final CustomerTrainingPlanDetails? next = bloc.getNext();
|
||||
final bool noFilter = next != null && next.exerciseTypeId == detail.exerciseTypeId;
|
||||
final bool done = detail.state == ExercisePlanDetailState.finished;
|
||||
final int step = bloc.getStep(detail); //detail.exercises.length;
|
||||
final bool buddyWarning = detail.exerciseType == null ? false : detail.exerciseType!.buddyWarning;
|
||||
|
||||
return Container(
|
||||
child: Stack(alignment: Alignment.bottomLeft, children: [
|
||||
Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topEnd(top: 5, end: 5),
|
||||
animationDuration: Duration(milliseconds: 1500),
|
||||
animationType: BadgeAnimationType.fade,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: noFilter || done,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 40,
|
||||
onPressed: () => !done ? skip() : {},
|
||||
icon: Icon(
|
||||
done ? CustomIcon.ok_circled : Icons.cancel,
|
||||
color: done ? Colors.green[600] : Colors.red[600],
|
||||
)),
|
||||
child: Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topStart(top: 5, start: 5),
|
||||
animationDuration: Duration(milliseconds: 500),
|
||||
animationType: BadgeAnimationType.slide,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: true,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 36,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogHTML(
|
||||
title: detail.exerciseType!.nameTranslation,
|
||||
htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
|
||||
}),
|
||||
icon: Icon(
|
||||
Icons.info_outline,
|
||||
color: Colors.yellow[200],
|
||||
)),
|
||||
child: Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topEnd(top: 65, end: 1),
|
||||
animationDuration: Duration(milliseconds: 500),
|
||||
animationType: BadgeAnimationType.fade,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: buddyWarning,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 50,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
warning: true,
|
||||
text: "Warning",
|
||||
descriptions: t("Attention!"),
|
||||
description2: t("The safe and exact execution of this exercise you need a training buddy or a trainer"),
|
||||
description3: t("Execution at your own risk!"),
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
onCancel: () => Navigator.of(context).pop(),
|
||||
title: t('Training Buddy'),
|
||||
);
|
||||
}),
|
||||
icon: Icon(
|
||||
CustomIcon.exclamation_circle,
|
||||
color: Colors.red[800],
|
||||
)),
|
||||
child: Column(children: [
|
||||
MenuImage(
|
||||
imageName: bloc.getActualImageName(detail.exerciseType!.exerciseTypeId),
|
||||
workoutTreeId: bloc.getActualWorkoutTreeId(detail.exerciseType!.exerciseTypeId)!,
|
||||
radius: 0,
|
||||
filter: !noFilter,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 20, top: 10, bottom: 0),
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_zold.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
foregroundDecoration: !noFilter
|
||||
? BoxDecoration(
|
||||
color: Colors.black38,
|
||||
backgroundBlendMode: BlendMode.darken,
|
||||
)
|
||||
: null,
|
||||
height: 80,
|
||||
width: double.infinity,
|
||||
child: getExerciseQuantities(detail, step, noFilter),
|
||||
)
|
||||
])))),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15, bottom: 80, right: 15),
|
||||
width: double.infinity,
|
||||
color: Colors.transparent,
|
||||
child: Text(
|
||||
detail.exerciseType!.nameTranslation,
|
||||
maxLines: 3,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
color: noFilter ? Colors.white : Colors.grey,
|
||||
fontSize: 36,
|
||||
height: 1.1,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(16.0, 16.0),
|
||||
blurRadius: 16.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(16.0, 16.0),
|
||||
blurRadius: 16.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
void skip() {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) => CupertinoAlertDialog(
|
||||
title: Text(t("You want to skip really this exercise?")),
|
||||
content: Column(children: [
|
||||
Divider(),
|
||||
]),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t("No")),
|
||||
onPressed: () => {
|
||||
Navigator.pop(context),
|
||||
}),
|
||||
TextButton(
|
||||
child: Text(t("Yes")),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
bloc.add(TrainingPlanSkipExercise(detail: detail));
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
170
lib/widgets/dialog_trial.dart
Normal file
170
lib/widgets/dialog_trial.dart
Normal file
@ -0,0 +1,170 @@
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class DialogTrialWidget extends StatefulWidget {
|
||||
final String title, description;
|
||||
final Widget widget;
|
||||
final VoidCallback onTap;
|
||||
final VoidCallback? onCancel;
|
||||
|
||||
DialogTrialWidget({Key? key, required this.title, required this.description, required this.widget, required this.onTap, this.onCancel})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_DialogTrialWidgetState createState() {
|
||||
return _DialogTrialWidgetState();
|
||||
}
|
||||
}
|
||||
|
||||
class _DialogTrialWidgetState extends State<DialogTrialWidget> with Trans {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(31),
|
||||
),
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
child: contentBox(context),
|
||||
);
|
||||
}
|
||||
|
||||
contentBox(context) {
|
||||
return Stack(alignment: AlignmentDirectional.topStart, children: [
|
||||
Stack(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 20, top: 24, right: 20, bottom: 30),
|
||||
margin: EdgeInsets.only(top: 30),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_G_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Stack(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
children: [
|
||||
Text(
|
||||
widget.title,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: Colors.yellow[400],
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
),
|
||||
Text(
|
||||
widget.description,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
Shadow(
|
||||
offset: Offset(-3.0, 3.0),
|
||||
blurRadius: 12.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
widget.widget,
|
||||
SizedBox(
|
||||
height: 52,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: widget.onCancel,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Image.asset('asset/icon/gomb_lila_b.png', width: 100, height: 45),
|
||||
Text(
|
||||
t("Nem"),
|
||||
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
],
|
||||
)),
|
||||
GestureDetector(
|
||||
onTap: widget.onTap,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Image.asset('asset/icon/gomb_orange_c.png', width: 100, height: 45),
|
||||
Text(
|
||||
t("Igen"),
|
||||
style: TextStyle(fontSize: 16, color: Colors.white),
|
||||
),
|
||||
],
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (widget.onCancel == null) {
|
||||
Navigator.of(context).pop();
|
||||
} else {
|
||||
widget.onCancel!();
|
||||
}
|
||||
},
|
||||
child: CircleAvatar(
|
||||
backgroundColor: Colors.transparent,
|
||||
radius: 28,
|
||||
child: Text(
|
||||
"X",
|
||||
style: GoogleFonts.archivoBlack(fontSize: 32, color: Colors.white54),
|
||||
),
|
||||
)),
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
@ -98,7 +98,7 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
}
|
||||
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
final TutorialBloc bloc = BlocProvider.of<TutorialBloc>(context);
|
||||
/* //final TutorialBloc bloc = BlocProvider.of<TutorialBloc>(context);
|
||||
if (bloc.actualCheck == "directTest") {
|
||||
Timer(
|
||||
Duration(milliseconds: 2000),
|
||||
@ -116,7 +116,7 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
);
|
||||
})
|
||||
});
|
||||
}
|
||||
} */
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,11 @@ import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/view/customer_goal_page.dart';
|
||||
import 'package:aitrainer_app/view/login.dart';
|
||||
import 'package:aitrainer_app/view/menu_page.dart';
|
||||
import 'package:aitrainer_app/view/registration.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
@ -37,6 +38,15 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
runDelayedEvent();
|
||||
});
|
||||
|
||||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||
print('-- FirebaseMessaging: Got a message whilst in the foreground!');
|
||||
print('-- FirebaseMessaging: Message data: ${message.data}');
|
||||
|
||||
if (message.notification != null) {
|
||||
print('-- FirebaseMessaging: Message also contained a notification: ${message.notification}');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future runDelayedEvent() async {
|
||||
@ -58,6 +68,7 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
||||
final appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml";
|
||||
final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
|
||||
print("Packageinfo ${Cache().packageInfo}");
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
body: UpgradeAlert(
|
||||
@ -101,7 +112,7 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
||||
if (Cache().startPage == 'login') {
|
||||
return LoginPage();
|
||||
} else if (Cache().startPage == 'registration') {
|
||||
return RegistrationPage();
|
||||
return CustomerGoalPage();
|
||||
} else {
|
||||
return MenuPage(parent: 0);
|
||||
}
|
||||
|
@ -3,16 +3,19 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||
import 'package:aitrainer_app/library/transparent_image.dart';
|
||||
import 'package:flutter_html/shims/dart_ui_real.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MenuImage extends StatelessWidget {
|
||||
final int? workoutTreeId;
|
||||
final String imageName;
|
||||
bool filter;
|
||||
double radius;
|
||||
MenuImage({
|
||||
required this.workoutTreeId,
|
||||
required this.imageName,
|
||||
this.radius = 24,
|
||||
this.filter = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -23,10 +26,16 @@ class MenuImage extends StatelessWidget {
|
||||
String? imageString = this.getImage(workoutTreeId!, imageName);
|
||||
Widget? widget;
|
||||
if (imageString != null) {
|
||||
print("MemoryImage $workoutTreeId - $imageName");
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
padding: EdgeInsets.zero,
|
||||
color: Colors.black38,
|
||||
foregroundDecoration: BoxDecoration(
|
||||
color: Colors.black38,
|
||||
backgroundBlendMode: BlendMode.darken,
|
||||
),
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 100),
|
||||
image: MemoryImage(base64Decode(imageString)),
|
||||
@ -35,10 +44,18 @@ class MenuImage extends StatelessWidget {
|
||||
));
|
||||
} else {
|
||||
if (imageName.contains("https")) {
|
||||
print("https image $workoutTreeId - $imageName");
|
||||
if (!wt.ImageCache().existsImageInMap(workoutTreeId!, imageName)) {
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
child: Container(
|
||||
padding: EdgeInsets.zero,
|
||||
foregroundDecoration: filter
|
||||
? BoxDecoration(
|
||||
color: Colors.black38,
|
||||
backgroundBlendMode: BlendMode.darken,
|
||||
)
|
||||
: null,
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 500),
|
||||
@ -51,7 +68,14 @@ class MenuImage extends StatelessWidget {
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
child: Container(
|
||||
padding: EdgeInsets.zero,
|
||||
color: Colors.transparent,
|
||||
foregroundDecoration: filter
|
||||
? BoxDecoration(
|
||||
color: Colors.black38,
|
||||
backgroundBlendMode: BlendMode.darken,
|
||||
)
|
||||
: null,
|
||||
child: Image.asset(imageName),
|
||||
));
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:ui';
|
||||
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
||||
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
|
||||
import 'package:aitrainer_app/model/exercise_ability.dart';
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/repository/training_plan_repository.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_trial.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_image.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
@ -15,9 +16,9 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:aitrainer_app/widgets/tutorial_widget.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:ezanimation/ezanimation.dart';
|
||||
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
@ -39,7 +40,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
final double baseWidth = 312;
|
||||
final double baseHeight = 675.2;
|
||||
late MenuBloc menuBloc;
|
||||
late TutorialBloc tutorialBloc;
|
||||
//late TutorialBloc tutorialBloc;
|
||||
final scrollController = ScrollController();
|
||||
final bool activeExercisePlan = Cache().activeExercisePlan != null;
|
||||
final EzAnimation animation = EzAnimation(35.0, 10.0, Duration(seconds: 2), reverseCurve: Curves.linear);
|
||||
@ -59,41 +60,11 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
menuBloc.add(MenuCreate());
|
||||
//runDelayedEvent();
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
Future runDelayedEvent() async {
|
||||
bool isFirst = false;
|
||||
await Future.delayed(Duration(milliseconds: 600), () async {
|
||||
if (Cache().userLoggedIn != null) {
|
||||
if (Cache().userLoggedIn!.sex == "m") {
|
||||
tutorialBloc.tutorialName = ActivityDone.tutorialBasicChestPress.toStr();
|
||||
} else {
|
||||
tutorialBloc.tutorialName = ActivityDone.tutorialBasicLegPress.toStr();
|
||||
}
|
||||
}
|
||||
if (!tutorialBloc.isTutorialDone()) {
|
||||
if (tutorialBloc.isActive == false && tutorialBloc.canActivate) {
|
||||
tutorialBloc.canActivate = true;
|
||||
tutorialBloc.isActive = true;
|
||||
tutorialBloc.menuBloc = menuBloc;
|
||||
tutorialBloc.add(TutorialLoad());
|
||||
tutorialBloc.init();
|
||||
isFirst = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
final bool canActivate = tutorialBloc.activateTutorial();
|
||||
if (canActivate) {
|
||||
if (!isFirst) {
|
||||
TutorialWidget().tip(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool didUpdateWidget(MenuPageWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
@ -102,10 +73,68 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
return true;
|
||||
}
|
||||
|
||||
Future runDelayedEvent() async {
|
||||
await Future.delayed(Duration(milliseconds: 3000), () async {
|
||||
if (Cache().userLoggedIn != null) {
|
||||
await initDynamicLinks();
|
||||
}
|
||||
if (Cache().canTrial()) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogTrialWidget(
|
||||
title: "10 days Premium for free",
|
||||
description: "Would you like to try all premium functions for 10 days, without any subscription or bank card data?",
|
||||
widget: Column(children: [
|
||||
Text(
|
||||
"If you click to 'Yes', all premium functions will be available right now.",
|
||||
style: GoogleFonts.inter(color: Colors.white),
|
||||
),
|
||||
Divider(),
|
||||
Text(
|
||||
"If you click to 'No', you can use all basic functions, and you will loose the oppurtunity to try the premium functions for free.",
|
||||
style: GoogleFonts.inter(color: Colors.white),
|
||||
),
|
||||
]),
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pop(),
|
||||
menuBloc.add(MenuStartTrial(start: DateTime.parse("1900-01-01 00:00:00"))),
|
||||
},
|
||||
onTap: () => {Navigator.of(context).pop(), menuBloc.add(MenuStartTrial(start: DateTime.now()))},
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> initDynamicLinks() async {
|
||||
FirebaseDynamicLinks.instance.onLink(onSuccess: (PendingDynamicLinkData? dynamicLink) async {
|
||||
final Uri? deepLink = dynamicLink?.link;
|
||||
print("DeepLink: $deepLink");
|
||||
if (deepLink != null) {
|
||||
// ignore: unawaited_futures
|
||||
final String deepLinkPath = deepLink.path.replaceFirst("/", "");
|
||||
Navigator.pushNamed(context, deepLinkPath);
|
||||
}
|
||||
}, onError: (OnLinkErrorException e) async {
|
||||
print('onLinkError');
|
||||
print(e.message);
|
||||
});
|
||||
|
||||
final PendingDynamicLinkData? data = await FirebaseDynamicLinks.instance.getInitialLink();
|
||||
final Uri? deepLink = data?.link;
|
||||
print("Pending DeepLink: $deepLink");
|
||||
if (deepLink != null) {
|
||||
// ignore: unawaited_futures
|
||||
final String deepLinkPath = deepLink.path.replaceFirst("/", "");
|
||||
Navigator.pushNamed(context, deepLinkPath);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
tutorialBloc = BlocProvider.of<TutorialBloc>(context);
|
||||
//tutorialBloc = BlocProvider.of<TutorialBloc>(context);
|
||||
setContext(context);
|
||||
double cWidth = MediaQuery.of(context).size.width;
|
||||
double cHeight = MediaQuery.of(context).size.height;
|
||||
@ -181,6 +210,10 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
});
|
||||
}
|
||||
|
||||
_columnChildren.add(SizedBox(
|
||||
height: 50,
|
||||
));
|
||||
|
||||
SliverList sliverList = SliverList(
|
||||
delegate: SliverChildListDelegate(_columnChildren),
|
||||
);
|
||||
@ -292,7 +325,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
}
|
||||
},
|
||||
),
|
||||
Cache().myTrainingPlan != null
|
||||
/* Cache().myTrainingPlan != null
|
||||
? GestureDetector(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
@ -326,7 +359,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
),
|
||||
);
|
||||
}))
|
||||
: Offstage(),
|
||||
: Offstage(), */
|
||||
/* activeExercisePlan
|
||||
? SizedBox(
|
||||
width: 10,
|
||||
@ -376,24 +409,59 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
}
|
||||
|
||||
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc) {
|
||||
if (tutorialBloc.isActive) {
|
||||
/* if (tutorialBloc.isActive) {
|
||||
final String checkText = workoutTree.nameEnglish;
|
||||
if (!tutorialBloc.checkAction(checkText)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} */
|
||||
print("ability: ${menuBloc.ability} tree: $workoutTree parent: ${workoutTree.parent}");
|
||||
|
||||
if (workoutTree.child == false) {
|
||||
if (menuBloc.ability != null && ExerciseAbility.mini_test_set.equalsTo(menuBloc.ability!) && workoutTree.parent != 0) {
|
||||
HashMap args = HashMap();
|
||||
args['templateName'] = workoutTree.nameEnglish;
|
||||
args['templateNameTranslation'] = workoutTree.name;
|
||||
Navigator.of(context).pushNamed('testSetEdit', arguments: args);
|
||||
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
|
||||
} else if (menuBloc.ability != null && ExerciseAbility.training.equalsTo(menuBloc.ability!) && workoutTree.parent != 0) {
|
||||
HashMap<String, dynamic> args = HashMap();
|
||||
args['parentName'] = workoutTree.internalName;
|
||||
Navigator.of(context).pushNamed("myTrainingPlanActivate", arguments: args);
|
||||
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
|
||||
} else if (workoutTree.internalName == "training_execute") {
|
||||
/* Cache().myTrainingPlan = null;
|
||||
Cache().deleteMyTrainingPlan(); */
|
||||
if (Cache().myTrainingPlan != null) {
|
||||
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
|
||||
bloc.setMyPlan(Cache().myTrainingPlan);
|
||||
Navigator.of(context).pushNamed("myTrainingPlanExecute");
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: t("No selected Training Plan"),
|
||||
descriptions: t("Based on your initial data, we will generate the personalized training plan for you."),
|
||||
text: "OK",
|
||||
onTap: () {
|
||||
TrainingPlanRepository trainingPlanRepository = TrainingPlanRepository();
|
||||
trainingPlanRepository.generateTrainingPlan();
|
||||
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
|
||||
bloc.setMyPlan(Cache().myTrainingPlan);
|
||||
Future.delayed(Duration(milliseconds: 1000), () async {
|
||||
Navigator.of(context).pushNamed("myTrainingPlanExecute");
|
||||
});
|
||||
},
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
|
||||
}
|
||||
menuBloc.add(MenuTreeDown(item: workoutTree, parent: workoutTree.id));
|
||||
} else {
|
||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||
|
||||
|
@ -11,6 +11,9 @@ class NumberPickerWidget extends StatefulWidget {
|
||||
final String unit;
|
||||
final Color color;
|
||||
double? fontSize;
|
||||
double? diameterRatio;
|
||||
double? itemExtent;
|
||||
FontWeight? fontWeight;
|
||||
|
||||
NumberPickerWidget(
|
||||
{Key? key,
|
||||
@ -19,10 +22,16 @@ class NumberPickerWidget extends StatefulWidget {
|
||||
required this.initalValue,
|
||||
required this.unit,
|
||||
this.fontSize,
|
||||
this.diameterRatio,
|
||||
this.itemExtent,
|
||||
this.fontWeight,
|
||||
required this.color,
|
||||
required this.onChange})
|
||||
: super(key: key) {
|
||||
fontSize = fontSize ?? 20;
|
||||
diameterRatio = diameterRatio ?? 0.85;
|
||||
itemExtent = itemExtent ?? 30;
|
||||
fontWeight = fontWeight ?? FontWeight.normal;
|
||||
}
|
||||
@override
|
||||
_NumberPickerWidgetState createState() => _NumberPickerWidgetState();
|
||||
@ -59,7 +68,7 @@ class _NumberPickerWidgetState extends State<NumberPickerWidget> with Trans {
|
||||
scrollController: _scrollController,
|
||||
useMagnifier: true,
|
||||
magnification: 1.2,
|
||||
diameterRatio: 0.85,
|
||||
diameterRatio: widget.diameterRatio!,
|
||||
backgroundColor: Colors.transparent,
|
||||
selectionOverlay: Container(),
|
||||
onSelectedItemChanged: (x) {
|
||||
@ -72,8 +81,10 @@ class _NumberPickerWidgetState extends State<NumberPickerWidget> with Trans {
|
||||
widget.onChange(value);
|
||||
},
|
||||
children: List.generate(
|
||||
widget.maxValue, (index) => Text('$index ' + widget.unit, style: TextStyle(color: widget.color, fontSize: widget.fontSize))),
|
||||
itemExtent: 30,
|
||||
widget.maxValue,
|
||||
(index) => Text('$index ' + widget.unit,
|
||||
style: TextStyle(color: widget.color, fontSize: widget.fontSize, fontWeight: widget.fontWeight))),
|
||||
itemExtent: widget.itemExtent!,
|
||||
);
|
||||
}
|
||||
|
||||
|
59
pubspec.lock
59
pubspec.lock
@ -43,13 +43,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.6.1"
|
||||
awesome_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: awesome_notifications
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.6+9"
|
||||
badges:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -70,7 +63,7 @@ packages:
|
||||
name: bloc_test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
version: "8.1.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -294,7 +287,7 @@ packages:
|
||||
name: equatable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.3"
|
||||
extended_tabs:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -343,7 +336,7 @@ packages:
|
||||
name: firebase_analytics
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.0"
|
||||
version: "8.3.0"
|
||||
firebase_analytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -364,28 +357,28 @@ packages:
|
||||
name: firebase_auth
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "3.0.2"
|
||||
firebase_auth_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_auth_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.3"
|
||||
version: "6.0.1"
|
||||
firebase_auth_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_auth_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
version: "3.0.1"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.5.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -400,41 +393,55 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
firebase_dynamic_links:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_dynamic_links
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
firebase_in_app_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_in_app_messaging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0+8"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "10.0.0"
|
||||
version: "10.0.5"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
version: "3.0.4"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.4"
|
||||
firebase_remote_config:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_remote_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.0"
|
||||
version: "0.10.0+4"
|
||||
firebase_remote_config_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_remote_config_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
version: "0.3.0+4"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -474,28 +481,28 @@ packages:
|
||||
name: flutter_bloc
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
version: "7.1.0"
|
||||
flutter_facebook_auth:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_facebook_auth
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
version: "3.5.1"
|
||||
flutter_facebook_auth_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_facebook_auth_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
version: "2.7.0"
|
||||
flutter_facebook_auth_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_facebook_auth_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
version: "2.6.0+2"
|
||||
flutter_fadein:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -561,7 +568,7 @@ packages:
|
||||
name: flutter_uxcam
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0-beta.1"
|
||||
version: "2.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -1285,7 +1292,7 @@ packages:
|
||||
name: upgrader
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
version: "3.5.1"
|
||||
url_launcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1477,4 +1484,4 @@ packages:
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=2.0.4"
|
||||
flutter: ">=2.0.0"
|
||||
|
31
pubspec.yaml
31
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.21+92
|
||||
version: 1.1.22+93
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
@ -28,8 +28,8 @@ dependencies:
|
||||
google_fonts: ^2.1.0
|
||||
devicelocale: ^0.4.1
|
||||
sentry_flutter: ^5.1.0-beta.1
|
||||
flutter_bloc: ^7.0.0
|
||||
equatable: ^2.0.2
|
||||
flutter_bloc: ^7.1.0
|
||||
equatable: ^2.0.3
|
||||
|
||||
spider_chart: ^0.1.5
|
||||
rainbow_color: ^2.0.1
|
||||
@ -49,33 +49,34 @@ dependencies:
|
||||
purchases_flutter: ^3.2.2
|
||||
package_info: ^2.0.0
|
||||
ezanimation: ^0.5.0
|
||||
flutter_fadein: ^2.0.0
|
||||
confetti: ^0.6.0-nullsafety
|
||||
crypto: ^3.0.0
|
||||
carousel_slider: ^4.0.0-nullsafety.0
|
||||
convex_bottom_bar: ^3.0.0
|
||||
flutter_app_badger: ^1.2.0
|
||||
extended_tabs: ^2.2.0
|
||||
upgrader: ^3.3.0
|
||||
upgrader: ^3.5.1
|
||||
web_browser: ^0.5.0
|
||||
|
||||
firebase_core: ^1.2.0
|
||||
flutter_fadein: ^2.0.0
|
||||
|
||||
firebase_core: ^1.5.0
|
||||
firebase_analytics: ^8.1.0
|
||||
firebase_messaging: ^10.0.0
|
||||
firebase_auth: ^1.2.0
|
||||
firebase_remote_config: ^0.10.0
|
||||
awesome_notifications: ^0.0.6+9
|
||||
firebase_auth: ^3.0.2
|
||||
firebase_remote_config: ^0.10.0+4
|
||||
firebase_dynamic_links: ^2.0.8
|
||||
firebase_in_app_messaging: ^0.5.0+8
|
||||
|
||||
syncfusion_flutter_gauges: ^19.1.63
|
||||
syncfusion_flutter_datagrid: ^19.1.63
|
||||
|
||||
flutter_facebook_auth: ^3.4.0
|
||||
flutter_facebook_auth: ^3.5.1
|
||||
google_sign_in: ^5.0.3
|
||||
sign_in_with_apple: ^3.0.0
|
||||
|
||||
#smartlook: ^1.0.7
|
||||
flurry_data: ^0.0.1
|
||||
flutter_uxcam: ^2.0.0-beta.1
|
||||
flutter_uxcam: ^2.0.0
|
||||
|
||||
animated_widgets: ^1.0.6
|
||||
|
||||
@ -94,7 +95,7 @@ dev_dependencies:
|
||||
test: '>=1.0.0 <2.0.0'
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
bloc_test: ^8.0.0
|
||||
bloc_test: ^8.1.0
|
||||
|
||||
build_runner:
|
||||
|
||||
@ -154,6 +155,7 @@ flutter:
|
||||
- asset/image/WT_Results_for_men.jpg
|
||||
- asset/image/WT_results_background.jpg
|
||||
- asset/image/WT_cup_victory400.png
|
||||
- asset/image/WT_zold.jpg
|
||||
|
||||
- asset/image/button_fb.png
|
||||
- asset/image/button_apple.png
|
||||
@ -179,6 +181,7 @@ flutter:
|
||||
- asset/image/gain_strength.jpg
|
||||
- asset/image/muscle_endurance.jpg
|
||||
- asset/image/shape_forming.jpg
|
||||
|
||||
- asset/image/woman_sizes.png
|
||||
- asset/image/weight_loss.jpg
|
||||
- asset/image/merleg.png
|
||||
@ -368,6 +371,7 @@ flutter:
|
||||
- asset/menu/situps.jpg
|
||||
- asset/menu/sizes.jpg
|
||||
- asset/menu/smith_machine_chest_press.jpg
|
||||
- asset/menu/smith_machine_squats.jpg
|
||||
- asset/menu/squats_with_kettlebell.jpg
|
||||
- asset/menu/squat_jump_weight.jpg
|
||||
- asset/menu/squat_jump.jpg
|
||||
@ -403,6 +407,7 @@ flutter:
|
||||
- asset/menu/training_plans_q_beginner.jpg
|
||||
- asset/menu/training_plans_q_advanced.jpg
|
||||
- asset/menu/training_plans_q_gain_strength.jpg
|
||||
- asset/menu/training_start.jpg
|
||||
- asset/menu/triceps_extension_on_cable_with_rope.jpg
|
||||
- asset/menu/triceps_kickback.jpg
|
||||
- asset/menu/triceps_pushdown.jpg
|
||||
|
Loading…
Reference in New Issue
Block a user