WT 1.1.22 reengineering: Training Plan execution, registration

This commit is contained in:
bossanyit 2021-08-25 01:05:03 +02:00
parent 6b25fdfe0e
commit cebd83648b
51 changed files with 2605 additions and 663 deletions

View File

@ -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'

View File

@ -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
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.google.firebase.messaging.default_notification_channel_id" android:value="high_importance_channel" />
android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity" <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation" <activity android:name="com.facebook.FacebookActivity" android:configChanges=
android:label="@string/app_name" /> "keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" />
<activity <activity android:name="com.facebook.CustomTabActivity" android:exported="true">
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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

View File

@ -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;

View File

@ -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)
} }
} }

View File

@ -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>

View File

@ -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>

View File

@ -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()) {

View File

@ -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();
}

View File

@ -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);
} }

View File

@ -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];
} }

View File

@ -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();
} }
} }

View File

@ -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!);

View File

@ -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;
}
} }

View File

@ -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(),
}, },

View File

@ -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;
}
} }

View File

@ -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) {

View File

@ -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;

View File

@ -75,6 +75,7 @@ class WorkoutMenuTree {
"is1RM": is1RM.toString(), "is1RM": is1RM.toString(),
"isRunning": isRunning.toString(), "isRunning": isRunning.toString(),
"sort": sort, "sort": sort,
"internalName": internalName,
}; };
} }

View File

@ -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 {

View File

@ -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;
}
}
}
} }

View File

@ -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((_) {

View File

@ -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);
}
} */

View File

@ -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) {

View File

@ -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;
} }
} }

View File

@ -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) {

View File

@ -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();

View File

@ -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;

View File

@ -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;
} }

View 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))
]);
}
}

View 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;
}
}

View 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)));
}
}

View File

@ -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),
),
], ],
), ),
))), ))),

View File

@ -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"),
], ],
), ),
); );

View File

@ -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(

View File

@ -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 = "'";
}
}
} }

View File

@ -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,
),
)), )),
], ],
), ),

View 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));
},
)
],
));
}
}

View 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();
}
}

View File

@ -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 {
); );
}) })
}); });
} } */
}); });
} }

View File

@ -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);
} }

View File

@ -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),
)); ));
} }

View File

@ -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));

View File

@ -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!,
); );
} }

View File

@ -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"

View File

@ -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