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.google.firebase:firebase-analytics:18.0.0'
|
||||||
implementation 'com.facebook.android:facebook-login:5.15.3'
|
implementation 'com.facebook.android:facebook-login:5.15.3'
|
||||||
implementation 'com.android.support:multidex:1.0.3'
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
|
implementation 'com.google.firebase:firebase-messaging:20.1.0'
|
||||||
}
|
}
|
||||||
sourceCompatibility = '1.8'
|
sourceCompatibility = '1.8'
|
@ -1,41 +1,23 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.aitrainer.aitrainer_app">
|
||||||
package="com.aitrainer.aitrainer_app">
|
|
||||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||||
In most cases you can leave this as-is, but you if you want to provide
|
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
|
additional functionality it is fine to subclass or reimplement
|
||||||
FlutterApplication and put your custom class here. -->
|
FlutterApplication and put your custom class here. -->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<application
|
<application android:name="io.flutter.app.FlutterApplication" android:label="WorkoutTest" android:icon="@mipmap/launcher_icon">
|
||||||
android:name="io.flutter.app.FlutterApplication"
|
<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">
|
||||||
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
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
to determine the Window background behind the Flutter UI. -->
|
to determine the Window background behind the Flutter UI. -->
|
||||||
<meta-data
|
<meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" />
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
|
||||||
android:resource="@style/NormalTheme"
|
|
||||||
/>
|
|
||||||
<!-- Displays an Android View that continues showing the launch screen
|
<!-- Displays an Android View that continues showing the launch screen
|
||||||
Drawable until Flutter paints its first frame, then this splash
|
Drawable until Flutter paints its first frame, then this splash
|
||||||
screen fades out. A splash screen is useful to avoid any visual
|
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
|
gap between the end of Android's launch screen and the painting of
|
||||||
Flutter's first frame. -->
|
Flutter's first frame. -->
|
||||||
<meta-data
|
<meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background" />
|
||||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
|
||||||
android:resource="@drawable/launch_background"
|
|
||||||
/>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
@ -44,27 +26,26 @@
|
|||||||
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</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>
|
</activity>
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
<meta-data
|
<meta-data android:name="flutterEmbedding" android:value="2" />
|
||||||
android:name="flutterEmbedding"
|
|
||||||
android:value="2" />
|
|
||||||
|
|
||||||
<meta-data
|
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="high_importance_channel" />
|
||||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
|
||||||
android:value="high_importance_channel" />
|
|
||||||
|
|
||||||
<meta-data android:name="com.facebook.sdk.ApplicationId"
|
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
|
||||||
android:value="@string/facebook_app_id"/>
|
|
||||||
|
|
||||||
<activity android:name="com.facebook.FacebookActivity"
|
<activity android:name="com.facebook.FacebookActivity" android:configChanges=
|
||||||
android:configChanges=
|
"keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" />
|
||||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
<activity android:name="com.facebook.CustomTabActivity" android:exported="true">
|
||||||
android:label="@string/app_name" />
|
|
||||||
<activity
|
|
||||||
android:name="com.facebook.CustomTabActivity"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<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",
|
"Exception: Please accept our data policy": "Please accept our data policy",
|
||||||
"Please accept our data protection policy.": "Please accept our data protection 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'",
|
"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",
|
"SignUpLink": "SignUp",
|
||||||
"Privacy": "Privacy",
|
"Privacy": "Privacy",
|
||||||
"Change App Language": "Change App Language",
|
"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?",
|
"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",
|
"New Training Plan": "New Training Plan",
|
||||||
"Restart": "Restart",
|
"Restart": "Restart",
|
||||||
"Training Day": "Day",
|
"Training Day": "Training Day",
|
||||||
"No Active Training Plan": "No Active Training Plan",
|
"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",
|
"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",
|
"Continue your training": "Continue your training",
|
||||||
@ -508,5 +508,6 @@
|
|||||||
"Reach all basic functions, suggestions and": "Reach all basic functions, suggestions and",
|
"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:",
|
"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",
|
"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",
|
"Change Language": "Nyelv",
|
||||||
"Password too short": "A jelszó min. 9 karakterből álljon",
|
"Password too short": "A jelszó min. 9 karakterből álljon",
|
||||||
"Please type an email address": "Kérlek írj be egy email címet",
|
"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ó",
|
"SignUpLink": "Regisztráció",
|
||||||
"SignUp with Email": "Email Regisztráció",
|
"SignUp with Email": "Email Regisztráció",
|
||||||
"Exception: Please accept our data policy": "Kérlek fogadd el az adatvédelmi szabályzatunkat",
|
"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?",
|
"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",
|
"New Training Plan": "Másik edzésterv",
|
||||||
"Restart": "Újraindítom",
|
"Restart": "Újraindítom",
|
||||||
"Training Day": "Nap",
|
"Training Day": "Edzésnap",
|
||||||
"No Active Training Plan": "Nincs aktív edzésterv",
|
"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",
|
"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",
|
"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,",
|
"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:",
|
"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",
|
"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/ExternalUserAgent (= 1.4.0)
|
||||||
- AppAuth/Core (1.4.0)
|
- AppAuth/Core (1.4.0)
|
||||||
- AppAuth/ExternalUserAgent (1.4.0)
|
- AppAuth/ExternalUserAgent (1.4.0)
|
||||||
- awesome_notifications (0.0.2):
|
|
||||||
- Flutter
|
|
||||||
- device_info (0.0.1):
|
- device_info (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- devicelocale (0.0.1):
|
- devicelocale (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FBSDKCoreKit (9.1.0):
|
- FBAEMKit (11.1.0):
|
||||||
- FBSDKCoreKit/Basics (= 9.1.0)
|
- FBAEMKit/AEM (= 11.1.0)
|
||||||
- FBSDKCoreKit/Core (= 9.1.0)
|
- FBAEMKit/AEM (11.1.0):
|
||||||
- FBSDKCoreKit/Basics (9.1.0)
|
- FBSDKCoreKit_Basics (~> 11.1.0)
|
||||||
- FBSDKCoreKit/Core (9.1.0):
|
- FBSDKCoreKit (11.1.0):
|
||||||
- FBSDKCoreKit/Basics
|
- FBSDKCoreKit/Core (= 11.1.0)
|
||||||
- FBSDKLoginKit (9.1.0):
|
- FBSDKCoreKit/Core (11.1.0):
|
||||||
- FBSDKLoginKit/Login (= 9.1.0)
|
- FBAEMKit (~> 11.1.0)
|
||||||
- FBSDKLoginKit/Login (9.1.0):
|
- FBSDKCoreKit_Basics (~> 11.1.0)
|
||||||
- FBSDKCoreKit (~> 9.1.0)
|
- FBSDKCoreKit_Basics (11.1.0):
|
||||||
- Firebase/Analytics (8.0.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/Core
|
||||||
- Firebase/Auth (8.0.0):
|
- Firebase/Auth (8.5.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseAuth (~> 8.0.0)
|
- FirebaseAuth (~> 8.5.0)
|
||||||
- Firebase/Core (8.0.0):
|
- Firebase/Core (8.5.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseAnalytics (~> 8.0.0)
|
- FirebaseAnalytics (~> 8.5.0)
|
||||||
- Firebase/CoreOnly (8.0.0):
|
- Firebase/CoreOnly (8.5.0):
|
||||||
- FirebaseCore (= 8.0.0)
|
- FirebaseCore (= 8.5.0)
|
||||||
- Firebase/Messaging (8.0.0):
|
- Firebase/DynamicLinks (8.5.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseMessaging (~> 8.0.0)
|
- FirebaseDynamicLinks (~> 8.5.0)
|
||||||
- Firebase/RemoteConfig (8.0.0):
|
- Firebase/InAppMessaging (8.5.0):
|
||||||
- Firebase/CoreOnly
|
- Firebase/CoreOnly
|
||||||
- FirebaseRemoteConfig (~> 8.0.0)
|
- FirebaseInAppMessaging (~> 8.5.0-beta)
|
||||||
- firebase_analytics (8.1.0):
|
- Firebase/Messaging (8.5.0):
|
||||||
- Firebase/Analytics (= 8.0.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
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_auth (1.2.0):
|
- firebase_auth (3.0.2):
|
||||||
- Firebase/Auth (= 8.0.0)
|
- Firebase/Auth (= 8.5.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_core (1.2.0):
|
- firebase_core (1.5.0):
|
||||||
- Firebase/CoreOnly (= 8.0.0)
|
- Firebase/CoreOnly (= 8.5.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_messaging (10.0.0):
|
- firebase_dynamic_links (2.0.8):
|
||||||
- Firebase/Messaging (= 8.0.0)
|
- Firebase/DynamicLinks (= 8.5.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- Flutter
|
||||||
- firebase_remote_config (0.10.0):
|
- firebase_in_app_messaging (0.5.0-8):
|
||||||
- Firebase/RemoteConfig (= 8.0.0)
|
- Firebase/InAppMessaging (= 8.5.0)
|
||||||
- firebase_core
|
- firebase_core
|
||||||
- Flutter
|
- 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)
|
- FirebaseCore (~> 8.0)
|
||||||
- FirebaseAnalytics (8.0.0):
|
- FirebaseAnalytics (8.5.0):
|
||||||
- FirebaseAnalytics/AdIdSupport (= 8.0.0)
|
- FirebaseAnalytics/AdIdSupport (= 8.5.0)
|
||||||
- FirebaseCore (~> 8.0)
|
- FirebaseCore (~> 8.0)
|
||||||
- FirebaseInstallations (~> 8.0)
|
- FirebaseInstallations (~> 8.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
@ -66,51 +85,50 @@ PODS:
|
|||||||
- GoogleUtilities/Network (~> 7.4)
|
- GoogleUtilities/Network (~> 7.4)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||||
- nanopb (~> 2.30908.0)
|
- nanopb (~> 2.30908.0)
|
||||||
- FirebaseAnalytics/AdIdSupport (8.0.0):
|
- FirebaseAnalytics/AdIdSupport (8.5.0):
|
||||||
- FirebaseAnalytics/Base (= 8.0.0)
|
|
||||||
- FirebaseCore (~> 8.0)
|
- FirebaseCore (~> 8.0)
|
||||||
- FirebaseInstallations (~> 8.0)
|
- FirebaseInstallations (~> 8.0)
|
||||||
- GoogleAppMeasurement (= 8.0.0)
|
- GoogleAppMeasurement (= 8.5.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/Network (~> 7.4)
|
- GoogleUtilities/Network (~> 7.4)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||||
- nanopb (~> 2.30908.0)
|
- nanopb (~> 2.30908.0)
|
||||||
- FirebaseAnalytics/Base (8.0.0):
|
- FirebaseAuth (8.5.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):
|
|
||||||
- FirebaseCore (~> 8.0)
|
- FirebaseCore (~> 8.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/Environment (~> 7.4)
|
- GoogleUtilities/Environment (~> 7.4)
|
||||||
- GTMSessionFetcher/Core (~> 1.5)
|
- GTMSessionFetcher/Core (~> 1.5)
|
||||||
- FirebaseCore (8.0.0):
|
- FirebaseCore (8.5.0):
|
||||||
- FirebaseCoreDiagnostics (~> 8.0)
|
- FirebaseCoreDiagnostics (~> 8.0)
|
||||||
- GoogleUtilities/Environment (~> 7.4)
|
- GoogleUtilities/Environment (~> 7.4)
|
||||||
- GoogleUtilities/Logger (~> 7.4)
|
- GoogleUtilities/Logger (~> 7.4)
|
||||||
- FirebaseCoreDiagnostics (8.0.0):
|
- FirebaseCoreDiagnostics (8.6.0):
|
||||||
- GoogleDataTransport (~> 9.0)
|
- GoogleDataTransport (~> 9.0)
|
||||||
- GoogleUtilities/Environment (~> 7.4)
|
- GoogleUtilities/Environment (~> 7.4)
|
||||||
- GoogleUtilities/Logger (~> 7.4)
|
- GoogleUtilities/Logger (~> 7.4)
|
||||||
- nanopb (~> 2.30908.0)
|
- 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)
|
- FirebaseCore (~> 8.0)
|
||||||
- GoogleUtilities/Environment (~> 7.4)
|
- GoogleUtilities/Environment (~> 7.4)
|
||||||
- GoogleUtilities/UserDefaults (~> 7.4)
|
- GoogleUtilities/UserDefaults (~> 7.4)
|
||||||
- PromisesObjC (~> 1.2)
|
- PromisesObjC (< 3.0, >= 1.2)
|
||||||
- FirebaseMessaging (8.0.0):
|
- FirebaseMessaging (8.5.0):
|
||||||
- FirebaseCore (~> 8.0)
|
- FirebaseCore (~> 8.0)
|
||||||
- FirebaseInstallations (~> 8.0)
|
- FirebaseInstallations (~> 8.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/Environment (~> 7.4)
|
- GoogleUtilities/Environment (~> 7.4)
|
||||||
- GoogleUtilities/Reachability (~> 7.4)
|
- GoogleUtilities/Reachability (~> 7.4)
|
||||||
- GoogleUtilities/UserDefaults (~> 7.4)
|
- GoogleUtilities/UserDefaults (~> 7.4)
|
||||||
- FirebaseRemoteConfig (8.0.0):
|
- FirebaseRemoteConfig (8.5.0):
|
||||||
- FirebaseABTesting (~> 8.0)
|
- FirebaseABTesting (~> 8.0)
|
||||||
- FirebaseCore (~> 8.0)
|
- FirebaseCore (~> 8.0)
|
||||||
- FirebaseInstallations (~> 8.0)
|
- FirebaseInstallations (~> 8.0)
|
||||||
@ -124,12 +142,12 @@ PODS:
|
|||||||
- flutter_app_badger (0.0.1):
|
- flutter_app_badger (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_facebook_auth (2.0.0):
|
- flutter_facebook_auth (2.0.0):
|
||||||
- FBSDKCoreKit (~> 9.1.0)
|
- FBSDKCoreKit (~> 11.1.0)
|
||||||
- FBSDKLoginKit (~> 9.1.0)
|
- FBSDKLoginKit (~> 11.1.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_secure_storage (3.3.1):
|
- flutter_secure_storage (3.3.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_uxcam (2.0.0-beta.1):
|
- flutter_uxcam (2.0.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- UXCam (~> 3.3.4)
|
- UXCam (~> 3.3.4)
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
@ -138,45 +156,45 @@ PODS:
|
|||||||
- google_sign_in (0.0.1):
|
- google_sign_in (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- GoogleSignIn (~> 5.0)
|
- GoogleSignIn (~> 5.0)
|
||||||
- GoogleAppMeasurement (8.0.0):
|
- GoogleAppMeasurement (8.5.0):
|
||||||
- GoogleAppMeasurement/AdIdSupport (= 8.0.0)
|
- GoogleAppMeasurement/AdIdSupport (= 8.5.0)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/Network (~> 7.4)
|
- GoogleUtilities/Network (~> 7.4)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||||
- nanopb (~> 2.30908.0)
|
- nanopb (~> 2.30908.0)
|
||||||
- GoogleAppMeasurement/AdIdSupport (8.0.0):
|
- GoogleAppMeasurement/AdIdSupport (8.5.0):
|
||||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
- GoogleUtilities/MethodSwizzler (~> 7.4)
|
||||||
- GoogleUtilities/Network (~> 7.4)
|
- GoogleUtilities/Network (~> 7.4)
|
||||||
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
- "GoogleUtilities/NSData+zlib (~> 7.4)"
|
||||||
- nanopb (~> 2.30908.0)
|
- nanopb (~> 2.30908.0)
|
||||||
- GoogleDataTransport (9.0.0):
|
- GoogleDataTransport (9.1.0):
|
||||||
- GoogleUtilities/Environment (~> 7.2)
|
- GoogleUtilities/Environment (~> 7.2)
|
||||||
- nanopb (~> 2.30908.0)
|
- nanopb (~> 2.30908.0)
|
||||||
- PromisesObjC (~> 1.2)
|
- PromisesObjC (< 3.0, >= 1.2)
|
||||||
- GoogleSignIn (5.0.2):
|
- GoogleSignIn (5.0.2):
|
||||||
- AppAuth (~> 1.2)
|
- AppAuth (~> 1.2)
|
||||||
- GTMAppAuth (~> 1.0)
|
- GTMAppAuth (~> 1.0)
|
||||||
- GTMSessionFetcher/Core (~> 1.1)
|
- GTMSessionFetcher/Core (~> 1.1)
|
||||||
- GoogleUtilities/AppDelegateSwizzler (7.4.1):
|
- GoogleUtilities/AppDelegateSwizzler (7.5.1):
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Network
|
- GoogleUtilities/Network
|
||||||
- GoogleUtilities/Environment (7.4.1):
|
- GoogleUtilities/Environment (7.5.1):
|
||||||
- PromisesObjC (~> 1.2)
|
- PromisesObjC (< 3.0, >= 1.2)
|
||||||
- GoogleUtilities/Logger (7.4.1):
|
- GoogleUtilities/Logger (7.5.1):
|
||||||
- GoogleUtilities/Environment
|
- GoogleUtilities/Environment
|
||||||
- GoogleUtilities/MethodSwizzler (7.4.1):
|
- GoogleUtilities/MethodSwizzler (7.5.1):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/Network (7.4.1):
|
- GoogleUtilities/Network (7.5.1):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- "GoogleUtilities/NSData+zlib"
|
- "GoogleUtilities/NSData+zlib"
|
||||||
- GoogleUtilities/Reachability
|
- GoogleUtilities/Reachability
|
||||||
- "GoogleUtilities/NSData+zlib (7.4.1)"
|
- "GoogleUtilities/NSData+zlib (7.5.1)"
|
||||||
- GoogleUtilities/Reachability (7.4.1):
|
- GoogleUtilities/Reachability (7.5.1):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GoogleUtilities/UserDefaults (7.4.1):
|
- GoogleUtilities/UserDefaults (7.5.1):
|
||||||
- GoogleUtilities/Logger
|
- GoogleUtilities/Logger
|
||||||
- GTMAppAuth (1.2.2):
|
- GTMAppAuth (1.2.2):
|
||||||
- AppAuth/Core (~> 1.4)
|
- AppAuth/Core (~> 1.4)
|
||||||
@ -195,7 +213,7 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- path_provider (0.0.1):
|
- path_provider (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- PromisesObjC (1.2.12)
|
- PromisesObjC (2.0.0)
|
||||||
- Purchases (3.11.1):
|
- Purchases (3.11.1):
|
||||||
- PurchasesCoreSwift (= 3.11.1)
|
- PurchasesCoreSwift (= 3.11.1)
|
||||||
- purchases_flutter (3.2.2):
|
- purchases_flutter (3.2.2):
|
||||||
@ -231,12 +249,13 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`)
|
|
||||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||||
- devicelocale (from `.symlinks/plugins/devicelocale/ios`)
|
- devicelocale (from `.symlinks/plugins/devicelocale/ios`)
|
||||||
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
|
||||||
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
|
- firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
|
||||||
- firebase_core (from `.symlinks/plugins/firebase_core/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_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
|
||||||
- firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`)
|
- firebase_remote_config (from `.symlinks/plugins/firebase_remote_config/ios`)
|
||||||
- flurry_data (from `.symlinks/plugins/flurry_data/ios`)
|
- flurry_data (from `.symlinks/plugins/flurry_data/ios`)
|
||||||
@ -264,7 +283,9 @@ DEPENDENCIES:
|
|||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- AppAuth
|
- AppAuth
|
||||||
|
- FBAEMKit
|
||||||
- FBSDKCoreKit
|
- FBSDKCoreKit
|
||||||
|
- FBSDKCoreKit_Basics
|
||||||
- FBSDKLoginKit
|
- FBSDKLoginKit
|
||||||
- Firebase
|
- Firebase
|
||||||
- FirebaseABTesting
|
- FirebaseABTesting
|
||||||
@ -272,6 +293,8 @@ SPEC REPOS:
|
|||||||
- FirebaseAuth
|
- FirebaseAuth
|
||||||
- FirebaseCore
|
- FirebaseCore
|
||||||
- FirebaseCoreDiagnostics
|
- FirebaseCoreDiagnostics
|
||||||
|
- FirebaseDynamicLinks
|
||||||
|
- FirebaseInAppMessaging
|
||||||
- FirebaseInstallations
|
- FirebaseInstallations
|
||||||
- FirebaseMessaging
|
- FirebaseMessaging
|
||||||
- FirebaseRemoteConfig
|
- FirebaseRemoteConfig
|
||||||
@ -292,8 +315,6 @@ SPEC REPOS:
|
|||||||
- UXCam
|
- UXCam
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
awesome_notifications:
|
|
||||||
:path: ".symlinks/plugins/awesome_notifications/ios"
|
|
||||||
device_info:
|
device_info:
|
||||||
:path: ".symlinks/plugins/device_info/ios"
|
:path: ".symlinks/plugins/device_info/ios"
|
||||||
devicelocale:
|
devicelocale:
|
||||||
@ -304,6 +325,10 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/firebase_auth/ios"
|
:path: ".symlinks/plugins/firebase_auth/ios"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
:path: ".symlinks/plugins/firebase_core/ios"
|
: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:
|
firebase_messaging:
|
||||||
:path: ".symlinks/plugins/firebase_messaging/ios"
|
:path: ".symlinks/plugins/firebase_messaging/ios"
|
||||||
firebase_remote_config:
|
firebase_remote_config:
|
||||||
@ -353,38 +378,43 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
||||||
awesome_notifications: 74462bc8e68b11f8235d78422266886759e9da61
|
|
||||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||||
devicelocale: b22617f40038496deffba44747101255cee005b0
|
devicelocale: b22617f40038496deffba44747101255cee005b0
|
||||||
FBSDKCoreKit: a00fe2efd780c195a5e09201bf51c56106245b40
|
FBAEMKit: 5c8a8d08e5b2c79628490784883e0fcc75b12615
|
||||||
FBSDKLoginKit: d98498c598ec09de657385a9349a1f21119b7f86
|
FBSDKCoreKit: 7ccb8b4bb2b5ee2ad94327b774dc23f03509675d
|
||||||
Firebase: 73c3e3b216ec1ecbc54d2ffdd4670c65c749edb1
|
FBSDKCoreKit_Basics: 8f978bce195845f609b0ec6b425949d0d24f525b
|
||||||
firebase_analytics: 221d3bc4e8f1b5144a4bd4cc6b33790ee51bd543
|
FBSDKLoginKit: d65eb587a9eaa89295338fb0bb3b358bde0b7ae4
|
||||||
firebase_auth: f960df4ddd8cb415859dbc01a02d7859925ddef0
|
Firebase: ff8c73105b90e33e1dc6c8e5445d7adc2ccdc7c1
|
||||||
firebase_core: e4d3efb030a2b2021819f8faa538bb23deb46695
|
firebase_analytics: 3b7d92b8d1a3482f557c201e5e46c2f7fa2644ff
|
||||||
firebase_messaging: 3b6e0657b21261a57a1cd041fafa713f2aa6923f
|
firebase_auth: 214ff86facd807bbb0ccff32f4b2d3865e3bc4f3
|
||||||
firebase_remote_config: 3a6e2db440f0e95baba3dfc3d4118b1a4bc792c4
|
firebase_core: 82d486a6231b636aea229bd471bceca82cbe00a6
|
||||||
FirebaseABTesting: daebc95ec8829607d07dfe5e92dc3285aca29bc4
|
firebase_dynamic_links: 0768a32e69be5b6f9af258f8e072537dff6b8969
|
||||||
FirebaseAnalytics: dcb92c7c9ef4fa7ffac276e8f87bd4fc8c97f1b8
|
firebase_in_app_messaging: 04572963cf1ef212ac23e188cb0324316e948bf9
|
||||||
FirebaseAuth: b8cd992fca5b53dc6eec09e873a3f375f000c5a1
|
firebase_messaging: 0c5342aa6d92d09429ef67c81a1345189fcb76c9
|
||||||
FirebaseCore: 3f09591d51292843e2a46f18358d60bf4e996255
|
firebase_remote_config: cd43874ff082605023b5913bb1d3206452f1ad48
|
||||||
FirebaseCoreDiagnostics: a31d987ba0fe16d59886a5dbadc2f1de871f88c8
|
FirebaseABTesting: c3e48ebf5e7e5c674c5a131c68e941d7921d83dc
|
||||||
FirebaseInstallations: c4aab1005d6547b00a7529777fe52f5d4d45165b
|
FirebaseAnalytics: 96325c1e0acbd2bb805c6a613028b1fe599d6a37
|
||||||
FirebaseMessaging: 1a33b4af3c8042ed6ddacb6c031894af2064bfab
|
FirebaseAuth: b152ea261b60eeb9419ae7e5bf34761382b33277
|
||||||
FirebaseRemoteConfig: 055f6b5ba1751547596ded5032c4d5c6054ca501
|
FirebaseCore: 1c1ca72483b59b17050f5b4cec4fb748425a3901
|
||||||
|
FirebaseCoreDiagnostics: 3721920bde3a9a6d5aa093c1d25e9d3e47f694af
|
||||||
|
FirebaseDynamicLinks: 6e406b3bb669f8c8a63e7254bb63251fa3f88a43
|
||||||
|
FirebaseInAppMessaging: ee6cd4397d1e81d34b14f90ec38697dc4ef9fe93
|
||||||
|
FirebaseInstallations: 0ede6ffcd215b8f93c19d9b06c1c54e2d4107e98
|
||||||
|
FirebaseMessaging: 0705ec705c21705efc51c071fba924c8e25c63e7
|
||||||
|
FirebaseRemoteConfig: 693c1f150408e9a727daf4d8c55c7f9c29ef9ad5
|
||||||
Flurry-iOS-SDK: 5831da8fc6bedb31fa1f94aac6fd204d36dd351d
|
Flurry-iOS-SDK: 5831da8fc6bedb31fa1f94aac6fd204d36dd351d
|
||||||
flurry_data: 49b7066a283aa41f4306974c1f2d74c61231ad74
|
flurry_data: 49b7066a283aa41f4306974c1f2d74c61231ad74
|
||||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||||
flutter_app_badger: 65de4d6f0c34a891df49e6cfb8a1c0496426fa68
|
flutter_app_badger: 65de4d6f0c34a891df49e6cfb8a1c0496426fa68
|
||||||
flutter_facebook_auth: 4b170c07b7fce791497093fcc3f134fb215f3f07
|
flutter_facebook_auth: 528d51ea1324741b366fa87fa5dfd41016422364
|
||||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||||
flutter_uxcam: ab8e5d3954eb448febd581375e2622e9eecb1066
|
flutter_uxcam: 5b2418884a3bf41284a888c7ecc50317c8a84727
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
|
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
|
||||||
GoogleAppMeasurement: c6bbc9753d046b5456dd4f940057fbad2c28419e
|
GoogleAppMeasurement: 8d10c1c470fcb0e5143ed74fddd164f0a0384800
|
||||||
GoogleDataTransport: 11e3a5f2c190327df1a4a5d7e7ae3d4d5b9c9e4c
|
GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
|
||||||
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
|
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
|
||||||
GoogleUtilities: f8a43108b38a68eebe8b3540e1f4f2d28843ce20
|
GoogleUtilities: 3df19e3c24f7bbc291d8b5809aa6b0d41e642437
|
||||||
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
||||||
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
|
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
|
||||||
modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
|
modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
|
||||||
@ -392,7 +422,7 @@ SPEC CHECKSUMS:
|
|||||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
|
||||||
Purchases: 6351f9ff6bd514e5ec5aa0f989ea181effa94bf5
|
Purchases: 6351f9ff6bd514e5ec5aa0f989ea181effa94bf5
|
||||||
purchases_flutter: 627527b070d80cdaf486fabe8b3d1dbe8d5cad92
|
purchases_flutter: 627527b070d80cdaf486fabe8b3d1dbe8d5cad92
|
||||||
PurchasesCoreSwift: ee857e4c21e6254b09d7e303a756fcf2b9164408
|
PurchasesCoreSwift: ee857e4c21e6254b09d7e303a756fcf2b9164408
|
||||||
@ -411,4 +441,4 @@ SPEC CHECKSUMS:
|
|||||||
|
|
||||||
PODFILE CHECKSUM: f10c0438b63bc24e6bbc207956dc27d16c4408f2
|
PODFILE CHECKSUM: f10c0438b63bc24e6bbc207956dc27d16c4408f2
|
||||||
|
|
||||||
COCOAPODS: 1.10.1
|
COCOAPODS: 1.11.0.beta.2
|
||||||
|
@ -396,7 +396,7 @@
|
|||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -405,12 +405,12 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.1.21;
|
MARKETING_VERSION = 1.1.22;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
@ -539,7 +539,7 @@
|
|||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -548,13 +548,13 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.1.21;
|
MARKETING_VERSION = 1.1.22;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@ -574,7 +574,7 @@
|
|||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -583,12 +583,12 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.1.21;
|
MARKETING_VERSION = 1.1.22;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
@ -10,6 +10,9 @@ import Firebase
|
|||||||
) -> Bool {
|
) -> Bool {
|
||||||
FirebaseApp.configure()
|
FirebaseApp.configure()
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
|
if #available(iOS 12.0, *) {
|
||||||
|
UNUserNotificationCenter.current().delegate = self
|
||||||
|
}
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,75 +1,97 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<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>
|
<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/>
|
<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>
|
</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>
|
</plist>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<array>
|
<array>
|
||||||
<string>Default</string>
|
<string>Default</string>
|
||||||
</array>
|
</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>
|
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
@ -29,8 +29,8 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
|||||||
weight = this.customerRepository.getWeight() == 0 ? 60 : this.customerRepository.getWeight();
|
weight = this.customerRepository.getWeight() == 0 ? 60 : this.customerRepository.getWeight();
|
||||||
height = this.customerRepository.getHeight() == 0 ? 170 : this.customerRepository.getHeight();
|
height = this.customerRepository.getHeight() == 0 ? 170 : this.customerRepository.getHeight();
|
||||||
|
|
||||||
selectedSport = customerRepository.getSport();
|
// selectedSport = customerRepository.getSport();
|
||||||
print("selected: $selectedFitnessItem sport: $selectedSport " + customerRepository.customer!.fitnessLevel.toString());
|
//print("selected: $selectedFitnessItem sport: $selectedSport " + customerRepository.customer!.fitnessLevel.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Sport? selectedSport;
|
Sport? selectedSport;
|
||||||
@ -41,6 +41,7 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
|||||||
CustomerChangeEvent event,
|
CustomerChangeEvent event,
|
||||||
) async* {
|
) async* {
|
||||||
try {
|
try {
|
||||||
|
print("Event: $event");
|
||||||
if (event is CustomerLoad) {
|
if (event is CustomerLoad) {
|
||||||
yield CustomerChangeLoading();
|
yield CustomerChangeLoading();
|
||||||
yield CustomerDataChanged();
|
yield CustomerDataChanged();
|
||||||
@ -63,7 +64,7 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
|||||||
year = event.year;
|
year = event.year;
|
||||||
yield CustomerDataChanged();
|
yield CustomerDataChanged();
|
||||||
} else if (event is CustomerWeightChange) {
|
} else if (event is CustomerWeightChange) {
|
||||||
yield CustomerChangeLoading();
|
//yield CustomerChangeLoading();
|
||||||
customerRepository.setWeight(event.weight);
|
customerRepository.setWeight(event.weight);
|
||||||
weight = event.weight.toDouble();
|
weight = event.weight.toDouble();
|
||||||
yield CustomerDataChanged();
|
yield CustomerDataChanged();
|
||||||
@ -88,12 +89,43 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
|||||||
customerRepository.setName(event.name);
|
customerRepository.setName(event.name);
|
||||||
yield CustomerDataChanged();
|
yield CustomerDataChanged();
|
||||||
} else if (event is CustomerGenderChange) {
|
} else if (event is CustomerGenderChange) {
|
||||||
|
yield CustomerChangeLoading();
|
||||||
customerRepository.setSex(event.gender == 0 ? "m" : "w");
|
customerRepository.setSex(event.gender == 0 ? "m" : "w");
|
||||||
yield CustomerDataChanged();
|
yield CustomerDataChanged();
|
||||||
} else if (event is CustomerSportChange) {
|
} else if (event is CustomerSportChange) {
|
||||||
yield CustomerChangeLoading();
|
yield CustomerChangeLoading();
|
||||||
selectedSport = event.sport;
|
selectedSport = event.sport;
|
||||||
yield CustomerDataChanged();
|
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) {
|
} else if (event is CustomerSave) {
|
||||||
yield CustomerSaving();
|
yield CustomerSaving();
|
||||||
if (validation()) {
|
if (validation()) {
|
||||||
|
@ -114,3 +114,23 @@ class CustomerLoad extends CustomerChangeEvent {
|
|||||||
class CustomerSave extends CustomerChangeEvent {
|
class CustomerSave extends CustomerChangeEvent {
|
||||||
const CustomerSave();
|
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:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_ability.dart';
|
import 'package:aitrainer_app/model/exercise_ability.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.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_device_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
|
import 'package:aitrainer_app/util/enums.dart';
|
||||||
|
import 'package:aitrainer_app/util/track.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
@ -111,6 +115,22 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
listFilterDevice.remove(deviceId);
|
listFilterDevice.remove(deviceId);
|
||||||
}
|
}
|
||||||
yield MenuReady();
|
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) {
|
} on Exception catch (ex) {
|
||||||
yield MenuError(message: ex.toString());
|
yield MenuError(message: ex.toString());
|
||||||
@ -134,6 +154,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
case "my_body":
|
case "my_body":
|
||||||
ability = ExerciseAbility.none;
|
ability = ExerciseAbility.none;
|
||||||
break;
|
break;
|
||||||
|
case "training_execute":
|
||||||
|
ability = ExerciseAbility.training_execute;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
log("Ability: " + ability.toString() + " name: " + name);
|
log("Ability: " + ability.toString() + " name: " + name);
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,15 @@ class MenuRecreateTree extends MenuEvent {
|
|||||||
class MenuFilterExerciseType extends MenuEvent {
|
class MenuFilterExerciseType extends MenuEvent {
|
||||||
final int deviceId;
|
final int deviceId;
|
||||||
const MenuFilterExerciseType({required this.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 {
|
class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
||||||
final Session session;
|
final Session session;
|
||||||
|
StreamSubscription? _sub;
|
||||||
|
|
||||||
SessionBloc({required this.session}) : super(SessionInitial());
|
SessionBloc({required this.session}) : super(SessionInitial());
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
|||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await this.close();
|
await this.close();
|
||||||
|
_sub?.cancel();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,10 +59,12 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
|||||||
|
|
||||||
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
trainingPlanBloc.getMyPlan()!.days[day]!.forEach((element) {
|
||||||
//if (!element.state.equalsTo(ExercisePlanDetailState.extra)) {
|
//if (!element.state.equalsTo(ExercisePlanDetailState.extra)) {
|
||||||
if (!findExerciseInEvaluationList(element.exerciseTypeId!)) {
|
if (element.exerciseTypeId != null) {
|
||||||
addEvaluationExercise(element);
|
if (!findExerciseInEvaluationList(element.exerciseTypeId!)) {
|
||||||
} else {
|
addEvaluationExercise(element);
|
||||||
//editEvaluationExercise(element);
|
} else {
|
||||||
|
//editEvaluationExercise(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
});
|
});
|
||||||
@ -93,7 +95,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
|||||||
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
||||||
this.evaluationList.add(exercise);
|
this.evaluationList.add(exercise);
|
||||||
} else {
|
} else {
|
||||||
if (detail.exerciseType!.unitQuantityUnit == null) {
|
if (detail.exerciseType!.unitQuantityUnit == null || detail.weight == null) {
|
||||||
exercise.type = TrainingEvaluationExerciseType.repeatBased;
|
exercise.type = TrainingEvaluationExerciseType.repeatBased;
|
||||||
exercise.repeats = detail.repeats;
|
exercise.repeats = detail.repeats;
|
||||||
exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!);
|
exercise.maxRepeats = getMaxRepeatsByExerciseType(detail.exerciseTypeId!);
|
||||||
|
@ -46,7 +46,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
try {
|
try {
|
||||||
if (event is TrainingPlanActivate) {
|
if (event is TrainingPlanActivate) {
|
||||||
yield TrainingPlanLoading();
|
yield TrainingPlanLoading();
|
||||||
_myPlan = await trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
|
_myPlan = trainingPlanRepository.activateTrainingPlan(event.trainingPlanId);
|
||||||
_myPlan!.type = CustomerTrainingPlanType.template;
|
_myPlan!.type = CustomerTrainingPlanType.template;
|
||||||
|
|
||||||
menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
|
||||||
@ -72,7 +72,6 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
event.detail.repeats =
|
event.detail.repeats =
|
||||||
Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.weight);
|
Common.reCalculateRepeatsByChangedWeight(event.detail.weight!, event.detail.repeats!.toDouble(), event.weight);
|
||||||
event.detail.weight = event.weight;
|
event.detail.weight = event.weight;
|
||||||
print(" weight: ${event.weight} new repeats: ${event.detail.repeats}");
|
|
||||||
|
|
||||||
yield TrainingPlanReady();
|
yield TrainingPlanReady();
|
||||||
} else if (event is TrainingPlanRepeatsChange) {
|
} else if (event is TrainingPlanRepeatsChange) {
|
||||||
@ -102,13 +101,12 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
exercise.unitQuantity = event.detail.weight;
|
exercise.unitQuantity = event.detail.weight;
|
||||||
exercise.dateAdd = DateTime.now();
|
exercise.dateAdd = DateTime.now();
|
||||||
event.detail.exercises.add(exercise);
|
event.detail.exercises.add(exercise);
|
||||||
if (event.detail.exercises.length >= event.detail.set!) {
|
if (this.isAllDetailsSameExerciseFinished(event.detail)) {
|
||||||
event.detail.state = ExercisePlanDetailState.finished;
|
event.detail.state = ExercisePlanDetailState.finished;
|
||||||
} else if (event.detail.exercises.length >= 0) {
|
} else if (event.detail.exercises.length >= 0) {
|
||||||
event.detail.state = ExercisePlanDetailState.inProgress;
|
event.detail.state = ExercisePlanDetailState.inProgress;
|
||||||
}
|
}
|
||||||
// recalculate the weight to the original planned repeats for the next details
|
// recalculate the weight to the original planned repeats for the next details
|
||||||
|
|
||||||
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
|
if (exercise.unitQuantity != null && exercise.unitQuantity! > 0) {
|
||||||
for (var nextDetail in _myPlan!.details) {
|
for (var nextDetail in _myPlan!.details) {
|
||||||
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
|
double weightFromPlan = trainingPlanRepository.getOriginalWeight(this.getMyPlan()!.trainingPlanId!, nextDetail);
|
||||||
@ -357,6 +355,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
return workoutTree.imageName;
|
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() {
|
CustomerTrainingPlanDetails? getNext() {
|
||||||
if (_myPlan == null || _myPlan!.details.isEmpty) {
|
if (_myPlan == null || _myPlan!.details.isEmpty) {
|
||||||
return null;
|
return null;
|
||||||
@ -373,12 +388,16 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
final int step = detail.exercises.length;
|
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;
|
next = detail;
|
||||||
minStep = step;
|
minStep = step;
|
||||||
if (detail.parallel != true) {
|
//if (detail.parallel != true) {
|
||||||
break;
|
break;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,18 +442,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
int indexInProgress = 0;
|
int indexInProgress = 0;
|
||||||
int indexInStart = 0;
|
int indexInStart = 0;
|
||||||
final String day = dayNames[this.activeDayIndex];
|
final String day = dayNames[this.activeDayIndex];
|
||||||
|
CustomerTrainingPlanDetails? prev;
|
||||||
for (var detail in _myPlan!.days[day]!) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
if (detail.state == ExercisePlanDetailState.start) {
|
|
||||||
break;
|
if (prev != null && prev.exerciseTypeId != detail.exerciseTypeId && detail.state != ExercisePlanDetailState.extra) {
|
||||||
|
//print(" --- offset + 1");
|
||||||
|
indexInStart++;
|
||||||
|
indexInProgress++;
|
||||||
}
|
}
|
||||||
indexInStart++;
|
prev = detail;
|
||||||
indexInProgress++;
|
|
||||||
}
|
}
|
||||||
int index = indexInStart > indexInProgress ? indexInStart : indexInProgress;
|
int index = indexInStart > indexInProgress ? indexInStart : indexInProgress;
|
||||||
offset = index * 80;
|
offset = (index) * 270;
|
||||||
print("Offset: $offset day: $day ($indexInStart, $indexInProgress)");
|
print("Offset: $offset day: $day ($indexInStart, $indexInProgress)");
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -573,4 +597,23 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
|||||||
}
|
}
|
||||||
return exists;
|
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_exercise_device.dart';
|
||||||
import 'package:aitrainer_app/view/customer_fitness_page.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_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_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/customer_welcome_page.dart';
|
||||||
import 'package:aitrainer_app/view/evaluation_page.dart';
|
import 'package:aitrainer_app/view/evaluation_page.dart';
|
||||||
import 'package:aitrainer_app/view/exercise_control_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/exercise_new_page.dart';
|
||||||
import 'package:aitrainer_app/view/training_plan_custom.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_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/training_plans_page.dart';
|
||||||
import 'package:aitrainer_app/view/mydevelopment_body_page.dart';
|
import 'package:aitrainer_app/view/mydevelopment_body_page.dart';
|
||||||
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
|
import 'package:aitrainer_app/view/mydevelopment_muscle_page.dart';
|
||||||
@ -146,7 +150,6 @@ Future<Null> main() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print(" -- FireBase init..");
|
print(" -- FireBase init..");
|
||||||
await FirebaseApi().initializeFlutterFire();
|
|
||||||
|
|
||||||
runApp(MultiBlocProvider(
|
runApp(MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
@ -177,8 +180,8 @@ Future<Null> main() async {
|
|||||||
BlocProvider<TestSetExecuteBloc>(
|
BlocProvider<TestSetExecuteBloc>(
|
||||||
create: (BuildContext context) => TestSetExecuteBloc(),
|
create: (BuildContext context) => TestSetExecuteBloc(),
|
||||||
),
|
),
|
||||||
BlocProvider<TutorialBloc>(
|
/* BlocProvider<TutorialBloc>(
|
||||||
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
|
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())), */
|
||||||
BlocProvider<TrainingPlanBloc>(create: (context) {
|
BlocProvider<TrainingPlanBloc>(create: (context) {
|
||||||
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
|
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
|
||||||
@ -196,6 +199,7 @@ Future<void> initThirdParty() async {
|
|||||||
await FlurryData.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
|
await FlurryData.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
|
||||||
FlutterUxcam.optIntoSchematicRecordings();
|
FlutterUxcam.optIntoSchematicRecordings();
|
||||||
}
|
}
|
||||||
|
await FirebaseApi().initializeFlutterFire();
|
||||||
}
|
}
|
||||||
|
|
||||||
class WorkoutTestApp extends StatelessWidget {
|
class WorkoutTestApp extends StatelessWidget {
|
||||||
@ -217,6 +221,7 @@ class WorkoutTestApp extends StatelessWidget {
|
|||||||
|
|
||||||
//facebookAppEvents.setAdvertiserTracking(enabled: true);
|
//facebookAppEvents.setAdvertiserTracking(enabled: true);
|
||||||
initThirdParty();
|
initThirdParty();
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
// ... app-specific localization delegate[s] here
|
// ... app-specific localization delegate[s] here
|
||||||
@ -249,6 +254,9 @@ class WorkoutTestApp extends StatelessWidget {
|
|||||||
'customerModifyPage': (context) => CustomerModifyPage(),
|
'customerModifyPage': (context) => CustomerModifyPage(),
|
||||||
'customerGoalPage': (context) => CustomerGoalPage(),
|
'customerGoalPage': (context) => CustomerGoalPage(),
|
||||||
'customerFitnessPage': (context) => CustomerFitnessPage(),
|
'customerFitnessPage': (context) => CustomerFitnessPage(),
|
||||||
|
'customerSexPage': (context) => CustomerSexPage(),
|
||||||
|
'customerWeightPage': (context) => CustomerWeightPage(),
|
||||||
|
'customerHeightPage': (context) => CustomerHeightPage(),
|
||||||
'customerBodyTypePage': (context) => CustomerBodyTypeAnimationPage(),
|
'customerBodyTypePage': (context) => CustomerBodyTypeAnimationPage(),
|
||||||
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
'customerWelcomePage': (context) => CustomerWelcomePage(),
|
||||||
'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(),
|
'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(),
|
||||||
@ -275,7 +283,8 @@ class WorkoutTestApp extends StatelessWidget {
|
|||||||
'myTrainingPlanCustom': (context) => TrainingPlanCustomPage(),
|
'myTrainingPlanCustom': (context) => TrainingPlanCustomPage(),
|
||||||
'myTrainingPlanCustomAdd': (context) => TrainingPlanCustomAddPage(),
|
'myTrainingPlanCustomAdd': (context) => TrainingPlanCustomAddPage(),
|
||||||
'myTrainingPlanActivate': (context) => TrainingPlanActivatePage(),
|
'myTrainingPlanActivate': (context) => TrainingPlanActivatePage(),
|
||||||
'myTrainingPlanExecute': (context) => TrainingPlanExecutePage(),
|
'myTrainingPlanExecute2': (context) => TrainingPlanExecutePage(),
|
||||||
|
'myTrainingPlanExecute': (context) => TrainingPlanExecute(),
|
||||||
'myTrainingPlanExercise': (context) => TrainingPlanExercise(),
|
'myTrainingPlanExercise': (context) => TrainingPlanExercise(),
|
||||||
'myTrainingEvaluation': (context) => TrainingEvaluationPage(),
|
'myTrainingEvaluation': (context) => TrainingEvaluationPage(),
|
||||||
},
|
},
|
||||||
|
@ -186,8 +186,8 @@ class Cache with Logging {
|
|||||||
Cache._internal() {
|
Cache._internal() {
|
||||||
String testEnv = EnvironmentConfig.test_env;
|
String testEnv = EnvironmentConfig.test_env;
|
||||||
this.testEnvironment = testEnv;
|
this.testEnvironment = testEnv;
|
||||||
|
print("testEnv $testEnv");
|
||||||
if (testEnv == "1") {
|
if (testEnv == "1") {
|
||||||
print("testEnv $testEnv");
|
|
||||||
baseUrl = baseUrlTest;
|
baseUrl = baseUrlTest;
|
||||||
liveServer = false;
|
liveServer = false;
|
||||||
}
|
}
|
||||||
@ -234,6 +234,17 @@ class Cache with Logging {
|
|||||||
sharedPreferences.setString(Cache.myTrainingPlanKey, myTrainingPlanJson);
|
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<void> getMyTrainingPlan() async {
|
||||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||||
SharedPreferences sharedPreferences;
|
SharedPreferences sharedPreferences;
|
||||||
@ -744,4 +755,21 @@ class Cache with Logging {
|
|||||||
|
|
||||||
List<TrainingPlanDay> getTrainingPlanDays() => this._trainingPlanDays;
|
List<TrainingPlanDay> getTrainingPlanDays() => this._trainingPlanDays;
|
||||||
setTrainingPlanDays(value) => this._trainingPlanDays = value;
|
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;
|
DateTime? dateChange;
|
||||||
int? emailSubscription;
|
int? emailSubscription;
|
||||||
int? sportId;
|
int? sportId;
|
||||||
|
DateTime? trialDate;
|
||||||
|
|
||||||
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
|
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ class Customer {
|
|||||||
this.dataPolicyAllowed = json['dataPolicyAllowed'];
|
this.dataPolicyAllowed = json['dataPolicyAllowed'];
|
||||||
this.emailSubscription = json['emailSubscription'];
|
this.emailSubscription = json['emailSubscription'];
|
||||||
this.sportId = json['sportId'];
|
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.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']);
|
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!),
|
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd!),
|
||||||
"dateChange": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateChange!),
|
"dateChange": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateChange!),
|
||||||
"emailSubscription": this.emailSubscription,
|
"emailSubscription": this.emailSubscription,
|
||||||
"sportId": this.sportId
|
"sportId": this.sportId,
|
||||||
|
"trialDate": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.trialDate!),
|
||||||
};
|
};
|
||||||
|
|
||||||
double getProperty(String propertyName) {
|
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 {
|
extension ExerciseAbilityExt on ExerciseAbility {
|
||||||
String enumToString() => this.toString().split(".").last;
|
String enumToString() => this.toString().split(".").last;
|
||||||
|
@ -75,6 +75,7 @@ class WorkoutMenuTree {
|
|||||||
"is1RM": is1RM.toString(),
|
"is1RM": is1RM.toString(),
|
||||||
"isRunning": isRunning.toString(),
|
"isRunning": isRunning.toString(),
|
||||||
"sort": sort,
|
"sort": sort,
|
||||||
|
"internalName": internalName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ class CustomerRepository with Logging {
|
|||||||
if (this.customer!.properties[propertyName] == null) {
|
if (this.customer!.properties[propertyName] == null) {
|
||||||
this.customer!.properties[propertyName] = CustomerProperty(
|
this.customer!.properties[propertyName] = CustomerProperty(
|
||||||
propertyId: propertyRepository.getPropertyByName("Height")!.propertyId,
|
propertyId: propertyRepository.getPropertyByName("Height")!.propertyId,
|
||||||
customerId: this.customer!.customerId!,
|
customerId: this.customer!.customerId == null ? 0 : this.customer!.customerId!,
|
||||||
propertyValue: value,
|
propertyValue: value,
|
||||||
dateAdd: DateTime.now());
|
dateAdd: DateTime.now());
|
||||||
} else {
|
} 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.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.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/model/training_plan.dart';
|
||||||
import 'package:aitrainer_app/repository/training_plan_day_repository.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';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
|
|
||||||
class TrainingPlanRepository {
|
class TrainingPlanRepository {
|
||||||
@ -40,14 +41,14 @@ class TrainingPlanRepository {
|
|||||||
/// 2. calculate customer_training_plan_details weights / repleats
|
/// 2. calculate customer_training_plan_details weights / repleats
|
||||||
/// 3. create new customer_training_plan
|
/// 3. create new customer_training_plan
|
||||||
|
|
||||||
Future<CustomerTrainingPlan?> activateTrainingPlan(int trainingPlanId) async {
|
CustomerTrainingPlan? activateTrainingPlan(int trainingPlanId) {
|
||||||
print(" **** Activate Plan: $trainingPlanId");
|
print(" **** Activate Plan: $trainingPlanId");
|
||||||
// 1. deactivate
|
// 1. deactivate
|
||||||
if (Cache().getCustomerTrainingPlans() != null) {
|
if (Cache().getCustomerTrainingPlans() != null) {
|
||||||
Cache().getCustomerTrainingPlans()!.forEach((plan) {
|
Cache().getCustomerTrainingPlans()!.forEach((plan) {
|
||||||
plan.active = false;
|
plan.active = false;
|
||||||
if (plan.customerTrainingPlanId != null) {
|
if (plan.customerTrainingPlanId != null) {
|
||||||
TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
|
//TrainingPlanApi().updateCustomerTrainingPlan(plan, plan.customerTrainingPlanId!);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -58,7 +59,7 @@ class TrainingPlanRepository {
|
|||||||
plan.active = true;
|
plan.active = true;
|
||||||
plan.status = "open";
|
plan.status = "open";
|
||||||
plan.dateAdd = DateTime.now();
|
plan.dateAdd = DateTime.now();
|
||||||
plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations["hu"];
|
plan.name = getTrainingPlanById(trainingPlanId)!.nameTranslations[AppLanguage().appLocal.toString()];
|
||||||
|
|
||||||
TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
|
TrainingPlan? trainingPlan = this.getTrainingPlanById(trainingPlanId);
|
||||||
if (trainingPlan == null || trainingPlan.details == null) {
|
if (trainingPlan == null || trainingPlan.details == null) {
|
||||||
@ -138,6 +139,23 @@ class TrainingPlanRepository {
|
|||||||
return plan;
|
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) {
|
CustomerTrainingPlanDetails getCalculatedWeightRepeats(int exerciseTypeId, CustomerTrainingPlanDetails detail) {
|
||||||
double weight = -1;
|
double weight = -1;
|
||||||
if (Cache().getExercises() == null) {
|
if (Cache().getExercises() == null) {
|
||||||
@ -247,4 +265,32 @@ class TrainingPlanRepository {
|
|||||||
|
|
||||||
return recalculatedDetail;
|
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 {
|
Future<String> buildImage(String imageUrl, int treeId) async {
|
||||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
|
print("asset image $assetImage");
|
||||||
return await rootBundle.load(assetImage).then((value) {
|
return await rootBundle.load(assetImage).then((value) {
|
||||||
return assetImage;
|
return assetImage;
|
||||||
}).catchError((_) {
|
}).catchError((_) {
|
||||||
|
@ -4,12 +4,10 @@ import 'package:crypto/crypto.dart';
|
|||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart' as logging;
|
import 'package:aitrainer_app/service/logging.dart' as logging;
|
||||||
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
|
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_auth/firebase_auth.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:firebase_remote_config/firebase_remote_config.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:flutter_facebook_auth/flutter_facebook_auth.dart';
|
||||||
import 'package:google_sign_in/google_sign_in.dart';
|
import 'package:google_sign_in/google_sign_in.dart';
|
||||||
|
|
||||||
@ -37,7 +35,8 @@ class FirebaseApi with logging.Logging {
|
|||||||
await Firebase.initializeApp();
|
await Firebase.initializeApp();
|
||||||
|
|
||||||
this.appleSignInAvailable = await SignInWithApple.isAvailable();
|
this.appleSignInAvailable = await SignInWithApple.isAvailable();
|
||||||
AwesomeNotifications().initialize(
|
|
||||||
|
/* AwesomeNotifications().initialize(
|
||||||
// set the icon to null if you want to use the default app icon
|
// set the icon to null if you want to use the default app icon
|
||||||
null,
|
null,
|
||||||
[
|
[
|
||||||
@ -55,7 +54,7 @@ class FirebaseApi with logging.Logging {
|
|||||||
// This is very important to not harm the user experience
|
// This is very important to not harm the user experience
|
||||||
AwesomeNotifications().requestPermissionToSendNotifications();
|
AwesomeNotifications().requestPermissionToSendNotifications();
|
||||||
}
|
}
|
||||||
});
|
}); */
|
||||||
|
|
||||||
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
|
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
|
||||||
alert: true, // Required to display a heads up notification
|
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 {
|
Future<String> signInEmail(String? email, String? password) async {
|
||||||
if (email == null) {
|
if (email == null) {
|
||||||
throw Exception("Please type an email address");
|
throw Exception("Please type an email address");
|
||||||
@ -395,7 +368,7 @@ class FirebaseApi with logging.Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> setupRemoteConfig() async {
|
Future<void> setupRemoteConfig() async {
|
||||||
initializeFlutterFire();
|
//initializeFlutterFire();
|
||||||
RemoteConfig? remoteConfig;
|
RemoteConfig? remoteConfig;
|
||||||
try {
|
try {
|
||||||
remoteConfig = RemoteConfig.instance;
|
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_execute,
|
||||||
training_plan_finished,
|
training_plan_finished,
|
||||||
training_plan_custom,
|
training_plan_custom,
|
||||||
|
trial
|
||||||
}
|
}
|
||||||
|
|
||||||
T enumFromString<T>(Iterable<T> values, String value) {
|
T enumFromString<T>(Iterable<T> values, String value) {
|
||||||
|
@ -46,7 +46,9 @@ class RevenueCatPurchases with Logging {
|
|||||||
log("Purchaserinfo not reachable " + e.toString());
|
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;
|
Cache().hasPurchased = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,13 @@ class Track with Logging {
|
|||||||
Track._internal();
|
Track._internal();
|
||||||
|
|
||||||
void track(TrackingEvent event, {String eventValue = ""}) {
|
void track(TrackingEvent event, {String eventValue = ""}) {
|
||||||
|
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
|
||||||
if (!isInDebugMode) {
|
if (!isInDebugMode) {
|
||||||
FlurryData.logEvent(event.toString());
|
FlurryData.logEvent(event.toString());
|
||||||
// Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
|
// Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
|
||||||
FlutterUxcam.logEventWithProperties(event.enumToString(), {"value": eventValue});
|
FlutterUxcam.logEventWithProperties(event.enumToString(), {"value": eventValue});
|
||||||
model.Tracking tracking = model.Tracking();
|
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.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
|
||||||
tracking.event = event.enumToString();
|
tracking.event = event.enumToString();
|
||||||
if (eventValue.isNotEmpty) {
|
if (eventValue.isNotEmpty) {
|
||||||
|
@ -12,6 +12,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
import 'package:aitrainer_app/widgets/bottom_nav.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class AccountPage extends StatelessWidget with Trans {
|
class AccountPage extends StatelessWidget with Trans {
|
||||||
@ -151,6 +152,7 @@ class AccountPage extends StatelessWidget with Trans {
|
|||||||
),
|
),
|
||||||
devices(context, accountBloc),
|
devices(context, accountBloc),
|
||||||
loginOut(context, accountBloc),
|
loginOut(context, accountBloc),
|
||||||
|
//messaging(),
|
||||||
//getMyTrainees(context, accountBloc),
|
//getMyTrainees(context, accountBloc),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -180,6 +182,25 @@ class AccountPage extends StatelessWidget with Trans {
|
|||||||
return element;
|
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 loginOut(BuildContext context, AccountBloc accountBloc) {
|
||||||
ListTile element = ListTile();
|
ListTile element = ListTile();
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/sport.dart';
|
import 'package:aitrainer_app/model/sport.dart';
|
||||||
import 'package:aitrainer_app/util/app_localization.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/rendering.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:google_fonts/google_fonts.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 '../bloc/customer_change/customer_change_bloc.dart';
|
||||||
import '../library/dropdown_search/dropdown_search.dart';
|
import '../library/dropdown_search/dropdown_search.dart';
|
||||||
@ -31,11 +33,13 @@ class CustomerFitnessPage extends StatefulWidget {
|
|||||||
class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
||||||
String? selected;
|
String? selected;
|
||||||
bool fulldata = false;
|
bool fulldata = false;
|
||||||
|
late CustomerChangeBloc changeBloc;
|
||||||
|
late double cWidth;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
setContext(context);
|
setContext(context);
|
||||||
final double cWidth = MediaQuery.of(context).size.width * 0.75;
|
cWidth = MediaQuery.of(context).size.width * 0.75;
|
||||||
CustomerRepository customerRepository;
|
CustomerRepository customerRepository;
|
||||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||||
if (args is HashMap && args['personal_data'] != null) {
|
if (args is HashMap && args['personal_data'] != null) {
|
||||||
@ -49,186 +53,122 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
|||||||
back: true,
|
back: true,
|
||||||
);
|
);
|
||||||
if (!fulldata) {
|
if (!fulldata) {
|
||||||
_bar = AppBarProgress(max: 50, min: 26);
|
_bar = AppBarProgress(max: 30, min: 15);
|
||||||
}
|
}
|
||||||
|
final double h = 27;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: _bar,
|
appBar: _bar,
|
||||||
body: BlocProvider(
|
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),
|
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||||
child: Builder(builder: (context) {
|
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||||
// ignore: close_sinks
|
listener: (context, state) {
|
||||||
CustomerChangeBloc changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
if (state is CustomerSaveError) {
|
||||||
selected = changeBloc.selectedFitnessItem;
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
if (selected == null) {
|
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||||
selected = FitnessState.beginner;
|
} else if (state is CustomerSaveSuccess) {
|
||||||
}
|
Navigator.of(context).pop();
|
||||||
return SingleChildScrollView(
|
Navigator.of(context).pushNamed("customerSexPage", arguments: changeBloc.customerRepository);
|
||||||
scrollDirection: Axis.vertical,
|
}
|
||||||
child: Container(
|
},
|
||||||
padding: EdgeInsets.only(bottom: 200),
|
builder: (context, state) {
|
||||||
decoration: BoxDecoration(
|
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||||
image: DecorationImage(
|
return ModalProgressHUD(
|
||||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
child: getPage(),
|
||||||
fit: BoxFit.cover,
|
inAsyncCall: state is CustomerChangeLoading,
|
||||||
alignment: Alignment.center,
|
opacity: 0.5,
|
||||||
),
|
color: Colors.black54,
|
||||||
),
|
progressIndicator: CircularProgressIndicator(),
|
||||||
child: Column(
|
);
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
},
|
||||||
children: [
|
),
|
||||||
Divider(),
|
)),
|
||||||
Wrap(
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
//runAlignment: WrapAlignment.center,
|
onPressed: () => {
|
||||||
alignment: WrapAlignment.center,
|
if (!fulldata)
|
||||||
children: [
|
{
|
||||||
Text(
|
changeBloc.add(CustomerSaveFitness()),
|
||||||
t("Your Fitness State"),
|
}
|
||||||
textAlign: TextAlign.center,
|
else
|
||||||
style: GoogleFonts.archivoBlack(
|
{
|
||||||
color: Colors.orange,
|
changeBloc.add(CustomerSave()),
|
||||||
fontSize: 30,
|
}
|
||||||
fontWeight: FontWeight.w900,
|
},
|
||||||
),
|
backgroundColor: Color(0xffb4f500),
|
||||||
)
|
icon: Icon(
|
||||||
]),
|
CustomIcon.save,
|
||||||
Divider(),
|
color: Colors.black,
|
||||||
TextButton(
|
size: 26,
|
||||||
style: TextButton.styleFrom(
|
),
|
||||||
padding: EdgeInsets.all(10.0),
|
label: Text(
|
||||||
shape: getShape(changeBloc, FitnessState.beginner),
|
fulldata ? t("Save") : t("Next"),
|
||||||
),
|
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
|
||||||
child: Container(
|
),
|
||||||
width: cWidth,
|
),
|
||||||
child: Column(
|
);
|
||||||
children: [
|
}
|
||||||
Text(t("Beginner"),
|
|
||||||
textWidthBasis: TextWidthBasis.longestLine,
|
Widget getPage() {
|
||||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900)),
|
final double h = 27;
|
||||||
Text(
|
return SingleChildScrollView(
|
||||||
t("I am beginner"),
|
scrollDirection: Axis.vertical,
|
||||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
child: Column(
|
||||||
),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
],
|
children: [
|
||||||
)),
|
SizedBox(
|
||||||
onPressed: () => {
|
height: h,
|
||||||
setState(() {
|
),
|
||||||
selected = FitnessState.beginner;
|
Wrap(alignment: WrapAlignment.center, children: [
|
||||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
Text(
|
||||||
}),
|
t("Your Fitness State"),
|
||||||
}),
|
textAlign: TextAlign.center,
|
||||||
Divider(),
|
style: GoogleFonts.archivoBlack(
|
||||||
TextButton(
|
color: Colors.white,
|
||||||
style: TextButton.styleFrom(
|
fontSize: 30,
|
||||||
padding: EdgeInsets.all(10.0),
|
fontWeight: FontWeight.w900,
|
||||||
shape: getShape(changeBloc, FitnessState.intermediate),
|
),
|
||||||
),
|
)
|
||||||
child: Container(
|
]),
|
||||||
width: cWidth,
|
SizedBox(
|
||||||
child: Column(
|
height: h,
|
||||||
children: [
|
),
|
||||||
InkWell(
|
|
||||||
child: Text(
|
getButton("Beginner", "I am beginner", FitnessState.beginner),
|
||||||
t("Intermediate"),
|
SizedBox(
|
||||||
style: TextStyle(color: Colors.blue, fontSize: 32, fontFamily: 'Arial', fontWeight: FontWeight.w900),
|
height: h,
|
||||||
),
|
),
|
||||||
highlightColor: Colors.white,
|
getButton("Intermediate", "I am intermediate", FitnessState.intermediate),
|
||||||
),
|
|
||||||
InkWell(
|
SizedBox(
|
||||||
child: Text(
|
height: h,
|
||||||
t("I am intermediate"),
|
),
|
||||||
style: TextStyle(color: Colors.black, fontSize: 20, fontFamily: 'Arial', fontWeight: FontWeight.w100),
|
getButton("Advanced", "I am advanced", FitnessState.advanced),
|
||||||
),
|
|
||||||
highlightColor: Colors.white,
|
SizedBox(
|
||||||
),
|
height: h,
|
||||||
],
|
),
|
||||||
),
|
getButton("Professional", "I am professional", FitnessState.professional),
|
||||||
),
|
|
||||||
onPressed: () => {
|
/* Divider(),
|
||||||
setState(() {
|
Text(
|
||||||
selected = FitnessState.intermediate;
|
t("Your Primary Sport") + ":",
|
||||||
changeBloc.add(CustomerFitnessChange(fitness: selected!));
|
textAlign: TextAlign.center,
|
||||||
print(selected);
|
style: GoogleFonts.archivoBlack(
|
||||||
}),
|
color: Colors.orange,
|
||||||
}),
|
fontSize: 20,
|
||||||
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,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
getSport(changeBloc),
|
), */
|
||||||
Divider(),
|
//getSport(changeBloc),
|
||||||
|
/* Divider(),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
onPrimary: Colors.white,
|
onPrimary: Colors.white,
|
||||||
@ -240,22 +180,58 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
|
|||||||
Navigator.of(context).pop(),
|
Navigator.of(context).pop(),
|
||||||
if (!fulldata) {Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)}
|
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) {
|
dynamic getShape(CustomerChangeBloc changeBloc, String fitnessLevel) {
|
||||||
String? selected = changeBloc.selectedFitnessItem;
|
String? selected = changeBloc.selectedFitnessItem;
|
||||||
|
|
||||||
dynamic returnCode = (selected == fitnessLevel)
|
dynamic returnCode = (selected == fitnessLevel)
|
||||||
? RoundedRectangleBorder(
|
? RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 4, color: Colors.orange),
|
side: BorderSide(
|
||||||
|
width: 4,
|
||||||
|
color: Color(0xffb4f500),
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
)
|
)
|
||||||
: RoundedRectangleBorder(
|
: RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 1, color: Colors.blue),
|
side: BorderSide(width: 4, color: Colors.white24),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
);
|
);
|
||||||
//return
|
//return
|
||||||
return returnCode;
|
return returnCode;
|
||||||
|
@ -10,6 +10,7 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:google_fonts/google_fonts.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 }
|
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;
|
CustomerRepository customerRepository;
|
||||||
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
dynamic args = ModalRoute.of(context)!.settings.arguments;
|
||||||
if (args is HashMap && args['personal_data'] != null) {
|
if (args != null) {
|
||||||
fulldata = args['personal_data'];
|
if (args is HashMap && args['personal_data'] != null) {
|
||||||
customerRepository = args['bloc'];
|
fulldata = args['personal_data'];
|
||||||
|
customerRepository = args['bloc'];
|
||||||
|
} else {
|
||||||
|
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
|
customerRepository = CustomerRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferredSizeWidget _bar = AppBarMin(
|
PreferredSizeWidget _bar = AppBarMin(
|
||||||
back: true,
|
back: false,
|
||||||
);
|
);
|
||||||
if (!fulldata) {
|
if (!fulldata) {
|
||||||
_bar = AppBarProgress(max: 50, min: 26);
|
_bar = AppBarProgress(max: 14, min: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -88,7 +92,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
|||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: AssetImage('asset/image/WT_light_background.jpg'),
|
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
@ -97,75 +101,120 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
create: (context) => CustomerChangeBloc(customerRepository: customerRepository),
|
||||||
child: Builder(builder: (context) {
|
child: BlocConsumer<CustomerChangeBloc, CustomerChangeState>(
|
||||||
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
listener: (context, state) {
|
||||||
|
if (state is CustomerSaveError) {
|
||||||
return SingleChildScrollView(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
child: Center(
|
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||||
child: Column(
|
} else if (state is CustomerSaveSuccess) {
|
||||||
children: [
|
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository);
|
||||||
Divider(),
|
}
|
||||||
Wrap(alignment: WrapAlignment.center, children: [
|
},
|
||||||
Text(
|
builder: (context, state) {
|
||||||
t("Set Your Primary Goal"),
|
changeBloc = BlocProvider.of<CustomerChangeBloc>(context);
|
||||||
maxLines: 2,
|
return ModalProgressHUD(
|
||||||
textAlign: TextAlign.center,
|
child: getPage(),
|
||||||
style: GoogleFonts.archivoBlack(
|
inAsyncCall: state is CustomerChangeLoading,
|
||||||
color: Colors.orange,
|
opacity: 0.5,
|
||||||
fontSize: 30,
|
color: Colors.black54,
|
||||||
shadows: <Shadow>[
|
progressIndicator: CircularProgressIndicator(),
|
||||||
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(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
onPressed: () => {
|
onPressed: () => {
|
||||||
//changingViewModel.saveCustomer(),
|
print("Fulldata: $fulldata bloc $changeBloc"),
|
||||||
changeBloc.add(CustomerSave()),
|
if (!fulldata)
|
||||||
Navigator.of(context).pop(),
|
{
|
||||||
if (!fulldata) {Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository)}
|
print("Savegoal"),
|
||||||
|
changeBloc.add(CustomerSaveGoal()),
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
changeBloc.add(CustomerSave()),
|
||||||
|
}
|
||||||
},
|
},
|
||||||
backgroundColor: Colors.orange[800],
|
backgroundColor: Color(0xffb4f500),
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
CustomIcon.save,
|
CustomIcon.save,
|
||||||
size: 20,
|
color: Colors.black,
|
||||||
|
size: 26,
|
||||||
),
|
),
|
||||||
label: Text(
|
label: Text(
|
||||||
fulldata ? t("Save") : t("Next"),
|
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) {
|
Widget getItem(CustomerChangeBloc changeBloc, Goals goal) {
|
||||||
return Stack(alignment: Alignment.bottomLeft, children: [
|
return Stack(alignment: Alignment.bottomLeft, children: [
|
||||||
TextButton(
|
TextButton(
|
||||||
@ -188,7 +237,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
|||||||
child: Text(
|
child: Text(
|
||||||
t(goal.description(goal)),
|
t(goal.description(goal)),
|
||||||
style: GoogleFonts.archivoBlack(
|
style: GoogleFonts.archivoBlack(
|
||||||
color: Colors.yellow[300],
|
color: Colors.white,
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
shadows: <Shadow>[
|
shadows: <Shadow>[
|
||||||
Shadow(
|
Shadow(
|
||||||
@ -204,13 +253,18 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dynamic getShape(CustomerChangeBloc customerBloc, String goal) {
|
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!;
|
String selectedGoal = customerBloc.customerRepository.goal!;
|
||||||
dynamic returnCode = (selectedGoal == goal)
|
dynamic returnCode = (selectedGoal == goal)
|
||||||
? RoundedRectangleBorder(
|
? RoundedRectangleBorder(
|
||||||
side: BorderSide(width: 4, color: Colors.red),
|
side: BorderSide(width: 6, color: Color(0xffb4f500)),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
)
|
)
|
||||||
: null;
|
: baseCode;
|
||||||
//return
|
//return
|
||||||
return returnCode;
|
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:aitrainer_app/widgets/app_bar_min.dart';
|
||||||
import 'package:flutter/material.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
|
// ignore: must_be_immutable
|
||||||
class CustomerWelcomePage extends StatefulWidget {
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
setContext(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarMin(),
|
appBar: AppBarMin(
|
||||||
|
back: true,
|
||||||
|
),
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
@ -30,17 +37,64 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> {
|
|||||||
child: Center(
|
child: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Divider(
|
SizedBox(
|
||||||
color: Colors.transparent,
|
height: 200,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
CircularPercentIndicator(
|
||||||
style: ElevatedButton.styleFrom(
|
radius: 250.0,
|
||||||
primary: Colors.orange,
|
animation: true,
|
||||||
onSurface: Colors.white,
|
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"))),
|
circularStrokeCap: CircularStrokeCap.round,
|
||||||
onPressed: () => {Navigator.of(context).pop(), Navigator.of(context).pushNamed("home")},
|
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),
|
Divider(color: Colors.transparent),
|
||||||
getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x4-8", 0.95, "3-5"),
|
getSuggestionWidget(resultBloc, "Gain Strength", "asset/image/pict_weight_volumen_tonna.png", "3x4-8", 0.95, "3-5"),
|
||||||
Divider(color: Colors.transparent),
|
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/account/account_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
|
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/repository/training_plan_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/user_repository.dart';
|
import 'package:aitrainer_app/repository/user_repository.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||||
@ -33,17 +34,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(backgroundColor: Colors.orange, content: Text(t(state.message), style: TextStyle(color: Colors.white))));
|
SnackBar(backgroundColor: Colors.orange, content: Text(t(state.message), style: TextStyle(color: Colors.white))));
|
||||||
} else if (state is LoginSuccess) {
|
} else if (state is LoginSuccess) {
|
||||||
|
TrainingPlanRepository trainingPlanRepository = TrainingPlanRepository();
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return DialogCommon(
|
return DialogCommon(
|
||||||
title: t("Successful Registration"),
|
title: t("Successful Registration"),
|
||||||
descriptions: t("Now we would like to know you better to lift the experience of the app."),
|
descriptions: t("Based on your initial data, we will generate the personalized training plan for you."),
|
||||||
description2: t("Please go through the pages, it will take couple of minutes!"),
|
|
||||||
text: "OK",
|
text: "OK",
|
||||||
onTap: () => {Navigator.of(context).pushNamed('customerModifyPage')},
|
onTap: () => {Navigator.of(context).pushNamed('customerWelcomePage')},
|
||||||
onCancel: () => {
|
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(
|
child: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: AssetImage('asset/image/WT_login.jpg'),
|
image: AssetImage('asset/image/WT_menu_dark.jpg'),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
@ -99,17 +101,32 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||||
child: ListView(shrinkWrap: false, padding: EdgeInsets.only(top: 10.0), children: <Widget>[
|
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(
|
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(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -140,7 +157,6 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
: Offstage(),
|
: Offstage(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
//ListTile(title: Text(t("OR"), style: GoogleFonts.inter())),
|
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
),
|
),
|
||||||
@ -149,6 +165,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||||
labelText: t('Email'),
|
labelText: t('Email'),
|
||||||
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Color(0xffb4f500),
|
||||||
|
),
|
||||||
fillColor: Colors.white24,
|
fillColor: Colors.white24,
|
||||||
filled: true,
|
filled: true,
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
@ -165,7 +185,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
},
|
},
|
||||||
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
|
onChanged: (value) => loginBloc.add(LoginEmailChange(email: value)),
|
||||||
keyboardType: TextInputType.emailAddress,
|
keyboardType: TextInputType.emailAddress,
|
||||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||||
),
|
),
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
@ -174,7 +194,10 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
key: LibraryKeys.loginPasswordField,
|
key: LibraryKeys.loginPasswordField,
|
||||||
obscureText: loginBloc.obscure,
|
obscureText: loginBloc.obscure,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelStyle: TextStyle(fontSize: 14),
|
labelStyle: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Color(0xffb4f500),
|
||||||
|
),
|
||||||
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
contentPadding: EdgeInsets.only(left: 15, top: 15, bottom: 15),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
|
onPressed: () => {loginBloc.add(LoginPasswordChangeObscure())},
|
||||||
@ -197,7 +220,7 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
},
|
},
|
||||||
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
|
onChanged: (value) => loginBloc.add(LoginPasswordChange(password: value)),
|
||||||
keyboardType: TextInputType.visiblePassword,
|
keyboardType: TextInputType.visiblePassword,
|
||||||
style: new TextStyle(fontSize: 16, color: Colors.indigo),
|
style: new TextStyle(fontSize: 16, color: Colors.white),
|
||||||
),
|
),
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
@ -214,7 +237,22 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
t("With the registration I accept the data policy and the terms of use."),
|
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>[
|
Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
|
||||||
@ -242,7 +280,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
InkWell(
|
InkWell(
|
||||||
child: Text(
|
child: Text(
|
||||||
t('Login'),
|
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'),
|
onTap: () => Navigator.of(context).pushNamed('login'),
|
||||||
),
|
),
|
||||||
@ -250,7 +304,23 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
InkWell(
|
InkWell(
|
||||||
child: Text(
|
child: Text(
|
||||||
t('Terms Of Use'),
|
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: () => {
|
onTap: () => {
|
||||||
showDialog(
|
showDialog(
|
||||||
@ -263,7 +333,18 @@ class RegistrationPage extends StatelessWidget with Trans {
|
|||||||
InkWell(
|
InkWell(
|
||||||
child: Text(
|
child: Text(
|
||||||
t('Privacy'),
|
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: () => {
|
onTap: () => {
|
||||||
showDialog(
|
showDialog(
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||||
import 'package:aitrainer_app/bloc/tutorial/tutorial_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:google_fonts/google_fonts.dart';
|
||||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||||
import 'package:toggle_switch/toggle_switch.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
|
// ignore: must_be_immutable
|
||||||
class SettingsPage extends StatelessWidget with Trans {
|
class SettingsPage extends StatelessWidget with Trans {
|
||||||
@ -81,7 +84,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
|||||||
Track().track(TrackingEvent.settings_lang, eventValue: lang)
|
Track().track(TrackingEvent.settings_lang, eventValue: lang)
|
||||||
})),
|
})),
|
||||||
getServer(settingsBloc),
|
getServer(settingsBloc),
|
||||||
getTuturialBasic(settingsBloc),
|
//getTuturialBasic(settingsBloc),
|
||||||
getTermsOfUse(),
|
getTermsOfUse(),
|
||||||
getPrivacy(),
|
getPrivacy(),
|
||||||
getFaq(),
|
getFaq(),
|
||||||
@ -96,7 +99,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
|||||||
title: Container(),
|
title: Container(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
print("Live: ${Cache().liveServer}");
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: Icon(Icons.data_usage_sharp),
|
leading: Icon(Icons.data_usage_sharp),
|
||||||
subtitle: Text("For Test purpuses select Test-Server. After that please restart the the App"),
|
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(
|
child: Text(
|
||||||
parentTitle,
|
parentTitle,
|
||||||
maxLines: 2,
|
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((_) {
|
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||||
final TutorialBloc bloc = BlocProvider.of<TutorialBloc>(context);
|
/* //final TutorialBloc bloc = BlocProvider.of<TutorialBloc>(context);
|
||||||
if (bloc.actualCheck == "directTest") {
|
if (bloc.actualCheck == "directTest") {
|
||||||
Timer(
|
Timer(
|
||||||
Duration(milliseconds: 2000),
|
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/service/logging.dart';
|
||||||
import 'package:aitrainer_app/util/app_language.dart';
|
import 'package:aitrainer_app/util/app_language.dart';
|
||||||
import 'package:aitrainer_app/util/trans.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/login.dart';
|
||||||
import 'package:aitrainer_app/view/menu_page.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:aitrainer_app/widgets/dialog_common.dart';
|
||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
@ -37,6 +38,15 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
|||||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||||
runDelayedEvent();
|
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 {
|
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 appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml";
|
||||||
final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
|
final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
|
||||||
print("Packageinfo ${Cache().packageInfo}");
|
print("Packageinfo ${Cache().packageInfo}");
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
body: UpgradeAlert(
|
body: UpgradeAlert(
|
||||||
@ -101,7 +112,7 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
|||||||
if (Cache().startPage == 'login') {
|
if (Cache().startPage == 'login') {
|
||||||
return LoginPage();
|
return LoginPage();
|
||||||
} else if (Cache().startPage == 'registration') {
|
} else if (Cache().startPage == 'registration') {
|
||||||
return RegistrationPage();
|
return CustomerGoalPage();
|
||||||
} else {
|
} else {
|
||||||
return MenuPage(parent: 0);
|
return MenuPage(parent: 0);
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,19 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||||
import 'package:aitrainer_app/library/transparent_image.dart';
|
import 'package:aitrainer_app/library/transparent_image.dart';
|
||||||
|
import 'package:flutter_html/shims/dart_ui_real.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class MenuImage extends StatelessWidget {
|
class MenuImage extends StatelessWidget {
|
||||||
final int? workoutTreeId;
|
final int? workoutTreeId;
|
||||||
final String imageName;
|
final String imageName;
|
||||||
|
bool filter;
|
||||||
double radius;
|
double radius;
|
||||||
MenuImage({
|
MenuImage({
|
||||||
required this.workoutTreeId,
|
required this.workoutTreeId,
|
||||||
required this.imageName,
|
required this.imageName,
|
||||||
this.radius = 24,
|
this.radius = 24,
|
||||||
|
this.filter = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -23,10 +26,16 @@ class MenuImage extends StatelessWidget {
|
|||||||
String? imageString = this.getImage(workoutTreeId!, imageName);
|
String? imageString = this.getImage(workoutTreeId!, imageName);
|
||||||
Widget? widget;
|
Widget? widget;
|
||||||
if (imageString != null) {
|
if (imageString != null) {
|
||||||
|
print("MemoryImage $workoutTreeId - $imageName");
|
||||||
widget = ClipRRect(
|
widget = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(24.0),
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.transparent,
|
padding: EdgeInsets.zero,
|
||||||
|
color: Colors.black38,
|
||||||
|
foregroundDecoration: BoxDecoration(
|
||||||
|
color: Colors.black38,
|
||||||
|
backgroundBlendMode: BlendMode.darken,
|
||||||
|
),
|
||||||
child: FadeInImage(
|
child: FadeInImage(
|
||||||
fadeInDuration: Duration(milliseconds: 100),
|
fadeInDuration: Duration(milliseconds: 100),
|
||||||
image: MemoryImage(base64Decode(imageString)),
|
image: MemoryImage(base64Decode(imageString)),
|
||||||
@ -35,10 +44,18 @@ class MenuImage extends StatelessWidget {
|
|||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
if (imageName.contains("https")) {
|
if (imageName.contains("https")) {
|
||||||
|
print("https image $workoutTreeId - $imageName");
|
||||||
if (!wt.ImageCache().existsImageInMap(workoutTreeId!, imageName)) {
|
if (!wt.ImageCache().existsImageInMap(workoutTreeId!, imageName)) {
|
||||||
widget = ClipRRect(
|
widget = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(radius),
|
borderRadius: BorderRadius.circular(radius),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
foregroundDecoration: filter
|
||||||
|
? BoxDecoration(
|
||||||
|
color: Colors.black38,
|
||||||
|
backgroundBlendMode: BlendMode.darken,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: FadeInImage(
|
child: FadeInImage(
|
||||||
fadeInDuration: Duration(milliseconds: 500),
|
fadeInDuration: Duration(milliseconds: 500),
|
||||||
@ -51,7 +68,14 @@ class MenuImage extends StatelessWidget {
|
|||||||
widget = ClipRRect(
|
widget = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(radius),
|
borderRadius: BorderRadius.circular(radius),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
|
foregroundDecoration: filter
|
||||||
|
? BoxDecoration(
|
||||||
|
color: Colors.black38,
|
||||||
|
backgroundBlendMode: BlendMode.darken,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
child: Image.asset(imageName),
|
child: Image.asset(imageName),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
|
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/model/exercise_ability.dart';
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.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/enums.dart';
|
||||||
import 'package:aitrainer_app/util/track.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_image.dart';
|
||||||
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
|
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
|
||||||
import 'package:aitrainer_app/util/app_language.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/service/logging.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||||
import 'package:aitrainer_app/widgets/tutorial_widget.dart';
|
|
||||||
import 'package:badges/badges.dart';
|
import 'package:badges/badges.dart';
|
||||||
import 'package:ezanimation/ezanimation.dart';
|
import 'package:ezanimation/ezanimation.dart';
|
||||||
|
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
@ -39,7 +40,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
final double baseWidth = 312;
|
final double baseWidth = 312;
|
||||||
final double baseHeight = 675.2;
|
final double baseHeight = 675.2;
|
||||||
late MenuBloc menuBloc;
|
late MenuBloc menuBloc;
|
||||||
late TutorialBloc tutorialBloc;
|
//late TutorialBloc tutorialBloc;
|
||||||
final scrollController = ScrollController();
|
final scrollController = ScrollController();
|
||||||
final bool activeExercisePlan = Cache().activeExercisePlan != null;
|
final bool activeExercisePlan = Cache().activeExercisePlan != null;
|
||||||
final EzAnimation animation = EzAnimation(35.0, 10.0, Duration(seconds: 2), reverseCurve: Curves.linear);
|
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
|
/// We require the initializers to run after the loading screen is rendered
|
||||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||||
menuBloc.add(MenuCreate());
|
menuBloc.add(MenuCreate());
|
||||||
//runDelayedEvent();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
super.initState();
|
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
|
@override
|
||||||
bool didUpdateWidget(MenuPageWidget oldWidget) {
|
bool didUpdateWidget(MenuPageWidget oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
@ -102,10 +73,68 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
return true;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
tutorialBloc = BlocProvider.of<TutorialBloc>(context);
|
//tutorialBloc = BlocProvider.of<TutorialBloc>(context);
|
||||||
setContext(context);
|
setContext(context);
|
||||||
double cWidth = MediaQuery.of(context).size.width;
|
double cWidth = MediaQuery.of(context).size.width;
|
||||||
double cHeight = MediaQuery.of(context).size.height;
|
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(
|
SliverList sliverList = SliverList(
|
||||||
delegate: SliverChildListDelegate(_columnChildren),
|
delegate: SliverChildListDelegate(_columnChildren),
|
||||||
);
|
);
|
||||||
@ -292,7 +325,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Cache().myTrainingPlan != null
|
/* Cache().myTrainingPlan != null
|
||||||
? GestureDetector(
|
? GestureDetector(
|
||||||
onTap: () => showDialog(
|
onTap: () => showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@ -326,7 +359,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}))
|
}))
|
||||||
: Offstage(),
|
: Offstage(), */
|
||||||
/* activeExercisePlan
|
/* activeExercisePlan
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: 10,
|
width: 10,
|
||||||
@ -376,24 +409,59 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc) {
|
void menuClick(WorkoutMenuTree workoutTree, MenuBloc menuBloc) {
|
||||||
if (tutorialBloc.isActive) {
|
/* if (tutorialBloc.isActive) {
|
||||||
final String checkText = workoutTree.nameEnglish;
|
final String checkText = workoutTree.nameEnglish;
|
||||||
if (!tutorialBloc.checkAction(checkText)) {
|
if (!tutorialBloc.checkAction(checkText)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
print("ability: ${menuBloc.ability} tree: $workoutTree parent: ${workoutTree.parent}");
|
||||||
|
|
||||||
if (workoutTree.child == false) {
|
if (workoutTree.child == false) {
|
||||||
if (menuBloc.ability != null && ExerciseAbility.mini_test_set.equalsTo(menuBloc.ability!) && workoutTree.parent != 0) {
|
if (menuBloc.ability != null && ExerciseAbility.mini_test_set.equalsTo(menuBloc.ability!) && workoutTree.parent != 0) {
|
||||||
HashMap args = HashMap();
|
HashMap args = HashMap();
|
||||||
args['templateName'] = workoutTree.nameEnglish;
|
args['templateName'] = workoutTree.nameEnglish;
|
||||||
args['templateNameTranslation'] = workoutTree.name;
|
args['templateNameTranslation'] = workoutTree.name;
|
||||||
Navigator.of(context).pushNamed('testSetEdit', arguments: args);
|
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) {
|
} else if (menuBloc.ability != null && ExerciseAbility.training.equalsTo(menuBloc.ability!) && workoutTree.parent != 0) {
|
||||||
HashMap<String, dynamic> args = HashMap();
|
HashMap<String, dynamic> args = HashMap();
|
||||||
args['parentName'] = workoutTree.internalName;
|
args['parentName'] = workoutTree.internalName;
|
||||||
Navigator.of(context).pushNamed("myTrainingPlanActivate", arguments: args);
|
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 {
|
} else {
|
||||||
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
menuBloc.add(MenuClickExercise(exerciseTypeId: workoutTree.id));
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ class NumberPickerWidget extends StatefulWidget {
|
|||||||
final String unit;
|
final String unit;
|
||||||
final Color color;
|
final Color color;
|
||||||
double? fontSize;
|
double? fontSize;
|
||||||
|
double? diameterRatio;
|
||||||
|
double? itemExtent;
|
||||||
|
FontWeight? fontWeight;
|
||||||
|
|
||||||
NumberPickerWidget(
|
NumberPickerWidget(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
@ -19,10 +22,16 @@ class NumberPickerWidget extends StatefulWidget {
|
|||||||
required this.initalValue,
|
required this.initalValue,
|
||||||
required this.unit,
|
required this.unit,
|
||||||
this.fontSize,
|
this.fontSize,
|
||||||
|
this.diameterRatio,
|
||||||
|
this.itemExtent,
|
||||||
|
this.fontWeight,
|
||||||
required this.color,
|
required this.color,
|
||||||
required this.onChange})
|
required this.onChange})
|
||||||
: super(key: key) {
|
: super(key: key) {
|
||||||
fontSize = fontSize ?? 20;
|
fontSize = fontSize ?? 20;
|
||||||
|
diameterRatio = diameterRatio ?? 0.85;
|
||||||
|
itemExtent = itemExtent ?? 30;
|
||||||
|
fontWeight = fontWeight ?? FontWeight.normal;
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
_NumberPickerWidgetState createState() => _NumberPickerWidgetState();
|
_NumberPickerWidgetState createState() => _NumberPickerWidgetState();
|
||||||
@ -59,7 +68,7 @@ class _NumberPickerWidgetState extends State<NumberPickerWidget> with Trans {
|
|||||||
scrollController: _scrollController,
|
scrollController: _scrollController,
|
||||||
useMagnifier: true,
|
useMagnifier: true,
|
||||||
magnification: 1.2,
|
magnification: 1.2,
|
||||||
diameterRatio: 0.85,
|
diameterRatio: widget.diameterRatio!,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
selectionOverlay: Container(),
|
selectionOverlay: Container(),
|
||||||
onSelectedItemChanged: (x) {
|
onSelectedItemChanged: (x) {
|
||||||
@ -72,8 +81,10 @@ class _NumberPickerWidgetState extends State<NumberPickerWidget> with Trans {
|
|||||||
widget.onChange(value);
|
widget.onChange(value);
|
||||||
},
|
},
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
widget.maxValue, (index) => Text('$index ' + widget.unit, style: TextStyle(color: widget.color, fontSize: widget.fontSize))),
|
widget.maxValue,
|
||||||
itemExtent: 30,
|
(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"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.1"
|
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:
|
badges:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -70,7 +63,7 @@ packages:
|
|||||||
name: bloc_test
|
name: bloc_test
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.0.0"
|
version: "8.1.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -294,7 +287,7 @@ packages:
|
|||||||
name: equatable
|
name: equatable
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.3"
|
||||||
extended_tabs:
|
extended_tabs:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -343,7 +336,7 @@ packages:
|
|||||||
name: firebase_analytics
|
name: firebase_analytics
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.1.0"
|
version: "8.3.0"
|
||||||
firebase_analytics_platform_interface:
|
firebase_analytics_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -364,28 +357,28 @@ packages:
|
|||||||
name: firebase_auth
|
name: firebase_auth
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "3.0.2"
|
||||||
firebase_auth_platform_interface:
|
firebase_auth_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_auth_platform_interface
|
name: firebase_auth_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.3"
|
version: "6.0.1"
|
||||||
firebase_auth_web:
|
firebase_auth_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_auth_web
|
name: firebase_auth_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.3"
|
version: "3.0.1"
|
||||||
firebase_core:
|
firebase_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_core
|
name: firebase_core
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.5.0"
|
||||||
firebase_core_platform_interface:
|
firebase_core_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -400,41 +393,55 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
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:
|
firebase_messaging:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging
|
name: firebase_messaging
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.0"
|
version: "10.0.5"
|
||||||
firebase_messaging_platform_interface:
|
firebase_messaging_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_platform_interface
|
name: firebase_messaging_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.0"
|
version: "3.0.4"
|
||||||
firebase_messaging_web:
|
firebase_messaging_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_messaging_web
|
name: firebase_messaging_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.4"
|
||||||
firebase_remote_config:
|
firebase_remote_config:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: firebase_remote_config
|
name: firebase_remote_config
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.0"
|
version: "0.10.0+4"
|
||||||
firebase_remote_config_platform_interface:
|
firebase_remote_config_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: firebase_remote_config_platform_interface
|
name: firebase_remote_config_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.3.0+4"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -474,28 +481,28 @@ packages:
|
|||||||
name: flutter_bloc
|
name: flutter_bloc
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "7.1.0"
|
||||||
flutter_facebook_auth:
|
flutter_facebook_auth:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_facebook_auth
|
name: flutter_facebook_auth
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "3.5.1"
|
||||||
flutter_facebook_auth_platform_interface:
|
flutter_facebook_auth_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_facebook_auth_platform_interface
|
name: flutter_facebook_auth_platform_interface
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.0"
|
version: "2.7.0"
|
||||||
flutter_facebook_auth_web:
|
flutter_facebook_auth_web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_facebook_auth_web
|
name: flutter_facebook_auth_web
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.0"
|
version: "2.6.0+2"
|
||||||
flutter_fadein:
|
flutter_fadein:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -561,7 +568,7 @@ packages:
|
|||||||
name: flutter_uxcam
|
name: flutter_uxcam
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0-beta.1"
|
version: "2.0.0"
|
||||||
flutter_web_plugins:
|
flutter_web_plugins:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -1285,7 +1292,7 @@ packages:
|
|||||||
name: upgrader
|
name: upgrader
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.3.0"
|
version: "3.5.1"
|
||||||
url_launcher:
|
url_launcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1477,4 +1484,4 @@ packages:
|
|||||||
version: "3.1.0"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.12.0 <3.0.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=2.0.4"
|
flutter: ">=2.0.0"
|
||||||
|
29
pubspec.yaml
29
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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.1.21+92
|
version: 1.1.22+93
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.12.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
@ -28,8 +28,8 @@ dependencies:
|
|||||||
google_fonts: ^2.1.0
|
google_fonts: ^2.1.0
|
||||||
devicelocale: ^0.4.1
|
devicelocale: ^0.4.1
|
||||||
sentry_flutter: ^5.1.0-beta.1
|
sentry_flutter: ^5.1.0-beta.1
|
||||||
flutter_bloc: ^7.0.0
|
flutter_bloc: ^7.1.0
|
||||||
equatable: ^2.0.2
|
equatable: ^2.0.3
|
||||||
|
|
||||||
spider_chart: ^0.1.5
|
spider_chart: ^0.1.5
|
||||||
rainbow_color: ^2.0.1
|
rainbow_color: ^2.0.1
|
||||||
@ -49,33 +49,34 @@ dependencies:
|
|||||||
purchases_flutter: ^3.2.2
|
purchases_flutter: ^3.2.2
|
||||||
package_info: ^2.0.0
|
package_info: ^2.0.0
|
||||||
ezanimation: ^0.5.0
|
ezanimation: ^0.5.0
|
||||||
flutter_fadein: ^2.0.0
|
|
||||||
confetti: ^0.6.0-nullsafety
|
confetti: ^0.6.0-nullsafety
|
||||||
crypto: ^3.0.0
|
crypto: ^3.0.0
|
||||||
carousel_slider: ^4.0.0-nullsafety.0
|
carousel_slider: ^4.0.0-nullsafety.0
|
||||||
convex_bottom_bar: ^3.0.0
|
convex_bottom_bar: ^3.0.0
|
||||||
flutter_app_badger: ^1.2.0
|
flutter_app_badger: ^1.2.0
|
||||||
extended_tabs: ^2.2.0
|
extended_tabs: ^2.2.0
|
||||||
upgrader: ^3.3.0
|
upgrader: ^3.5.1
|
||||||
web_browser: ^0.5.0
|
web_browser: ^0.5.0
|
||||||
|
flutter_fadein: ^2.0.0
|
||||||
|
|
||||||
firebase_core: ^1.2.0
|
firebase_core: ^1.5.0
|
||||||
firebase_analytics: ^8.1.0
|
firebase_analytics: ^8.1.0
|
||||||
firebase_messaging: ^10.0.0
|
firebase_messaging: ^10.0.0
|
||||||
firebase_auth: ^1.2.0
|
firebase_auth: ^3.0.2
|
||||||
firebase_remote_config: ^0.10.0
|
firebase_remote_config: ^0.10.0+4
|
||||||
awesome_notifications: ^0.0.6+9
|
firebase_dynamic_links: ^2.0.8
|
||||||
|
firebase_in_app_messaging: ^0.5.0+8
|
||||||
|
|
||||||
syncfusion_flutter_gauges: ^19.1.63
|
syncfusion_flutter_gauges: ^19.1.63
|
||||||
syncfusion_flutter_datagrid: ^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
|
google_sign_in: ^5.0.3
|
||||||
sign_in_with_apple: ^3.0.0
|
sign_in_with_apple: ^3.0.0
|
||||||
|
|
||||||
#smartlook: ^1.0.7
|
#smartlook: ^1.0.7
|
||||||
flurry_data: ^0.0.1
|
flurry_data: ^0.0.1
|
||||||
flutter_uxcam: ^2.0.0-beta.1
|
flutter_uxcam: ^2.0.0
|
||||||
|
|
||||||
animated_widgets: ^1.0.6
|
animated_widgets: ^1.0.6
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ dev_dependencies:
|
|||||||
test: '>=1.0.0 <2.0.0'
|
test: '>=1.0.0 <2.0.0'
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
bloc_test: ^8.0.0
|
bloc_test: ^8.1.0
|
||||||
|
|
||||||
build_runner:
|
build_runner:
|
||||||
|
|
||||||
@ -154,6 +155,7 @@ flutter:
|
|||||||
- asset/image/WT_Results_for_men.jpg
|
- asset/image/WT_Results_for_men.jpg
|
||||||
- asset/image/WT_results_background.jpg
|
- asset/image/WT_results_background.jpg
|
||||||
- asset/image/WT_cup_victory400.png
|
- asset/image/WT_cup_victory400.png
|
||||||
|
- asset/image/WT_zold.jpg
|
||||||
|
|
||||||
- asset/image/button_fb.png
|
- asset/image/button_fb.png
|
||||||
- asset/image/button_apple.png
|
- asset/image/button_apple.png
|
||||||
@ -179,6 +181,7 @@ flutter:
|
|||||||
- asset/image/gain_strength.jpg
|
- asset/image/gain_strength.jpg
|
||||||
- asset/image/muscle_endurance.jpg
|
- asset/image/muscle_endurance.jpg
|
||||||
- asset/image/shape_forming.jpg
|
- asset/image/shape_forming.jpg
|
||||||
|
|
||||||
- asset/image/woman_sizes.png
|
- asset/image/woman_sizes.png
|
||||||
- asset/image/weight_loss.jpg
|
- asset/image/weight_loss.jpg
|
||||||
- asset/image/merleg.png
|
- asset/image/merleg.png
|
||||||
@ -368,6 +371,7 @@ flutter:
|
|||||||
- asset/menu/situps.jpg
|
- asset/menu/situps.jpg
|
||||||
- asset/menu/sizes.jpg
|
- asset/menu/sizes.jpg
|
||||||
- asset/menu/smith_machine_chest_press.jpg
|
- asset/menu/smith_machine_chest_press.jpg
|
||||||
|
- asset/menu/smith_machine_squats.jpg
|
||||||
- asset/menu/squats_with_kettlebell.jpg
|
- asset/menu/squats_with_kettlebell.jpg
|
||||||
- asset/menu/squat_jump_weight.jpg
|
- asset/menu/squat_jump_weight.jpg
|
||||||
- asset/menu/squat_jump.jpg
|
- asset/menu/squat_jump.jpg
|
||||||
@ -403,6 +407,7 @@ flutter:
|
|||||||
- asset/menu/training_plans_q_beginner.jpg
|
- asset/menu/training_plans_q_beginner.jpg
|
||||||
- asset/menu/training_plans_q_advanced.jpg
|
- asset/menu/training_plans_q_advanced.jpg
|
||||||
- asset/menu/training_plans_q_gain_strength.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_extension_on_cable_with_rope.jpg
|
||||||
- asset/menu/triceps_kickback.jpg
|
- asset/menu/triceps_kickback.jpg
|
||||||
- asset/menu/triceps_pushdown.jpg
|
- asset/menu/triceps_pushdown.jpg
|
||||||
|
Loading…
Reference in New Issue
Block a user