WT1.1.11 Null-Safe migration

This commit is contained in:
bossanyit 2021-04-02 11:42:26 +02:00
parent a656562c49
commit 01148c6e39
219 changed files with 3208 additions and 5334 deletions

View File

@ -50,6 +50,10 @@
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> 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.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/> android:value="@string/facebook_app_id"/>

View File

@ -408,6 +408,7 @@
"Start":"Start", "Start":"Start",
"Compact Test":"Compact Test", "Compact Test":"Compact Test",
"Custom Test":"Custom Test", "Custom Test":"Custom Test",
"Set": "Set" "Set": "Set",
"Add this exercise to execute it paralell":"Add this exercise to execute it paralell"
} }

View File

@ -404,7 +404,8 @@
"Start":"Kezdd el", "Start":"Kezdd el",
"Compact Test":"Kompakt teszt", "Compact Test":"Kompakt teszt",
"Custom Test":"Egyedi teszt", "Custom Test":"Egyedi teszt",
"Set": "Széria" "Set": "Széria",
"Add this exercise to execute it paralell":"Adj hozzá egy gyakorlatot a párhuzamos végrehajtáshoz"
} }

View File

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
platform :ios, '10.0' platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'

View File

@ -6,102 +6,92 @@ PODS:
- AppAuth/ExternalUserAgent (1.4.0) - AppAuth/ExternalUserAgent (1.4.0)
- apple_sign_in (0.0.1): - apple_sign_in (0.0.1):
- Flutter - Flutter
- audioplayer (0.0.1):
- Flutter
- devicelocale (0.0.1): - devicelocale (0.0.1):
- Flutter - Flutter
- FBSDKCoreKit (9.0.0): - FBSDKCoreKit (9.1.0):
- FBSDKCoreKit/Basics (= 9.0.0) - FBSDKCoreKit/Basics (= 9.1.0)
- FBSDKCoreKit/Core (= 9.0.0) - FBSDKCoreKit/Core (= 9.1.0)
- FBSDKCoreKit/Basics (9.0.0) - FBSDKCoreKit/Basics (9.1.0)
- FBSDKCoreKit/Core (9.0.0): - FBSDKCoreKit/Core (9.1.0):
- FBSDKCoreKit/Basics - FBSDKCoreKit/Basics
- FBSDKLoginKit (9.0.0): - FBSDKLoginKit (9.1.0):
- FBSDKLoginKit/Login (= 9.0.0) - FBSDKLoginKit/Login (= 9.1.0)
- FBSDKLoginKit/Login (9.0.0): - FBSDKLoginKit/Login (9.1.0):
- FBSDKCoreKit (~> 9.0.0) - FBSDKCoreKit (~> 9.1.0)
- Firebase/Analytics (6.33.0): - Firebase/Analytics (7.3.0):
- Firebase/Core - Firebase/Core
- Firebase/Auth (6.33.0): - Firebase/Auth (7.3.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseAuth (~> 6.9.2) - FirebaseAuth (~> 7.3.0)
- Firebase/Core (6.33.0): - Firebase/Core (7.3.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseAnalytics (= 6.8.3) - FirebaseAnalytics (= 7.3.0)
- Firebase/CoreOnly (6.33.0): - Firebase/CoreOnly (7.3.0):
- FirebaseCore (= 6.10.3) - FirebaseCore (= 7.3.0)
- Firebase/Messaging (6.33.0): - Firebase/Messaging (7.3.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseMessaging (~> 4.7.0) - FirebaseMessaging (~> 7.3.0)
- firebase_analytics (6.3.0): - firebase_analytics (8.0.0-dev.0):
- Firebase/Analytics (~> 6.33.0) - Firebase/Analytics (= 7.3.0)
- Firebase/CoreOnly (~> 6.33.0)
- firebase_core - firebase_core
- Flutter - Flutter
- firebase_auth (0.18.4-1): - firebase_auth (1.0.1):
- Firebase/Auth (~> 6.33.0) - Firebase/Auth (= 7.3.0)
- Firebase/CoreOnly (~> 6.33.0)
- firebase_core - firebase_core
- Flutter - Flutter
- firebase_core (0.5.3): - firebase_core (1.0.2):
- Firebase/CoreOnly (~> 6.33.0) - Firebase/CoreOnly (= 7.3.0)
- Flutter - Flutter
- firebase_messaging (7.0.3): - firebase_messaging (9.1.0):
- Firebase/CoreOnly (~> 6.33.0) - Firebase/Messaging (= 7.3.0)
- Firebase/Messaging (~> 6.33.0)
- firebase_core - firebase_core
- Flutter - Flutter
- FirebaseAnalytics (6.8.3): - FirebaseAnalytics (7.3.0):
- FirebaseCore (~> 6.10) - FirebaseCore (~> 7.0)
- FirebaseInstallations (~> 1.6) - FirebaseInstallations (~> 7.0)
- GoogleAppMeasurement (= 6.8.3) - GoogleAppMeasurement (= 7.3.0)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7) - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/MethodSwizzler (~> 6.7) - GoogleUtilities/MethodSwizzler (~> 7.0)
- GoogleUtilities/Network (~> 6.7) - GoogleUtilities/Network (~> 7.0)
- "GoogleUtilities/NSData+zlib (~> 6.7)" - "GoogleUtilities/NSData+zlib (~> 7.0)"
- nanopb (~> 1.30906.0) - nanopb (~> 2.30906.0)
- FirebaseAuth (6.9.2): - FirebaseAuth (7.3.0):
- FirebaseCore (~> 6.10) - FirebaseCore (~> 7.0)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7) - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GTMSessionFetcher/Core (~> 1.1) - GTMSessionFetcher/Core (~> 1.4)
- FirebaseCore (6.10.3): - FirebaseCore (7.3.0):
- FirebaseCoreDiagnostics (~> 1.6) - FirebaseCoreDiagnostics (~> 7.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Logger (~> 6.7) - GoogleUtilities/Logger (~> 7.0)
- FirebaseCoreDiagnostics (1.7.0): - FirebaseCoreDiagnostics (7.3.0):
- GoogleDataTransport (~> 7.4) - GoogleDataTransport (~> 8.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Logger (~> 6.7) - GoogleUtilities/Logger (~> 7.0)
- nanopb (~> 1.30906.0) - nanopb (~> 2.30906.0)
- FirebaseInstallations (1.7.0): - FirebaseInstallations (7.9.0):
- FirebaseCore (~> 6.10) - FirebaseCore (~> 7.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/UserDefaults (~> 6.7) - GoogleUtilities/UserDefaults (~> 7.0)
- PromisesObjC (~> 1.2) - PromisesObjC (~> 1.2)
- FirebaseInstanceID (4.8.0): - FirebaseInstanceID (7.9.0):
- FirebaseCore (~> 6.10) - FirebaseCore (~> 7.0)
- FirebaseInstallations (~> 1.6) - FirebaseInstallations (~> 7.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/UserDefaults (~> 6.7) - GoogleUtilities/UserDefaults (~> 7.0)
- FirebaseMessaging (4.7.1): - FirebaseMessaging (7.3.0):
- FirebaseCore (~> 6.10) - FirebaseCore (~> 7.0)
- FirebaseInstanceID (~> 4.7) - FirebaseInstanceID (~> 7.0)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7) - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/Environment (~> 6.7) - GoogleUtilities/Environment (~> 7.0)
- GoogleUtilities/Reachability (~> 6.7) - GoogleUtilities/Reachability (~> 7.0)
- GoogleUtilities/UserDefaults (~> 6.7) - GoogleUtilities/UserDefaults (~> 7.0)
- Protobuf (>= 3.9.2, ~> 3.9)
- flurry (0.0.4):
- Flurry-iOS-SDK/FlurrySDK
- Flutter
- Flurry-iOS-SDK/FlurrySDK (11.2.0)
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_facebook_auth (1.0.0): - flutter_facebook_auth (2.0.0):
- FBSDKCoreKit (~> 9.0.0) - FBSDKCoreKit (~> 9.1.0)
- FBSDKLoginKit (~> 9.0.0) - FBSDKLoginKit (~> 9.1.0)
- Flutter - Flutter
- flutter_keyboard_visibility (0.0.1): - flutter_local_notifications (0.0.1):
- Flutter - Flutter
- flutter_secure_storage (3.3.1): - flutter_secure_storage (3.3.1):
- Flutter - Flutter
@ -111,36 +101,36 @@ PODS:
- google_sign_in (0.0.1): - google_sign_in (0.0.1):
- Flutter - Flutter
- GoogleSignIn (~> 5.0) - GoogleSignIn (~> 5.0)
- GoogleAppMeasurement (6.8.3): - GoogleAppMeasurement (7.3.0):
- GoogleUtilities/AppDelegateSwizzler (~> 6.7) - GoogleUtilities/AppDelegateSwizzler (~> 7.0)
- GoogleUtilities/MethodSwizzler (~> 6.7) - GoogleUtilities/MethodSwizzler (~> 7.0)
- GoogleUtilities/Network (~> 6.7) - GoogleUtilities/Network (~> 7.0)
- "GoogleUtilities/NSData+zlib (~> 6.7)" - "GoogleUtilities/NSData+zlib (~> 7.0)"
- nanopb (~> 1.30906.0) - nanopb (~> 2.30906.0)
- GoogleDataTransport (7.5.1): - GoogleDataTransport (8.1.0):
- nanopb (~> 1.30906.0) - nanopb (~> 2.30906.0)
- 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 (6.7.2): - GoogleUtilities/AppDelegateSwizzler (7.3.1):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GoogleUtilities/Network - GoogleUtilities/Network
- GoogleUtilities/Environment (6.7.2): - GoogleUtilities/Environment (7.3.1):
- PromisesObjC (~> 1.2) - PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2): - GoogleUtilities/Logger (7.3.1):
- GoogleUtilities/Environment - GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (6.7.2): - GoogleUtilities/MethodSwizzler (7.3.1):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GoogleUtilities/Network (6.7.2): - GoogleUtilities/Network (7.3.1):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib" - "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability - GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (6.7.2)" - "GoogleUtilities/NSData+zlib (7.3.1)"
- GoogleUtilities/Reachability (6.7.2): - GoogleUtilities/Reachability (7.3.1):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/UserDefaults (7.3.1):
- GoogleUtilities/Logger - GoogleUtilities/Logger
- GTMAppAuth (1.1.0): - GTMAppAuth (1.1.0):
- AppAuth/Core (~> 1.4) - AppAuth/Core (~> 1.4)
@ -150,25 +140,26 @@ PODS:
- GTMSessionFetcher/Core (1.5.0) - GTMSessionFetcher/Core (1.5.0)
- GTMSessionFetcher/Full (1.5.0): - GTMSessionFetcher/Full (1.5.0):
- GTMSessionFetcher/Core (= 1.5.0) - GTMSessionFetcher/Core (= 1.5.0)
- nanopb (1.30906.0): - modal_progress_hud_nsn (0.0.1):
- nanopb/decode (= 1.30906.0) - Flutter
- nanopb/encode (= 1.30906.0) - nanopb (2.30906.0):
- nanopb/decode (1.30906.0) - nanopb/decode (= 2.30906.0)
- nanopb/encode (1.30906.0) - nanopb/encode (= 2.30906.0)
- nanopb/decode (2.30906.0)
- nanopb/encode (2.30906.0)
- package_info (0.0.1): - package_info (0.0.1):
- Flutter - Flutter
- path_provider (0.0.1): - path_provider (0.0.1):
- Flutter - Flutter
- PromisesObjC (1.2.12) - PromisesObjC (1.2.12)
- Protobuf (3.14.0) - Purchases (3.10.6):
- Purchases (3.9.2): - PurchasesCoreSwift (= 3.10.6)
- PurchasesCoreSwift (= 3.9.2) - purchases_flutter (3.1.0):
- purchases_flutter (2.0.3):
- Flutter - Flutter
- PurchasesHybridCommon (= 1.5.0) - PurchasesHybridCommon (= 1.6.1)
- PurchasesCoreSwift (3.9.2) - PurchasesCoreSwift (3.10.6)
- PurchasesHybridCommon (1.5.0): - PurchasesHybridCommon (1.6.1):
- Purchases (= 3.9.2) - Purchases (= 3.10.6)
- shared_preferences (0.0.1): - shared_preferences (0.0.1):
- Flutter - Flutter
- smartlook (0.0.5): - smartlook (0.0.5):
@ -185,18 +176,17 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- apple_sign_in (from `.symlinks/plugins/apple_sign_in/ios`) - apple_sign_in (from `.symlinks/plugins/apple_sign_in/ios`)
- audioplayer (from `.symlinks/plugins/audioplayer/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_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- flurry (from `.symlinks/plugins/flurry/ios`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`) - flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- google_sign_in (from `.symlinks/plugins/google_sign_in/ios`) - google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
- modal_progress_hud_nsn (from `.symlinks/plugins/modal_progress_hud_nsn/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`)
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`) - purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
@ -220,7 +210,6 @@ SPEC REPOS:
- FirebaseInstallations - FirebaseInstallations
- FirebaseInstanceID - FirebaseInstanceID
- FirebaseMessaging - FirebaseMessaging
- Flurry-iOS-SDK
- FMDB - FMDB
- GoogleAppMeasurement - GoogleAppMeasurement
- GoogleDataTransport - GoogleDataTransport
@ -230,7 +219,6 @@ SPEC REPOS:
- GTMSessionFetcher - GTMSessionFetcher
- nanopb - nanopb
- PromisesObjC - PromisesObjC
- Protobuf
- Purchases - Purchases
- PurchasesCoreSwift - PurchasesCoreSwift
- PurchasesHybridCommon - PurchasesHybridCommon
@ -238,8 +226,6 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
apple_sign_in: apple_sign_in:
:path: ".symlinks/plugins/apple_sign_in/ios" :path: ".symlinks/plugins/apple_sign_in/ios"
audioplayer:
:path: ".symlinks/plugins/audioplayer/ios"
devicelocale: devicelocale:
:path: ".symlinks/plugins/devicelocale/ios" :path: ".symlinks/plugins/devicelocale/ios"
firebase_analytics: firebase_analytics:
@ -250,18 +236,18 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/firebase_core/ios" :path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging: firebase_messaging:
:path: ".symlinks/plugins/firebase_messaging/ios" :path: ".symlinks/plugins/firebase_messaging/ios"
flurry:
:path: ".symlinks/plugins/flurry/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_facebook_auth: flutter_facebook_auth:
:path: ".symlinks/plugins/flutter_facebook_auth/ios" :path: ".symlinks/plugins/flutter_facebook_auth/ios"
flutter_keyboard_visibility: flutter_local_notifications:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios" :path: ".symlinks/plugins/flutter_local_notifications/ios"
flutter_secure_storage: flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios" :path: ".symlinks/plugins/flutter_secure_storage/ios"
google_sign_in: google_sign_in:
:path: ".symlinks/plugins/google_sign_in/ios" :path: ".symlinks/plugins/google_sign_in/ios"
modal_progress_hud_nsn:
:path: ".symlinks/plugins/modal_progress_hud_nsn/ios"
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider: path_provider:
@ -284,52 +270,49 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7 AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4 apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
audioplayer: 0584f31a697e4b0bbad405ae7903d7a93585e784 devicelocale: b22617f40038496deffba44747101255cee005b0
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 FBSDKCoreKit: a00fe2efd780c195a5e09201bf51c56106245b40
FBSDKCoreKit: ac6cc500b8e104bb9a4dd20b1527b5d199123c2e FBSDKLoginKit: d98498c598ec09de657385a9349a1f21119b7f86
FBSDKLoginKit: e9b6542fdee322333502ab497f628b011dce7d78 Firebase: 26223c695fe322633274198cb19dca8cb7e54416
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 firebase_analytics: c9b8ddc8e864e45cd70761c5d972bd11c83574ab
firebase_analytics: 36a619088c46224900829f14f4daa71585693a6f firebase_auth: 9f6491ea8e44570323361ae713a2ae3175b3f21a
firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a firebase_core: e6cbb0d1f7091edfcae31559e58224bfc1e455dc
firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 firebase_messaging: 9c746d6c52bb05764e73bbe745d0d698e5afb695
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseAnalytics: 2580c2d62535ae7b644143d48941fcc239ea897a
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193 FirebaseAuth: c224a0cf1afa0949bd5c7bfcf154b4f5ce8ddef2
FirebaseAuth: c92d49ada7948d1a23466e3db17bc4c2039dddc3 FirebaseCore: 4d3c72622ce0e2106aaa07bb4b2935ba2c370972
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd FirebaseCoreDiagnostics: d50e11039e5984d92c8a512be2395f13df747350
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 FirebaseInstallations: 5e777e6640fa060405cc7632447b6c5ca5af4742
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 FirebaseInstanceID: 53140c03b9f6136f890d7901399f85a4c90ab2d0
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 FirebaseMessaging: 68d1bcb14880189558a8ae57167abe0b7e417232
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad flutter_facebook_auth: 4b170c07b7fce791497093fcc3f134fb215f3f07
Flurry-iOS-SDK: 6636d30c30f12010e7c7c71d84b443416a168efc flutter_local_notifications: 0c0b1ae97e741e1521e4c1629a459d04b9aec743
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_facebook_auth: d952ca599c6a76439c54472b0b225004e1b880c4
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436 GoogleAppMeasurement: 8d3c0aeede16ab7764144b5a4ca8e1d4323841b7
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleDataTransport: 116c84c4bdeb76be2a7a46de51244368f9794eab
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213 GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 GoogleUtilities: e1d9ed4e544fc32a93e00e721400cbc3f377200d
GTMAppAuth: 197a8dabfea5d665224aa00d17f164fc2248dab9 GTMAppAuth: 197a8dabfea5d665224aa00d17f164fc2248dab9
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52 GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
nanopb: 1bf24dd71191072e120b83dd02d08f3da0d65e53
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
Protobuf: 0cde852566359049847168e51bd1c690e0f70056 Purchases: 520fdb59140fed96932a30d02a3ec04858cb541c
Purchases: d8a798c9c7552fe66b550bf314a143e94ffa70c8 purchases_flutter: 05472ba84c83f05a138a3a657f1013f5f7143539
purchases_flutter: c1ef4056da1346795a708bdefce81e0a56e8134f PurchasesCoreSwift: 31c2a3d7394432abbe64d46f0933835de0b33033
PurchasesCoreSwift: ea4eabae180416e580ac60366f41aa1fefec0693 PurchasesHybridCommon: 013c8072b73e752a206779747e88c068fbf999ec
PurchasesHybridCommon: d9bfb34309db4c9ba82a6f7f3a6275c13befdca7
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
smartlook: bda0b1561935a02ef0fea5448258d5ac75027859 smartlook: bda0b1561935a02ef0fea5448258d5ac75027859
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107 wakelock: b0843b2479edbf6504d8d262c2959446f35373aa
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b
PODFILE CHECKSUM: ffdd26129895d158b3c89ac44e19a7e054386b90 PODFILE CHECKSUM: f10c0438b63bc24e6bbc207956dc27d16c4408f2
COCOAPODS: 1.10.0 COCOAPODS: 1.10.1

View File

@ -2,10 +2,9 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class TestProgress extends AnimatedWidget { class TestProgress extends AnimatedWidget {
TestProgress({ TestProgress({
Key key, Key? key,
@required Animation<double> animation, required Animation<double> animation,
}) : super(key: key, listenable: animation); }) : super(key: key, listenable: animation);
@override @override
@ -15,14 +14,14 @@ class TestProgress extends AnimatedWidget {
return Transform.scale( return Transform.scale(
alignment: Alignment.center, alignment: Alignment.center,
scale: animation.value, scale: animation.value,
origin: Offset(-5,0), origin: Offset(-5, 0),
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
padding: EdgeInsets.only(left: 0), padding: EdgeInsets.only(left: 0),
child: Icon(Icons.star, color: Colors.yellow,) child: Icon(
), Icons.star,
color: Colors.yellow,
)),
); );
} }
}
}

View File

@ -16,9 +16,9 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
bool loggedIn = false; bool loggedIn = false;
int traineeId = 0; int traineeId = 0;
AccountBloc({this.customerRepository}) : super(AccountInitial()) { AccountBloc({required this.customerRepository}) : super(AccountInitial()) {
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
customerRepository.customer = Cache().userLoggedIn; customerRepository.customer = Cache().userLoggedIn!;
loggedIn = true; loggedIn = true;
} }
} }
@ -74,7 +74,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
yield AccountLoggedIn(); yield AccountLoggedIn();
} else if (event is AccountLogout) { } else if (event is AccountLogout) {
await Cache().logout(); await Cache().logout();
customerRepository.customer = null; //customerRepository.customer = null;
customerRepository.emptyTrainees(); customerRepository.emptyTrainees();
loggedIn = false; loggedIn = false;
yield AccountLoggedOut(); yield AccountLoggedOut();
@ -85,7 +85,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
} else if (event is AccountSelectTrainee) { } else if (event is AccountSelectTrainee) {
yield AccountLoading(); yield AccountLoading();
customerRepository.setTrainee(event.traineeId); customerRepository.setTrainee(event.traineeId);
Cache().setTrainee(customerRepository.getTraineeById(event.traineeId)); Cache().setTrainee(customerRepository.getTraineeById(event.traineeId)!);
ExerciseRepository exerciseRepository = ExerciseRepository(); ExerciseRepository exerciseRepository = ExerciseRepository();
await exerciseRepository.getExercisesByCustomer(event.traineeId); await exerciseRepository.getExercisesByCustomer(event.traineeId);
this.traineeId = event.traineeId; this.traineeId = event.traineeId;

View File

@ -9,37 +9,21 @@ abstract class AccountEvent extends Equatable {
} }
class AccountChangeCustomer extends AccountEvent { class AccountChangeCustomer extends AccountEvent {
final Customer customer; const AccountChangeCustomer();
const AccountChangeCustomer({this.customer});
@override
List<Object> get props => [customer];
} }
class AccountLogout extends AccountEvent { class AccountLogout extends AccountEvent {
final Customer customer; const AccountLogout();
const AccountLogout({this.customer});
@override
List<Object> get props => [customer];
} }
class AccountLogin extends AccountEvent { class AccountLogin extends AccountEvent {
final Customer customer; const AccountLogin();
const AccountLogin({this.customer});
@override
List<Object> get props => [customer];
} }
class AccountLogInFinished extends AccountEvent { class AccountLogInFinished extends AccountEvent {
final Customer customer; final Customer customer;
const AccountLogInFinished({this.customer}); const AccountLogInFinished({required this.customer});
@override @override
List<Object> get props => [customer]; List<Object> get props => [customer];
@ -51,8 +35,8 @@ class AccountGetTrainees extends AccountEvent {
class AccountSelectTrainee extends AccountEvent { class AccountSelectTrainee extends AccountEvent {
final int traineeId; final int traineeId;
const AccountSelectTrainee({this.traineeId}); const AccountSelectTrainee({required this.traineeId});
@override @override
List<Object> get props => [traineeId]; List<Object> get props => [traineeId];
} }

View File

@ -29,7 +29,7 @@ class AccountLoggedIn extends AccountState {
class AccountError extends AccountState { class AccountError extends AccountState {
final String message; final String message;
const AccountError({this.message}); const AccountError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -13,14 +13,14 @@ class BodyDevelopmentBloc extends Bloc<BodyDevelopmentEvent, BodyDevelopmentStat
final WorkoutTreeRepository workoutTreeRepository; final WorkoutTreeRepository workoutTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
List<int> radarTicks = List(); List<int> radarTicks = [];
List<String> radarFeatures = List(); List<String> radarFeatures = [];
List<List<int>> radarData = List(); List<List<int>> radarData = [];
@override @override
BodyDevelopmentBloc({this.workoutTreeRepository}): super(BodyDevelopmentInitial()); BodyDevelopmentBloc({required this.workoutTreeRepository}) : super(BodyDevelopmentInitial());
Future<void> getData() async{ Future<void> getData() async {
radarTicks = [20, 40, 60, 80, 100]; radarTicks = [20, 40, 60, 80, 100];
radarFeatures = ["Mell", "Bicepsz", "Tricepsz", "Hát", "Váll"]; radarFeatures = ["Mell", "Bicepsz", "Tricepsz", "Hát", "Váll"];
radarData = [ radarData = [

View File

@ -22,9 +22,8 @@ class BodyDevelopmentReady extends BodyDevelopmentState {
class BodyDevelopmentError extends BodyDevelopmentState { class BodyDevelopmentError extends BodyDevelopmentState {
final String message; final String message;
const BodyDevelopmentError({this.message}); const BodyDevelopmentError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -15,11 +15,11 @@ part 'bodytype_state.dart';
class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> { class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> {
static const int numberQuestions = 22; static const int numberQuestions = 22;
final CustomerRepository repository; final CustomerRepository repository;
final List<String> questions = List(); final List<String> questions = [];
final List<int> answers = List(); final List<int> answers = [];
final weights = List.generate(numberQuestions, (i) => List(3), growable: false); final weights = List.generate(numberQuestions, (i) => []..length = 3, growable: false);
BodytypeBloc({this.repository}) : super(BodytypeInitial()) { BodytypeBloc({required this.repository}) : super(BodytypeInitial()) {
questions.add("1. Basicly I am skinny and bonny"); questions.add("1. Basicly I am skinny and bonny");
questions.add("2. question"); questions.add("2. question");
questions.add("3. question"); questions.add("3. question");
@ -71,15 +71,14 @@ class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> {
weights[21] = [7, 3, 0]; weights[21] = [7, 3, 0];
final double value = repository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()); final double value = repository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr());
if (value != null) {
_ecto = value.toInt(); _ecto = value.toInt();
_mezo = repository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt(); _mezo = repository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt();
_endo = repository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt(); _endo = repository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt();
print("** Init ecto: " + _ecto.toString() + " mezo: " + _mezo.toString() + " endo: " + _endo.toString()); print("** Init ecto: " + _ecto.toString() + " mezo: " + _mezo.toString() + " endo: " + _endo.toString());
if (_ecto > 0 && _mezo > 0 && _endo > 0) { if (_ecto > 0 && _mezo > 0 && _endo > 0) {
calculateBodyType(init: true); calculateBodyType(init: true);
origBodyTypeValue = bodyTypeValue; origBodyTypeValue = bodyTypeValue;
}
} }
} }
@ -135,13 +134,13 @@ class BodytypeBloc extends Bloc<BodytypeEvent, BodytypeState> {
Future<void> savePropertyDB(String name, double value) async { Future<void> savePropertyDB(String name, double value) async {
final now = DateTime.now(); final now = DateTime.now();
Property property = repository.propertyRepository.getPropertyByName(name); Property? property = repository.propertyRepository.getPropertyByName(name);
if (property != null) { if (property != null) {
int propertyId = property.propertyId; int propertyId = property.propertyId;
CustomerProperty customerProperty = repository.getCustomerProperty(name); CustomerProperty? customerProperty = repository.getCustomerProperty(name);
if (customerProperty == null || customerProperty.customerPropertyId == null) { if (customerProperty == null || customerProperty.customerPropertyId == null) {
customerProperty = customerProperty =
CustomerProperty(customerId: Cache().userLoggedIn.customerId, propertyId: propertyId, propertyValue: value, dateAdd: now); CustomerProperty(customerId: Cache().userLoggedIn!.customerId!, propertyId: propertyId, propertyValue: value, dateAdd: now);
CustomerProperty newProperty = await CustomerApi().addProperty(customerProperty); CustomerProperty newProperty = await CustomerApi().addProperty(customerProperty);
repository.setCustomerProperty(name, value, id: newProperty.customerPropertyId); repository.setCustomerProperty(name, value, id: newProperty.customerPropertyId);

View File

@ -17,7 +17,7 @@ class BodytypeSave extends BodytypeEvent {
class BodytypeClick extends BodytypeEvent { class BodytypeClick extends BodytypeEvent {
final int value; final int value;
const BodytypeClick({this.value}); const BodytypeClick({required this.value});
@override @override
List<Object> get props => [value]; List<Object> get props => [value];

View File

@ -25,7 +25,7 @@ class BodytypeFinished extends BodytypeState {
class BodytypeError extends BodytypeState { class BodytypeError extends BodytypeState {
final String error; final String error;
const BodytypeError({this.error}); const BodytypeError({required this.error});
@override @override
List<Object> get props => [error]; List<Object> get props => [error];

View File

@ -1,127 +0,0 @@
import 'dart:math';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class CustomExerciseFormBloc extends FormBloc<String, String> {
final ExerciseRepository exerciseRepository;
bool loading = false;
final quantityField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
final unitQuantityField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
//1RM calculated Fields
final rmWendlerField = TextFieldBloc(
initialValue: "0",
);
final rmMayhewField = TextFieldBloc(initialValue: "0");
final rmOconnerField = TextFieldBloc(initialValue: "0");
final rmWathenField = TextFieldBloc(initialValue: "0");
final rmAverageField = TextFieldBloc(initialValue: "0");
final rm90Field = TextFieldBloc(initialValue: "0");
final rm80Field = TextFieldBloc(initialValue: "0");
final rm75Field = TextFieldBloc(initialValue: "0");
final rm75WendlerField = TextFieldBloc(initialValue: "0");
final rm75OconnorField = TextFieldBloc(initialValue: "0");
final rm70Field = TextFieldBloc(initialValue: "0");
final rm60Field = TextFieldBloc(initialValue: "0");
final rm50Field = TextFieldBloc(initialValue: "0");
CustomExerciseFormBloc({this.exerciseRepository}) {
addFieldBlocs(fieldBlocs: [
quantityField,
unitQuantityField,
rmWendlerField,
rmMayhewField,
rmOconnerField,
rmWathenField,
rmAverageField,
rm90Field,
rm80Field,
rm70Field,
rm75Field,
rm75WendlerField,
rm75OconnorField,
rm60Field,
rm50Field
]);
quantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setQuantity(current.valueToDouble);
calculate1RM();
});
unitQuantityField.onValueChanges(onData: (previous, current) async* {
exerciseRepository.setUnitQuantity(current.valueToDouble);
calculate1RM();
});
}
@override
void onSubmitting() async {
try {
loading = true;
emitLoading(progress: 30);
// Emit either Loaded or Error
emitSuccess(canSubmitAgain: false);
loading = false;
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
void calculate1RM() {
double weight = exerciseRepository.exercise.unitQuantity;
double repeat = exerciseRepository.exercise.quantity;
if (weight == 0 || repeat == 0) {
return;
}
exerciseRepository.rmWendler = weight * repeat * 0.0333 + weight;
rmWendlerField.updateValue(exerciseRepository.rmWendler.toStringAsFixed(1));
exerciseRepository.rmOconner = weight * (1 + repeat / 40);
rmOconnerField.updateValue(exerciseRepository.rmOconner.toStringAsFixed(1));
exerciseRepository.rmMayhew = 100 * weight / (52.2 + 41.9 * pow(e, -0.055 * repeat));
rmMayhewField.updateValue(exerciseRepository.rmMayhew.toStringAsFixed(1));
exerciseRepository.rmWathen = 100 * weight / (48.8 + 53.8 * pow(e, -0.075 * repeat));
rmWathenField.updateValue(exerciseRepository.rmWathen.toStringAsFixed(1));
double average = (exerciseRepository.rmWendler + exerciseRepository.rmOconner) / 2;
rmAverageField.updateValue(average.toStringAsFixed(1));
rm90Field.updateValue((average * 0.9).toStringAsFixed(1));
rm80Field.updateValue((average * 0.8).toStringAsFixed(1));
rm75Field.updateValue((average * 0.75).toStringAsFixed(1));
rm75OconnorField.updateValue((exerciseRepository.rmOconner * 0.75).toStringAsFixed(1));
rm75WendlerField.updateValue((exerciseRepository.rmWendler * 0.75).toStringAsFixed(1));
rm70Field.updateValue((average * 0.7).toStringAsFixed(1));
rm60Field.updateValue((average * 0.6).toStringAsFixed(1));
rm50Field.updateValue((average * 0.5).toStringAsFixed(1));
}
//@override
Future<void> close() {
quantityField.close();
unitQuantityField.close();
rmWendlerField.close();
rmMayhewField.close();
rmOconnerField.close();
rmWathenField.close();
rmAverageField.close();
rm90Field.close();
rm80Field.close();
rm75WendlerField.close();
rm75OconnorField.close();
rm75Field.close();
rm70Field.close();
rm60Field.close();
rm50Field.close();
return super.close();
}
}

View File

@ -14,14 +14,13 @@ part 'customer_change_state.dart';
class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState> with Trans { class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState> with Trans {
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
final BuildContext context;
bool visiblePassword = false; bool visiblePassword = false;
int year = 1990; int? year = 1990;
double weight = 60; double weight = 60;
double height = 170; double height = 170;
CustomerChangeBloc({this.customerRepository, this.context}) : super(CustomerChangeInitial()) { CustomerChangeBloc({required this.customerRepository}) : super(CustomerChangeInitial()) {
year = this.customerRepository.customer.birthYear; year = this.customerRepository.customer.birthYear;
if (year == 0) { if (year == null || year == 0) {
year = 1990; year = 1990;
} }
weight = this.customerRepository.getWeight() == 0 ? 60 : this.customerRepository.getWeight(); weight = this.customerRepository.getWeight() == 0 ? 60 : this.customerRepository.getWeight();
@ -102,23 +101,23 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
(nameValidation(customerRepository.customer.name) == null); */ (nameValidation(customerRepository.customer.name) == null); */
} }
String emailValidation(String email) { String? emailValidation(String email) {
String message = Common.emailValidation(email); String? message = Common.emailValidation(email);
if (message != null) { if (message != null) {
message = t(message); message = t(message);
} }
return message; return message;
} }
String passwordValidation(String value) { String? passwordValidation(String value) {
String message = Common.passwordValidation(value); String? message = Common.passwordValidation(value);
if (message != null) { if (message != null) {
message = t(message); message = t(message);
} }
return message; return message;
} }
String nameValidation(String value) { String? nameValidation(String? value) {
if (value == null || value.length == 0) { if (value == null || value.length == 0) {
return t("Name too short"); return t("Name too short");
} }

View File

@ -9,7 +9,7 @@ abstract class CustomerChangeEvent extends Equatable {
class CustomerGoalChange extends CustomerChangeEvent { class CustomerGoalChange extends CustomerChangeEvent {
final String goal; final String goal;
const CustomerGoalChange({this.goal}); const CustomerGoalChange({required this.goal});
@override @override
List<Object> get props => [goal]; List<Object> get props => [goal];
@ -17,7 +17,7 @@ class CustomerGoalChange extends CustomerChangeEvent {
class CustomerFitnessChange extends CustomerChangeEvent { class CustomerFitnessChange extends CustomerChangeEvent {
final String fitness; final String fitness;
const CustomerFitnessChange({this.fitness}); const CustomerFitnessChange({required this.fitness});
@override @override
List<Object> get props => [fitness]; List<Object> get props => [fitness];
@ -25,7 +25,7 @@ class CustomerFitnessChange extends CustomerChangeEvent {
class CustomerBodyTypeChange extends CustomerChangeEvent { class CustomerBodyTypeChange extends CustomerChangeEvent {
final String bodyType; final String bodyType;
const CustomerBodyTypeChange({this.bodyType}); const CustomerBodyTypeChange({required this.bodyType});
@override @override
List<Object> get props => [bodyType]; List<Object> get props => [bodyType];
@ -33,7 +33,7 @@ class CustomerBodyTypeChange extends CustomerChangeEvent {
class CustomerBirthYearChange extends CustomerChangeEvent { class CustomerBirthYearChange extends CustomerChangeEvent {
final int year; final int year;
const CustomerBirthYearChange({this.year}); const CustomerBirthYearChange({required this.year});
@override @override
List<Object> get props => [year]; List<Object> get props => [year];
@ -41,7 +41,7 @@ class CustomerBirthYearChange extends CustomerChangeEvent {
class CustomerWeightChange extends CustomerChangeEvent { class CustomerWeightChange extends CustomerChangeEvent {
final int weight; final int weight;
const CustomerWeightChange({this.weight}); const CustomerWeightChange({required this.weight});
@override @override
List<Object> get props => [weight]; List<Object> get props => [weight];
@ -49,7 +49,7 @@ class CustomerWeightChange extends CustomerChangeEvent {
class CustomerHeightChange extends CustomerChangeEvent { class CustomerHeightChange extends CustomerChangeEvent {
final int height; final int height;
const CustomerHeightChange({this.height}); const CustomerHeightChange({required this.height});
@override @override
List<Object> get props => [height]; List<Object> get props => [height];
@ -57,7 +57,7 @@ class CustomerHeightChange extends CustomerChangeEvent {
class CustomerGenderChange extends CustomerChangeEvent { class CustomerGenderChange extends CustomerChangeEvent {
final int gender; final int gender;
const CustomerGenderChange({this.gender}); const CustomerGenderChange({required this.gender});
@override @override
List<Object> get props => [gender]; List<Object> get props => [gender];
@ -65,7 +65,7 @@ class CustomerGenderChange extends CustomerChangeEvent {
class CustomerEmailChange extends CustomerChangeEvent { class CustomerEmailChange extends CustomerChangeEvent {
final String email; final String email;
const CustomerEmailChange({this.email}); const CustomerEmailChange({required this.email});
@override @override
List<Object> get props => [email]; List<Object> get props => [email];
@ -73,7 +73,7 @@ class CustomerEmailChange extends CustomerChangeEvent {
class CustomerFirstNameChange extends CustomerChangeEvent { class CustomerFirstNameChange extends CustomerChangeEvent {
final String firstName; final String firstName;
const CustomerFirstNameChange({this.firstName}); const CustomerFirstNameChange({required this.firstName});
@override @override
List<Object> get props => [firstName]; List<Object> get props => [firstName];
@ -81,7 +81,7 @@ class CustomerFirstNameChange extends CustomerChangeEvent {
class CustomerNameChange extends CustomerChangeEvent { class CustomerNameChange extends CustomerChangeEvent {
final String name; final String name;
const CustomerNameChange({this.name}); const CustomerNameChange({required this.name});
@override @override
List<Object> get props => [name]; List<Object> get props => [name];
@ -89,7 +89,7 @@ class CustomerNameChange extends CustomerChangeEvent {
class CustomerPasswordChange extends CustomerChangeEvent { class CustomerPasswordChange extends CustomerChangeEvent {
final String password; final String password;
const CustomerPasswordChange({this.password}); const CustomerPasswordChange({required this.password});
@override @override
List<Object> get props => [password]; List<Object> get props => [password];

View File

@ -29,7 +29,7 @@ class CustomerSaveSuccess extends CustomerChangeState {
class CustomerSaveError extends CustomerChangeState { class CustomerSaveError extends CustomerChangeState {
final String message; final String message;
const CustomerSaveError({this.message}); const CustomerSaveError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -13,11 +13,11 @@ part 'customer_exercise_device_state.dart';
class CustomerExerciseDeviceBloc extends Bloc<CustomerExerciseDeviceEvent, CustomerExerciseDeviceState> { class CustomerExerciseDeviceBloc extends Bloc<CustomerExerciseDeviceEvent, CustomerExerciseDeviceState> {
final CustomerExerciseDeviceRepository repository; final CustomerExerciseDeviceRepository repository;
final List<ExerciseDevice> devices; final List<ExerciseDevice>? devices;
CustomerExerciseDeviceBloc({this.repository, this.devices}) : super(CustomerExerciseDeviceInitial()) { CustomerExerciseDeviceBloc({required this.repository, required this.devices}) : super(CustomerExerciseDeviceInitial()) {
if (repository.getDevices().isEmpty) { if (repository.getDevices().isEmpty) {
repository.setDevices(Cache().getCustomerDevices()); repository.setDevices(Cache().getCustomerDevices()!);
} }
Track().track(TrackingEvent.exercise_device); Track().track(TrackingEvent.exercise_device);
} }

View File

@ -13,7 +13,7 @@ class CustomerExerciseDeviceLoad extends CustomerExerciseDeviceEvent {
class CustomerExerciseDeviceAdd extends CustomerExerciseDeviceEvent { class CustomerExerciseDeviceAdd extends CustomerExerciseDeviceEvent {
final ExerciseDevice device; final ExerciseDevice device;
const CustomerExerciseDeviceAdd({this.device}); const CustomerExerciseDeviceAdd({required this.device});
@override @override
List<Object> get props => [device]; List<Object> get props => [device];
@ -21,7 +21,7 @@ class CustomerExerciseDeviceAdd extends CustomerExerciseDeviceEvent {
class CustomerExerciseDeviceRemove extends CustomerExerciseDeviceEvent { class CustomerExerciseDeviceRemove extends CustomerExerciseDeviceEvent {
final ExerciseDevice device; final ExerciseDevice device;
const CustomerExerciseDeviceRemove({this.device}); const CustomerExerciseDeviceRemove({required this.device});
@override @override
List<Object> get props => [device]; List<Object> get props => [device];

View File

@ -21,7 +21,7 @@ class CustomerExerciseDeviceReady extends CustomerExerciseDeviceState {
class CustomerExerciseDeviceError extends CustomerExerciseDeviceState { class CustomerExerciseDeviceError extends CustomerExerciseDeviceState {
final String message; final String message;
const CustomerExerciseDeviceError({this.message}); const CustomerExerciseDeviceError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -13,11 +13,10 @@ import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/group_data.dart'; import 'package:aitrainer_app/util/group_data.dart';
import 'package:aitrainer_app/util/track.dart'; import 'package:aitrainer_app/util/track.dart';
import 'package:intl/intl.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';
@ -36,35 +35,35 @@ class DiagramType {
*/ */
class GroupDate extends GroupData with Calculate, Common { class GroupDate extends GroupData with Calculate, Common {
final List<dynamic> inputList; final List<Exercise> inputList;
final List<dynamic> outputList; final List<Exercise> outputList;
String _origDatePart; String? _origDatePart;
int _origExerciseTypeId; late int _origExerciseTypeId;
Exercise _origExercise; late Exercise _origExercise;
double _sumQuantity; late double _sumQuantity;
double _maxQuantity; late double _maxQuantity;
int _countExercises; late int _countExercises;
String diagramType; late String diagramType;
String dateRate; late String dateRate;
GroupDate({this.inputList, this.outputList}); GroupDate({required this.inputList, required this.outputList});
double getQuantityByDate(Exercise exercise) { double getQuantityByDate(Exercise exercise) {
double sum = 0; double sum = 0;
if (this.diagramType == DiagramType.sumMass) { if (this.diagramType == DiagramType.sumMass) {
if (exercise.unitQuantity != null) { if (exercise.unitQuantity != null) {
sum = exercise.quantity * exercise.unitQuantity; sum = exercise.quantity! * exercise.unitQuantity!;
} else { } else {
sum = exercise.quantity; sum = exercise.quantity!;
} }
} else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) { } else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
if (exercise.unitQuantity != null) { if (exercise.unitQuantity != null) {
sum = calculate1RM(exercise.quantity, exercise.unitQuantity); sum = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
} else { } else {
sum = exercise.quantity; sum = exercise.quantity!;
} }
} }
return sum; return sum;
@ -73,26 +72,26 @@ class GroupDate extends GroupData with Calculate, Common {
@override @override
void addTempData(Exercise exercise) { void addTempData(Exercise exercise) {
double newQuantity = getQuantityByDate(exercise); double newQuantity = getQuantityByDate(exercise);
_sumQuantity += newQuantity; _sumQuantity = _sumQuantity + newQuantity;
if (_maxQuantity < newQuantity) { if (_maxQuantity < newQuantity) {
_maxQuantity = newQuantity; _maxQuantity = newQuantity;
} }
_countExercises++; _countExercises = _countExercises + 1;
_origDatePart = getDatePart(exercise.dateAdd, dateRate); _origDatePart = getDatePart(exercise.dateAdd!, dateRate);
_origExerciseTypeId = exercise.exerciseTypeId; _origExerciseTypeId = exercise.exerciseTypeId!;
_origExercise = exercise; _origExercise = exercise;
} }
@override @override
bool checkNewType(Exercise exercise) { bool checkNewType(Exercise exercise) {
String exerciseDatePart = getDatePart(exercise.dateAdd, dateRate); String exerciseDatePart = getDatePart(exercise.dateAdd!, dateRate);
return _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId; return _origDatePart == null || _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
} }
@override @override
void iteration() { void iteration() {
this.resetTemp(); this.resetTemp();
Exercise tempExercise; Exercise? tempExercise;
inputList.forEach((element) { inputList.forEach((element) {
tempExercise = element; tempExercise = element;
if (this.checkNewType(element)) { if (this.checkNewType(element)) {
@ -108,7 +107,7 @@ class GroupDate extends GroupData with Calculate, Common {
} }
}); });
if (tempExercise != null) { if (tempExercise != null) {
this.temp2Output(tempExercise); this.temp2Output(tempExercise!);
} }
} }
@ -142,21 +141,21 @@ class GroupChart extends GroupData with Calculate {
final List<dynamic> inputList; final List<dynamic> inputList;
LinkedHashMap<int, ChartDataExtended> outputList = LinkedHashMap(); LinkedHashMap<int, ChartDataExtended> outputList = LinkedHashMap();
int _origExerciseTypeId; int? _origExerciseTypeId;
double _minData = 999999999999; late double _minData = 999999999999;
double _maxData = 0; late double _maxData = 0;
List<BarChartGroupData> _chartData; late List<BarChartGroupData> _chartData;
double _basePercent; late double _basePercent;
String diagramType = DiagramType.sumMass; String diagramType = DiagramType.sumMass;
GroupChart({this.inputList, this.outputList}); GroupChart({required this.inputList, required this.outputList});
double getBasePercent(Exercise exercise) { double getBasePercent(Exercise exercise) {
if (exercise.unitQuantity != null) { if (exercise.unitQuantity != null) {
this._basePercent = calculate1RM(exercise.quantity, exercise.unitQuantity); this._basePercent = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
} else { } else {
this._basePercent = exercise.quantity; this._basePercent = exercise.quantity!;
} }
return this._basePercent; return this._basePercent;
} }
@ -166,13 +165,13 @@ class GroupChart extends GroupData with Calculate {
if (diagramType == DiagramType.percent) { if (diagramType == DiagramType.percent) {
if (exercise.unitQuantity != null) { if (exercise.unitQuantity != null) {
double oneRepMax = calculate1RM(exercise.quantity, exercise.unitQuantity); double oneRepMax = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
value = (oneRepMax / this._basePercent) * 100; value = (oneRepMax / this._basePercent) * 100;
} else { } else {
value = (exercise.quantity / this._basePercent) * 100; value = (exercise.quantity! / this._basePercent) * 100;
} }
} else if (diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) { } else if (diagramType == DiagramType.oneRepMax || diagramType == DiagramType.sumMass) {
value = exercise.calculated; value = exercise.calculated!;
} }
return value; return value;
} }
@ -188,22 +187,22 @@ class GroupChart extends GroupData with Calculate {
_minData = diagramValue; _minData = diagramValue;
} }
BarChartGroupData data = BarChartGroupData(x: exercise.dateAdd.millisecondsSinceEpoch, barRods: [ BarChartGroupData data = BarChartGroupData(x: exercise.dateAdd!.millisecondsSinceEpoch, barRods: [
BarChartRodData(y: diagramValue, width: 12, colors: [Colors.lightBlue, Colors.lightBlueAccent]) BarChartRodData(y: diagramValue, width: 12, colors: [Colors.lightBlue, Colors.lightBlueAccent])
]); ]);
_chartData.add(data); _chartData.add(data);
_origExerciseTypeId = exercise.exerciseTypeId; _origExerciseTypeId = exercise.exerciseTypeId!;
} }
@override @override
bool checkNewType(Exercise exercise) { bool checkNewType(Exercise exercise) {
return _origExerciseTypeId != exercise.exerciseTypeId; return _origExerciseTypeId == null || _origExerciseTypeId != exercise.exerciseTypeId;
} }
@override @override
void iteration() { void iteration() {
this.resetTemp(); this.resetTemp();
Exercise tempExercise; Exercise? tempExercise;
inputList.forEach((element) { inputList.forEach((element) {
tempExercise = element; tempExercise = element;
@ -222,7 +221,7 @@ class GroupChart extends GroupData with Calculate {
} }
}); });
if (tempExercise != null) { if (tempExercise != null) {
this.temp2Output(tempExercise); this.temp2Output(tempExercise!);
} }
} }
@ -234,9 +233,9 @@ class GroupChart extends GroupData with Calculate {
ChartDataExtended extended; ChartDataExtended extended;
if (outputList[_origExerciseTypeId] == null) { if (outputList[_origExerciseTypeId] == null) {
extended = ChartDataExtended(data: _chartData, interval: dInterval, gridInterval: gridInterval); extended = ChartDataExtended(data: _chartData, interval: dInterval, gridInterval: gridInterval);
outputList[_origExerciseTypeId] = extended; outputList[_origExerciseTypeId!] = extended;
} else { } else {
extended = outputList[_origExerciseTypeId]; extended = outputList[_origExerciseTypeId]!;
_chartData.forEach((element) { _chartData.forEach((element) {
extended.data.add(element); extended.data.add(element);
}); });
@ -247,7 +246,7 @@ class GroupChart extends GroupData with Calculate {
void resetTemp() { void resetTemp() {
_minData = 999999999999; _minData = 999999999999;
_maxData = 0; _maxData = 0;
_chartData = List(); _chartData = [];
} }
} }
@ -256,10 +255,10 @@ class ChartDataExtended {
final double interval; final double interval;
final int gridInterval; final int gridInterval;
const ChartDataExtended({this.data, this.interval, this.gridInterval}); const ChartDataExtended({required this.data, required this.interval, required this.gridInterval});
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
List listBarChartData = List(); List listBarChartData = [];
data.forEach((element) { data.forEach((element) {
element.barRods.forEach((rods) { element.barRods.forEach((rods) {
var barChartData = { var barChartData = {
@ -280,18 +279,19 @@ class ChartDataExtended {
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate, Logging { class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate, Logging {
final WorkoutTreeRepository workoutTreeRepository; final WorkoutTreeRepository workoutTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap(); LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap();
List<BarChartGroupData> chartData; late List<BarChartGroupData> chartData;
String diagramType = DiagramType.sumMass; String diagramType = DiagramType.sumMass;
String dateRate = DateRate.daily; String dateRate = DateRate.daily;
double basePercent = 0; double basePercent = 0;
@override @override
DevelopmentByMuscleBloc({this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial()); DevelopmentByMuscleBloc({required this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial());
Future<void> getData() async { Future<void> getData() async {
workoutTreeRepository.sortedTree = null; workoutTreeRepository.sortedTree.clear();
workoutTreeRepository.sortByMuscleType(); workoutTreeRepository.sortByMuscleType();
workoutTreeRepository.sortedTree.forEach((key, value) { workoutTreeRepository.sortedTree.forEach((key, value) {
@ -305,7 +305,7 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
} }
void getChartData() { void getChartData() {
List<Exercise> exercises = exerciseRepository.getExerciseList(); List<Exercise>? exercises = exerciseRepository.getExerciseList();
//print("-- Start calculate --- "); //print("-- Start calculate --- ");
exercises = this.groupByDate(exercises); exercises = this.groupByDate(exercises);
@ -322,24 +322,25 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
listChartData = groupChart.outputList; listChartData = groupChart.outputList;
listChartData.forEach((key, value) { listChartData.forEach((key, value) {
trace("typeid " + key.toString() + " chardata " + value.toJson().toString()); //trace("typeid " + key.toString() + " chardata " + value.toJson().toString());
}); });
return; return;
} }
List<Exercise> groupByDate(List<Exercise> exercises) { List<Exercise> groupByDate(List<Exercise>? exercises) {
List<Exercise> groupedExercises = List(); List<Exercise> groupedExercises = [];
if (exercises != null) {
exercises = sort(exercises, false);
exercises.forEach((exercise) {
//trace("Date exercise " + exercise.toJsonDatePart().toString());
});
exercises = sort(exercises, false); GroupDate groupDate = GroupDate(inputList: exercises, outputList: groupedExercises);
exercises.forEach((exercise) { groupDate.dateRate = this.dateRate;
trace("Date exercise " + exercise.toJsonDatePart().toString()); groupDate.diagramType = this.diagramType;
}); groupDate.iteration();
groupedExercises = groupDate.outputList;
GroupDate groupDate = GroupDate(inputList: exercises, outputList: groupedExercises); }
groupDate.dateRate = this.dateRate;
groupDate.diagramType = this.diagramType;
groupDate.iteration();
groupedExercises = groupDate.outputList;
/* groupedExercises.forEach((element) { /* groupedExercises.forEach((element) {
print("Grouped " + element.toJsonDatePart().toString()); print("Grouped " + element.toJsonDatePart().toString());

View File

@ -14,7 +14,7 @@ class DevelopmentByMuscleLoad extends DevelopmentByMuscleEvent {
class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent { class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
final String dateRate; final String dateRate;
const DevelopmentByMuscleDateRateChange({this.dateRate}); const DevelopmentByMuscleDateRateChange({required this.dateRate});
@override @override
List<Object> get props => [dateRate]; List<Object> get props => [dateRate];
@ -22,7 +22,7 @@ class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
class DevelopmentByMuscleDiagramTypeChange extends DevelopmentByMuscleEvent { class DevelopmentByMuscleDiagramTypeChange extends DevelopmentByMuscleEvent {
final String diagramType; final String diagramType;
const DevelopmentByMuscleDiagramTypeChange({this.diagramType}); const DevelopmentByMuscleDiagramTypeChange({required this.diagramType});
@override @override
List<Object> get props => [diagramType]; List<Object> get props => [diagramType];

View File

@ -1,7 +1,7 @@
part of 'development_by_muscle_bloc.dart'; part of 'development_by_muscle_bloc.dart';
@immutable @immutable
abstract class DevelopmentByMuscleState extends Equatable{ abstract class DevelopmentByMuscleState extends Equatable {
const DevelopmentByMuscleState(); const DevelopmentByMuscleState();
@override @override
@ -20,10 +20,9 @@ class DevelopmentByMuscleReadyState extends DevelopmentByMuscleState {
const DevelopmentByMuscleReadyState(); const DevelopmentByMuscleReadyState();
} }
class DevelopmentByMuscleErrorState extends DevelopmentByMuscleState { class DevelopmentByMuscleErrorState extends DevelopmentByMuscleState {
final String message; final String message;
const DevelopmentByMuscleErrorState({this.message}); const DevelopmentByMuscleErrorState({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -10,11 +10,11 @@ part 'development_sizes_state.dart';
class DevelopmentSizesBloc extends Bloc<DevelopmentSizesEvent, DevelopmentSizesState> { class DevelopmentSizesBloc extends Bloc<DevelopmentSizesEvent, DevelopmentSizesState> {
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
DevelopmentSizesBloc({this.customerRepository}) : super(DevelopmentSizesInitial()) { DevelopmentSizesBloc({required this.customerRepository}) : super(DevelopmentSizesInitial()) {
isMan = Cache().userLoggedIn.sex == "m"; isMan = Cache().userLoggedIn!.sex == "m";
} }
bool isMan; late bool isMan;
@override @override
Stream<DevelopmentSizesState> mapEventToState( Stream<DevelopmentSizesState> mapEventToState(

View File

@ -21,7 +21,7 @@ class DevelopmentSizesReady extends DevelopmentSizesState {
class DevelopmentSizesError extends DevelopmentSizesState { class DevelopmentSizesError extends DevelopmentSizesState {
final String message; final String message;
const DevelopmentSizesError({this.message}); const DevelopmentSizesError({required this.message});
@override @override
List<Object> get props => [this.message]; List<Object> get props => [this.message];

View File

@ -15,23 +15,24 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
final bool readonly; final bool readonly;
int step = 1; int step = 1;
double initialRM; late double initialRM;
double unitQuantity; late double unitQuantity;
double quantity; late double quantity;
double origQuantity; late double origQuantity;
double oneRepQuantity; late double oneRepQuantity;
double oneRepUnitQuantity; late double oneRepUnitQuantity;
double firstQuantity; // quantity of the first test double? firstQuantity; // quantity of the first test
double firstUnitQuantity; // unit quantity of the first test double? firstUnitQuantity; // unit quantity of the first test
double scrollOffset = 0; double scrollOffset = 0;
@override @override
ExerciseControlBloc({this.exerciseRepository, this.readonly, @required this.timerBloc}) : super(ExerciseControlInitial()) { ExerciseControlBloc({required this.exerciseRepository, required this.readonly, required this.timerBloc})
print("Exercise ${exerciseRepository.exercise.toJson()}"); : super(ExerciseControlInitial()) {
oneRepQuantity = exerciseRepository.exercise.quantity; print("Exercise ${exerciseRepository.exercise!.toJson()}");
oneRepUnitQuantity = exerciseRepository.exercise.unitQuantity; oneRepQuantity = exerciseRepository.exercise!.quantity!;
oneRepUnitQuantity = exerciseRepository.exercise!.unitQuantity!;
initialRM = this.calculate1RM(percent75: false); initialRM = this.calculate1RM(percent75: false);
unitQuantity = this.calculate1RM(percent75: true).roundToDouble(); unitQuantity = this.calculate1RM(percent75: true).roundToDouble();
quantity = 12; quantity = 12;
@ -76,14 +77,14 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
scrollOffset = step * 400.0; scrollOffset = step * 400.0;
quantity = origQuantity; quantity = origQuantity;
if (exerciseRepository.exercise.quantity == null) { if (exerciseRepository.exercise!.quantity == null) {
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
} }
exerciseRepository.end = DateTime.now(); exerciseRepository.end = DateTime.now();
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
//exerciseRepository.initExercise(); //exerciseRepository.initExercise();
step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd()); step <= 3 ? timerBloc.add(TimerStart(duration: 300)) : timerBloc.add(TimerEnd(duration: 300));
} }
yield ExerciseControlReady(); yield ExerciseControlReady();
} }
@ -92,12 +93,12 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
} }
} }
double calculate1RM({bool percent75}) { double calculate1RM({bool percent75 = true}) {
if (exerciseRepository.exercise == null) { if (exerciseRepository.exercise == null) {
exerciseRepository.getLastExercise(); exerciseRepository.getLastExercise();
} }
double weight = exerciseRepository.exercise.unitQuantity; double weight = exerciseRepository.exercise!.unitQuantity!;
double repeat = exerciseRepository.exercise.quantity; double repeat = exerciseRepository.exercise!.quantity!;
if (weight == 0 || repeat == 0) { if (weight == 0 || repeat == 0) {
return 0; return 0;
} }
@ -117,8 +118,8 @@ class ExerciseControlBloc extends Bloc<ExerciseControlEvent, ExerciseControlStat
final double rmOconner = weight * (1 + repeat / 40); final double rmOconner = weight * (1 + repeat / 40);
print("Weight: $weight oneRepQuantity: $repeat, $rmWendler, Oconner: $rmOconner"); print("Weight: $weight oneRepQuantity: $repeat, $rmWendler, Oconner: $rmOconner");
weight = exerciseRepository.exercise.unitQuantity; weight = exerciseRepository.exercise!.unitQuantity!;
repeat = exerciseRepository.exercise.quantity; repeat = exerciseRepository.exercise!.quantity!;
final double repeatWendler = (rmWendler - weight) / 0.0333 / weight; final double repeatWendler = (rmWendler - weight) / 0.0333 / weight;
final double repeatOconner = (rmOconner / weight - 1) * 40; final double repeatOconner = (rmOconner / weight - 1) * 40;

View File

@ -15,16 +15,16 @@ class ExerciseControlLoad extends ExerciseControlEvent {
class ExerciseControlQuantityChange extends ExerciseControlEvent { class ExerciseControlQuantityChange extends ExerciseControlEvent {
final double quantity; final double quantity;
final int step; final int step;
const ExerciseControlQuantityChange({this.quantity, this.step}); const ExerciseControlQuantityChange({required this.quantity, required this.step});
} }
class ExerciseControlUnitQuantityChange extends ExerciseControlEvent { class ExerciseControlUnitQuantityChange extends ExerciseControlEvent {
final double quantity; final double quantity;
final int step; final int step;
const ExerciseControlUnitQuantityChange({this.quantity, this.step}); const ExerciseControlUnitQuantityChange({required this.quantity, required this.step});
} }
class ExerciseControlSubmit extends ExerciseControlEvent { class ExerciseControlSubmit extends ExerciseControlEvent {
final int step; final int step;
const ExerciseControlSubmit({this.step}); const ExerciseControlSubmit({required this.step});
} }

View File

@ -22,9 +22,8 @@ class ExerciseControlReady extends ExerciseControlState {
class ExerciseControlError extends ExerciseControlState { class ExerciseControlError extends ExerciseControlState {
final String message; final String message;
const ExerciseControlError({this.message}); const ExerciseControlError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -14,16 +14,17 @@ part 'exercise_execute_plan_state.dart';
class ExerciseExecutePlanBloc extends Bloc<ExerciseExecutePlanEvent, ExerciseExecutePlanState> { class ExerciseExecutePlanBloc extends Bloc<ExerciseExecutePlanEvent, ExerciseExecutePlanState> {
final WorkoutTreeRepository menuTreeRepository; final WorkoutTreeRepository menuTreeRepository;
final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository(); final ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
int customerId; int? customerId;
int selectedNumber = 0; int selectedNumber = 0;
@override @override
ExerciseExecutePlanBloc({this.menuTreeRepository}) : super(ExerciseByPlanStateInitial()); ExerciseExecutePlanBloc({required this.menuTreeRepository}) : super(ExerciseByPlanStateInitial());
Future<void> getData() async { Future<void> getData() async {
exercisePlanRepository.setCustomerId(customerId); exercisePlanRepository.setCustomerId(customerId!);
await exercisePlanRepository.getLastExercisePlan(); await exercisePlanRepository.getLastExercisePlan();
await exercisePlanRepository.getExercisePlanDetails(); await exercisePlanRepository.getExercisePlanDetails();
menuTreeRepository.sortedTree = null; menuTreeRepository.sortedTree.clear();
menuTreeRepository.sortByMuscleType(); menuTreeRepository.sortByMuscleType();
menuTreeRepository.sortedTree.forEach((key, value) { menuTreeRepository.sortedTree.forEach((key, value) {

View File

@ -10,7 +10,7 @@ abstract class ExerciseExecutePlanEvent extends Equatable {
class AddExerciseByPlanEvent extends ExerciseExecutePlanEvent { class AddExerciseByPlanEvent extends ExerciseExecutePlanEvent {
final ExerciseType exerciseType; final ExerciseType exerciseType;
const AddExerciseByPlanEvent({this.exerciseType}); const AddExerciseByPlanEvent({required this.exerciseType});
@override @override
List<Object> get props => [exerciseType]; List<Object> get props => [exerciseType];

View File

@ -24,8 +24,8 @@ class ExerciseByPlanReady extends ExerciseExecutePlanState {
// error splash screen // error splash screen
class ExerciseByPlanError extends ExerciseExecutePlanState { class ExerciseByPlanError extends ExerciseExecutePlanState {
final String message; final String message;
const ExerciseByPlanError({this.message}); const ExerciseByPlanError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -22,30 +22,35 @@ class ExerciseExecutePlanAddBloc extends Bloc<ExerciseExecutePlanAddEvent, Exerc
final ExerciseExecutePlanBloc planBloc; final ExerciseExecutePlanBloc planBloc;
final int customerId; final int customerId;
Customer customer; late Customer customer;
int step = 1; int step = 1;
int countSteps = 1; int countSteps = 1;
double quantity; late double quantity;
double unitQuantity; late double unitQuantity;
double scrollOffset = 0; double scrollOffset = 0;
@override @override
ExerciseExecutePlanAddBloc({this.exerciseRepository, this.exercisePlanRepository, this.customerId, this.workoutTree, this.planBloc}) ExerciseExecutePlanAddBloc(
{required this.exerciseRepository,
required this.exercisePlanRepository,
required this.customerId,
required this.workoutTree,
required this.planBloc})
: super(ExerciseExecutePlanAddInitial()) { : super(ExerciseExecutePlanAddInitial()) {
exerciseRepository.exerciseType = workoutTree.exerciseType; exerciseRepository.exerciseType = workoutTree.exerciseType;
if (Cache().userLoggedIn.customerId == customerId) { if (Cache().userLoggedIn!.customerId == customerId) {
customer = Cache().userLoggedIn; customer = Cache().userLoggedIn!;
} else if (Cache().getTrainee().customerId == customerId) { } else if (Cache().getTrainee()!.customerId == customerId) {
customer = Cache().getTrainee(); customer = Cache().getTrainee()!;
} }
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType); exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType!);
exerciseRepository.customer = customer; exerciseRepository.customer = customer;
countSteps = exercisePlanRepository.getActualPlanDetail().serie; countSteps = exercisePlanRepository.getActualPlanDetail()!.serie!;
unitQuantity = double.parse(exercisePlanRepository.getActualPlanDetail().weightEquation); unitQuantity = double.parse(exercisePlanRepository.getActualPlanDetail()!.weightEquation!);
quantity = exercisePlanRepository.getActualPlanDetail().repeats.toDouble(); quantity = exercisePlanRepository.getActualPlanDetail()!.repeats!.toDouble();
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
@ -70,8 +75,8 @@ class ExerciseExecutePlanAddBloc extends Bloc<ExerciseExecutePlanAddEvent, Exerc
yield ExerciseExecutePlanAddReady(); yield ExerciseExecutePlanAddReady();
} else if (event is ExerciseExecutePlanAddSubmit) { } else if (event is ExerciseExecutePlanAddSubmit) {
yield ExerciseExecutePlanAddLoading(); yield ExerciseExecutePlanAddLoading();
exerciseRepository.exercise.exercisePlanDetailId = exercisePlanRepository.getActualPlanDetail().exercisePlanDetailId; exerciseRepository.exercise!.exercisePlanDetailId = exercisePlanRepository.getActualPlanDetail()!.exercisePlanDetailId;
exerciseRepository.exercise.unit = workoutTree.exerciseType.unit; exerciseRepository.exercise!.unit = workoutTree.exerciseType!.unit;
workoutTree.executed = true; workoutTree.executed = true;
await exerciseRepository.addExercise(); await exerciseRepository.addExercise();
exerciseRepository.initExercise(); exerciseRepository.initExercise();

View File

@ -14,7 +14,7 @@ class ExerciseExecutePlanAddLoad extends ExerciseExecutePlanAddEvent {
class ExerciseExecutePlanAddChangeQuantity extends ExerciseExecutePlanAddEvent { class ExerciseExecutePlanAddChangeQuantity extends ExerciseExecutePlanAddEvent {
final double quantity; final double quantity;
const ExerciseExecutePlanAddChangeQuantity({this.quantity}); const ExerciseExecutePlanAddChangeQuantity({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -22,7 +22,7 @@ class ExerciseExecutePlanAddChangeQuantity extends ExerciseExecutePlanAddEvent {
class ExerciseExecutePlanAddChangeUnitQuantity extends ExerciseExecutePlanAddEvent { class ExerciseExecutePlanAddChangeUnitQuantity extends ExerciseExecutePlanAddEvent {
final double quantity; final double quantity;
const ExerciseExecutePlanAddChangeUnitQuantity({this.quantity}); const ExerciseExecutePlanAddChangeUnitQuantity({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];

View File

@ -24,8 +24,8 @@ class ExerciseExecutePlanAddReady extends ExerciseExecutePlanAddState {
// error splash screen // error splash screen
class ExerciseExecutePlanAddError extends ExerciseExecutePlanAddState { class ExerciseExecutePlanAddError extends ExerciseExecutePlanAddState {
final String message; final String message;
const ExerciseExecutePlanAddError({this.message}); const ExerciseExecutePlanAddError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -15,7 +15,7 @@ part 'exercise_log_state.dart';
class ExerciseLogBloc extends Bloc<ExerciseLogEvent, ExerciseLogState> { class ExerciseLogBloc extends Bloc<ExerciseLogEvent, ExerciseLogState> {
final ExerciseRepository exerciseRepository; final ExerciseRepository exerciseRepository;
@override @override
ExerciseLogBloc({this.exerciseRepository}) : super(ExerciseLogInitial()); ExerciseLogBloc({required this.exerciseRepository}) : super(ExerciseLogInitial());
@override @override
Stream<ExerciseLogState> mapEventToState(ExerciseLogEvent event) async* { Stream<ExerciseLogState> mapEventToState(ExerciseLogEvent event) async* {
@ -27,7 +27,7 @@ class ExerciseLogBloc extends Bloc<ExerciseLogEvent, ExerciseLogState> {
yield ExerciseLogReady(); yield ExerciseLogReady();
} else if (event is ExerciseLogDelete) { } else if (event is ExerciseLogDelete) {
yield ExerciseLogLoading(); yield ExerciseLogLoading();
exerciseRepository.exerciseList.remove(event.exercise); exerciseRepository.exerciseList!.remove(event.exercise);
await exerciseRepository.deleteExercise(event.exercise); await exerciseRepository.deleteExercise(event.exercise);
Track().track(TrackingEvent.exercise_log_delete); Track().track(TrackingEvent.exercise_log_delete);
yield ExerciseLogReady(); yield ExerciseLogReady();

View File

@ -14,7 +14,7 @@ class ExerciseLogLoad extends ExerciseLogEvent {
class ExerciseLogDelete extends ExerciseLogEvent { class ExerciseLogDelete extends ExerciseLogEvent {
final Exercise exercise; final Exercise exercise;
const ExerciseLogDelete({this.exercise}); const ExerciseLogDelete({required this.exercise});
@override @override
List<Object> get props => [exercise]; List<Object> get props => [exercise];

View File

@ -22,9 +22,8 @@ class ExerciseLogReady extends ExerciseLogState {
class ExerciseLogError extends ExerciseLogState { class ExerciseLogError extends ExerciseLogState {
final String message; final String message;
const ExerciseLogError({this.message}); const ExerciseLogError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -1,4 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:intl/intl.dart';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/exercise_type.dart';
@ -12,7 +14,6 @@ import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/animation.dart'; import 'package:flutter/animation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:stop_watch_timer/stop_watch_timer.dart'; import 'package:stop_watch_timer/stop_watch_timer.dart';
@ -23,7 +24,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
final ExerciseRepository exerciseRepository; final ExerciseRepository exerciseRepository;
final CustomerRepository customerRepository; final CustomerRepository customerRepository;
final MenuBloc menuBloc; final MenuBloc menuBloc;
AnimationController bmiAnimationController; late AnimationController bmiAnimationController;
double quantity = 12; double quantity = 12;
double unitQuantity = 30; double unitQuantity = 30;
double bmi = 0; double bmi = 0;
@ -35,11 +36,11 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
double bmiAngle = 0; double bmiAngle = 0;
double bmiTop = 0; double bmiTop = 0;
double bmiLeft = 0; double bmiLeft = 0;
double weight; late double weight;
double height; late double height;
double bmrEnergy = 0; double bmrEnergy = 0;
int birthYear; late int birthYear;
String fitnessLevel; late String fitnessLevel;
bool changedWeight = false; bool changedWeight = false;
bool changedSizes = false; bool changedSizes = false;
@ -53,23 +54,24 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
final StopWatchTimer stopWatchTimer = StopWatchTimer( final StopWatchTimer stopWatchTimer = StopWatchTimer(
isLapHours: false, isLapHours: false,
); );
int timerValue; late int timerValue;
@override @override
ExerciseNewBloc({this.exerciseRepository, this.menuBloc, this.customerRepository, ExerciseType exerciseType}) ExerciseNewBloc(
{required this.exerciseRepository, required this.menuBloc, required this.customerRepository, required ExerciseType exerciseType})
: super(ExerciseNewInitial()) { : super(ExerciseNewInitial()) {
exerciseRepository.exerciseType = exerciseType; exerciseRepository.exerciseType = exerciseType;
exerciseRepository.setUnit(exerciseType.unit); exerciseRepository.setUnit(exerciseType.unit);
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
exerciseRepository.exercise.exercisePlanDetailId = 0; exerciseRepository.exercise!.exercisePlanDetailId = 0;
exerciseRepository.start = DateTime.now(); exerciseRepository.start = DateTime.now();
if (Cache().userLoggedIn != null) { if (Cache().userLoggedIn != null) {
customerRepository.customer = Cache().userLoggedIn; customerRepository.customer = Cache().userLoggedIn!;
weight = customerRepository.customer.getProperty("Weight"); weight = customerRepository.customer.getProperty("Weight");
height = customerRepository.customer.getProperty("Height"); height = customerRepository.customer.getProperty("Height");
birthYear = customerRepository.customer.birthYear; birthYear = customerRepository.customer.birthYear!;
fitnessLevel = customerRepository.customer.fitnessLevel; fitnessLevel = customerRepository.customer.fitnessLevel!;
} }
if (exerciseType.unit == "second") { if (exerciseType.unit == "second") {
stopWatchTimer.rawTime.listen((value) => {timerValue = value, this.setQuantity((value / 1000).toDouble())}); stopWatchTimer.rawTime.listen((value) => {timerValue = value, this.setQuantity((value / 1000).toDouble())});
@ -151,7 +153,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
// exerciseRepository.initExercise(); // exerciseRepository.initExercise();
menuBloc.add(MenuTreeDown(parent: 0)); menuBloc.add(MenuTreeDown(parent: 0));
Cache().initBadges(); Cache().initBadges();
Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType.name); Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name);
yield ExerciseNewSaved(); yield ExerciseNewSaved();
} else if (event is ExerciseNewBMIAnimate) { } else if (event is ExerciseNewBMIAnimate) {
yield ExerciseNewLoading(); yield ExerciseNewLoading();
@ -183,10 +185,10 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
if (customerRepository.customer.sex == "m") { if (customerRepository.customer.sex == "m") {
//66.47 + ( 13.75 × tömeg kg-ban ) + ( 5.003 × magasság cm-ben ) ( 6.755 × életkor évben kifejezve ) //66.47 + ( 13.75 × tömeg kg-ban ) + ( 5.003 × magasság cm-ben ) ( 6.755 × életkor évben kifejezve )
bmr = 66.47 + (13.75 * weight) + (5.003 * height) - (6.755 * (year - customerRepository.customer.birthYear)); bmr = 66.47 + (13.75 * weight) + (5.003 * height) - (6.755 * (year - customerRepository.customer.birthYear!));
} else { } else {
//BMR = 655.1 + ( 9.563 × ömeg kg-ban ) + ( 1.85 × magasság cm-ben) ( 4.676 × életkor évben kifejezve ) //BMR = 655.1 + ( 9.563 × ömeg kg-ban ) + ( 1.85 × magasság cm-ben) ( 4.676 × életkor évben kifejezve )
bmr = 655.1 + (9.563 * weight) + (1.85 * height) - (4.676 * (year - customerRepository.customer.birthYear)); bmr = 655.1 + (9.563 * weight) + (1.85 * height) - (4.676 * (year - customerRepository.customer.birthYear!));
} }
bmrEnergy = bmr; bmrEnergy = bmr;

View File

@ -14,7 +14,7 @@ class ExerciseNewLoad extends ExerciseNewEvent {
class ExerciseNewQuantityChange extends ExerciseNewEvent { class ExerciseNewQuantityChange extends ExerciseNewEvent {
final double quantity; final double quantity;
const ExerciseNewQuantityChange({this.quantity}); const ExerciseNewQuantityChange({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -22,7 +22,7 @@ class ExerciseNewQuantityChange extends ExerciseNewEvent {
class ExerciseNewQuantityUnitChange extends ExerciseNewEvent { class ExerciseNewQuantityUnitChange extends ExerciseNewEvent {
final double quantity; final double quantity;
const ExerciseNewQuantityUnitChange({this.quantity}); const ExerciseNewQuantityUnitChange({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -30,21 +30,21 @@ class ExerciseNewQuantityUnitChange extends ExerciseNewEvent {
class ExerciseNewBirthyearChange extends ExerciseNewEvent { class ExerciseNewBirthyearChange extends ExerciseNewEvent {
final int value; final int value;
const ExerciseNewBirthyearChange({this.value}); const ExerciseNewBirthyearChange({required this.value});
@override @override
List<Object> get props => [value]; List<Object> get props => [value];
} }
class ExerciseNewWeightChange extends ExerciseNewEvent { class ExerciseNewWeightChange extends ExerciseNewEvent {
final double value; final double value;
const ExerciseNewWeightChange({this.value}); const ExerciseNewWeightChange({required this.value});
@override @override
List<Object> get props => [value]; List<Object> get props => [value];
} }
class ExerciseNewHeightChange extends ExerciseNewEvent { class ExerciseNewHeightChange extends ExerciseNewEvent {
final double value; final double value;
const ExerciseNewHeightChange({this.value}); const ExerciseNewHeightChange({required this.value});
@override @override
List<Object> get props => [value]; List<Object> get props => [value];
@ -52,7 +52,7 @@ class ExerciseNewHeightChange extends ExerciseNewEvent {
class ExerciseNewFitnessLevelChange extends ExerciseNewEvent { class ExerciseNewFitnessLevelChange extends ExerciseNewEvent {
final String value; final String value;
const ExerciseNewFitnessLevelChange({this.value}); const ExerciseNewFitnessLevelChange({required this.value});
@override @override
List<Object> get props => [value]; List<Object> get props => [value];
@ -61,7 +61,7 @@ class ExerciseNewFitnessLevelChange extends ExerciseNewEvent {
class ExerciseNewSizeChange extends ExerciseNewEvent { class ExerciseNewSizeChange extends ExerciseNewEvent {
final String propertyName; final String propertyName;
final double value; final double value;
const ExerciseNewSizeChange({this.propertyName, this.value}); const ExerciseNewSizeChange({required this.propertyName, required this.value});
@override @override
List<Object> get props => [propertyName, value]; List<Object> get props => [propertyName, value];

View File

@ -26,7 +26,7 @@ class ExerciseNewSaved extends ExerciseNewState {
class ExerciseNewError extends ExerciseNewState { class ExerciseNewError extends ExerciseNewState {
final String message; final String message;
const ExerciseNewError({this.message}); const ExerciseNewError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -17,15 +17,15 @@ part 'exercise_plan_state.dart';
class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> { class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
final WorkoutTreeRepository menuTreeRepository; final WorkoutTreeRepository menuTreeRepository;
ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository(); ExercisePlanRepository exercisePlanRepository = ExercisePlanRepository();
int customerId; late int customerId;
ExercisePlanBloc({this.menuTreeRepository}) : super(ExercisePlanInitial()); ExercisePlanBloc({required this.menuTreeRepository}) : super(ExercisePlanInitial());
Future<void> getData() async { Future<void> getData() async {
exercisePlanRepository.setCustomerId(customerId); exercisePlanRepository.setCustomerId(customerId);
await exercisePlanRepository.getLastExercisePlan(); await exercisePlanRepository.getLastExercisePlan();
await exercisePlanRepository.getExercisePlanDetails(); await exercisePlanRepository.getExercisePlanDetails();
menuTreeRepository.sortedTree = null; menuTreeRepository.sortedTree.clear();
menuTreeRepository.sortByMuscleType(); menuTreeRepository.sortByMuscleType();
menuTreeRepository.sortedTree.forEach((key, value) { menuTreeRepository.sortedTree.forEach((key, value) {
@ -33,7 +33,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
listWorkoutTree.forEach((workoutTree) { listWorkoutTree.forEach((workoutTree) {
workoutTree.selected = false; workoutTree.selected = false;
if (exercisePlanRepository.getExercisePlanDetailSize() > 0) { if (exercisePlanRepository.getExercisePlanDetailSize() > 0) {
ExercisePlanDetail planDetail = exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId); ExercisePlanDetail? planDetail = exercisePlanRepository.getExercisePlanDetailByExerciseId(workoutTree.exerciseTypeId);
if (planDetail != null && planDetail.change != ModelChange.deleted) { if (planDetail != null && planDetail.change != ModelChange.deleted) {
workoutTree.selected = true; workoutTree.selected = true;
} }
@ -58,10 +58,8 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
yield ExercisePlanLoading(); yield ExercisePlanLoading();
WorkoutMenuTree workoutTree = event.workoutTree; WorkoutMenuTree workoutTree = event.workoutTree;
if (workoutTree != null) { exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType!);
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutTree.exerciseType); workoutTree.selected = true;
workoutTree.selected = true;
}
yield ExercisePlanReady(); yield ExercisePlanReady();
} else if (event is ExercisePlanAddExercise) { } else if (event is ExercisePlanAddExercise) {
@ -76,7 +74,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
this.menuTreeRepository.sortedTree.forEach((key, value) { this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value; List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) { listTreeItem.forEach((element) {
if (element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) { if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = true; element.selected = true;
} }
}); });
@ -91,7 +89,7 @@ class ExercisePlanBloc extends Bloc<ExercisePlanEvent, ExercisePlanState> {
this.menuTreeRepository.sortedTree.forEach((key, value) { this.menuTreeRepository.sortedTree.forEach((key, value) {
List<WorkoutMenuTree> listTreeItem = value; List<WorkoutMenuTree> listTreeItem = value;
listTreeItem.forEach((element) { listTreeItem.forEach((element) {
if (element.exerciseType.exerciseTypeId == planDetail.exerciseTypeId) { if (element.exerciseType!.exerciseTypeId == planDetail.exerciseTypeId) {
element.selected = false; element.selected = false;
} }
}); });

View File

@ -11,20 +11,18 @@ class ExercisePlanLoad extends ExercisePlanEvent {
const ExercisePlanLoad(); const ExercisePlanLoad();
} }
// update UI // update UI
class ExercisePlanUpdateUI extends ExercisePlanEvent { class ExercisePlanUpdateUI extends ExercisePlanEvent {
final WorkoutMenuTree workoutTree; final WorkoutMenuTree workoutTree;
const ExercisePlanUpdateUI({this.workoutTree}); const ExercisePlanUpdateUI({required this.workoutTree});
@override @override
List<Object> get props => [workoutTree]; List<Object> get props => [workoutTree];
} }
class ExercisePlanRemoveExercise extends ExercisePlanEvent { class ExercisePlanRemoveExercise extends ExercisePlanEvent {
final ExercisePlanDetail exercisePlanDetail; final ExercisePlanDetail exercisePlanDetail;
const ExercisePlanRemoveExercise({this.exercisePlanDetail}); const ExercisePlanRemoveExercise({required this.exercisePlanDetail});
@override @override
List<Object> get props => [exercisePlanDetail]; List<Object> get props => [exercisePlanDetail];
@ -32,8 +30,8 @@ class ExercisePlanRemoveExercise extends ExercisePlanEvent {
class ExercisePlanAddExercise extends ExercisePlanEvent { class ExercisePlanAddExercise extends ExercisePlanEvent {
final ExercisePlanDetail exercisePlanDetail; final ExercisePlanDetail exercisePlanDetail;
const ExercisePlanAddExercise({this.exercisePlanDetail}); const ExercisePlanAddExercise({required this.exercisePlanDetail});
@override @override
List<Object> get props => [exercisePlanDetail]; List<Object> get props => [exercisePlanDetail];
} }

View File

@ -1,7 +1,7 @@
part of 'exercise_plan_bloc.dart'; part of 'exercise_plan_bloc.dart';
@immutable @immutable
abstract class ExercisePlanState extends Equatable{ abstract class ExercisePlanState extends Equatable {
const ExercisePlanState(); const ExercisePlanState();
@override @override
@ -26,12 +26,8 @@ class ExercisePlanReady extends ExercisePlanState {
// error splash screen // error splash screen
class ExercisePlanError extends ExercisePlanState { class ExercisePlanError extends ExercisePlanState {
final String message; final String message;
const ExercisePlanError({this.message}); const ExercisePlanError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -22,23 +22,30 @@ class ExercisePlanCustomAddBloc extends Bloc<ExercisePlanCustomAddEvent, Exercis
final ExercisePlanBloc planBloc; final ExercisePlanBloc planBloc;
final WorkoutMenuTree workoutMenuTree; final WorkoutMenuTree workoutMenuTree;
double quantity; late double quantity;
double serie; double? serie;
double quantityUnit; late double quantityUnit;
@override @override
ExercisePlanCustomAddBloc({this.exercisePlanRepository, this.planBloc, this.workoutMenuTree}) : super(ExercisePlanCustomAddInitial()) { ExercisePlanCustomAddBloc({required this.exercisePlanRepository, required this.planBloc, required this.workoutMenuTree})
exercisePlanRepository.setActualPlanDetailByExerciseType(workoutMenuTree.exerciseType); : super(ExercisePlanCustomAddInitial()) {
quantity = // init();
exercisePlanRepository.getActualPlanDetail().repeats != null ? exercisePlanRepository.getActualPlanDetail().repeats.toDouble() : 12; }
serie = exercisePlanRepository.getActualPlanDetail().serie != null ? exercisePlanRepository.getActualPlanDetail().serie.toDouble() : 3;
quantityUnit = exercisePlanRepository.getActualPlanDetail().weightEquation != null void init() {
? double.parse(exercisePlanRepository.getActualPlanDetail().weightEquation) exercisePlanRepository.setActualPlanDetailByExerciseType(workoutMenuTree.exerciseType!);
quantity = exercisePlanRepository.getActualPlanDetail()!.repeats != null
? exercisePlanRepository.getActualPlanDetail()!.repeats!.toDouble()
: 12;
serie =
exercisePlanRepository.getActualPlanDetail()!.serie != null ? exercisePlanRepository.getActualPlanDetail()!.serie!.toDouble() : 3;
quantityUnit = exercisePlanRepository.getActualPlanDetail()!.weightEquation != null
? double.parse(exercisePlanRepository.getActualPlanDetail()!.weightEquation!)
: 30; : 30;
exercisePlanRepository.getActualPlanDetail().weightEquation = quantityUnit.toString(); exercisePlanRepository.getActualPlanDetail()!.weightEquation = quantityUnit.toString();
exercisePlanRepository.getActualPlanDetail().serie = serie.toInt(); exercisePlanRepository.getActualPlanDetail()!.serie = serie!.toInt();
exercisePlanRepository.getActualPlanDetail().repeats = quantity.toInt(); exercisePlanRepository.getActualPlanDetail()!.repeats = quantity.toInt();
} }
@override @override
@ -46,36 +53,37 @@ class ExercisePlanCustomAddBloc extends Bloc<ExercisePlanCustomAddEvent, Exercis
try { try {
if (event is ExercisePlanCustomAddLoad) { if (event is ExercisePlanCustomAddLoad) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
init();
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeSerie) { } else if (event is ExercisePlanCustomAddChangeSerie) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
serie = event.quantity; serie = event.quantity;
exercisePlanRepository.getActualPlanDetail().serie = event.quantity.toInt(); exercisePlanRepository.getActualPlanDetail()!.serie = event.quantity.toInt();
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeQuantity) { } else if (event is ExercisePlanCustomAddChangeQuantity) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
quantity = event.quantity; quantity = event.quantity;
exercisePlanRepository.getActualPlanDetail().repeats = event.quantity.toInt(); exercisePlanRepository.getActualPlanDetail()!.repeats = event.quantity.toInt();
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddChangeQuantityUnit) { } else if (event is ExercisePlanCustomAddChangeQuantityUnit) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
quantityUnit = event.quantity; quantityUnit = event.quantity;
exercisePlanRepository.getActualPlanDetail().weightEquation = event.quantity.toStringAsFixed(0); exercisePlanRepository.getActualPlanDetail()!.weightEquation = event.quantity.toStringAsFixed(0);
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddSubmit) { } else if (event is ExercisePlanCustomAddSubmit) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
if (exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null) { if (exercisePlanRepository.exercisePlanDetails[exercisePlanRepository.getActualPlanDetail()] == null) {
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.add; exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.add;
} else { } else {
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.update; exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.update;
} }
exercisePlanRepository.addDetailToPlan(); exercisePlanRepository.addDetailToPlan();
planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail())); planBloc.add(ExercisePlanAddExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} else if (event is ExercisePlanCustomAddRemove) { } else if (event is ExercisePlanCustomAddRemove) {
yield ExercisePlanCustomAddLoading(); yield ExercisePlanCustomAddLoading();
exercisePlanRepository.getActualPlanDetail().change = ExercisePlanDetailChange.delete; exercisePlanRepository.getActualPlanDetail()!.change = ExercisePlanDetailChange.delete;
planBloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail())); planBloc.add(ExercisePlanRemoveExercise(exercisePlanDetail: exercisePlanRepository.getActualPlanDetail()!));
yield ExercisePlanCustomAddReady(); yield ExercisePlanCustomAddReady();
} }

View File

@ -14,7 +14,7 @@ class ExercisePlanCustomAddLoad extends ExercisePlanCustomAddEvent {
class ExercisePlanCustomAddChangeSerie extends ExercisePlanCustomAddEvent { class ExercisePlanCustomAddChangeSerie extends ExercisePlanCustomAddEvent {
final double quantity; final double quantity;
const ExercisePlanCustomAddChangeSerie({this.quantity}); const ExercisePlanCustomAddChangeSerie({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -22,7 +22,7 @@ class ExercisePlanCustomAddChangeSerie extends ExercisePlanCustomAddEvent {
class ExercisePlanCustomAddChangeQuantity extends ExercisePlanCustomAddEvent { class ExercisePlanCustomAddChangeQuantity extends ExercisePlanCustomAddEvent {
final double quantity; final double quantity;
const ExercisePlanCustomAddChangeQuantity({this.quantity}); const ExercisePlanCustomAddChangeQuantity({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -30,7 +30,7 @@ class ExercisePlanCustomAddChangeQuantity extends ExercisePlanCustomAddEvent {
class ExercisePlanCustomAddChangeQuantityUnit extends ExercisePlanCustomAddEvent { class ExercisePlanCustomAddChangeQuantityUnit extends ExercisePlanCustomAddEvent {
final double quantity; final double quantity;
const ExercisePlanCustomAddChangeQuantityUnit({this.quantity}); const ExercisePlanCustomAddChangeQuantityUnit({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -42,4 +42,4 @@ class ExercisePlanCustomAddSubmit extends ExercisePlanCustomAddEvent {
class ExercisePlanCustomAddRemove extends ExercisePlanCustomAddEvent { class ExercisePlanCustomAddRemove extends ExercisePlanCustomAddEvent {
const ExercisePlanCustomAddRemove(); const ExercisePlanCustomAddRemove();
} }

View File

@ -22,9 +22,8 @@ class ExercisePlanCustomAddReady extends ExercisePlanCustomAddState {
class ExercisePlanCustomAddError extends ExercisePlanCustomAddState { class ExercisePlanCustomAddError extends ExercisePlanCustomAddState {
final String message; final String message;
const ExercisePlanCustomAddError({this.message}); const ExercisePlanCustomAddError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -23,7 +23,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
final bool isRegistration; final bool isRegistration;
bool dataPolicyAllowed = false; bool dataPolicyAllowed = false;
bool obscure = true; bool obscure = true;
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial());
LoginBloc({required this.accountBloc, required this.userRepository, required this.context, required this.isRegistration})
: super(LoginInitial());
@override @override
Stream<LoginState> mapEventToState( Stream<LoginState> mapEventToState(
@ -43,7 +45,7 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
} else if (event is LoginSubmit) { } else if (event is LoginSubmit) {
yield LoginLoading(); yield LoginLoading();
await userRepository.getUser(); await userRepository.getUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "email"); Track().track(TrackingEvent.login, eventValue: "email");
Cache().setLoginType(LoginType.email); Cache().setLoginType(LoginType.email);
yield LoginSuccess(); yield LoginSuccess();
@ -51,31 +53,30 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
yield LoginLoading(); yield LoginLoading();
Cache().setLoginType(LoginType.fb); Cache().setLoginType(LoginType.fb);
await userRepository.getUserByFB(); await userRepository.getUserByFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "FB"); Track().track(TrackingEvent.login, eventValue: "FB");
yield LoginSuccess(); yield LoginSuccess();
} else if (event is LoginGoogle) { } else if (event is LoginGoogle) {
yield LoginLoading(); yield LoginLoading();
Cache().setLoginType(LoginType.google); Cache().setLoginType(LoginType.google);
await userRepository.getUserByGoogle(); await userRepository.getUserByGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Google"); Track().track(TrackingEvent.login, eventValue: "Google");
yield LoginSuccess(); yield LoginSuccess();
} else if (event is LoginApple) { } else if (event is LoginApple) {
yield LoginLoading(); yield LoginLoading();
Cache().setLoginType(LoginType.apple); Cache().setLoginType(LoginType.apple);
await userRepository.getUserByApple(); await userRepository.getUserByApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
Track().track(TrackingEvent.login, eventValue: "Apple"); Track().track(TrackingEvent.login, eventValue: "Apple");
yield LoginSuccess(); yield LoginSuccess();
} else if (event is RegistrationSubmit) { } else if (event is RegistrationSubmit) {
yield LoginLoading(); yield LoginLoading();
if (!this.dataPolicyAllowed) { if (!this.dataPolicyAllowed) {
yield LoginError();
throw Exception("Please accept our data policy"); throw Exception("Please accept our data policy");
} }
await userRepository.addUser(); await userRepository.addUser();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
await saveCustomer(); await saveCustomer();
Track().track(TrackingEvent.registration, eventValue: "email"); Track().track(TrackingEvent.registration, eventValue: "email");
Cache().setLoginType(LoginType.email); Cache().setLoginType(LoginType.email);
@ -83,36 +84,33 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
} else if (event is RegistrationFB) { } else if (event is RegistrationFB) {
yield LoginLoading(); yield LoginLoading();
if (!this.dataPolicyAllowed) { if (!this.dataPolicyAllowed) {
yield LoginError();
throw Exception("Please accept our data policy"); throw Exception("Please accept our data policy");
} }
Cache().setLoginType(LoginType.fb); Cache().setLoginType(LoginType.fb);
await userRepository.addUserFB(); await userRepository.addUserFB();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
await saveCustomer(); await saveCustomer();
Track().track(TrackingEvent.registration, eventValue: "FB"); Track().track(TrackingEvent.registration, eventValue: "FB");
yield LoginSuccess(); yield LoginSuccess();
} else if (event is RegistrationGoogle) { } else if (event is RegistrationGoogle) {
yield LoginLoading(); yield LoginLoading();
if (!this.dataPolicyAllowed) { if (!this.dataPolicyAllowed) {
yield LoginError();
throw Exception("Please accept our data policy"); throw Exception("Please accept our data policy");
} }
Cache().setLoginType(LoginType.google); Cache().setLoginType(LoginType.google);
await userRepository.addUserGoogle(); await userRepository.addUserGoogle();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
await saveCustomer(); await saveCustomer();
Track().track(TrackingEvent.registration, eventValue: "Google"); Track().track(TrackingEvent.registration, eventValue: "Google");
yield LoginSuccess(); yield LoginSuccess();
} else if (event is RegistrationApple) { } else if (event is RegistrationApple) {
yield LoginLoading(); yield LoginLoading();
if (!this.dataPolicyAllowed) { if (!this.dataPolicyAllowed) {
yield LoginError();
throw Exception("Please accept our data policy"); throw Exception("Please accept our data policy");
} }
Cache().setLoginType(LoginType.apple); Cache().setLoginType(LoginType.apple);
await userRepository.addUserApple(); await userRepository.addUserApple();
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn)); accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
await saveCustomer(); await saveCustomer();
Track().track(TrackingEvent.registration, eventValue: "Apple"); Track().track(TrackingEvent.registration, eventValue: "Apple");
@ -132,21 +130,18 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
} }
Future<void> saveCustomer() async { Future<void> saveCustomer() async {
customerRepository.customer = Cache().userLoggedIn; customerRepository.customer = Cache().userLoggedIn!;
customerRepository.customer.dataPolicyAllowed = 1; customerRepository.customer.dataPolicyAllowed = 1;
await customerRepository.saveCustomer(); await customerRepository.saveCustomer();
} }
String emailValidation(String email) { String? emailValidation(String email) {
String message = Common.emailValidation(email); String? message = Common.emailValidation(email);
if (message != null) {
message = t(message);
}
return message; return message;
} }
String passwordValidation(String value) { String? passwordValidation(String value) {
String message = Common.passwordValidation(value); String? message = Common.passwordValidation(value);
if (message != null) { if (message != null) {
message = t(message); message = t(message);
} }

View File

@ -9,7 +9,7 @@ abstract class LoginEvent extends Equatable {
class LoginEmailChange extends LoginEvent { class LoginEmailChange extends LoginEvent {
final String email; final String email;
const LoginEmailChange({this.email}); const LoginEmailChange({required this.email});
@override @override
List<Object> get props => [email]; List<Object> get props => [email];
@ -17,7 +17,7 @@ class LoginEmailChange extends LoginEvent {
class LoginPasswordChange extends LoginEvent { class LoginPasswordChange extends LoginEvent {
final String password; final String password;
const LoginPasswordChange({this.password}); const LoginPasswordChange({required this.password});
@override @override
List<Object> get props => [password]; List<Object> get props => [password];
@ -45,7 +45,7 @@ class LoginApple extends LoginEvent {
class DataProtectionClicked extends LoginEvent { class DataProtectionClicked extends LoginEvent {
final bool marked; final bool marked;
const DataProtectionClicked({this.marked}); const DataProtectionClicked({required this.marked});
} }
class RegistrationSubmit extends LoginEvent { class RegistrationSubmit extends LoginEvent {

View File

@ -25,7 +25,7 @@ class LoginSuccess extends LoginState {
class LoginError extends LoginState { class LoginError extends LoginState {
final String message; final String message;
const LoginError({this.message}); const LoginError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -23,8 +23,8 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository(); ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository();
int parent = 0; int parent = 0;
WorkoutMenuTree workoutItem; WorkoutMenuTree? workoutItem;
final List<int> listFilterDevice = List(); final List<int> listFilterDevice = [];
String infoTitle = ""; String infoTitle = "";
String infoText = ""; String infoText = "";
@ -32,13 +32,13 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
String infoText3 = ""; String infoText3 = "";
String infoLink = ""; String infoLink = "";
int missingParent = 0; int missingParent = 0;
String missingTreeName = ""; String? missingTreeName = "";
BuildContext context; late BuildContext context;
ExerciseAbility ability; ExerciseAbility? ability;
MenuBloc({this.menuTreeRepository}) : super(MenuInitial()) { MenuBloc({required this.menuTreeRepository}) : super(MenuInitial()) {
parent = 0; parent = 0;
} }
@ -48,7 +48,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
exerciseRepository.getBaseExerciseFinishedPercent(); exerciseRepository.getBaseExerciseFinishedPercent();
percent = Cache().getPercentExercises(); percent = Cache().getPercentExercises();
} }
if (context == null) return;
percent = percent * 100; percent = percent * 100;
//log("Percent " + percent.toString()); //log("Percent " + percent.toString());
if (percent == -1 || percent == 0) { if (percent == -1 || percent == 0) {
@ -78,7 +78,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
//log("Missing " + missingTreeName); //log("Missing " + missingTreeName);
if (missingTreeName != null) { if (missingTreeName != null) {
if (percent > 0) { if (percent > 0) {
infoText = t("Please continue your tests with a") + " '" + missingTreeName + "' " + t("exercise!"); infoText = t("Please continue your tests with a") + " '" + missingTreeName! + "' " + t("exercise!");
infoLink = t("Bring me there"); infoLink = t("Bring me there");
} }
} }
@ -97,13 +97,13 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
yield MenuLoading(); yield MenuLoading();
//await menuTreeRepository.createTree(); //await menuTreeRepository.createTree();
//menuTreeRepository.getBranch(this.parent); //menuTreeRepository.getBranch(this.parent);
setMenuInfo(); //setMenuInfo();
exerciseDeviceRepository.setDevices(Cache().getDevices()); exerciseDeviceRepository.setDevices(Cache().getDevices()!);
yield MenuReady(); yield MenuReady();
} else if (event is MenuRecreateTree) { } else if (event is MenuRecreateTree) {
yield MenuLoading(); yield MenuLoading();
// ie. at language changes // ie. at language changes
await menuTreeRepository.createTree(); menuTreeRepository.createTree();
yield MenuReady(); yield MenuReady();
} else if (event is MenuTreeDown) { } else if (event is MenuTreeDown) {
yield MenuLoading(); yield MenuLoading();
@ -111,7 +111,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
workoutItem = event.item; workoutItem = event.item;
if (workoutItem != null) { if (workoutItem != null) {
setAbility(workoutItem.nameEnglish); setAbility(workoutItem!.nameEnglish);
} }
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent); final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent);
@ -126,8 +126,8 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
LinkedHashMap<String, WorkoutMenuTree> branch; LinkedHashMap<String, WorkoutMenuTree> branch;
if (workoutItem != null) { if (workoutItem != null) {
setAbility(workoutItem.nameEnglish); setAbility(workoutItem!.nameEnglish);
branch = menuTreeRepository.getBranch(workoutItem.parent); branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch); await getImages(branch);
} }
@ -138,12 +138,11 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
workoutItem = menuTreeRepository.getParentItem(parent); workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) { if (workoutItem != null) {
setAbility(workoutItem.nameEnglish); setAbility(workoutItem!.nameEnglish);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem.parent);
if (branch != null) {
await getImages(branch);
} }
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem!.parent);
await getImages(branch);
yield MenuReady(); yield MenuReady();
} else if (event is MenuClickExercise) { } else if (event is MenuClickExercise) {
yield MenuLoading(); yield MenuLoading();
@ -193,15 +192,15 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
Future<void> putBranchImageToHash(LinkedHashMap<String, WorkoutMenuTree> branch) async { Future<void> putBranchImageToHash(LinkedHashMap<String, WorkoutMenuTree> branch) async {
await Future.forEach(branch.keys, (key) async { await Future.forEach(branch.keys, (key) async {
final WorkoutMenuTree value = branch[key]; final WorkoutMenuTree? value = branch[key];
if (!value.imageName.contains("asset")) { if (value != null && !value.imageName.contains("asset")) {
await wt.ImageCache().putImageToList(value.id, value.imageName); await wt.ImageCache().putImageToList(value.id, value.imageName);
} }
}); });
} }
String getImage(int id, String name) { String? getImage(int id, String name) {
String imageString; String? imageString;
if (name.contains("http")) { if (name.contains("http")) {
imageString = wt.ImageCache().getImageString(id, name); imageString = wt.ImageCache().getImageString(id, name);
} }
@ -212,7 +211,7 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
return !listFilterDevice.contains(deviceId); return !listFilterDevice.contains(deviceId);
} }
LinkedHashMap<String, WorkoutMenuTree> getFilteredBranch(int parent) { LinkedHashMap<String, WorkoutMenuTree> getFilteredBranch(int? parent) {
if (parent == null) return LinkedHashMap(); if (parent == null) return LinkedHashMap();
LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(parent); LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(parent);
@ -224,8 +223,8 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
branch.forEach((key, value) { branch.forEach((key, value) {
final WorkoutMenuTree elem = value; final WorkoutMenuTree elem = value;
if (elem.exerciseType != null) { if (elem.exerciseType != null) {
for (int i = 0; i < elem.exerciseType.devices.length; i++) { for (int i = 0; i < elem.exerciseType!.devices.length; i++) {
if (listFilterDevice.contains(elem.exerciseType.devices[i])) { if (listFilterDevice.contains(elem.exerciseType!.devices[i])) {
filtered[elem.name] = elem; filtered[elem.name] = elem;
} }
} }

View File

@ -16,26 +16,26 @@ class MenuCreate extends MenuEvent {
} }
class MenuTreeDown extends MenuEvent { class MenuTreeDown extends MenuEvent {
final WorkoutMenuTree item; final WorkoutMenuTree? item;
final int parent; final int parent;
const MenuTreeDown({this.parent, this.item}); MenuTreeDown({required this.parent, this.item});
@override @override
List<Object> get props => [parent, item]; List<Object> get props => [parent];
} }
class MenuTreeUp extends MenuEvent { class MenuTreeUp extends MenuEvent {
final int parent; final int parent;
final WorkoutMenuTree item; final WorkoutMenuTree? item;
const MenuTreeUp({this.parent, this.item}); const MenuTreeUp({required this.parent, this.item});
@override @override
List<Object> get props => [parent, item]; List<Object> get props => [parent];
} }
class MenuTreeJump extends MenuEvent { class MenuTreeJump extends MenuEvent {
final int parent; final int parent;
const MenuTreeJump({this.parent}); const MenuTreeJump({required this.parent});
@override @override
List<Object> get props => [parent]; List<Object> get props => [parent];
@ -43,7 +43,7 @@ class MenuTreeJump extends MenuEvent {
class MenuClickExercise extends MenuEvent { class MenuClickExercise extends MenuEvent {
final int exerciseTypeId; final int exerciseTypeId;
const MenuClickExercise({this.exerciseTypeId}); const MenuClickExercise({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];
@ -55,5 +55,5 @@ class MenuRecreateTree extends MenuEvent {
class MenuFilterExerciseType extends MenuEvent { class MenuFilterExerciseType extends MenuEvent {
final int deviceId; final int deviceId;
const MenuFilterExerciseType({this.deviceId}); const MenuFilterExerciseType({required this.deviceId});
} }

View File

@ -1,7 +1,7 @@
part of 'menu_bloc.dart'; part of 'menu_bloc.dart';
@immutable @immutable
abstract class MenuState extends Equatable { abstract class MenuState extends Equatable {
const MenuState(); const MenuState();
@override @override
@ -12,22 +12,15 @@ class MenuInitial extends MenuState {
const MenuInitial(); const MenuInitial();
} }
class MenuLoading extends MenuState { class MenuLoading extends MenuState {}
}
class MenuReady extends MenuState { class MenuReady extends MenuState {
final WorkoutMenuTree workoutTree; const MenuReady();
const MenuReady({this.workoutTree});
@override
List<Object> get props => [workoutTree];
} }
class MenuError extends MenuState { class MenuError extends MenuState {
final String message; final String message;
const MenuError({this.message}); const MenuError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -0,0 +1,40 @@
import 'dart:async';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'password_reset_event.dart';
part 'password_reset_state.dart';
class PasswordResetBloc extends Bloc<PasswordResetEvent, PasswordResetState> {
final UserRepository userRepository;
PasswordResetBloc({required this.userRepository}) : super(PasswordResetInitial());
@override
Stream<PasswordResetState> mapEventToState(
PasswordResetEvent event,
) async* {
try {
if (event is PasswordResetEmailChange) {
yield PasswordResetLoading();
final String email = event.email;
userRepository.setEmail(email);
yield PasswordResetReady();
} else if (event is PasswordResetSubmit) {
yield PasswordResetLoading();
await userRepository.resetPassword();
yield PasswordResetReady();
}
} on Exception catch (e) {
yield PasswordResetError(message: e.toString());
}
}
String? emailValidation(String email) {
String? message = Common.emailValidation(email);
return message;
}
}

View File

@ -0,0 +1,24 @@
part of 'password_reset_bloc.dart';
abstract class PasswordResetEvent extends Equatable {
const PasswordResetEvent();
@override
List<Object> get props => [];
}
class PasswordResetEmailChange extends PasswordResetEvent {
final String email;
const PasswordResetEmailChange({required this.email});
@override
List<Object> get props => [email];
}
class PasswordResetLoad extends PasswordResetEvent {
const PasswordResetLoad();
}
class PasswordResetSubmit extends PasswordResetEvent {
const PasswordResetSubmit();
}

View File

@ -0,0 +1,28 @@
part of 'password_reset_bloc.dart';
abstract class PasswordResetState extends Equatable {
const PasswordResetState();
@override
List<Object> get props => [];
}
class PasswordResetInitial extends PasswordResetState {
const PasswordResetInitial();
}
class PasswordResetLoading extends PasswordResetState {
const PasswordResetLoading();
}
class PasswordResetError extends PasswordResetState {
final String message;
const PasswordResetError({required this.message});
@override
List<Object> get props => [message];
}
class PasswordResetReady extends PasswordResetState {
const PasswordResetReady();
}

View File

@ -1,47 +0,0 @@
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
class ResetPasswordFormBloc extends FormBloc<String, String> with Common {
final UserRepository userRepository;
bool loading = false;
final emailField = TextFieldBloc(
validators: [
FieldBlocValidators.required,
],
);
ResetPasswordFormBloc({this.userRepository}) {
addFieldBlocs(fieldBlocs: [emailField]);
emailField.onValueChanges(onData: (previous, current) async* {
userRepository.setEmail(current.value);
});
}
@override
void onSubmitting() async {
try {
emitLoading(progress: 30);
loading = true;
if (!validateEmail(userRepository)) {
emailField.addFieldError(EMAIL_ERROR, isPermanent: true);
emitFailure(failureResponse: EMAIL_ERROR);
} else {
// Emit either Loaded or Error
await userRepository.resetPassword();
emitSuccess(canSubmitAgain: false);
}
loading = false;
} on Exception catch (ex) {
emitFailure(failureResponse: ex.toString());
}
}
Future<void> close() {
emailField.close();
return super.close();
}
}

View File

@ -8,7 +8,7 @@ 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';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_form_bloc/flutter_form_bloc.dart';
//import 'package:health/health.dart'; //import 'package:health/health.dart';
part 'result_event.dart'; part 'result_event.dart';
@ -18,9 +18,9 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
final ExerciseResultRepository resultRepository; final ExerciseResultRepository resultRepository;
final ExerciseRepository exerciseRepository; final ExerciseRepository exerciseRepository;
final BuildContext context; final BuildContext context;
//List<HealthDataPoint> _healthDataList = List(); //List<HealthDataPoint> _healthDataList = [];
DateTime startTime; DateTime? startTime;
DateTime endTime; DateTime? endTime;
/* final HealthFactory health = HealthFactory(); /* final HealthFactory health = HealthFactory();
final List<HealthDataType> types = [ final List<HealthDataType> types = [
HealthDataType.ACTIVE_ENERGY_BURNED, HealthDataType.ACTIVE_ENERGY_BURNED,
@ -34,12 +34,12 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
HealthDataType.RESTING_HEART_RATE HealthDataType.RESTING_HEART_RATE
]; */ ]; */
ResultBloc({this.resultRepository, this.exerciseRepository, this.context}) : super(ResultInitial()) { ResultBloc({required this.resultRepository, required this.exerciseRepository, required this.context}) : super(ResultInitial()) {
this.startTime = exerciseRepository.start; this.startTime = exerciseRepository.start;
this.endTime = exerciseRepository.end; this.endTime = exerciseRepository.end;
if (this.startTime == null) { if (this.startTime == null) {
this.startTime = exerciseRepository.exercise.dateAdd; this.startTime = exerciseRepository.exercise!.dateAdd!;
exerciseRepository.start = exerciseRepository.exercise.dateAdd; exerciseRepository.start = exerciseRepository.exercise!.dateAdd!;
} }
} }
@ -65,7 +65,7 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
resultRepository.getResults().forEach((element) { resultRepository.getResults().forEach((element) {
element.dateFrom = startTime; element.dateFrom = startTime;
element.dateTo = endTime; element.dateTo = endTime;
element.exerciseId = exerciseRepository.actualExerciseList[0].exerciseId; element.exerciseId = exerciseRepository.actualExerciseList![0].exerciseId;
switch (element.item) { switch (element.item) {
case ResultItem.bpm_avg: case ResultItem.bpm_avg:
//element.data = _gethHealthDataPointValueAvg(HealthDataType.HEART_RATE); //element.data = _gethHealthDataPointValueAvg(HealthDataType.HEART_RATE);
@ -80,11 +80,10 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
//element.data = _gethHealthDataPointValueSum(HealthDataType.ACTIVE_ENERGY_BURNED); //element.data = _gethHealthDataPointValueSum(HealthDataType.ACTIVE_ENERGY_BURNED);
break; break;
case ResultItem.development_percent_bodypart: case ResultItem.development_percent_bodypart:
// TODO: Handle this case.
break; break;
case ResultItem.distance: case ResultItem.distance:
if (exerciseRepository.exerciseType.unit == "meter") { if (exerciseRepository.exerciseType!.unit == "meter") {
element.data = exerciseRepository.exercise.quantity; element.data = exerciseRepository.exercise!.quantity!;
} }
break; break;
case ResultItem.fatburn_percent: case ResultItem.fatburn_percent:
@ -109,13 +108,12 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
} */ } */
break; break;
case ResultItem.speed_max: case ResultItem.speed_max:
// TODO: Handle this case.
break; break;
case ResultItem.reps_volume: case ResultItem.reps_volume:
if (exerciseRepository.exerciseType.unit == "repeat") { if (exerciseRepository.exerciseType!.unit == "repeat") {
double value = 0; double value = 0;
exerciseRepository.actualExerciseList.forEach((actual) { exerciseRepository.actualExerciseList!.forEach((actual) {
value += actual.quantity; value += actual.quantity!;
}); });
element.data = value; element.data = value;
} }
@ -128,10 +126,10 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
element.data = _printDuration(duration); element.data = _printDuration(duration);
break; */ break; */
case ResultItem.weight_volume: case ResultItem.weight_volume:
if (exerciseRepository.exerciseType.unitQuantityUnit == "kilogram") { if (exerciseRepository.exerciseType!.unitQuantityUnit == "kilogram") {
double value = 0; double value = 0;
exerciseRepository.actualExerciseList.forEach((actual) { exerciseRepository.actualExerciseList!.forEach((actual) {
value += actual.quantity * actual.unitQuantity; value += actual.quantity! * actual.unitQuantity!;
}); });
element.data = value; element.data = value;
} }
@ -233,12 +231,12 @@ class ResultBloc extends Bloc<ResultEvent, ResultState> with Logging, Trans {
} }
} */ } */
double calculate1RM({double percent}) { double calculate1RM({double percent = 0.75}) {
if (exerciseRepository.exercise == null) { if (exerciseRepository.exercise == null) {
exerciseRepository.getLastExercise(); exerciseRepository.getLastExercise();
} }
double weight = exerciseRepository.exercise.unitQuantity; double weight = exerciseRepository.exercise!.unitQuantity!;
double repeat = exerciseRepository.exercise.quantity; double repeat = exerciseRepository.exercise!.quantity!;
if (weight == 0 || repeat == 0) { if (weight == 0 || repeat == 0) {
return 0; return 0;
} }

View File

@ -21,7 +21,7 @@ class ResultReady extends ResultState {
class ResultError extends ResultState { class ResultError extends ResultState {
final String error; final String error;
const ResultError({this.error}); const ResultError({required this.error});
@override @override
List<Object> get props => [this.error]; List<Object> get props => [this.error];

View File

@ -8,21 +8,19 @@ import 'package:aitrainer_app/model/product_test.dart';
import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/model/purchase.dart';
import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/service/purchase_service.dart'; import 'package:aitrainer_app/service/purchase_service.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/purchases.dart'; import 'package:aitrainer_app/util/purchases.dart';
import 'package:aitrainer_app/util/track.dart'; import 'package:aitrainer_app/util/track.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flurry/flurry.dart';
import 'package:purchases_flutter/offering_wrapper.dart'; import 'package:purchases_flutter/offering_wrapper.dart';
part 'sales_event.dart'; part 'sales_event.dart';
part 'sales_state.dart'; part 'sales_state.dart';
class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging { class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
List<ProductTest> tests = List(); List<ProductTest>? tests = [];
List<Product> product2Display = List(); List<Product> product2Display = [];
int productSet = -1; int productSet = -1;
SalesBloc() : super(SalesInitial()); SalesBloc() : super(SalesInitial());
@ -35,7 +33,6 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
yield SalesLoading(); yield SalesLoading();
log("Load Sales"); log("Load Sales");
Track().track(TrackingEvent.sales_page); Track().track(TrackingEvent.sales_page);
//await PlatformPurchaseApi().initPurchasePlatform();
await RevenueCatPurchases().getOfferings(); await RevenueCatPurchases().getOfferings();
this.getProductSet(); this.getProductSet();
yield SalesReady(); yield SalesReady();
@ -47,27 +44,30 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
final int productId = event.productId; final int productId = event.productId;
log("Requesting purchase for: " + productId.toString()); log("Requesting purchase for: " + productId.toString());
Track().track(TrackingEvent.purchase_request); Track().track(TrackingEvent.purchase_request);
final Product selectedProduct = this.getSelectedProduct(productId); final Product? selectedProduct = this.getSelectedProduct(productId);
log("SelectedProduct for purchase " + selectedProduct.toString()); log("SelectedProduct for purchase $selectedProduct");
await RevenueCatPurchases().makePurchase(selectedProduct); if (selectedProduct != null) {
if (Cache().hasPurchased) { await RevenueCatPurchases().makePurchase(selectedProduct);
Purchase purchase = Purchase(customerId: Cache().userLoggedIn.customerId, productId: productId); if (Cache().hasPurchased) {
purchase.dateAdd = DateTime.now(); Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
purchase.purchaseSum = 0; purchase.dateAdd = DateTime.now();
purchase.currency = "EUR"; purchase.purchaseSum = 0;
await PurchaseApi().savePurchase(purchase); purchase.currency = "EUR";
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString()); await PurchaseApi().savePurchase(purchase);
Common.sendMessage("Purchase: " + purchase.toJson().toString()); Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
}
yield SalesSuccessful();
} else {
yield SalesError(message: "No selected product");
} }
yield SalesSuccessful();
} }
} on Exception catch (ex) { } on Exception catch (ex) {
yield SalesError(message: ex.toString()); yield SalesError(message: ex.toString());
} }
} }
Product getSelectedProduct(int productId) { Product? getSelectedProduct(int productId) {
Product prod; Product? prod;
for (var product in this.product2Display) { for (var product in this.product2Display) {
if (product.productId == productId) { if (product.productId == productId) {
prod = product; prod = product;
@ -78,7 +78,7 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
String getLocalizedPrice(String productId) { String getLocalizedPrice(String productId) {
String price = ""; String price = "";
Offering offering = RevenueCatPurchases().offering; Offering? offering = RevenueCatPurchases().offering;
if (offering != null) { if (offering != null) {
for (var package in offering.availablePackages) { for (var package in offering.availablePackages) {
log("PlatformProduct " + package.toString()); log("PlatformProduct " + package.toString());
@ -100,15 +100,19 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
void getProductSet() { void getProductSet() {
int productId = 0; int productId = 0;
this.tests = Cache().productTests; this.tests = Cache().productTests;
List<Product>? products = Cache().products;
if (products == null) {
return;
}
if (tests.isEmpty) { if (tests != null && tests!.isEmpty) {
var rand = math.Random.secure(); var rand = math.Random.secure();
productSet = rand.nextInt(5) + 1; productSet = rand.nextInt(5) + 1;
} else { } else {
trace("Previous ProductTest: " + tests[0].toJson().toString()); trace("Previous ProductTest: " + tests![0].toJson().toString());
productId = tests[0].productId; productId = tests![0].productId;
for (var elem in Cache().products) { for (var elem in products) {
final Product product = elem as Product; final Product product = elem;
if (product.productId == productId) { if (product.productId == productId) {
productSet = product.productSet; productSet = product.productSet;
break; break;
@ -120,12 +124,12 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
productSet = 2; productSet = 2;
log("ProductSet: " + productSet.toString()); log("ProductSet: " + productSet.toString());
for (var elem in Cache().products) { for (var elem in products) {
Product product = elem as Product; Product product = elem;
if (product.productSet == productSet) { if (product.productSet == productSet) {
productId = product.productId; productId = product.productId;
final String platformProductId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos; final String platformProductId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
product.localizedPrice = getLocalizedPrice(platformProductId); product.localizedPrice = getLocalizedPrice(platformProductId);
product2Display.add(product); product2Display.add(product);
} }
@ -136,7 +140,7 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
}); });
productTest.productId = productId; productTest.productId = productId;
productTest.customerId = Cache().userLoggedIn.customerId; productTest.customerId = Cache().userLoggedIn!.customerId!;
productTest.dateView = DateTime.now(); productTest.dateView = DateTime.now();
//ProductTestApi().saveProductTest(productTest); //ProductTestApi().saveProductTest(productTest);
//Cache().productTests.add(productTest); //Cache().productTests.add(productTest);

View File

@ -13,5 +13,5 @@ class SalesLoad extends SalesEvent {
class SalesPurchase extends SalesEvent { class SalesPurchase extends SalesEvent {
final int productId; final int productId;
const SalesPurchase({this.productId}); const SalesPurchase({required this.productId});
} }

View File

@ -25,7 +25,7 @@ class SalesSuccessful extends SalesState {
class SalesError extends SalesState { class SalesError extends SalesState {
final String message; final String message;
const SalesError({this.message}); const SalesError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -13,7 +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;
SessionBloc({this.session}) : super(SessionInitial()); SessionBloc({required this.session}) : super(SessionInitial());
@override @override
Stream<SessionState> mapEventToState( Stream<SessionState> mapEventToState(

View File

@ -9,7 +9,7 @@ abstract class SessionEvent extends Equatable {
class SessionStart extends SessionEvent { class SessionStart extends SessionEvent {
final SettingsBloc settingsBloc; final SettingsBloc settingsBloc;
const SessionStart({this.settingsBloc}); const SessionStart({required this.settingsBloc});
@override @override
List<Object> get props => [settingsBloc]; List<Object> get props => [settingsBloc];

View File

@ -21,7 +21,7 @@ class SessionReady extends SessionState {
class SessionFailure extends SessionState { class SessionFailure extends SessionState {
final String message; final String message;
const SessionFailure({this.message}); const SessionFailure({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -16,9 +16,9 @@ part 'settings_event.dart';
part 'settings_state.dart'; part 'settings_state.dart';
class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging { class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
String language; String? language;
Locale _locale; Locale? _locale;
BuildContext context; BuildContext? context;
SettingsBloc({this.context}) : super(SettingsInitial()); SettingsBloc({this.context}) : super(SettingsInitial());
@ -26,7 +26,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
_locale = locale; _locale = locale;
} }
Locale getLocale() { Locale? getLocale() {
return _locale; return _locale;
} }
@ -37,11 +37,11 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
if (event is SettingsChangeLanguage) { if (event is SettingsChangeLanguage) {
yield SettingsLoading(); yield SettingsLoading();
await _changeLang(event.language); await _changeLang(event.language);
yield SettingsReady(_locale); yield SettingsReady();
} else if (event is SettingsGetLanguage) { } else if (event is SettingsGetLanguage) {
await AppLanguage().fetchLocale(); await AppLanguage().fetchLocale();
_locale = AppLanguage().appLocal; _locale = AppLanguage().appLocal;
yield SettingsReady(_locale); yield SettingsReady();
} else if (event is SettingsSetServer) { } else if (event is SettingsSetServer) {
//yield SettingsLoading(); //yield SettingsLoading();
final bool live = event.live; final bool live = event.live;
@ -60,7 +60,7 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
await _accessHealthData(); await _accessHealthData();
} }
Cache().initBadges(); Cache().initBadges();
yield SettingsReady(_locale); yield SettingsReady();
} }
} }
@ -97,17 +97,17 @@ class SettingsBloc extends Bloc<SettingsEvent, SettingsState> with Logging {
break; break;
} }
this.language = lang; this.language = lang;
AppLanguage().changeLanguage(_locale); AppLanguage().changeLanguage(_locale!);
await loadLang(); await loadLang();
await Cache().initBadges(); Cache().initBadges();
} }
Future<void> loadLang() async { Future<void> loadLang() async {
if (_locale != null) { if (_locale != null) {
log(" -- Loading lang $_locale"); log(" -- Loading lang $_locale");
if (context != null) { if (context != null) {
AppLocalizations.of(context).setLocale(_locale); AppLocalizations.of(context!)!.setLocale(_locale!);
await AppLocalizations.of(context).load(); await AppLocalizations.of(context!)!.load();
} else { } else {
log("no context, does not load"); log("no context, does not load");
} }

View File

@ -9,7 +9,7 @@ abstract class SettingsEvent extends Equatable {
class SettingsChangeLanguage extends SettingsEvent { class SettingsChangeLanguage extends SettingsEvent {
final String language; final String language;
const SettingsChangeLanguage({this.language}); const SettingsChangeLanguage({required this.language});
} }
class SettingsGetLanguage extends SettingsEvent { class SettingsGetLanguage extends SettingsEvent {
@ -18,7 +18,7 @@ class SettingsGetLanguage extends SettingsEvent {
class SettingsSetServer extends SettingsEvent { class SettingsSetServer extends SettingsEvent {
final bool live; final bool live;
const SettingsSetServer({this.live}); const SettingsSetServer({required this.live});
@override @override
List<Object> get props => [this.live]; List<Object> get props => [this.live];
@ -26,7 +26,7 @@ class SettingsSetServer extends SettingsEvent {
class SettingsSetHardware extends SettingsEvent { class SettingsSetHardware extends SettingsEvent {
final bool hasHardware; final bool hasHardware;
const SettingsSetHardware({this.hasHardware}); const SettingsSetHardware({required this.hasHardware});
@override @override
List<Object> get props => [this.hasHardware]; List<Object> get props => [this.hasHardware];

View File

@ -10,31 +10,15 @@ abstract class SettingsState extends Equatable {
// ignore: must_be_immutable // ignore: must_be_immutable
class SettingsInitial extends SettingsState { class SettingsInitial extends SettingsState {
Locale locale;
SettingsInitial(); SettingsInitial();
setLocale(locale) {
this.locale = locale;
}
@override
List<Object> get props => [locale];
} }
class SettingsLoading extends SettingsState { class SettingsLoading extends SettingsState {
final Locale locale; const SettingsLoading();
const SettingsLoading({this.locale});
@override
List<Object> get props => [locale];
} }
class SettingsReady extends SettingsState { class SettingsReady extends SettingsState {
final Locale locale; const SettingsReady();
const SettingsReady(this.locale);
@override
List<Object> get props => [locale];
} }
class SettingsError extends SettingsState { class SettingsError extends SettingsState {
@ -43,4 +27,4 @@ class SettingsError extends SettingsState {
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }

View File

@ -17,30 +17,31 @@ class TestSetControlBloc extends Bloc<TestSetControlEvent, TestSetControlState>
final TestSetExecuteBloc executeBloc; final TestSetExecuteBloc executeBloc;
final ExerciseType exerciseType; final ExerciseType exerciseType;
final ExerciseRepository exerciseRepository = ExerciseRepository(); final ExerciseRepository exerciseRepository = ExerciseRepository();
TestSetControlBloc({this.exercisePlanDetail, this.executeBloc, this.exerciseType}) : super(TestSetControlInitial()) {
late double initQuantity;
late double initUnitQuantity;
late double quantity;
late double unitQuantity;
late double oneRepMax;
late int step;
TestSetControlBloc({required this.exercisePlanDetail, required this.executeBloc, required this.exerciseType})
: super(TestSetControlInitial()) {
initBloc(); initBloc();
} }
void initBloc() { void initBloc() {
if (exercisePlanDetail.exerciseType.unitQuantity != null) { oneRepMax = executeBloc.calculate1RM(exercisePlanDetail.exercises!.last.unitQuantity, exercisePlanDetail.exercises!.last.quantity);
oneRepMax = executeBloc.calculate1RM(exercisePlanDetail.exercises.last.unitQuantity, exercisePlanDetail.exercises.last.quantity); initQuantity = 12;
initQuantity = 12; quantity = initQuantity;
quantity = initQuantity; initUnitQuantity = oneRepMax * 0.75;
initUnitQuantity = oneRepMax * 0.75; unitQuantity = initUnitQuantity;
unitQuantity = initUnitQuantity;
} step = exercisePlanDetail.exercises!.length;
step = exercisePlanDetail.exercises.length;
exerciseRepository.customer = Cache().userLoggedIn; exerciseRepository.customer = Cache().userLoggedIn;
exerciseRepository.exerciseType = exerciseType; exerciseRepository.exerciseType = exerciseType;
} }
double initQuantity;
double initUnitQuantity;
double quantity;
double unitQuantity;
double oneRepMax;
int step;
@override @override
Stream<TestSetControlState> mapEventToState( Stream<TestSetControlState> mapEventToState(
TestSetControlEvent event, TestSetControlEvent event,

View File

@ -13,7 +13,7 @@ class TestSetControlLoad extends TestSetControlEvent {
class TestSetControlQuantityChange extends TestSetControlEvent { class TestSetControlQuantityChange extends TestSetControlEvent {
final double quantity; final double quantity;
const TestSetControlQuantityChange({this.quantity}); const TestSetControlQuantityChange({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -21,7 +21,7 @@ class TestSetControlQuantityChange extends TestSetControlEvent {
class TestSetControlUnitQuantityChange extends TestSetControlEvent { class TestSetControlUnitQuantityChange extends TestSetControlEvent {
final double quantity; final double quantity;
const TestSetControlUnitQuantityChange({this.quantity}); const TestSetControlUnitQuantityChange({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];

View File

@ -21,7 +21,7 @@ class TestSetControlReady extends TestSetControlState {
class TestSetControlError extends TestSetControlState { class TestSetControlError extends TestSetControlState {
final String message; final String message;
const TestSetControlError({this.message}); const TestSetControlError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -21,14 +21,15 @@ part 'test_set_edit_state.dart';
class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> { class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
final String templateName; final String templateName;
final String templateNameTranslation; final String templateNameTranslation;
String templateDescription; late String templateDescription;
final WorkoutTreeRepository workoutTreeRepository; final WorkoutTreeRepository workoutTreeRepository;
final MenuBloc menuBloc; final MenuBloc menuBloc;
final List<ExerciseType> _exerciseTypes = List(); final List<ExerciseType> _exerciseTypes = [];
final List<ExerciseType> _actualExerciseTypes = List(); final List<ExerciseType> _actualExerciseTypes = [];
final HashMap<int, ExerciseType> _exercisePlanDetails = HashMap(); final HashMap<int, ExerciseType?> _exercisePlanDetails = HashMap();
TestSetEditBloc({this.templateName, this.templateNameTranslation, this.workoutTreeRepository, this.menuBloc}) TestSetEditBloc(
{required this.templateName, required this.templateNameTranslation, required this.workoutTreeRepository, required this.menuBloc})
: super(TestSetEditInitial()) { : super(TestSetEditInitial()) {
if (Cache().exercisePlanTemplates.isNotEmpty) { if (Cache().exercisePlanTemplates.isNotEmpty) {
Cache().exercisePlanTemplates.forEach((element) { Cache().exercisePlanTemplates.forEach((element) {
@ -36,10 +37,12 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
if (template.name == templateName) { if (template.name == templateName) {
templateDescription = template.descriptionTranslation; templateDescription = template.descriptionTranslation;
template.exerciseTypes.forEach((id) { template.exerciseTypes.forEach((id) {
final ExerciseType exerciseType = Cache().getExerciseTypeById(id); final ExerciseType? exerciseType = Cache().getExerciseTypeById(id);
_exerciseTypes.add(exerciseType); if (exerciseType != null) {
_actualExerciseTypes.add(exerciseType); _exerciseTypes.add(exerciseType);
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType; _actualExerciseTypes.add(exerciseType);
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
}
}); });
} }
}); });
@ -52,17 +55,18 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
if (event is TestSetEditChangeExerciseType) { if (event is TestSetEditChangeExerciseType) {
yield TestSetEditLoading(); yield TestSetEditLoading();
final List<ExerciseType> alternatives = workoutTreeRepository.getExerciseTypeAlternatives(event.exerciseTypeId); final List<ExerciseType> alternatives = workoutTreeRepository.getExerciseTypeAlternatives(event.exerciseTypeId);
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId); final ExerciseType? exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId);
if (exerciseType != null) {
if (_exercisePlanDetails[event.exerciseTypeId] == null) { if (_exercisePlanDetails[event.exerciseTypeId] == null) {
/// it was skipped /// it was skipped
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
} else {
if (event.index == 0) {
_exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType; _exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
} else { } else {
final changedExerciseType = alternatives[event.index - 1]; if (event.index == 0) {
_exercisePlanDetails[exerciseType.exerciseTypeId] = changedExerciseType; _exercisePlanDetails[exerciseType.exerciseTypeId] = exerciseType;
} else {
final changedExerciseType = alternatives[event.index - 1];
_exercisePlanDetails[exerciseType.exerciseTypeId] = changedExerciseType;
}
} }
} }
@ -71,28 +75,30 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
yield TestSetEditReady(); yield TestSetEditReady();
} else if (event is TestSetEditDeleteExerciseType) { } else if (event is TestSetEditDeleteExerciseType) {
yield TestSetEditLoading(); yield TestSetEditLoading();
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId); final ExerciseType? exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId);
_exercisePlanDetails[exerciseType.exerciseTypeId] = null; if (exerciseType != null) {
_exercisePlanDetails[exerciseType.exerciseTypeId] = null;
}
refreshActualPlan(); refreshActualPlan();
yield TestSetEditReady(); yield TestSetEditReady();
} else if (event is TestSetEditSubmit) { } else if (event is TestSetEditSubmit) {
yield TestSetEditLoading(); yield TestSetEditLoading();
ExercisePlan exercisePlan = ExercisePlan(templateNameTranslation, Cache().userLoggedIn.customerId); ExercisePlan exercisePlan = ExercisePlan(templateNameTranslation, Cache().userLoggedIn!.customerId!);
exercisePlan.private = true; exercisePlan.private = true;
exercisePlan.type = ExerciseAbility.mini_test_set.enumToString(); exercisePlan.type = ExerciseAbility.mini_test_set.enumToString();
exercisePlan.dateAdd = DateTime.now(); exercisePlan.dateAdd = DateTime.now();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan); ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan);
List<ExercisePlanDetail> details = List(); List<ExercisePlanDetail> details = [];
for (var entry in _exercisePlanDetails.entries) { for (var entry in _exercisePlanDetails.entries) {
if (entry.value != null) { if (entry.value != null) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(entry.value.exerciseTypeId); ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(entry.value!.exerciseTypeId);
exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId; exercisePlanDetail.exercisePlanId = savedExercisePlan.exercisePlanId!;
exercisePlanDetail.serie = 1; exercisePlanDetail.serie = 1;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail); ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId; exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.exercises = List(); exercisePlanDetail.exercises = [];
details.add(exercisePlanDetail); details.add(exercisePlanDetail);
} }
} }
@ -112,8 +118,10 @@ class TestSetEditBloc extends Bloc<TestSetEditEvent, TestSetEditState> {
void refreshActualPlan() { void refreshActualPlan() {
_actualExerciseTypes.removeRange(0, _actualExerciseTypes.length - 1); _actualExerciseTypes.removeRange(0, _actualExerciseTypes.length - 1);
_exercisePlanDetails.keys.forEach((element) { _exercisePlanDetails.keys.forEach((element) {
final ExerciseType exerciseType = Cache().getExerciseTypeById(element); final ExerciseType? exerciseType = Cache().getExerciseTypeById(element);
_actualExerciseTypes.add(exerciseType); if (exerciseType != null) {
_actualExerciseTypes.add(exerciseType);
}
}); });
} }
} }

View File

@ -14,7 +14,7 @@ class TestSetEditLoad extends TestSetEditEvent {
class TestSetEditChangeExerciseType extends TestSetEditEvent { class TestSetEditChangeExerciseType extends TestSetEditEvent {
final int index; final int index;
final int exerciseTypeId; final int exerciseTypeId;
const TestSetEditChangeExerciseType({this.index, this.exerciseTypeId}); const TestSetEditChangeExerciseType({required this.index, required this.exerciseTypeId});
@override @override
List<Object> get props => [index, exerciseTypeId]; List<Object> get props => [index, exerciseTypeId];
@ -22,7 +22,7 @@ class TestSetEditChangeExerciseType extends TestSetEditEvent {
class TestSetEditDeleteExerciseType extends TestSetEditEvent { class TestSetEditDeleteExerciseType extends TestSetEditEvent {
final int exerciseTypeId; final int exerciseTypeId;
const TestSetEditDeleteExerciseType({this.exerciseTypeId}); const TestSetEditDeleteExerciseType({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];
@ -30,7 +30,7 @@ class TestSetEditDeleteExerciseType extends TestSetEditEvent {
class TestSetEditSkipExerciseType extends TestSetEditEvent { class TestSetEditSkipExerciseType extends TestSetEditEvent {
final int exerciseTypeId; final int exerciseTypeId;
const TestSetEditSkipExerciseType({this.exerciseTypeId}); const TestSetEditSkipExerciseType({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];

View File

@ -25,7 +25,7 @@ class TestSetEditLoading extends TestSetEditState {
class TestSetEditError extends TestSetEditState { class TestSetEditError extends TestSetEditState {
final String message; final String message;
const TestSetEditError({this.message}); const TestSetEditError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -18,17 +18,17 @@ part 'test_set_execute_state.dart';
class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState> { class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState> {
// ignore: close_sinks // ignore: close_sinks
MenuBloc menuBloc; late MenuBloc menuBloc;
int exerciseTypeId; int? exerciseTypeId;
String testName; String? testName;
String testType = ""; String testType = "";
bool miniTestSet = false; bool miniTestSet = false;
bool paralellTest = false; bool paralellTest = false;
double scrollOffset = 0; double scrollOffset = 0;
ExercisePlan exercisePlan; ExercisePlan? exercisePlan;
bool isDone100 = false; bool isDone100 = false;
List<ExercisePlanDetail> exercisePlanDetails; List<ExercisePlanDetail>? exercisePlanDetails;
TestSetExecuteBloc() : super(TestSetExecuteInitial()); TestSetExecuteBloc() : super(TestSetExecuteInitial());
@ -37,19 +37,19 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
void initExercisePlan() { void initExercisePlan() {
exercisePlan = Cache().activeExercisePlan; exercisePlan = Cache().activeExercisePlan;
if (exercisePlan != null) { if (exercisePlan != null) {
testName = exercisePlan.name; testName = exercisePlan!.name;
this.miniTestSet = exercisePlan.type != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan.type); this.miniTestSet = exercisePlan!.type != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!);
this.paralellTest = exercisePlan.type != null && ExerciseAbility.paralell_test.equalsStringTo(exercisePlan.type); this.paralellTest = exercisePlan!.type != null && ExerciseAbility.paralell_test.equalsStringTo(exercisePlan!.type!);
testType = ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan.type) testType = ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!)
? ExerciseAbility.mini_test_set.description ? ExerciseAbility.mini_test_set.description
: ExerciseAbility.paralell_test.description; : ExerciseAbility.paralell_test.description;
print("exercisePlan: $testName type: $testType"); print("exercisePlan: $testName type: $testType");
} }
exercisePlanDetails = Cache().activeExercisePlanDetails; exercisePlanDetails = Cache().activeExercisePlanDetails;
if (exercisePlanDetails != null) { if (exercisePlanDetails != null) {
exercisePlanDetails.forEach((element) { exercisePlanDetails!.forEach((element) {
final ExerciseType exerciseType = Cache().getExerciseTypeById(element.exerciseTypeId); final ExerciseType? exerciseType = Cache().getExerciseTypeById(element.exerciseTypeId);
if (exerciseType != null) { if (exerciseType != null) {
element.exerciseType = exerciseType; element.exerciseType = exerciseType;
} }
@ -69,7 +69,7 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
if (exerciseTypeId != null) { if (exerciseTypeId != null) {
int step = 0; int step = 0;
if (exercisePlanDetails != null) { if (exercisePlanDetails != null) {
exercisePlanDetails.forEach((element) { exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == this.exerciseTypeId) { if (element.exerciseTypeId == this.exerciseTypeId) {
scrollOffset = (step * 85).toDouble() + 10; scrollOffset = (step * 85).toDouble() + 10;
} }
@ -79,44 +79,44 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
} }
yield TestSetExecuteReady(); yield TestSetExecuteReady();
} else if (event is TestSetExecuteDeleteActive) { } else if (event is TestSetExecuteDeleteActive) {
print("Delete: ${exercisePlan.type} paralellTest: $paralellTest"); print("Delete: ${exercisePlan!.type} paralellTest: $paralellTest");
if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan.type)) { if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!)) {
exercisePlan = null; exercisePlan = null;
if (exercisePlanDetails != null) { if (exercisePlanDetails != null) {
exercisePlanDetails.removeRange(0, exercisePlanDetails.length - 1); exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
} }
await Cache().deleteActiveExercisePlan(); await Cache().deleteActiveExercisePlan();
} }
} else if (event is TestSetExecuteDeleteAllActive) { } else if (event is TestSetExecuteDeleteAllActive) {
print("DeleteAll Test Set: ${exercisePlan.type}");
if (exercisePlan != null) { if (exercisePlan != null) {
print("DeleteAll Test Set: ${exercisePlan!.type}");
exercisePlan = null; exercisePlan = null;
if (exercisePlanDetails != null) { if (exercisePlanDetails != null) {
exercisePlanDetails.removeRange(0, exercisePlanDetails.length - 1); exercisePlanDetails!.removeRange(0, exercisePlanDetails!.length - 1);
} }
await Cache().deleteActiveExercisePlan(); await Cache().deleteActiveExercisePlan();
} }
} else if (event is TestSetExecuteExerciseFinished) { } else if (event is TestSetExecuteExerciseFinished) {
yield TestSetExecuteLoading(); yield TestSetExecuteLoading();
exercisePlanDetails.forEach((element) { exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == event.exerciseTypeId) { if (element.exerciseTypeId == event.exerciseTypeId) {
element.repeats = event.quantity.toInt(); element.repeats = event.quantity.toInt();
element.weightEquation = event.unitQuantity.toString(); element.weightEquation = event.unitQuantity.toString();
if (element.exercises == null) { if (element.exercises == null) {
element.exercises = List(); element.exercises = [];
} }
final Exercise exercise = Exercise(); final Exercise exercise = Exercise();
exercise.customerId = Cache().userLoggedIn.customerId; exercise.customerId = Cache().userLoggedIn!.customerId!;
exercise.exerciseTypeId = event.exerciseTypeId; exercise.exerciseTypeId = event.exerciseTypeId;
exercise.quantity = event.quantity; exercise.quantity = event.quantity;
exercise.unit = element.exerciseType.unit; exercise.unit = element.exerciseType!.unit;
exercise.unitQuantity = event.unitQuantity; exercise.unitQuantity = event.unitQuantity;
exercise.dateAdd = DateTime.now(); exercise.dateAdd = DateTime.now();
element.exercises.add(exercise); element.exercises!.add(exercise);
setPlanDetailState(element); setPlanDetailState(element);
} }
}); });
Cache().saveActiveExercisePlan(exercisePlan, exercisePlanDetails); Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
if (this.isDone100Percent()) { if (this.isDone100Percent()) {
add(TestSetExecuteFinish()); add(TestSetExecuteFinish());
} else { } else {
@ -125,45 +125,51 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
} else if (event is TestSetExecuteNewExercise) { } else if (event is TestSetExecuteNewExercise) {
yield TestSetExecuteLoading(); yield TestSetExecuteLoading();
if (exercisePlan == null) { if (exercisePlan == null) {
exercisePlan = ExercisePlan(Cache().userLoggedIn.name + " Custom Test", Cache().userLoggedIn.customerId); exercisePlan = ExercisePlan(Cache().userLoggedIn!.name! + " Custom Test", Cache().userLoggedIn!.customerId!);
exercisePlan.private = true; exercisePlan!.private = true;
exercisePlan.dateAdd = DateTime.now(); exercisePlan!.dateAdd = DateTime.now();
exercisePlan.type = ExerciseAbility.paralell_test.enumToString(); exercisePlan!.type = ExerciseAbility.paralell_test.enumToString();
ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan); ExercisePlan savedExercisePlan = await ExercisePlanApi().saveExercisePlan(exercisePlan!);
exercisePlan = savedExercisePlan; exercisePlan = savedExercisePlan;
exercisePlanDetails = List(); exercisePlanDetails = [];
} }
if (!this.existsInPlanDetails(event.exerciseTypeId)) { if (!this.existsInPlanDetails(event.exerciseTypeId)) {
ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(event.exerciseTypeId); ExercisePlanDetail exercisePlanDetail = ExercisePlanDetail(event.exerciseTypeId);
exercisePlanDetail.exercisePlanId = exercisePlan.exercisePlanId; exercisePlanDetail.exercisePlanId = exercisePlan!.exercisePlanId!;
final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId); final ExerciseType exerciseType = Cache().getExerciseTypeById(event.exerciseTypeId)!;
exercisePlanDetail.serie = exerciseType.unitQuantityUnit == null ? 1 : 4; exercisePlanDetail.serie = exerciseType.unitQuantityUnit == null ? 1 : 4;
exercisePlanDetail.exerciseType = exerciseType; exercisePlanDetail.exerciseType = exerciseType;
exercisePlanDetail.exerciseTypeId = event.exerciseTypeId; exercisePlanDetail.exerciseTypeId = event.exerciseTypeId;
ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail); ExercisePlanDetail savedDetail = await ExercisePlanApi().saveExercisePlanDetail(exercisePlanDetail);
exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId; exercisePlanDetail.exercisePlanDetailId = savedDetail.exercisePlanDetailId;
exercisePlanDetail.state = ExercisePlanDetailState.start; exercisePlanDetail.state = ExercisePlanDetailState.start;
exercisePlanDetail.exercises = List(); exercisePlanDetail.exercises = [];
exercisePlanDetails.add(exercisePlanDetail); if (exercisePlanDetails == null) {
await Cache().saveActiveExercisePlan(exercisePlan, exercisePlanDetails); exercisePlanDetails = [];
}
exercisePlanDetails!.add(exercisePlanDetail);
await Cache().saveActiveExercisePlan(exercisePlan!, exercisePlanDetails!);
paralellTest = true; paralellTest = true;
} }
yield TestSetExecuteReady(); yield TestSetExecuteReady();
} else if (event is TestSetExecuteDeleteExercise) { } else if (event is TestSetExecuteDeleteExercise) {
yield TestSetExecuteLoading(); yield TestSetExecuteLoading();
ExercisePlanDetail deleteDetail; ExercisePlanDetail? deleteDetail;
exercisePlanDetails.forEach((element) { if (exercisePlanDetails != null) {
if (element.exerciseTypeId == event.exerciseTypeId) { exercisePlanDetails!.forEach((element) {
deleteDetail = element; if (element.exerciseTypeId == event.exerciseTypeId) {
} deleteDetail = element;
}); }
if (deleteDetail != null) { });
exercisePlanDetails.remove(deleteDetail); if (deleteDetail != null) {
if (exercisePlanDetails.isEmpty) { exercisePlanDetails!.remove(deleteDetail);
exercisePlan = null; if (exercisePlanDetails!.isEmpty) {
exercisePlanDetails = null; exercisePlan = null;
Cache().deleteActiveExercisePlan(); exercisePlanDetails = null;
Cache().deleteActiveExercisePlan();
}
} }
} }
yield TestSetExecuteReady(); yield TestSetExecuteReady();
@ -181,9 +187,9 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
bool hasBegun() { bool hasBegun() {
if (exercisePlanDetails == null || if (exercisePlanDetails == null ||
exercisePlanDetails.isEmpty || exercisePlanDetails!.isEmpty ||
exercisePlanDetails[0].exercises == null || exercisePlanDetails![0].exercises == null ||
exercisePlanDetails[0].exercises.length == 0) { exercisePlanDetails![0].exercises!.length == 0) {
return false; return false;
} }
@ -191,14 +197,14 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
} }
void setPlanDetailState(ExercisePlanDetail exercisePlanDetail) { void setPlanDetailState(ExercisePlanDetail exercisePlanDetail) {
if (exercisePlanDetail.exercises == null || exercisePlanDetail.exercises.length == 0) { if (exercisePlanDetail.exercises == null || exercisePlanDetail.exercises!.length == 0) {
exercisePlanDetail.state = ExercisePlanDetailState.start; exercisePlanDetail.state = ExercisePlanDetailState.start;
} else { } else {
int maxLength = 1; int maxLength = 1;
if (exercisePlanDetail.exerciseType.unitQuantityUnit != null) { if (exercisePlanDetail.exerciseType!.unitQuantityUnit != null) {
maxLength = 4; maxLength = 4;
} }
if (exercisePlanDetail.exercises.length >= maxLength) { if (exercisePlanDetail.exercises!.length >= maxLength) {
exercisePlanDetail.state = ExercisePlanDetailState.finished; exercisePlanDetail.state = ExercisePlanDetailState.finished;
} else { } else {
exercisePlanDetail.state = ExercisePlanDetailState.inProgress; exercisePlanDetail.state = ExercisePlanDetailState.inProgress;
@ -208,7 +214,8 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
ExercisePlanDetailState actualState(int exerciseTypeId) { ExercisePlanDetailState actualState(int exerciseTypeId) {
ExercisePlanDetailState state = ExercisePlanDetailState.start; ExercisePlanDetailState state = ExercisePlanDetailState.start;
exercisePlanDetails.forEach((element) { if (exercisePlanDetails == null) return state;
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == exerciseTypeId) { if (element.exerciseTypeId == exerciseTypeId) {
state = element.state; state = element.state;
} }
@ -218,7 +225,8 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
bool existsInPlanDetails(int exerciseTypeId) { bool existsInPlanDetails(int exerciseTypeId) {
bool found = false; bool found = false;
exercisePlanDetails.forEach((element) { if (exercisePlanDetails == null) return found;
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == exerciseTypeId) { if (element.exerciseTypeId == exerciseTypeId) {
found = true; found = true;
} }
@ -226,9 +234,11 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
return found; return found;
} }
ExercisePlanDetail actualExercisePlanDetail(int exerciseTypeId) { ExercisePlanDetail? actualExercisePlanDetail(int exerciseTypeId) {
ExercisePlanDetail found; ExercisePlanDetail? found;
exercisePlanDetails.forEach((element) { if (exercisePlanDetails == null) return found;
exercisePlanDetails!.forEach((element) {
if (element.exerciseTypeId == exerciseTypeId) { if (element.exerciseTypeId == exerciseTypeId) {
found = element; found = element;
} }
@ -238,10 +248,10 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
bool isDone100Percent() { bool isDone100Percent() {
bool done = true; bool done = true;
if (exercisePlanDetails == null || exercisePlanDetails.isEmpty) { if (exercisePlanDetails == null || exercisePlanDetails!.isEmpty) {
return false; return false;
} }
exercisePlanDetails.forEach((element) { exercisePlanDetails!.forEach((element) {
if (!element.state.equalsTo(ExercisePlanDetailState.finished)) { if (!element.state.equalsTo(ExercisePlanDetailState.finished)) {
done = false; done = false;
} }
@ -251,7 +261,7 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
HashMap canAddNewExercise() { HashMap canAddNewExercise() {
HashMap ret = HashMap(); HashMap ret = HashMap();
if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan.type)) { if (exercisePlan != null && ExerciseAbility.mini_test_set.equalsStringTo(exercisePlan!.type!)) {
final String message = "You have an active Test Set!"; final String message = "You have an active Test Set!";
final String message2 = "Do you want you to override it?"; final String message2 = "Do you want you to override it?";
ret['message'] = message; ret['message'] = message;
@ -264,8 +274,8 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
return ret; return ret;
} }
int getActualWorkoutTreeId(int exerciseTypeId) { int? getActualWorkoutTreeId(int exerciseTypeId) {
final WorkoutMenuTree workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId); final WorkoutMenuTree? workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId);
if (workoutTree == null) { if (workoutTree == null) {
return null; return null;
} }
@ -276,7 +286,7 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
if (exerciseTypeId <= 0) { if (exerciseTypeId <= 0) {
return ""; return "";
} }
final WorkoutMenuTree workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId); final WorkoutMenuTree? workoutTree = this.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseTypeId);
if (workoutTree == null) { if (workoutTree == null) {
return ""; return "";
} }
@ -288,14 +298,14 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
if (exercisePlanDetails == null) { if (exercisePlanDetails == null) {
return true; return true;
} }
if (exercisePlanDetails.isEmpty) { if (exercisePlanDetails!.isEmpty) {
return true; return true;
} }
return (exercisePlanDetails[0].exercises == null || exercisePlanDetails[0].exercises.length == 0); return (exercisePlanDetails![0].exercises == null || exercisePlanDetails![0].exercises!.length == 0);
} }
bool existsActivePlan() { bool existsActivePlan() {
final bool exists = exercisePlan != null && exercisePlanDetails.length > 0; final bool exists = exercisePlan != null && exercisePlanDetails != null && exercisePlanDetails!.isNotEmpty;
print("Exists active plan: $exists"); print("Exists active plan: $exists");
return exists; return exists;
} }
@ -304,20 +314,22 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
return (exercisePlanDetail.state.equalsTo(ExercisePlanDetailState.finished)); return (exercisePlanDetail.state.equalsTo(ExercisePlanDetailState.finished));
} }
ExercisePlanDetail getNext() { ExercisePlanDetail? getNext() {
ExercisePlanDetail nextExercisePlanDetail; ExercisePlanDetail? nextExercisePlanDetail;
int minStep = 99; int minStep = 99;
for (final detail in this.exercisePlanDetails) { if (this.exercisePlanDetails == null) {
if (!detail.state.equalsTo(ExercisePlanDetailState.finished)) { for (final detail in this.exercisePlanDetails!) {
if (detail.exercises == null) { if (!detail.state.equalsTo(ExercisePlanDetailState.finished)) {
nextExercisePlanDetail = detail; if (detail.exercises == null) {
minStep = 1;
break;
} else {
final int step = detail.exercises.length;
if (step < minStep) {
nextExercisePlanDetail = detail; nextExercisePlanDetail = detail;
minStep = step; minStep = 1;
break;
} else {
final int step = detail.exercises!.length;
if (step < minStep) {
nextExercisePlanDetail = detail;
minStep = step;
}
} }
} }
} }
@ -341,10 +353,10 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
String repeatTimesText(ExercisePlanDetail exercisePlanDetail) { String repeatTimesText(ExercisePlanDetail exercisePlanDetail) {
String text = "maximum"; String text = "maximum";
if (!hasBegun() || exercisePlanDetail.exerciseType.unitQuantityUnit == null) { if (!hasBegun() || exercisePlanDetail.exerciseType!.unitQuantityUnit == null) {
return text; return text;
} }
int step = exercisePlanDetail.exercises.length; int step = exercisePlanDetail.exercises!.length;
print("repeatTimes step $step"); print("repeatTimes step $step");
if (step == 2) { if (step == 2) {
text = "12"; text = "12";
@ -354,13 +366,13 @@ class TestSetExecuteBloc extends Bloc<TestSetExecuteEvent, TestSetExecuteState>
String getExerciseWeight(ExercisePlanDetail exercisePlanDetail) { String getExerciseWeight(ExercisePlanDetail exercisePlanDetail) {
String text = "you are able to do 12-20 repeats with"; String text = "you are able to do 12-20 repeats with";
if (!hasBegun() || exercisePlanDetail.exercises.length < 2) { if (!hasBegun() || exercisePlanDetail.exercises!.length < 2) {
return text; return text;
} }
final double unitQuantity = exercisePlanDetail.exercises.last.unitQuantity; final double unitQuantity = exercisePlanDetail.exercises!.last.unitQuantity;
final double quantity = exercisePlanDetail.exercises.last.quantity; final double quantity = exercisePlanDetail.exercises!.last.quantity;
double oneRepMax = this.calculate1RM(quantity, unitQuantity); double oneRepMax = this.calculate1RM(quantity, unitQuantity);
text = (oneRepMax * 0.75).round().toStringAsFixed(0) + " " + exercisePlanDetail.exerciseType.unitQuantityUnit; text = (oneRepMax * 0.75).round().toStringAsFixed(0) + " " + exercisePlanDetail.exerciseType!.unitQuantityUnit!;
return text; return text;
} }
} }

View File

@ -13,7 +13,7 @@ class TestSetExecuteLoad extends TestSetExecuteEvent {
class TestSetExecuteExecute extends TestSetExecuteEvent { class TestSetExecuteExecute extends TestSetExecuteEvent {
final int exerciseTypeId; final int exerciseTypeId;
const TestSetExecuteExecute({this.exerciseTypeId}); const TestSetExecuteExecute({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];
@ -27,7 +27,7 @@ class TestSetExecuteExerciseFinished extends TestSetExecuteEvent {
final int exerciseTypeId; final int exerciseTypeId;
final double quantity; final double quantity;
final double unitQuantity; final double unitQuantity;
const TestSetExecuteExerciseFinished({this.exerciseTypeId, this.quantity, this.unitQuantity}); const TestSetExecuteExerciseFinished({required this.exerciseTypeId, required this.quantity, required this.unitQuantity});
@override @override
List<Object> get props => [exerciseTypeId, quantity, unitQuantity]; List<Object> get props => [exerciseTypeId, quantity, unitQuantity];
@ -35,7 +35,7 @@ class TestSetExecuteExerciseFinished extends TestSetExecuteEvent {
class TestSetExecuteNewExercise extends TestSetExecuteEvent { class TestSetExecuteNewExercise extends TestSetExecuteEvent {
final int exerciseTypeId; final int exerciseTypeId;
const TestSetExecuteNewExercise({this.exerciseTypeId}); const TestSetExecuteNewExercise({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];
@ -43,7 +43,7 @@ class TestSetExecuteNewExercise extends TestSetExecuteEvent {
class TestSetExecuteDeleteExercise extends TestSetExecuteEvent { class TestSetExecuteDeleteExercise extends TestSetExecuteEvent {
final int exerciseTypeId; final int exerciseTypeId;
const TestSetExecuteDeleteExercise({this.exerciseTypeId}); const TestSetExecuteDeleteExercise({required this.exerciseTypeId});
@override @override
List<Object> get props => [exerciseTypeId]; List<Object> get props => [exerciseTypeId];

View File

@ -25,7 +25,7 @@ class TestSetExecuteReady extends TestSetExecuteState {
class TestSetExecuteError extends TestSetExecuteState { class TestSetExecuteError extends TestSetExecuteState {
final String message; final String message;
const TestSetExecuteError({this.message}); const TestSetExecuteError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -18,21 +18,23 @@ class TestSetNewBloc extends Bloc<TestSetNewEvent, TestSetNewState> {
final int exercisePlanDetailId; final int exercisePlanDetailId;
final TestSetExecuteBloc executeBloc; final TestSetExecuteBloc executeBloc;
TestSetNewBloc({this.exerciseRepository, this.exerciseType, this.exercisePlanDetailId, this.executeBloc}) : super(TestSetNewInitial()) { late double quantity;
late double unitQuantity;
TestSetNewBloc(
{required this.exerciseRepository, required this.exerciseType, required this.exercisePlanDetailId, required this.executeBloc})
: super(TestSetNewInitial()) {
exerciseRepository.exerciseType = exerciseType; exerciseRepository.exerciseType = exerciseType;
quantity = 12; quantity = 12;
unitQuantity = 30; unitQuantity = 30;
exerciseRepository.setQuantity(quantity); exerciseRepository.setQuantity(quantity);
exerciseRepository.setUnit(exerciseType.unit); exerciseRepository.setUnit(exerciseType.unit);
exerciseRepository.setUnitQuantity(unitQuantity); exerciseRepository.setUnitQuantity(unitQuantity);
exerciseRepository.exercise.exercisePlanDetailId = exercisePlanDetailId; exerciseRepository.exercise!.exercisePlanDetailId = exercisePlanDetailId;
exerciseRepository.start = DateTime.now(); exerciseRepository.start = DateTime.now();
exerciseRepository.setCustomer(Cache().userLoggedIn); exerciseRepository.setCustomer(Cache().userLoggedIn!);
} }
double quantity;
double unitQuantity;
@override @override
Stream<TestSetNewState> mapEventToState( Stream<TestSetNewState> mapEventToState(
TestSetNewEvent event, TestSetNewEvent event,

View File

@ -13,7 +13,7 @@ class TestSetNewLoad extends TestSetNewEvent {
class TestSetNewChangeQuantity extends TestSetNewEvent { class TestSetNewChangeQuantity extends TestSetNewEvent {
final double quantity; final double quantity;
const TestSetNewChangeQuantity({this.quantity}); const TestSetNewChangeQuantity({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];
@ -21,7 +21,7 @@ class TestSetNewChangeQuantity extends TestSetNewEvent {
class TestSetNewChangeQuantityUnit extends TestSetNewEvent { class TestSetNewChangeQuantityUnit extends TestSetNewEvent {
final double quantity; final double quantity;
const TestSetNewChangeQuantityUnit({this.quantity}); const TestSetNewChangeQuantityUnit({required this.quantity});
@override @override
List<Object> get props => [quantity]; List<Object> get props => [quantity];

View File

@ -21,7 +21,7 @@ class TestSetNewReady extends TestSetNewState {
class TestSetNewError extends TestSetNewState { class TestSetNewError extends TestSetNewState {
final String message; final String message;
const TestSetNewError({this.message}); const TestSetNewError({required this.message});
@override @override
List<Object> get props => [message]; List<Object> get props => [message];

View File

@ -1,6 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:audioplayer/audioplayer.dart'; //import 'package:audioplayer/audioplayer.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
@ -8,7 +8,7 @@ part 'timer_event.dart';
part 'timer_state.dart'; part 'timer_state.dart';
class Ticker { class Ticker {
Stream<int> tick({int ticks}) { Stream<int> tick({required int ticks}) {
return Stream.periodic(Duration(seconds: 1), (x) => compute(ticks, x)).take(ticks); return Stream.periodic(Duration(seconds: 1), (x) => compute(ticks, x)).take(ticks);
} }
@ -22,11 +22,12 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
final Ticker _ticker = Ticker(); final Ticker _ticker = Ticker();
int _duration = 0; int _duration = 0;
final AudioPlayer audioPlayer = AudioPlayer(); //final AudioPlayer audioPlayer = AudioPlayer();
int minutes = 0; int minutes = 0;
int seconds = 0; int seconds = 0;
StreamSubscription<int> _tickerSubscription; // ignore: cancel_subscriptions
StreamSubscription<int>? _tickerSubscription;
TimerBloc() : super(TimerReady(300)); TimerBloc() : super(TimerReady(300));
@ -52,21 +53,27 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
yield* _mapTickToState(event); yield* _mapTickToState(event);
} else if (event is TimerEnd) { } else if (event is TimerEnd) {
print("$event"); print("$event");
_tickerSubscription?.cancel(); if (_tickerSubscription != null) {
_tickerSubscription!.cancel();
}
yield TimerFinished(state.duration); yield TimerFinished(state.duration);
} }
} }
@override @override
Future<void> close() { Future<void> close() {
_tickerSubscription?.cancel(); if (_tickerSubscription != null) {
_tickerSubscription!.cancel();
}
return super.close(); return super.close();
} }
Stream<TimerState> _mapStartToState(TimerStart start) async* { Stream<TimerState> _mapStartToState(TimerStart start) async* {
//print("$start"); //print("$start");
yield TimerRunning(start.duration); yield TimerRunning(start.duration);
_tickerSubscription?.cancel(); if (_tickerSubscription != null) {
_tickerSubscription!.cancel();
}
_tickerSubscription = _ticker.tick(ticks: start.duration).listen( _tickerSubscription = _ticker.tick(ticks: start.duration).listen(
(localDuration) { (localDuration) {
//print("local: $localDuration"); //print("local: $localDuration");
@ -77,14 +84,19 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
Stream<TimerState> _mapPauseToState(TimerPause pause) async* { Stream<TimerState> _mapPauseToState(TimerPause pause) async* {
if (state is TimerRunning) { if (state is TimerRunning) {
_tickerSubscription?.pause(); if (_tickerSubscription != null) {
_tickerSubscription!.pause();
}
yield TimerPaused(state.duration); yield TimerPaused(state.duration);
} }
} }
Stream<TimerState> _mapResumeToState(TimerResume pause) async* { Stream<TimerState> _mapResumeToState(TimerResume pause) async* {
if (state is TimerPaused) { if (state is TimerPaused) {
_tickerSubscription?.resume(); if (_tickerSubscription != null) {
_tickerSubscription!.resume();
}
yield TimerRunning(state.duration); yield TimerRunning(state.duration);
} }
} }
@ -100,7 +112,7 @@ class TimerBloc extends Bloc<TimerEvent, TimerState> {
yield tick.duration >= 0 ? TimerRunning(tick.duration) : TimerFinished(tick.duration); yield tick.duration >= 0 ? TimerRunning(tick.duration) : TimerFinished(tick.duration);
} }
Future _play() async { /* Future _play() async {
await audioPlayer.play('asset/wine-glass.mp3', isLocal: true); await audioPlayer.play('asset/wine-glass.mp3', isLocal: true);
} } */
} }

View File

@ -9,7 +9,7 @@ abstract class TimerEvent extends Equatable {
class TimerStart extends TimerEvent { class TimerStart extends TimerEvent {
final int duration; final int duration;
const TimerStart({this.duration}); const TimerStart({required this.duration});
@override @override
String toString() => "TimerStart { duration: $duration }"; String toString() => "TimerStart { duration: $duration }";
@ -17,12 +17,12 @@ class TimerStart extends TimerEvent {
class TimerEnd extends TimerEvent { class TimerEnd extends TimerEvent {
final int duration; final int duration;
const TimerEnd({this.duration}); const TimerEnd({required this.duration});
} }
class TimerTick extends TimerEvent { class TimerTick extends TimerEvent {
final int duration; final int duration;
const TimerTick({this.duration}); const TimerTick({required this.duration});
@override @override
String toString() => "Tick { duration: $duration }"; String toString() => "Tick { duration: $duration }";

View File

@ -45,5 +45,5 @@ class TimerFinished extends TimerState {
class TimerError extends TimerState { class TimerError extends TimerState {
final String message; final String message;
TimerError(int duration, {this.message}) : super(duration); TimerError(int duration, {required this.message}) : super(duration);
} }

View File

@ -5,7 +5,7 @@ import 'package:sqflite/sqflite.dart';
class DB { class DB {
static final DB _singleton = DB._internal(); static final DB _singleton = DB._internal();
String dbName = "workouttest.db"; String dbName = "workouttest.db";
Database _db; late Database _db;
factory DB() { factory DB() {
return _singleton; return _singleton;
@ -30,9 +30,7 @@ class DB {
} }
Future<void> closeDb() async { Future<void> closeDb() async {
if ( _db != null ) { this._db.close();
this._db.close();
}
} }
Database getDB() => this._db; Database getDB() => this._db;

View File

@ -1,9 +1,11 @@
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart'; import 'dart:math';
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 'dart:math';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';
final temperatureColors = [ final temperatureColors = [
const Color(0xFFB50DE2), // -20 Celsius , friggin cold const Color(0xFFB50DE2), // -20 Celsius , friggin cold
const Color(0xFFAE0DE2), const Color(0xFFAE0DE2),
@ -42,7 +44,7 @@ class Clock extends StatelessWidget {
final TimerBloc bloc; final TimerBloc bloc;
final List<Color> colors = temperatureColors; final List<Color> colors = temperatureColors;
Clock({this.bloc}); Clock({required this.bloc});
// ignore: close_sinks // ignore: close_sinks
@ -109,10 +111,10 @@ class ArcPainter extends CustomPainter {
List<Color> _gradient; List<Color> _gradient;
Offset center; Offset? center;
double _radius; double _radius;
Paint paintMarkerEmpty; late Paint paintMarkerEmpty;
ArcPainter( ArcPainter(
this._progress, this._progress,
@ -132,7 +134,7 @@ class ArcPainter extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
center = Offset(size.width / 2, size.height / 2); center = Offset(size.width / 2, size.height / 2);
var rect = Rect.fromCircle(center: center, radius: this._radius); var rect = Rect.fromCircle(center: center!, radius: this._radius);
final gradient2 = new SweepGradient( final gradient2 = new SweepGradient(
startAngle: -pi / 2, startAngle: -pi / 2,

View File

@ -1,529 +0,0 @@
library dropdown_search;
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'popup_menu.dart';
import 'select_dialog.dart';
typedef Future<List<T>> DropdownSearchOnFind<T>(String text);
typedef String DropdownSearchItemAsString<T>(T item);
typedef bool DropdownSearchFilterFn<T>(T item, String filter);
typedef bool DropdownSearchCompareFn<T>(T item, T selectedItem);
typedef Widget DropdownSearchBuilder<T>(BuildContext context, T selectedItem, String itemAsString);
typedef Widget DropdownSearchPopupItemBuilder<T>(
BuildContext context,
T item,
bool isSelected,
);
typedef bool DropdownSearchPopupItemEnabled<T>(T item);
typedef Widget ErrorBuilder<T>(BuildContext context, String searchEntry, dynamic exception);
typedef Widget EmptyBuilder<T>(BuildContext context, String searchEntry);
typedef Widget LoadingBuilder<T>(BuildContext context, String searchEntry);
typedef Widget IconButtonBuilder(BuildContext context);
typedef Future<bool> BeforeChange<T>(T prevItem, T nextItem);
enum Mode { DIALOG, BOTTOM_SHEET, MENU }
class DropdownSearch<T> extends StatefulWidget {
///DropDownSearch label
final String label;
///DropDownSearch hint
final String hint;
///show/hide the search box
final bool showSearchBox;
///true if the filter on items is applied onlie (via API)
final bool isFilteredOnline;
///show/hide clear selected item
final bool showClearButton;
///offline items list
final List<T> items;
///selected item
final T selectedItem;
///function that returns item from API
final DropdownSearchOnFind<T> onFind;
///called when a new item is selected
final ValueChanged<T> onChanged;
///to customize list of items UI
final DropdownSearchBuilder<T> dropdownBuilder;
///to customize selected item
final DropdownSearchPopupItemBuilder<T> popupItemBuilder;
///decoration for search box
final InputDecoration searchBoxDecoration;
///the title for dialog/menu/bottomSheet
final Color popupBackgroundColor;
///custom widget for the popup title
final Widget popupTitle;
///customize the fields the be shown
final DropdownSearchItemAsString<T> itemAsString;
/// custom filter function
final DropdownSearchFilterFn<T> filterFn;
///enable/disable dropdownSearch
final bool enabled;
///MENU / DIALOG/ BOTTOM_SHEET
final Mode mode;
///the max height for dialog/bottomSheet/Menu
final double maxHeight;
///the max width for the dialog
final double dialogMaxWidth;
///select the selected item in the menu/dialog/bottomSheet of items
final bool showSelectedItem;
///function that compares two object with the same type to detected if it's the selected item or not
final DropdownSearchCompareFn<T> compareFn;
///dropdownSearch input decoration
final InputDecoration dropdownSearchDecoration;
///custom layout for empty results
final EmptyBuilder emptyBuilder;
///custom layout for loading items
final LoadingBuilder loadingBuilder;
///custom layout for error
final ErrorBuilder errorBuilder;
///the search box will be focused if true
final bool autoFocusSearchBox;
///custom shape for the popup
final ShapeBorder popupShape;
final AutovalidateMode autoValidateMode;
/// An optional method to call with the final value when the form is saved via
final FormFieldSetter<T> onSaved;
/// An optional method that validates an input. Returns an error string to
/// display if the input is invalid, or null otherwise.
final FormFieldValidator<T> validator;
///custom dropdown clear button icon widget
final Widget clearButton;
///custom clear button widget builder
final IconButtonBuilder clearButtonBuilder;
///custom dropdown icon button widget
final Widget dropDownButton;
///custom dropdown button widget builder
final IconButtonBuilder dropdownButtonBuilder;
///whether to manage the clear and dropdown icons via InputDecoration suffixIcon
final bool showAsSuffixIcons;
///If true, the dropdownBuilder will continue the uses of material behavior
///This will be useful if you want to handle a custom UI only if the item !=null
final bool dropdownBuilderSupportsNullItem;
///defines if an item of the popup is enabled or not, if the item is disabled,
///it cannot be clicked
final DropdownSearchPopupItemEnabled<T> popupItemDisabled;
///set a custom color for the popup barrier
final Color popupBarrierColor;
///text controller to set default search word for example
final TextEditingController searchBoxController;
///called when popup is dismissed
final VoidCallback onPopupDismissed;
/// callback executed before applying value change
///delay before searching, change it to Duration(milliseconds: 0)
///if you do not use online search
final Duration searchDelay;
/// callback executed before applying value change
final BeforeChange<T> onBeforeChange;
DropdownSearch({
Key key,
this.onSaved,
this.validator,
this.autoValidateMode = AutovalidateMode.disabled,
this.onChanged,
this.mode = Mode.DIALOG,
this.label,
this.hint,
this.isFilteredOnline = false,
this.popupTitle,
this.items,
this.selectedItem,
this.onFind,
this.dropdownBuilder,
this.popupItemBuilder,
this.showSearchBox = false,
this.showClearButton = false,
this.searchBoxDecoration,
this.popupBackgroundColor,
this.enabled = true,
this.maxHeight,
this.filterFn,
this.itemAsString,
this.showSelectedItem = false,
this.compareFn,
this.dropdownSearchDecoration,
this.emptyBuilder,
this.loadingBuilder,
this.errorBuilder,
this.autoFocusSearchBox = false,
this.dialogMaxWidth,
this.clearButton,
this.clearButtonBuilder,
this.dropDownButton,
this.dropdownButtonBuilder,
this.showAsSuffixIcons = false,
this.dropdownBuilderSupportsNullItem = false,
this.popupShape,
this.popupItemDisabled,
this.popupBarrierColor,
this.onPopupDismissed,
this.searchBoxController,
this.searchDelay,
this.onBeforeChange,
}) : assert(isFilteredOnline != null),
assert(dropdownBuilderSupportsNullItem != null),
assert(enabled != null),
assert(showSelectedItem != null),
assert(autoFocusSearchBox != null),
assert(showClearButton != null),
assert(showSearchBox != null),
assert(!showSelectedItem || T == String || compareFn != null),
super(key: key);
@override
DropdownSearchState<T> createState() => DropdownSearchState<T>();
}
class DropdownSearchState<T> extends State<DropdownSearch<T>> {
final ValueNotifier<T> _selectedItemNotifier = ValueNotifier(null);
final ValueNotifier<bool> _isFocused = ValueNotifier(false);
@override
void initState() {
super.initState();
_selectedItemNotifier.value = widget.selectedItem;
}
@override
void didUpdateWidget(DropdownSearch<T> oldWidget) {
final oldSelectedItem = oldWidget.selectedItem;
final newSelectedItem = widget.selectedItem;
if (oldSelectedItem != newSelectedItem) {
_selectedItemNotifier.value = newSelectedItem;
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<T>(
valueListenable: _selectedItemNotifier,
builder: (context, T data, wt) {
return IgnorePointer(
ignoring: !widget.enabled,
child: GestureDetector(
onTap: () => _selectSearchMode(data),
child: _formField(data),
),
);
},
);
}
Widget _defaultSelectItemWidget(T data) {
return Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: widget.dropdownBuilder != null
? widget.dropdownBuilder(
context,
data,
_selectedItemAsString(data),
)
: Text(_selectedItemAsString(data), style: Theme.of(context).textTheme.subtitle1),
),
if (!widget.showAsSuffixIcons) _manageTrailingIcons(data),
],
);
}
Widget _formField(T value) {
return FormField(
enabled: widget.enabled,
onSaved: widget.onSaved,
validator: widget.validator,
autovalidateMode: widget.autoValidateMode,
initialValue: widget.selectedItem,
builder: (FormFieldState<T> state) {
if (state.value != value) {
WidgetsBinding.instance.addPostFrameCallback((_) {
state.didChange(value);
});
}
return ValueListenableBuilder(
valueListenable: _isFocused,
builder: (context, bool isFocused, w) {
return InputDecorator(
isEmpty: value == null && (widget.dropdownBuilder == null || widget.dropdownBuilderSupportsNullItem),
isFocused: isFocused,
decoration: _manageDropdownDecoration(state, value),
child: _defaultSelectItemWidget(value),
);
});
},
);
}
///manage dropdownSearch field decoration
InputDecoration _manageDropdownDecoration(FormFieldState state, T data) {
return (widget.dropdownSearchDecoration ??
InputDecoration(contentPadding: EdgeInsets.fromLTRB(12, 12, 0, 0), border: OutlineInputBorder()))
.applyDefaults(Theme.of(state.context).inputDecorationTheme)
.copyWith(
enabled: widget.enabled,
labelText: widget.label,
hintText: widget.hint,
suffixIcon: widget.showAsSuffixIcons ? _manageTrailingIcons(data) : null,
errorText: state.errorText);
}
///function that return the String value of an object
String _selectedItemAsString(T data) {
if (data == null) {
return "";
} else if (widget.itemAsString != null) {
return widget.itemAsString(data);
} else {
return data.toString();
}
}
///function that manage Trailing icons(close, dropDown)
Widget _manageTrailingIcons(T data) {
final clearButtonPressed = () => _handleOnChangeSelectedItem(null);
final dropdownButtonPressed = () => _selectSearchMode(data);
return Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
if (data != null && widget.showClearButton)
widget.clearButtonBuilder != null
? GestureDetector(
onTap: clearButtonPressed,
child: widget.clearButtonBuilder(context),
)
: IconButton(
icon: widget.clearButton ?? const Icon(Icons.clear, size: 24),
onPressed: clearButtonPressed,
),
widget.dropdownButtonBuilder != null
? GestureDetector(
onTap: dropdownButtonPressed,
child: widget.dropdownButtonBuilder(context),
)
: IconButton(
icon: widget.dropDownButton ?? const Icon(Icons.arrow_drop_down, size: 24),
onPressed: dropdownButtonPressed,
),
],
);
}
///open dialog
Future<T> _openSelectDialog(T data) {
return showGeneralDialog(
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
transitionDuration: const Duration(milliseconds: 400),
barrierColor: widget.popupBarrierColor ?? const Color(0x80000000),
context: context,
pageBuilder: (context, animation, secondaryAnimation) {
return AlertDialog(
contentPadding: EdgeInsets.all(0),
shape: widget.popupShape,
backgroundColor: widget.popupBackgroundColor,
content: _selectDialogInstance(data),
);
},
);
}
///open BottomSheet (Dialog mode)
Future<T> _openBottomSheet(T data) {
return showModalBottomSheet<T>(
barrierColor: widget.popupBarrierColor,
isScrollControlled: true,
backgroundColor: widget.popupBackgroundColor,
shape: widget.popupShape,
context: context,
builder: (context) {
return AnimatedPadding(
duration: Duration(milliseconds: 300),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: _selectDialogInstance(data, defaultHeight: 350),
);
});
}
///openMenu
Future<T> _openMenu(T data) {
// Here we get the render object of our physical button, later to get its size & position
final RenderBox popupButtonObject = context.findRenderObject();
// Get the render object of the overlay used in `Navigator` / `MaterialApp`, i.e. screen size reference
final RenderBox overlay = Overlay.of(context).context.findRenderObject();
// Calculate the show-up area for the dropdown using button's size & position based on the `overlay` used as the coordinate space.
final RelativeRect position = RelativeRect.fromSize(
Rect.fromPoints(
popupButtonObject.localToGlobal(popupButtonObject.size.bottomLeft(Offset.zero), ancestor: overlay),
popupButtonObject.localToGlobal(popupButtonObject.size.bottomRight(Offset.zero), ancestor: overlay),
),
Size(overlay.size.width, overlay.size.height),
);
return customShowMenu<T>(
barrierColor: widget.popupBarrierColor,
shape: widget.popupShape,
color: widget.popupBackgroundColor,
context: context,
position: position,
elevation: 8,
items: [
CustomPopupMenuItem(
enabled: false,
child: Container(
width: popupButtonObject.size.width,
child: _selectDialogInstance(data, defaultHeight: 224),
),
),
]);
}
SelectDialog<T> _selectDialogInstance(T data, {double defaultHeight}) {
return SelectDialog<T>(
popupTitle: widget.popupTitle,
maxHeight: widget.maxHeight ?? defaultHeight,
isFilteredOnline: widget.isFilteredOnline,
itemAsString: widget.itemAsString,
filterFn: widget.filterFn,
items: widget.items,
onFind: widget.onFind,
showSearchBox: widget.showSearchBox,
itemBuilder: widget.popupItemBuilder,
selectedValue: data,
searchBoxDecoration: widget.searchBoxDecoration,
onChanged: _handleOnChangeSelectedItem,
showSelectedItem: widget.showSelectedItem,
compareFn: widget.compareFn,
emptyBuilder: widget.emptyBuilder,
loadingBuilder: widget.loadingBuilder,
errorBuilder: widget.errorBuilder,
autoFocusSearchBox: widget.autoFocusSearchBox,
dialogMaxWidth: widget.dialogMaxWidth,
itemDisabled: widget.popupItemDisabled,
searchBoxController: widget.searchBoxController ?? TextEditingController(),
searchDelay: widget.searchDelay,
);
}
///Function that manage focus listener
///set true only if the widget already not focused to prevent unnecessary build
///same thing for clear focus,
void _handleFocus(bool isFocused) {
if (isFocused && !_isFocused.value) {
FocusScope.of(context).unfocus();
_isFocused.value = true;
} else if (!isFocused && _isFocused.value) _isFocused.value = false;
}
///handle on change value , if the validation is active , we validate the new selected item
void _handleOnChangeSelectedItem(T selectedItem) {
final changeItem = () {
_selectedItemNotifier.value = selectedItem;
if (widget.onChanged != null) widget.onChanged(selectedItem);
};
if (widget.onBeforeChange != null) {
widget.onBeforeChange(_selectedItemNotifier.value, selectedItem).then((value) {
if (value == true) {
changeItem();
}
});
} else {
changeItem();
}
_handleFocus(false);
}
///Function that return then UI based on searchMode
///[data] selected item to be passed to the UI
///If we close the popup , or maybe we just selected
///another widget we should clear the focus
Future<T> _selectSearchMode(T data) async {
_handleFocus(true);
T selectedItem;
if (widget.mode == Mode.MENU) {
selectedItem = await _openMenu(data);
} else if (widget.mode == Mode.BOTTOM_SHEET) {
selectedItem = await _openBottomSheet(data);
} else {
selectedItem = await _openSelectDialog(data);
}
_handleFocus(false);
widget.onPopupDismissed?.call();
return selectedItem;
}
///Public Function that return then UI based on searchMode
///[data] selected item to be passed to the UI
///If we close the popup , or maybe we just selected
///another widget we should clear the focus
///THIS USED FOR OPEN DROPDOWN_SEARCH PROGRAMMATICALLY,
///otherwise you can you [_selectSearchMode]
Future<T> openDropDownSearch() => _selectSearchMode(_selectedItemNotifier.value);
///Change selected Value; this function is public USED to change the selected
///value PROGRAMMATICALLY, Otherwise you can use [_handleOnChangeSelectedItem]
void changeSelectedItem(T selectedItem) => _handleOnChangeSelectedItem(selectedItem);
///Change selected Value; this function is public USED to clear selected
///value PROGRAMMATICALLY, Otherwise you can use [_handleOnChangeSelectedItem]
void clear() => _handleOnChangeSelectedItem(null);
///get selected value programmatically
T get getSelectedItem => _selectedItemNotifier.value;
///check if the dropdownSearch is focused
bool get isFocused => _isFocused.value;
}

View File

@ -16,9 +16,9 @@ class FadeIn extends StatefulWidget {
final Curve curve; final Curve curve;
const FadeIn({ const FadeIn({
Key key, Key? key,
this.controller, required this.controller,
this.child, required this.child,
this.duration = const Duration(milliseconds: 250), this.duration = const Duration(milliseconds: 250),
this.curve = Curves.easeIn, this.curve = Curves.easeIn,
}) : super(key: key); }) : super(key: key);
@ -57,8 +57,8 @@ class FadeInController {
} }
class _FadeInState extends State<FadeIn> with TickerProviderStateMixin { class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
AnimationController _controller; late AnimationController _controller;
StreamSubscription<FadeInAction> _listener; late StreamSubscription<FadeInAction> _listener;
@override @override
void initState() { void initState() {
@ -71,11 +71,11 @@ class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
_setupCurve(); _setupCurve();
if (widget.controller?.autoStart != false) { if (widget.controller.autoStart != false) {
fadeIn(); fadeIn();
} }
_listen(); _listener = widget.controller.stream.listen(_onAction);
} }
void _setupCurve() { void _setupCurve() {
@ -87,17 +87,6 @@ class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
).animate(curve); ).animate(curve);
} }
void _listen() {
if (_listener != null) {
_listener.cancel();
_listener = null;
}
if (widget.controller != null) {
_listener = widget.controller.stream.listen(_onAction);
}
}
void _onAction(FadeInAction action) { void _onAction(FadeInAction action) {
switch (action) { switch (action) {
case FadeInAction.fadeIn: case FadeInAction.fadeIn:
@ -112,7 +101,7 @@ class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
@override @override
void didUpdateWidget(FadeIn oldWidget) { void didUpdateWidget(FadeIn oldWidget) {
if (oldWidget.controller != widget.controller) { if (oldWidget.controller != widget.controller) {
_listen(); _listener = widget.controller.stream.listen(_onAction);
} }
if (oldWidget.duration != widget.duration) { if (oldWidget.duration != widget.duration) {
@ -129,6 +118,7 @@ class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
@override @override
void dispose() { void dispose() {
_controller.dispose(); _controller.dispose();
_listener.cancel();
super.dispose(); super.dispose();
} }

39
lib/library/flurry.dart Normal file
View File

@ -0,0 +1,39 @@
import 'dart:async';
import 'package:flutter/services.dart';
class Flurry {
static const MethodChannel _channel = const MethodChannel('flurry');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
static Future<Null> initialize({String androidKey = "", String iosKey = "", bool enableLog = true}) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("api_key_android", () => androidKey);
args.putIfAbsent("api_key_ios", () => iosKey);
args.putIfAbsent("is_log_enabled", () => enableLog);
await _channel.invokeMethod('initialize', args);
return null;
}
static Future<Null> logEvent(String message) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("message", () => message);
await _channel.invokeMethod('logEvent', args);
return null;
}
static Future<Null> setUserId(String userId) async {
Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent("userId", () => userId);
await _channel.invokeMethod('userId', args);
return null;
}
}

View File

@ -119,21 +119,17 @@ class GradientBottomNavigationBar extends StatefulWidget {
/// [ThemeData.primaryColor], is used. However if [GradientBottomNavigationBar.type] is /// [ThemeData.primaryColor], is used. However if [GradientBottomNavigationBar.type] is
/// [BottomNavigationBarType.shifting] then [fixedColor] is ignored. /// [BottomNavigationBarType.shifting] then [fixedColor] is ignored.
GradientBottomNavigationBar({ GradientBottomNavigationBar({
Key key, Key? key,
@required this.items, required this.items,
this.onTap, required this.onTap,
@required this.backgroundColorStart, required this.backgroundColorStart,
@required this.backgroundColorEnd, required this.backgroundColorEnd,
this.currentIndex = 0, this.currentIndex = 0,
BottomNavigationBarType type, BottomNavigationBarType? type,
this.fixedColor, this.fixedColor = Colors.white,
this.iconSize = 24.0, this.iconSize = 24.0,
}) : assert(items != null), }) : assert(items.length >= 2),
assert(items.length >= 2),
assert(backgroundColorStart != null),
assert(backgroundColorEnd != null),
assert(0 <= currentIndex && currentIndex < items.length), assert(0 <= currentIndex && currentIndex < items.length),
assert(iconSize != null),
type = type ?? (items.length <= 3 ? BottomNavigationBarType.fixed : BottomNavigationBarType.shifting), type = type ?? (items.length <= 3 ? BottomNavigationBarType.fixed : BottomNavigationBarType.shifting),
super(key: key); super(key: key);
@ -188,30 +184,30 @@ class _BottomNavigationTile extends StatelessWidget {
this.item, this.item,
this.animation, this.animation,
this.iconSize, { this.iconSize, {
this.onTap, required this.onTap,
this.colorTween, this.colorTween,
this.flex, this.flex,
this.selected = false, this.selected = false,
this.indexLabel, required this.indexLabel,
}) : assert(selected != null); });
final BottomNavigationBarType type; final BottomNavigationBarType type;
final BottomNavigationBarItem item; final BottomNavigationBarItem item;
final Animation<double> animation; final Animation<double> animation;
final double iconSize; final double iconSize;
final VoidCallback onTap; final VoidCallback onTap;
final ColorTween colorTween; final ColorTween? colorTween;
final double flex; final double? flex;
final bool selected; final bool selected;
final String indexLabel; final String indexLabel;
Widget _buildIcon() { Widget _buildIcon() {
double tweenStart; double tweenStart;
Color iconColor; Color? iconColor;
switch (type) { switch (type) {
case BottomNavigationBarType.fixed: case BottomNavigationBarType.fixed:
tweenStart = 8.0; tweenStart = 8.0;
iconColor = colorTween.evaluate(animation); iconColor = colorTween!.evaluate(animation);
break; break;
case BottomNavigationBarType.shifting: case BottomNavigationBarType.shifting:
tweenStart = 16.0; tweenStart = 16.0;
@ -248,7 +244,7 @@ class _BottomNavigationTile extends StatelessWidget {
child: DefaultTextStyle.merge( child: DefaultTextStyle.merge(
style: TextStyle( style: TextStyle(
fontSize: _kActiveFontSize, fontSize: _kActiveFontSize,
color: colorTween.evaluate(animation), color: colorTween!.evaluate(animation),
), ),
// The font size should grow here when active, but because of the way // The font size should grow here when active, but because of the way
// font rendering works, it doesn't grow smoothly if we just animate // font rendering works, it doesn't grow smoothly if we just animate
@ -293,7 +289,7 @@ class _BottomNavigationTile extends StatelessWidget {
fontSize: _kActiveFontSize, fontSize: _kActiveFontSize,
color: Colors.white, color: Colors.white,
), ),
child: item.title, child: item.title!,
), ),
), ),
), ),
@ -314,7 +310,7 @@ class _BottomNavigationTile extends StatelessWidget {
label = _buildFixedLabel(); label = _buildFixedLabel();
break; break;
case BottomNavigationBarType.shifting: case BottomNavigationBarType.shifting:
size = (flex * 1000.0).round(); size = (flex! * 1000.0).round();
label = _buildShiftingLabel(); label = _buildShiftingLabel();
break; break;
} }
@ -350,14 +346,14 @@ class _BottomNavigationTile extends StatelessWidget {
class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBar> with TickerProviderStateMixin { class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBar> with TickerProviderStateMixin {
List<AnimationController> _controllers = <AnimationController>[]; List<AnimationController> _controllers = <AnimationController>[];
List<CurvedAnimation> _animations; late List<CurvedAnimation> _animations;
// A queue of color splashes currently being animated. // A queue of color splashes currently being animated.
final Queue<_Circle> _circles = Queue<_Circle>(); final Queue<_Circle> _circles = Queue<_Circle>();
// Last splash circle's color, and the final color of the control after // Last splash circle's color, and the final color of the control after
// animation is complete. // animation is complete.
Color _backgroundColor; late Color _backgroundColor;
static final Animatable<double> _flexTween = Tween<double>(begin: 1.0, end: 1.5); static final Animatable<double> _flexTween = Tween<double>(begin: 1.0, end: 1.5);
@ -380,7 +376,7 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
); );
}); });
_controllers[widget.currentIndex].value = 1.0; _controllers[widget.currentIndex].value = 1.0;
_backgroundColor = widget.items[widget.currentIndex].backgroundColor; _backgroundColor = widget.items[widget.currentIndex].backgroundColor!;
} }
@override @override
@ -411,7 +407,7 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
_Circle( _Circle(
state: this, state: this,
index: index, index: index,
color: widget.items[index].backgroundColor, color: widget.items[index].backgroundColor!,
vsync: this, vsync: this,
)..controller.addStatusListener( )..controller.addStatusListener(
(AnimationStatus status) { (AnimationStatus status) {
@ -456,30 +452,22 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
_controllers[widget.currentIndex].forward(); _controllers[widget.currentIndex].forward();
} else { } else {
if (_backgroundColor != widget.items[widget.currentIndex].backgroundColor) if (_backgroundColor != widget.items[widget.currentIndex].backgroundColor)
_backgroundColor = widget.items[widget.currentIndex].backgroundColor; _backgroundColor = widget.items[widget.currentIndex].backgroundColor!;
} }
} }
List<Widget> _createTiles() { List<Widget> _createTiles() {
final MaterialLocalizations localizations = MaterialLocalizations.of(context); final MaterialLocalizations localizations = MaterialLocalizations.of(context);
assert(localizations != null);
final List<Widget> children = <Widget>[]; final List<Widget> children = <Widget>[];
switch (widget.type) { switch (widget.type) {
case BottomNavigationBarType.fixed: case BottomNavigationBarType.fixed:
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
final TextTheme textTheme = themeData.textTheme; final TextTheme textTheme = themeData.textTheme;
Color themeColor;
switch (themeData.brightness) {
case Brightness.light:
themeColor = themeData.primaryColor;
break;
case Brightness.dark:
themeColor = themeData.accentColor;
break;
}
final ColorTween colorTween = ColorTween( final ColorTween colorTween = ColorTween(
begin: textTheme.caption.color, begin: textTheme.caption!.color,
end: widget.fixedColor ?? themeColor, end: widget.fixedColor,
); );
for (int i = 0; i < widget.items.length; i += 1) { for (int i = 0; i < widget.items.length; i += 1) {
children.add( children.add(
@ -488,9 +476,7 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
widget.items[i], widget.items[i],
_animations[i], _animations[i],
widget.iconSize, widget.iconSize,
onTap: () { onTap: () => widget.onTap(i),
if (widget.onTap != null) widget.onTap(i);
},
colorTween: colorTween, colorTween: colorTween,
selected: i == widget.currentIndex, selected: i == widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length), indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length),
@ -506,9 +492,7 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
widget.items[i], widget.items[i],
_animations[i], _animations[i],
widget.iconSize, widget.iconSize,
onTap: () { onTap: () => widget.onTap(i),
if (widget.onTap != null) widget.onTap(i);
},
flex: _evaluateFlex(_animations[i]), flex: _evaluateFlex(_animations[i]),
selected: i == widget.currentIndex, selected: i == widget.currentIndex,
indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length), indexLabel: localizations.tabLabel(tabIndex: i + 1, tabCount: widget.items.length),
@ -599,13 +583,11 @@ class _GradientBottomNavigationBarState extends State<GradientBottomNavigationBa
// Describes an animating color splash circle. // Describes an animating color splash circle.
class _Circle { class _Circle {
_Circle({ _Circle({
@required this.state, required this.state,
@required this.index, required this.index,
@required this.color, required this.color,
@required TickerProvider vsync, required TickerProvider vsync,
}) : assert(state != null), }) {
assert(index != null),
assert(color != null) {
controller = AnimationController( controller = AnimationController(
duration: kThemeAnimationDuration, duration: kThemeAnimationDuration,
vsync: vsync, vsync: vsync,
@ -620,8 +602,8 @@ class _Circle {
final _GradientBottomNavigationBarState state; final _GradientBottomNavigationBarState state;
final int index; final int index;
final Color color; final Color color;
AnimationController controller; late AnimationController controller;
CurvedAnimation animation; late CurvedAnimation animation;
double get horizontalLeadingOffset { double get horizontalLeadingOffset {
double weightSum(Iterable<Animation<double>> animations) { double weightSum(Iterable<Animation<double>> animations) {
@ -646,10 +628,9 @@ class _Circle {
// Paints the animating color splash circles. // Paints the animating color splash circles.
class _RadialPainter extends CustomPainter { class _RadialPainter extends CustomPainter {
_RadialPainter({ _RadialPainter({
@required this.circles, required this.circles,
@required this.textDirection, required this.textDirection,
}) : assert(circles != null), });
assert(textDirection != null);
final List<_Circle> circles; final List<_Circle> circles;
final TextDirection textDirection; final TextDirection textDirection;

View File

@ -4,7 +4,7 @@ import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/not_found_exception.dart'; import 'package:aitrainer_app/util/not_found_exception.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:network_image_to_byte/network_image_to_byte.dart'; import 'package:aitrainer_app/library//network_image_to_byte.dart';
import 'dart:collection'; import 'dart:collection';
class ImageCache with Logging { class ImageCache with Logging {
@ -31,7 +31,7 @@ class ImageCache with Logging {
return _imageMap[imageKey] != null && _imageMap[imageKey] == true; return _imageMap[imageKey] != null && _imageMap[imageKey] == true;
} }
String getImageString(int id, String url) { String? getImageString(int id, String url) {
final String imageKey = generateMd5(url + "_" + id.toString()); final String imageKey = generateMd5(url + "_" + id.toString());
return _images[imageKey]; return _images[imageKey];
} }
@ -40,11 +40,10 @@ class ImageCache with Logging {
final String imageKey = generateMd5(url + "_" + id.toString()); final String imageKey = generateMd5(url + "_" + id.toString());
// get from storage // get from storage
final String imageString = await getImageAs64BaseString(id, url); final String imageString = (await getImageAs64BaseString(id, url))!;
if (imageString != null) {
_images[imageKey] = imageString; _images[imageKey] = imageString;
_imageMap[imageKey] = true; _imageMap[imageKey] = true;
}
/* final String imageString = await getImageAs64BaseString(id, url); /* final String imageString = await getImageAs64BaseString(id, url);
if (imageString != null) { if (imageString != null) {
@ -67,8 +66,8 @@ class ImageCache with Logging {
return; return;
} }
Future<String> loadImageFromPrefs(String key) async { Future<String?> loadImageFromPrefs(String key) async {
String value = await storage.read(key: key); String? value = await storage.read(key: key);
return value; return value;
} }
@ -83,47 +82,40 @@ class ImageCache with Logging {
// decode bytes from a string // decode bytes from a string
Image imageFrom64BaseString(String base64String) { Image imageFrom64BaseString(String base64String) {
if (base64String == null) {
return null;
}
return Image.memory( return Image.memory(
base64Decode(base64String), base64Decode(base64String),
fit: BoxFit.fill, fit: BoxFit.fill,
); );
} }
Future<Image> getImage(int id, String name) async { Future<Image?> getImage(int id, String name) async {
if (storage == null) { if (name.length == 0) {
return null;
}
if (name == null || name.length == 0) {
return null; return null;
} }
final String imageKey = generateMd5(name + "_" + id.toString()); final String imageKey = generateMd5(name + "_" + id.toString());
final String imageString = await storage.read(key: imageKey); final String? imageString = await storage.read(key: imageKey);
if (imageString == null) {
return null;
}
final Image image = imageFrom64BaseString(imageString); final Image image = imageFrom64BaseString(imageString);
return image; return image;
} }
Future<String> getImageAs64BaseString(int id, String name) async { Future<String?> getImageAs64BaseString(int id, String name) async {
if (name == null) {
return null;
}
final String imageKey = generateMd5(name + "_" + id.toString()); final String imageKey = generateMd5(name + "_" + id.toString());
String imageString; String? imageString;
if (await storage.containsKey(key: imageKey)) { if (await storage.containsKey(key: imageKey)) {
//log(" .. get from storage"); //log(" .. get from storage");
imageString = await storage.read(key: imageKey); imageString = await storage.read(key: imageKey);
} else { } else {
imageString = await downloadAndSaveImage(id, name); imageString = (await downloadAndSaveImage(id, name))!;
//log(" .. downloaded"); //log(" .. downloaded");
} }
return imageString; return imageString;
} }
Future<String> downloadAndSaveImage(int id, String url) async { Future<String?> downloadAndSaveImage(int id, String url) async {
final String imageKey = generateMd5(url + "_" + id.toString()); final String imageKey = generateMd5(url + "_" + id.toString());
if (!await existImageInPrefs(imageKey)) { if (!await existImageInPrefs(imageKey)) {
try { try {
@ -143,12 +135,7 @@ class ImageCache with Logging {
} }
} else { } else {
//log(" .. from storage"); //log(" .. from storage");
final String storageString = await storage.read(key: imageKey); //await storage.read(key: imageKey);
if (storageString != null) {
//log(" .. storage String: " + storageString);
} else {
// log(" .. storage String is NULL");
}
} }
return null; return null;
} }

View File

@ -0,0 +1,14 @@
library network_image_to_byte;
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
Future<Uint8List> networkImageToByte(String path) async {
HttpClient httpClient = HttpClient();
var request = await httpClient.getUrl(Uri.parse(path));
var response = await request.close();
Uint8List bytes = await consolidateHttpClientResponseBytes(response);
return bytes;
}

View File

@ -1,599 +0,0 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
const Duration _kMenuDuration = Duration(milliseconds: 300);
const double _kMenuCloseIntervalEnd = 2.0 / 3.0;
const double _kMenuHorizontalPadding = 0.0;
const double _kMenuMinWidth = 2.0 * _kMenuWidthStep;
const double _kMenuVerticalPadding = 0.0;
const double _kMenuWidthStep = 1.0;
const double _kMenuScreenPadding = 0.0;
// This widget only exists to enable _PopupMenuRoute to save the sizes of
// each menu item. The sizes are used by _PopupMenuRouteLayout to compute the
// y coordinate of the menu's origin so that the center of selected menu
// item lines up with the center of its PopupMenuButton.
class _MenuItem extends SingleChildRenderObjectWidget {
const _MenuItem({
Key key,
@required this.onLayout,
Widget child,
}) : assert(onLayout != null),
super(key: key, child: child);
final ValueChanged<Size> onLayout;
@override
RenderObject createRenderObject(BuildContext context) {
return _RenderMenuItem(onLayout);
}
@override
void updateRenderObject(BuildContext context, covariant _RenderMenuItem renderObject) {
renderObject.onLayout = onLayout;
}
}
class _RenderMenuItem extends RenderShiftedBox {
_RenderMenuItem(this.onLayout, [RenderBox child])
: assert(onLayout != null),
super(child);
ValueChanged<Size> onLayout;
@override
void performLayout() {
if (child == null) {
size = Size.zero;
} else {
child.layout(constraints, parentUsesSize: true);
size = constraints.constrain(child.size);
}
final BoxParentData childParentData = child.parentData;
childParentData.offset = Offset.zero;
onLayout(size);
}
}
/// An item in a material design popup menu.
///
/// To show a popup menu, use the [customShowMenu] function. To create a button that
/// shows a popup menu, consider using [PopupMenuButton].
///
/// To show a checkmark next to a popup menu item, consider using
/// [CheckedPopupMenuItem].
///
/// Typically the [child] of a [CustomPopupMenuItem] is a [Text] widget. More
/// elaborate menus with icons can use a [ListTile]. By default, a
/// [CustomPopupMenuItem] is kMinInteractiveDimension pixels high. If you use a widget
/// with a different height, it must be specified in the [height] property.
///
/// {@tool sample}
///
/// Here, a [Text] widget is used with a popup menu item. The `WhyFarther` type
/// is an enum, not shown here.
///
/// ```dart
/// const CustomPopupMenuItem<WhyFarther>(
/// value: WhyFarther.harder,
/// child: Text('Working a lot harder'),
/// )
/// ```
/// {@end-tool}
///
/// See the example at [PopupMenuButton] for how this example could be used in a
/// complete menu, and see the example at [CheckedPopupMenuItem] for one way to
/// keep the text of [CustomPopupMenuItem]s that use [Text] widgets in their [child]
/// slot aligned with the text of [CheckedPopupMenuItem]s or of [CustomPopupMenuItem]
/// that use a [ListTile] in their [child] slot.
///
/// See also:
///
/// * [PopupMenuDivider], which can be used to divide items from each other.
/// * [CheckedPopupMenuItem], a variant of [CustomPopupMenuItem] with a checkmark.
/// * [customShowMenu], a method to dynamically show a popup menu at a given location.
/// * [PopupMenuButton], an [IconButton] that automatically shows a menu when
/// it is tapped.
class CustomPopupMenuItem<T> extends PopupMenuEntry<T> {
/// Creates an item for a popup menu.
///
/// By default, the item is [enabled].
///
/// The `enabled` and `height` arguments must not be null.
const CustomPopupMenuItem({
Key key,
this.value,
this.enabled = true,
this.height = kMinInteractiveDimension,
this.textStyle,
@required this.child,
}) : assert(enabled != null),
assert(height != null),
super(key: key);
/// The value that will be returned by [customShowMenu] if this entry is selected.
final T value;
/// Whether the user is permitted to select this item.
///
/// Defaults to true. If this is false, then the item will not react to
/// touches.
final bool enabled;
/// The minimum height height of the menu item.
///
/// Defaults to [kMinInteractiveDimension] pixels.
@override
final double height;
/// The text style of the popup menu item.
///
/// If this property is null, then [PopupMenuThemeData.textStyle] is used.
/// If [PopupMenuThemeData.textStyle] is also null, then [ThemeData.textTheme.subhead] is used.
final TextStyle textStyle;
/// The widget below this widget in the tree.
///
/// Typically a single-line [ListTile] (for menus with icons) or a [Text]. An
/// appropriate [DefaultTextStyle] is put in scope for the child. In either
/// case, the text should be short enough that it won't wrap.
final Widget child;
@override
bool represents(T value) => value == this.value;
@override
PopupMenuItemState<T, CustomPopupMenuItem<T>> createState() => PopupMenuItemState<T, CustomPopupMenuItem<T>>();
}
/// The [State] for [CustomPopupMenuItem] subclasses.
///
/// By default this implements the basic styling and layout of Material Design
/// popup menu items.
///
/// The [buildChild] method can be overridden to adjust exactly what gets placed
/// in the menu. By default it returns [CustomPopupMenuItem.child].
///
/// The [handleTap] method can be overridden to adjust exactly what happens when
/// the item is tapped. By default, it uses [Navigator.pop] to return the
/// [CustomPopupMenuItem.value] from the menu route.
///
/// This class takes two type arguments. The second, `W`, is the exact type of
/// the [Widget] that is using this [State]. It must be a subclass of
/// [CustomPopupMenuItem]. The first, `T`, must match the type argument of that widget
/// class, and is the type of values returned from this menu.
class PopupMenuItemState<T, W extends CustomPopupMenuItem<T>> extends State<W> {
/// The menu item contents.
///
/// Used by the [build] method.
///
/// By default, this returns [CustomPopupMenuItem.child]. Override this to put
/// something else in the menu entry.
@protected
Widget buildChild() => widget.child;
/// The handler for when the user selects the menu item.
///
/// Used by the [InkWell] inserted by the [build] method.
///
/// By default, uses [Navigator.pop] to return the [CustomPopupMenuItem.value] from
/// the menu route.
@protected
void handleTap() {
Navigator.pop<T>(context, widget.value);
}
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final PopupMenuThemeData popupMenuTheme = PopupMenuTheme.of(context);
TextStyle style = widget.textStyle ?? popupMenuTheme.textStyle ?? theme.textTheme.subtitle1;
if (!widget.enabled) style = style.copyWith(color: theme.disabledColor);
Widget item = AnimatedDefaultTextStyle(
style: style,
duration: kThemeChangeDuration,
child: Container(
alignment: AlignmentDirectional.centerStart,
constraints: BoxConstraints(minHeight: widget.height),
padding: const EdgeInsets.symmetric(horizontal: _kMenuHorizontalPadding),
child: buildChild(),
),
);
if (!widget.enabled) {
final bool isDark = theme.brightness == Brightness.dark;
item = IconTheme.merge(
data: IconThemeData(opacity: isDark ? 0.5 : 0.38),
child: item,
);
}
return InkWell(
onTap: widget.enabled ? handleTap : null,
canRequestFocus: widget.enabled,
child: item,
);
}
}
class _PopupMenu<T> extends StatelessWidget {
const _PopupMenu({
Key key,
this.route,
this.semanticLabel,
}) : super(key: key);
final _PopupMenuRoute<T> route;
final String semanticLabel;
@override
Widget build(BuildContext context) {
final double unit = 1.0 / (route.items.length + 1.5); // 1.0 for the width and 0.5 for the last item's fade.
final List<Widget> children = <Widget>[];
final PopupMenuThemeData popupMenuTheme = PopupMenuTheme.of(context);
for (int i = 0; i < route.items.length; i += 1) {
final double start = (i + 1) * unit;
final double end = (start + 1.5 * unit).clamp(0.0, 1.0);
final CurvedAnimation opacity = CurvedAnimation(
parent: route.animation,
curve: Interval(start, end),
);
Widget item = route.items[i];
if (route.initialValue != null && route.items[i].represents(route.initialValue)) {
item = Container(
color: Theme.of(context).highlightColor,
child: item,
);
}
children.add(
_MenuItem(
onLayout: (Size size) {
route.itemSizes[i] = size;
},
child: FadeTransition(
opacity: opacity,
child: item,
),
),
);
}
final CurveTween opacity = CurveTween(curve: const Interval(0.0, 1.0 / 3.0));
final CurveTween width = CurveTween(curve: Interval(0.0, unit));
final CurveTween height = CurveTween(curve: Interval(0.0, unit * route.items.length));
final Widget child = ConstrainedBox(
constraints: const BoxConstraints(minWidth: _kMenuMinWidth),
child: IntrinsicWidth(
stepWidth: _kMenuWidthStep,
child: Semantics(
scopesRoute: true,
namesRoute: true,
explicitChildNodes: true,
label: semanticLabel,
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: _kMenuVerticalPadding),
child: ListBody(children: children),
),
),
),
);
return AnimatedBuilder(
animation: route.animation,
builder: (BuildContext context, Widget child) {
return Opacity(
opacity: opacity.evaluate(route.animation),
child: Material(
shape: route.shape ?? popupMenuTheme.shape,
color: route.color ?? popupMenuTheme.color,
type: MaterialType.card,
elevation: route.elevation ?? popupMenuTheme.elevation ?? 8.0,
child: Align(
alignment: AlignmentDirectional.topEnd,
widthFactor: width.evaluate(route.animation),
heightFactor: height.evaluate(route.animation),
child: child,
),
),
);
},
child: child,
);
}
}
// Positioning of the menu on the screen.
class _PopupMenuRouteLayout extends SingleChildLayoutDelegate {
_PopupMenuRouteLayout(this.position, this.itemSizes, this.selectedItemIndex, this.textDirection);
// Rectangle of underlying button, relative to the overlay's dimensions.
final RelativeRect position;
// The sizes of each item are computed when the menu is laid out, and before
// the route is laid out.
List<Size> itemSizes;
// The index of the selected item, or null if PopupMenuButton.initialValue
// was not specified.
final int selectedItemIndex;
// Whether to prefer going to the left or to the right.
final TextDirection textDirection;
// We put the child wherever position specifies, so long as it will fit within
// the specified parent size padded (inset) by 8. If necessary, we adjust the
// child's position so that it fits.
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
// The menu can be at most the size of the overlay minus 8.0 pixels in each
// direction.
return BoxConstraints.loose(constraints.biggest - const Offset(_kMenuScreenPadding * 2.0, _kMenuScreenPadding * 2.0));
}
@override
Offset getPositionForChild(Size size, Size childSize) {
// size: The size of the overlay.
// childSize: The size of the menu, when fully open, as determined by
// getConstraintsForChild.
// Find the ideal vertical position.
double y = position.top;
if (selectedItemIndex != null && itemSizes != null) {
double selectedItemOffset = _kMenuVerticalPadding;
for (int index = 0; index < selectedItemIndex; index += 1) selectedItemOffset += itemSizes[index].height;
selectedItemOffset += itemSizes[selectedItemIndex].height / 2;
y = position.top + (size.height - position.top - position.bottom) / 2.0 - selectedItemOffset;
}
// Find the ideal horizontal position.
double x;
if (position.left > position.right) {
// Menu button is closer to the right edge, so grow to the left, aligned to the right edge.
x = size.width - position.right - childSize.width;
} else if (position.left < position.right) {
// Menu button is closer to the left edge, so grow to the right, aligned to the left edge.
x = position.left;
} else {
// Menu button is equidistant from both edges, so grow in reading direction.
assert(textDirection != null);
switch (textDirection) {
case TextDirection.rtl:
x = size.width - position.right - childSize.width;
break;
case TextDirection.ltr:
x = position.left;
break;
}
}
// Avoid going outside an area defined as the rectangle 8.0 pixels from the
// edge of the screen in every direction.
if (x < _kMenuScreenPadding)
x = _kMenuScreenPadding;
else if (x + childSize.width > size.width - _kMenuScreenPadding) x = size.width - childSize.width - _kMenuScreenPadding;
if (y < _kMenuScreenPadding)
y = _kMenuScreenPadding;
else if (y + childSize.height > size.height - _kMenuScreenPadding) y = size.height - childSize.height - _kMenuScreenPadding;
return Offset(x, y);
}
@override
bool shouldRelayout(_PopupMenuRouteLayout oldDelegate) {
// If called when the old and new itemSizes have been initialized then
// we expect them to have the same length because there's no practical
// way to change length of the items list once the menu has been shown.
assert(itemSizes.length == oldDelegate.itemSizes.length);
return position != oldDelegate.position ||
selectedItemIndex != oldDelegate.selectedItemIndex ||
textDirection != oldDelegate.textDirection ||
!listEquals(itemSizes, oldDelegate.itemSizes);
}
}
class _PopupMenuRoute<T> extends PopupRoute<T> {
_PopupMenuRoute({
this.position,
this.items,
this.initialValue,
this.elevation,
this.theme,
this.popupMenuTheme,
this.barrierLabel,
this.semanticLabel,
this.shape,
this.color,
this.showMenuContext,
this.captureInheritedThemes,
this.barrierColor,
}) : itemSizes = List<Size>(items.length);
final RelativeRect position;
final List<PopupMenuEntry<T>> items;
final List<Size> itemSizes;
final dynamic initialValue;
final double elevation;
final ThemeData theme;
final String semanticLabel;
final ShapeBorder shape;
final Color color;
final PopupMenuThemeData popupMenuTheme;
final BuildContext showMenuContext;
final bool captureInheritedThemes;
final Color barrierColor;
@override
Animation<double> createAnimation() {
return CurvedAnimation(
parent: super.createAnimation(),
curve: Curves.linear,
reverseCurve: const Interval(0.0, _kMenuCloseIntervalEnd),
);
}
@override
Duration get transitionDuration => _kMenuDuration;
@override
bool get barrierDismissible => true;
@override
final String barrierLabel;
@override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
int selectedItemIndex;
if (initialValue != null) {
for (int index = 0; selectedItemIndex == null && index < items.length; index += 1) {
if (items[index].represents(initialValue)) selectedItemIndex = index;
}
}
Widget menu = _PopupMenu<T>(route: this, semanticLabel: semanticLabel);
if (captureInheritedThemes) {
menu = InheritedTheme.captureAll(showMenuContext, menu);
} else {
// For the sake of backwards compatibility. An (unlikely) app that relied
// on having menus only inherit from the material Theme could set
// captureInheritedThemes to false and get the original behavior.
if (theme != null) menu = Theme(data: theme, child: menu);
}
return MediaQuery.removePadding(
context: context,
removeTop: true,
removeBottom: true,
removeLeft: true,
removeRight: true,
child: Builder(
builder: (BuildContext context) {
return CustomSingleChildLayout(
delegate: _PopupMenuRouteLayout(
position,
itemSizes,
selectedItemIndex,
Directionality.of(context),
),
child: menu,
);
},
),
);
}
}
/// Show a popup menu that contains the `items` at `position`.
///
/// `items` should be non-null and not empty.
///
/// If `initialValue` is specified then the first item with a matching value
/// will be highlighted and the value of `position` gives the rectangle whose
/// vertical center will be aligned with the vertical center of the highlighted
/// item (when possible).
///
/// If `initialValue` is not specified then the top of the menu will be aligned
/// with the top of the `position` rectangle.
///
/// In both cases, the menu position will be adjusted if necessary to fit on the
/// screen.
///
/// Horizontally, the menu is positioned so that it grows in the direction that
/// has the most room. For example, if the `position` describes a rectangle on
/// the left edge of the screen, then the left edge of the menu is aligned with
/// the left edge of the `position`, and the menu grows to the right. If both
/// edges of the `position` are equidistant from the opposite edge of the
/// screen, then the ambient [Directionality] is used as a tie-breaker,
/// preferring to grow in the reading direction.
///
/// The positioning of the `initialValue` at the `position` is implemented by
/// iterating over the `items` to find the first whose
/// [CustomPopupMenuEntry.represents] method returns true for `initialValue`, and then
/// summing the values of [CustomPopupMenuEntry.height] for all the preceding widgets
/// in the list.
///
/// The `elevation` argument specifies the z-coordinate at which to place the
/// menu. The elevation defaults to 8, the appropriate elevation for popup
/// menus.
///
/// The `context` argument is used to look up the [Navigator] and [Theme] for
/// the menu. It is only used when the method is called. Its corresponding
/// widget can be safely removed from the tree before the popup menu is closed.
///
/// The `useRootNavigator` argument is used to determine whether to push the
/// menu to the [Navigator] furthest from or nearest to the given `context`. It
/// is `false` by default.
///
/// The `semanticLabel` argument is used by accessibility frameworks to
/// announce screen transitions when the menu is opened and closed. If this
/// label is not provided, it will default to
/// [MaterialLocalizations.popupMenuLabel].
///
/// See also:
///
/// * [CustomPopupMenuItem], a popup menu entry for a single value.
/// * [PopupMenuDivider], a popup menu entry that is just a horizontal line.
/// * [CheckedPopupMenuItem], a popup menu item with a checkmark.
/// * [PopupMenuButton], which provides an [IconButton] that shows a menu by
/// calling this method automatically.
/// * [SemanticsConfiguration.namesRoute], for a description of edge triggered
/// semantics.
Future<T> customShowMenu<T>({
@required BuildContext context,
@required RelativeRect position,
@required List<PopupMenuEntry<T>> items,
T initialValue,
double elevation,
String semanticLabel,
Color barrierColor,
ShapeBorder shape,
Color color,
bool captureInheritedThemes = true,
bool useRootNavigator = false,
}) {
assert(context != null);
assert(position != null);
assert(useRootNavigator != null);
assert(items != null && items.isNotEmpty);
assert(captureInheritedThemes != null);
assert(debugCheckHasMaterialLocalizations(context));
String label = semanticLabel;
switch (Theme.of(context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
label = semanticLabel;
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
label = semanticLabel ?? MaterialLocalizations.of(context)?.popupMenuLabel;
}
return Navigator.of(context, rootNavigator: useRootNavigator).push(
_PopupMenuRoute<T>(
position: position,
items: items,
initialValue: initialValue,
elevation: elevation,
semanticLabel: label,
theme: Theme.of(context),
popupMenuTheme: PopupMenuTheme.of(context),
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: barrierColor,
shape: shape,
color: color,
showMenuContext: context,
captureInheritedThemes: captureInheritedThemes,
),
);
}

View File

@ -26,10 +26,10 @@ class RadarChart extends StatefulWidget {
final int sides; final int sides;
const RadarChart({ const RadarChart({
Key key, Key? key,
@required this.ticks, required this.ticks,
@required this.features, required this.features,
@required this.data, required this.data,
this.reverseAxis = false, this.reverseAxis = false,
this.ticksTextStyle = const TextStyle(color: Colors.grey, fontSize: 12), this.ticksTextStyle = const TextStyle(color: Colors.grey, fontSize: 12),
this.featuresTextStyle = const TextStyle(color: Colors.black, fontSize: 16), this.featuresTextStyle = const TextStyle(color: Colors.black, fontSize: 16),
@ -40,53 +40,46 @@ class RadarChart extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
factory RadarChart.light({ factory RadarChart.light({
@required List<int> ticks, required List<int> ticks,
@required List<String> features, required List<String> features,
@required List<List<int>> data, required List<List<int>> data,
bool reverseAxis = false, bool reverseAxis = false,
bool useSides = false, bool useSides = false,
}) { }) {
return RadarChart( return RadarChart(ticks: ticks, features: features, data: data, reverseAxis: reverseAxis, sides: useSides ? features.length : 0);
ticks: ticks,
features: features,
data: data,
reverseAxis: reverseAxis,
sides: useSides ? features.length : 0);
} }
factory RadarChart.dark({ factory RadarChart.dark({
@required List<int> ticks, required List<int> ticks,
@required List<String> features, required List<String> features,
@required List<List<int>> data, required List<List<int>> data,
bool reverseAxis = false, bool reverseAxis = false,
bool useSides = false, bool useSides = false,
}) { }) {
return RadarChart( return RadarChart(
ticks: ticks, ticks: ticks,
features: features, features: features,
data: data, data: data,
featuresTextStyle: const TextStyle(color: Colors.white, fontSize: 16), featuresTextStyle: const TextStyle(color: Colors.white, fontSize: 16),
outlineColor: Colors.white, outlineColor: Colors.white,
axisColor: Colors.grey, axisColor: Colors.grey,
reverseAxis: reverseAxis, reverseAxis: reverseAxis,
sides: useSides ? features.length : 0); sides: useSides ? features.length : 0);
} }
@override @override
_RadarChartState createState() => _RadarChartState(); _RadarChartState createState() => _RadarChartState();
} }
class _RadarChartState extends State<RadarChart> class _RadarChartState extends State<RadarChart> with SingleTickerProviderStateMixin {
with SingleTickerProviderStateMixin {
double fraction = 0; double fraction = 0;
Animation<double> animation; late Animation<double> animation;
AnimationController animationController; late AnimationController animationController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
animationController = AnimationController( animationController = AnimationController(duration: Duration(milliseconds: 1000), vsync: this);
duration: Duration(milliseconds: 1000), vsync: this);
animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( animation = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
curve: Curves.fastOutSlowIn, curve: Curves.fastOutSlowIn,
@ -113,18 +106,8 @@ class _RadarChartState extends State<RadarChart>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CustomPaint( return CustomPaint(
size: Size(double.infinity, double.infinity), size: Size(double.infinity, double.infinity),
painter: RadarChartPainter( painter: RadarChartPainter(widget.ticks, widget.features, widget.data, widget.reverseAxis, widget.ticksTextStyle,
widget.ticks, widget.featuresTextStyle, widget.outlineColor, widget.axisColor, widget.graphColors, widget.sides, this.fraction),
widget.features,
widget.data,
widget.reverseAxis,
widget.ticksTextStyle,
widget.featuresTextStyle,
widget.outlineColor,
widget.axisColor,
widget.graphColors,
widget.sides,
this.fraction),
); );
} }
@ -160,7 +143,7 @@ class RadarChartPainter extends CustomPainter {
this.graphColors, this.graphColors,
this.sides, this.sides,
this.fraction, this.fraction,
); );
Path variablePath(Size size, double radius, int sides) { Path variablePath(Size size, double radius, int sides) {
var path = Path(); var path = Path();
@ -223,14 +206,10 @@ class RadarChartPainter extends CustomPainter {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
) )
..layout(minWidth: 0, maxWidth: size.width) ..layout(minWidth: 0, maxWidth: size.width)
..paint(canvas, Offset(centerX, centerY - ticksTextStyle.fontSize)); ..paint(canvas, Offset(centerX, centerY - ticksTextStyle.fontSize!));
} }
tickLabels tickLabels.sublist(reverseAxis ? 1 : 0, reverseAxis ? ticks.length : ticks.length - 1).asMap().forEach((index, tick) {
.sublist(
reverseAxis ? 1 : 0, reverseAxis ? ticks.length : ticks.length - 1)
.asMap()
.forEach((index, tick) {
var tickRadius = tickDistance * (index + 1); var tickRadius = tickDistance * (index + 1);
canvas.drawPath(variablePath(size, tickRadius, this.sides), ticksPaint); canvas.drawPath(variablePath(size, tickRadius, this.sides), ticksPaint);
@ -240,8 +219,7 @@ class RadarChartPainter extends CustomPainter {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
) )
..layout(minWidth: 0, maxWidth: size.width) ..layout(minWidth: 0, maxWidth: size.width)
..paint(canvas, ..paint(canvas, Offset(centerX, centerY - tickRadius - ticksTextStyle.fontSize!));
Offset(centerX, centerY - tickRadius - ticksTextStyle.fontSize));
}); });
// Painting the axis for each given feature // Painting the axis for each given feature
@ -251,16 +229,14 @@ class RadarChartPainter extends CustomPainter {
var xAngle = cos(angle * index - pi / 2); var xAngle = cos(angle * index - pi / 2);
var yAngle = sin(angle * index - pi / 2); var yAngle = sin(angle * index - pi / 2);
var featureOffset = var featureOffset = Offset(centerX + radius * xAngle, centerY + radius * yAngle);
Offset(centerX + radius * xAngle, centerY + radius * yAngle);
canvas.drawLine(centerOffset, featureOffset, ticksPaint); canvas.drawLine(centerOffset, featureOffset, ticksPaint);
var featureLabelFontHeight = featuresTextStyle.fontSize; var featureLabelFontHeight = featuresTextStyle.fontSize;
var featureLabelFontWidth = featuresTextStyle.fontSize - 5; var featureLabelFontWidth = featuresTextStyle.fontSize! - 5;
var labelYOffset = yAngle < 0 ? -featureLabelFontHeight : 0; var labelYOffset = yAngle < 0 ? -featureLabelFontHeight! : 0;
var labelXOffset = var labelXOffset = xAngle < 0 ? -featureLabelFontWidth * feature.length : 0;
xAngle < 0 ? -featureLabelFontWidth * feature.length : 0;
TextPainter( TextPainter(
text: TextSpan(text: feature, style: featuresTextStyle), text: TextSpan(text: feature, style: featuresTextStyle),
@ -268,10 +244,7 @@ class RadarChartPainter extends CustomPainter {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
) )
..layout(minWidth: 0, maxWidth: size.width) ..layout(minWidth: 0, maxWidth: size.width)
..paint( ..paint(canvas, Offset(featureOffset.dx + labelXOffset, featureOffset.dy + labelYOffset));
canvas,
Offset(featureOffset.dx + labelXOffset,
featureOffset.dy + labelYOffset));
}); });
// Painting each graph // Painting each graph
@ -304,11 +277,9 @@ class RadarChartPainter extends CustomPainter {
var scaledPoint = scale * point * fraction; var scaledPoint = scale * point * fraction;
if (reverseAxis) { if (reverseAxis) {
path.lineTo(centerX + (radius * fraction - scaledPoint) * xAngle, path.lineTo(centerX + (radius * fraction - scaledPoint) * xAngle, centerY + (radius * fraction - scaledPoint) * yAngle);
centerY + (radius * fraction - scaledPoint) * yAngle);
} else { } else {
path.lineTo( path.lineTo(centerX + scaledPoint * xAngle, centerY + scaledPoint * yAngle);
centerX + scaledPoint * xAngle, centerY + scaledPoint * yAngle);
} }
}); });

View File

@ -1,407 +0,0 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'dropdown_search.dart';
class SelectDialog<T> extends StatefulWidget {
final T selectedValue;
final List<T> items;
final bool showSearchBox;
final bool isFilteredOnline;
final ValueChanged<T> onChanged;
final DropdownSearchOnFind<T> onFind;
final DropdownSearchPopupItemBuilder<T> itemBuilder;
final InputDecoration searchBoxDecoration;
final DropdownSearchItemAsString<T> itemAsString;
final DropdownSearchFilterFn<T> filterFn;
final String hintText;
final double maxHeight;
final double dialogMaxWidth;
final Widget popupTitle;
final bool showSelectedItem;
final DropdownSearchCompareFn<T> compareFn;
final DropdownSearchPopupItemEnabled<T> itemDisabled;
///custom layout for empty results
final EmptyBuilder emptyBuilder;
///custom layout for loading items
final LoadingBuilder loadingBuilder;
///custom layout for error
final ErrorBuilder errorBuilder;
///the search box will be focused if true
final bool autoFocusSearchBox;
///text controller to set default search word for example
final TextEditingController searchBoxController;
///delay before searching
final Duration searchDelay;
const SelectDialog({
Key key,
this.popupTitle,
this.items,
this.maxHeight,
this.showSearchBox = false,
this.isFilteredOnline = false,
this.onChanged,
this.selectedValue,
this.onFind,
this.itemBuilder,
this.searchBoxDecoration,
this.hintText,
this.itemAsString,
this.filterFn,
this.showSelectedItem = false,
this.compareFn,
this.emptyBuilder,
this.loadingBuilder,
this.errorBuilder,
this.autoFocusSearchBox = false,
this.dialogMaxWidth,
this.itemDisabled,
this.searchBoxController,
this.searchDelay,
}) : super(key: key);
@override
_SelectDialogState<T> createState() => _SelectDialogState<T>();
}
class _SelectDialogState<T> extends State<SelectDialog<T>> {
final FocusNode focusNode = new FocusNode();
final StreamController<List<T>> _itemsStream = StreamController();
final ValueNotifier<bool> _loadingNotifier = ValueNotifier(false);
final List<T> _items = List<T>();
Debouncer _debouncer;
@override
void initState() {
super.initState();
_debouncer = Debouncer(delay: widget.searchDelay);
Future.delayed(
Duration.zero,
() => manageItemsByFilter(widget.searchBoxController?.text ?? '', isFistLoad: true),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
if (widget.autoFocusSearchBox) FocusScope.of(context).requestFocus(focusNode);
}
@override
void dispose() {
_itemsStream.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
Size deviceSize = MediaQuery.of(context).size;
bool isTablet = deviceSize.width > deviceSize.height;
double maxHeight = deviceSize.height * (isTablet ? .8 : .6);
double maxWidth = deviceSize.width * (isTablet ? .7 : .9);
return Container(
width: widget.dialogMaxWidth ?? maxWidth,
constraints: BoxConstraints(maxHeight: widget.maxHeight ?? maxHeight),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_searchField(),
Expanded(
child: Stack(
children: <Widget>[
StreamBuilder<List<T>>(
stream: _itemsStream.stream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return _errorWidget(snapshot?.error);
} else if (!snapshot.hasData) {
return _loadingWidget();
} else if (snapshot.data.isEmpty) {
if (widget.emptyBuilder != null)
return widget.emptyBuilder(context, widget.searchBoxController?.text);
else
return const Center(
child: const Text("No data found"),
);
}
return ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.symmetric(vertical: 0),
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
var item = snapshot.data[index];
return _itemWidget(item);
},
);
},
),
_loadingWidget()
],
),
),
],
),
);
}
void _showErrorDialog(dynamic error) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Error while getting online items"),
content: _errorWidget(error),
actions: <Widget>[
FlatButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop(false);
},
)
],
);
},
);
}
Widget _errorWidget(dynamic error) {
if (widget.errorBuilder != null)
return widget.errorBuilder(context, widget.searchBoxController?.text, error);
else
return Padding(
padding: EdgeInsets.all(8),
child: Text(
error?.toString() ?? 'Error',
),
);
}
Widget _loadingWidget() {
return ValueListenableBuilder(
valueListenable: _loadingNotifier,
builder: (context, bool isLoading, wid) {
if (isLoading) {
if (widget.loadingBuilder != null)
return widget.loadingBuilder(context, widget.searchBoxController?.text);
else
return Padding(
padding: const EdgeInsets.all(24.0),
child: const Center(
child: const CircularProgressIndicator(),
),
);
}
return Container();
});
}
void _onTextChanged(String filter) async {
manageItemsByFilter(filter);
}
///Function that filter item (online and offline) base on user filter
///[filter] is the filter keyword
///[isFirstLoad] true if it's the first time we load data from online, false other wises
void manageItemsByFilter(String filter, {bool isFistLoad = false}) async {
_loadingNotifier.value = true;
String encoded(String item) {
String encodedItem = "";
for (int i = 0; i < item.length; i++) {
var char = item[i];
switch (char) {
case 'Á':
case 'á':
case 'ą':
case 'ä':
char = 'a';
break;
case 'é':
case 'É':
char = 'e';
break;
case 'ú':
case 'ű':
case 'ü':
case 'Ú':
case 'Ű':
case 'Ü':
char = 'u';
break;
case 'ö':
case 'ő':
case 'ó':
case 'Ö':
case 'Ő':
case 'Ó':
char = 'o';
break;
case 'í':
case 'Í':
char = 'i';
break;
}
encodedItem += char;
}
return encodedItem;
}
List<T> applyFilter(String filter) {
return _items.where((i) {
if (widget.filterFn != null) {
return (widget.filterFn(i, filter));
} else if (i.toString().toLowerCase().contains(filter.toLowerCase()) ||
encoded(i.toString()).toLowerCase().contains(encoded(filter.toLowerCase()))) {
return true;
} else if (widget.itemAsString != null) {
bool found = (widget.itemAsString(i))?.toLowerCase()?.contains(filter.toLowerCase()) ?? false;
if (!found) {
found = (encoded(widget.itemAsString(i)))?.toLowerCase()?.contains(encoded(filter.toLowerCase())) ?? false;
}
return found;
}
return false;
}).toList();
}
//load offline data for the first time
if (isFistLoad && widget.items != null) _items.addAll(widget.items);
//manage offline items
if (widget.onFind != null && (widget.isFilteredOnline || isFistLoad)) {
try {
final List<T> onlineItems = List();
onlineItems.addAll(await widget.onFind(filter) ?? List());
//Remove all old data
_items.clear();
//add offline items
if (widget.items != null) {
_items.addAll(widget.items);
//if filter online we filter only local list based on entred keyword (filter)
if (widget.isFilteredOnline == true) {
var filteredLocalList = applyFilter(filter);
_items.clear();
_items.addAll(filteredLocalList);
}
}
//add new online items to list
_items.addAll(onlineItems);
_addDataToStream(applyFilter(filter));
} catch (e) {
_addErrorToStream(e);
//if offline items count > 0 , the error will be not visible for the user
//As solution we show it in dialog
if (widget.items != null && widget.items.isNotEmpty) {
_showErrorDialog(e);
_addDataToStream(applyFilter(filter));
}
}
} else {
_addDataToStream(applyFilter(filter));
}
_loadingNotifier.value = false;
}
void _addDataToStream(List<T> data) {
if (_itemsStream.isClosed) return;
_itemsStream.add(data);
}
void _addErrorToStream(Object error, [StackTrace stackTrace]) {
if (_itemsStream.isClosed) return;
_itemsStream.addError(error, stackTrace);
}
Widget _itemWidget(T item) {
if (widget.itemBuilder != null)
return InkWell(
child: widget.itemBuilder(
context,
item,
_manageSelectedItemVisibility(item),
),
onTap: widget.itemDisabled != null && (widget.itemDisabled(item) ?? false) == true
? null
: () {
Navigator.pop(context, item);
if (widget.onChanged != null) widget.onChanged(item);
},
);
else
return ListTile(
title: Text(
widget.itemAsString != null ? (widget.itemAsString(item) ?? "") : item.toString(),
),
selected: _manageSelectedItemVisibility(item),
onTap: widget.itemDisabled != null && (widget.itemDisabled(item) ?? false) == true
? null
: () {
Navigator.pop(context, item);
if (widget.onChanged != null) widget.onChanged(item);
},
);
}
/// selected item will be highlighted only when [widget.showSelectedItem] is true,
/// if our object is String [widget.compareFn] is not required , other wises it's required
bool _manageSelectedItemVisibility(T item) {
if (!widget.showSelectedItem) return false;
if (T == String) {
return item == widget.selectedValue;
} else {
return widget.compareFn(item, widget.selectedValue);
}
}
Widget _searchField() {
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: <Widget>[
widget.popupTitle ?? const SizedBox.shrink(),
if (widget.showSearchBox)
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: widget.searchBoxController,
focusNode: focusNode,
onChanged: (f) => _debouncer(() {
_onTextChanged(f);
}),
decoration: widget.searchBoxDecoration ??
InputDecoration(
hintText: widget.hintText,
border: const OutlineInputBorder(),
contentPadding: const EdgeInsets.symmetric(horizontal: 16),
),
),
)
]);
}
}
class Debouncer {
final Duration delay;
Timer _timer;
Debouncer({this.delay});
call(Function action) {
_timer?.cancel();
_timer = Timer(delay ?? const Duration(milliseconds: 500), action);
}
}

View File

@ -0,0 +1,70 @@
library transparent_image;
import 'dart:typed_data';
final Uint8List kTransparentImage = new Uint8List.fromList(<int>[
0x89,
0x50,
0x4E,
0x47,
0x0D,
0x0A,
0x1A,
0x0A,
0x00,
0x00,
0x00,
0x0D,
0x49,
0x48,
0x44,
0x52,
0x00,
0x00,
0x00,
0x01,
0x00,
0x00,
0x00,
0x01,
0x08,
0x06,
0x00,
0x00,
0x00,
0x1F,
0x15,
0xC4,
0x89,
0x00,
0x00,
0x00,
0x0A,
0x49,
0x44,
0x41,
0x54,
0x78,
0x9C,
0x63,
0x00,
0x01,
0x00,
0x00,
0x05,
0x00,
0x01,
0x0D,
0x0A,
0x2D,
0xB4,
0x00,
0x00,
0x00,
0x00,
0x49,
0x45,
0x4E,
0x44,
0xAE,
]);

View File

@ -30,8 +30,8 @@ class TreeView extends InheritedWidget {
final bool startExpanded; final bool startExpanded;
TreeView({ TreeView({
Key key, Key? key,
@required List<Widget> children, required List<Widget> children,
bool startExpanded = false, bool startExpanded = false,
}) : this.children = children, }) : this.children = children,
this.startExpanded = startExpanded, this.startExpanded = startExpanded,
@ -42,7 +42,7 @@ class TreeView extends InheritedWidget {
), ),
); );
static TreeView of(BuildContext context) { static TreeView? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType(aspect: TreeView); return context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
} }
@ -59,7 +59,7 @@ class _TreeViewData extends StatefulWidget {
final List<Widget> children; final List<Widget> children;
_TreeViewData({ _TreeViewData({
this.children, required this.children,
}); });
@override @override
@ -69,14 +69,14 @@ class _TreeViewData extends StatefulWidget {
class __TreeViewDataState extends State<_TreeViewData> { class __TreeViewDataState extends State<_TreeViewData> {
final ScrollController _controller = ScrollController(); final ScrollController _controller = ScrollController();
final Stream stream = TreeViewStream().stream; final Stream stream = TreeViewStream().stream;
var subscription; late var subscription;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
/// 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((_) {
final double cHeight = MediaQuery.of(context).size.height; final double cHeight = MediaQuery.of(context).size.height;
subscription = stream.listen((value) { subscription = stream.listen((value) {
if (value) { if (value) {
@ -120,43 +120,41 @@ class __TreeViewDataState extends State<_TreeViewData> {
} }
class TreeViewChild extends StatefulWidget { class TreeViewChild extends StatefulWidget {
final bool startExpanded; final bool? startExpanded;
final Widget parent; final Widget parent;
final List<Widget> children; final List<Widget> children;
final VoidCallback onTap; final VoidCallback? onTap;
TreeViewChild({ TreeViewChild({
@required this.parent, required this.parent,
@required this.children, required this.children,
this.startExpanded, this.startExpanded,
this.onTap, this.onTap,
Key key, Key? key,
}) : super(key: key) { }) : super(key: key);
assert(parent != null);
assert(children != null);
}
@override @override
TreeViewChildState createState() => TreeViewChildState(); TreeViewChildState createState() => TreeViewChildState();
TreeViewChild copyWith( TreeViewChild copyWith(
TreeViewChild source, { TreeViewChild source, {
bool startExpanded, bool? startExpanded,
Widget parent, Widget? parent,
List<Widget> children, List<Widget>? children,
VoidCallback onTap, VoidCallback? onTap,
}) { }) {
return TreeViewChild( return TreeViewChild(
parent: parent ?? source.parent, parent: parent ?? source.parent,
children: children ?? source.children, children: children ?? source.children,
startExpanded: startExpanded ?? source.startExpanded, startExpanded: startExpanded ?? source.startExpanded,
onTap: onTap ?? source.onTap, onTap: onTap ?? source.onTap,
key: key,
); );
} }
} }
class TreeViewChildState extends State<TreeViewChild> with Common { class TreeViewChildState extends State<TreeViewChild> with Common {
bool isExpanded; late bool? isExpanded;
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>(); final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
@override @override
@ -167,7 +165,7 @@ class TreeViewChildState extends State<TreeViewChild> with Common {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
isExpanded = widget.startExpanded ?? TreeView.of(context).startExpanded; isExpanded = widget.startExpanded ?? TreeView.of(context)!.startExpanded;
super.didChangeDependencies(); super.didChangeDependencies();
} }
@ -177,17 +175,14 @@ class TreeViewChildState extends State<TreeViewChild> with Common {
key: listKey, key: listKey,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
GestureDetector( GestureDetector(child: widget.parent, onTap: widget.onTap ?? () => toggleExpanded()),
child: widget.parent,
onTap: widget.onTap ?? () => toggleExpanded(),
),
Flexible( Flexible(
child: Container( child: Container(
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: Duration(milliseconds: 200), duration: Duration(milliseconds: 200),
reverseDuration: Duration(milliseconds: 200), reverseDuration: Duration(milliseconds: 200),
switchInCurve: Curves.easeIn, switchInCurve: Curves.easeIn,
child: isExpanded child: isExpanded!
? Column( ? Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: widget.children, children: widget.children,
@ -202,14 +197,14 @@ class TreeViewChildState extends State<TreeViewChild> with Common {
void toggleExpanded() { void toggleExpanded() {
setState(() { setState(() {
this.isExpanded = !this.isExpanded; this.isExpanded = !this.isExpanded!;
TreeViewStream().positionY = getPosition(); TreeViewStream().positionY = getPosition();
TreeViewStream().getStreamController().add(this.isExpanded); TreeViewStream().getStreamController().add(this.isExpanded);
}); });
} }
double getPosition() { double getPosition() {
RenderBox box = listKey.currentContext.findRenderObject(); RenderBox? box = listKey.currentContext!.findRenderObject() as RenderBox;
Offset position = box.localToGlobal(Offset.zero); //this is global position Offset position = box.localToGlobal(Offset.zero); //this is global position
double y = position.dy; double y = position.dy;
return y; return y;

View File

@ -6,7 +6,6 @@ import 'package:aitrainer_app/repository/workout_tree_repository.dart';
import 'package:aitrainer_app/service/firebase_api.dart'; import 'package:aitrainer_app/service/firebase_api.dart';
import 'package:aitrainer_app/util/session.dart'; import 'package:aitrainer_app/util/session.dart';
import 'package:aitrainer_app/view/account.dart'; import 'package:aitrainer_app/view/account.dart';
import 'package:aitrainer_app/view/custom_exercise_page.dart';
import 'package:aitrainer_app/view/customer_bodytype_animation.dart'; 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';
@ -38,7 +37,7 @@ import 'package:aitrainer_app/view/test_set_new.dart';
import 'package:aitrainer_app/widgets/home.dart'; import 'package:aitrainer_app/widgets/home.dart';
import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_analytics/observer.dart'; import 'package:firebase_analytics/observer.dart';
import 'package:flurry/flurry.dart'; import 'package:aitrainer_app/library/flurry.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -103,7 +102,7 @@ Future<Null> main() async {
} else { } else {
// In production mode report to the application zone to report to // In production mode report to the application zone to report to
// Sentry. // Sentry.
Zone.current.handleUncaughtError(details.exception, details.stack); Zone.current.handleUncaughtError(details.exception, details.stack!);
} }
}; };
@ -134,7 +133,7 @@ Future<Null> main() async {
create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository), create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository),
), ),
BlocProvider<SettingsBloc>( BlocProvider<SettingsBloc>(
create: (BuildContext context) => SettingsBloc(), create: (BuildContext context) => SettingsBloc(context: context),
), ),
BlocProvider<AccountBloc>( BlocProvider<AccountBloc>(
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()), create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
@ -199,13 +198,13 @@ class WorkoutTestApp extends StatelessWidget {
const Locale('hu', "HU"), // Hungarian const Locale('hu', "HU"), // Hungarian
// ... other locales the app supports // ... other locales the app supports
], ],
localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) { localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) {
//myLocale = deviceLocale ; //myLocale = deviceLocale ;
// here you make your app language similar to device language , // here you make your app language similar to device language ,
// but you should check whether the localization is supported by your app // but you should check whether the localization is supported by your app
Locale realSupportedLocale = Locale('en', "US"); Locale realSupportedLocale = Locale('en', "US");
supportedLocales.forEach((supportedLocale) { supportedLocales.forEach((supportedLocale) {
if (locale != null && supportedLocale != null && supportedLocale.countryCode == locale.countryCode) { if (locale != null && supportedLocale.countryCode == locale.countryCode) {
realSupportedLocale = supportedLocale; realSupportedLocale = supportedLocale;
} }
}); });
@ -223,7 +222,6 @@ class WorkoutTestApp extends StatelessWidget {
'customerWelcomePage': (context) => CustomerWelcomePage(), 'customerWelcomePage': (context) => CustomerWelcomePage(),
'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(), 'customerExerciseDevicePage': (context) => CustomerExerciseDevicePage(),
'exerciseNewPage': (context) => ExerciseNewPage(), 'exerciseNewPage': (context) => ExerciseNewPage(),
'exerciseCustomPage': (context) => CustomExercisePage(),
'exerciseControlPage': (context) => ExerciseControlPage(), 'exerciseControlPage': (context) => ExerciseControlPage(),
'login': (context) => LoginPage(), 'login': (context) => LoginPage(),
'resetPassword': (context) => ResetPasswordPage(), 'resetPassword': (context) => ResetPasswordPage(),

View File

@ -8,6 +8,7 @@ import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise.dart';
import 'package:aitrainer_app/model/model_change.dart'; import 'package:aitrainer_app/model/model_change.dart';
import 'package:aitrainer_app/model/product.dart' as wt_product; import 'package:aitrainer_app/model/product.dart' as wt_product;
import 'package:aitrainer_app/model/product.dart';
import 'package:aitrainer_app/model/product_test.dart'; import 'package:aitrainer_app/model/product_test.dart';
import 'package:aitrainer_app/model/property.dart'; import 'package:aitrainer_app/model/property.dart';
import 'package:aitrainer_app/model/purchase.dart'; import 'package:aitrainer_app/model/purchase.dart';
@ -20,7 +21,7 @@ import 'package:aitrainer_app/main.dart';
import 'package:aitrainer_app/util/enums.dart'; import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/env.dart'; import 'package:aitrainer_app/util/env.dart';
import 'package:aitrainer_app/util/track.dart'; import 'package:aitrainer_app/util/track.dart';
import 'package:flurry/flurry.dart'; import 'package:aitrainer_app/library/flurry.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart'; import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
import 'package:package_info/package_info.dart'; import 'package:package_info/package_info.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -57,22 +58,22 @@ class Cache with Logging {
static final Cache _singleton = Cache._internal(); static final Cache _singleton = Cache._internal();
// Keys to store and fetch data from SharedPreferences // Keys to store and fetch data from SharedPreferences
static final String authTokenKey = 'auth_token'; static final String authTokenKey = "auth_token";
static final String customerIdKey = 'customer_id'; static final String customerIdKey = "customer_id";
static final String firebaseUidKey = 'firebase_uid'; static final String firebaseUidKey = "firebase_uid";
static final String lastStoreDateKey = 'last_date'; static final String lastStoreDateKey = "last_date";
static final String isRegisteredKey = 'is_registered'; static final String isRegisteredKey = "is_registered";
static final String isLoggedInKey = 'is_logged_in'; static final String isLoggedInKey = "is_logged_in";
static final String langKey = 'lang'; static final String langKey = "lang";
static final String serverKey = 'live'; static final String serverKey = "live";
static final String hardwareKey = 'hardware'; static final String hardwareKey = "hardware";
static final String loginTypeKey = 'login_type'; static final String loginTypeKey = "login_type";
static final String timerDisplayKey = 'timer_display'; static final String timerDisplayKey = "timer_display";
static final String activeExercisePlanKey = 'active_exercise_plan'; static final String activeExercisePlanKey = "active_exercise_plan";
static final String activeExercisePlanDateKey = 'active_exercise_plan_date'; static final String activeExercisePlanDateKey = "active_exercise_plan_date";
static final String activeExercisePlanDetailsKey = 'active_exercise_details_plan'; static final String activeExercisePlanDetailsKey = "active_exercise_details_plan";
static final String exerciseLogSeenKey = 'exercise_log_seen'; static final String exerciseLogSeenKey = "exercise_log_seen";
static final String muscleDevelopmentSeenKey = 'muscle_development_seen_key'; static final String muscleDevelopmentSeenKey = "muscle_development_seen_key";
static String baseUrl = 'http://aitrainer.info:8888/api/'; static String baseUrl = 'http://aitrainer.info:8888/api/';
static final String mediaUrl = 'https://aitrainer.info:4343/media/'; static final String mediaUrl = 'https://aitrainer.info:4343/media/';
@ -80,51 +81,51 @@ class Cache with Logging {
static final String password = 'andio2009'; static final String password = 'andio2009';
String authToken = ""; String authToken = "";
AccessToken accessTokenFacebook; AccessToken? accessTokenFacebook;
Customer userLoggedIn; Customer? userLoggedIn;
String firebaseUid; String? firebaseUid;
LoginType loginType; late LoginType loginType;
PackageInfo packageInfo; late PackageInfo packageInfo;
bool hasPurchased = false; bool hasPurchased = false;
bool firstLoad = true; bool firstLoad = true;
List<ExerciseType> _exerciseTypes; List<ExerciseType>? _exerciseTypes;
List<ExerciseTree> _exerciseTree; List<ExerciseTree>? _exerciseTree;
List<Exercise> _exercises; List<Exercise>? _exercises;
ExercisePlan _myExercisePlan; ExercisePlan? _myExercisePlan;
List<Property> _properties; List<Property>? _properties;
List<wt_product.Product> _products; List<wt_product.Product>? _products;
List<Purchase> _purchases = List(); List<Purchase> _purchases = [];
List<ProductTest> _productTests; List<ProductTest>? _productTests;
List<ExercisePlanTemplate> _exercisePlanTemplates = List(); List<ExercisePlanTemplate> _exercisePlanTemplates = [];
ExercisePlan activeExercisePlan; ExercisePlan? activeExercisePlan;
List<ExercisePlanDetail> activeExercisePlanDetails; List<ExercisePlanDetail>? activeExercisePlanDetails;
List<ExerciseDevice> _devices; List<ExerciseDevice>? _devices;
List<CustomerExerciseDevice> _customerDevices; List<CustomerExerciseDevice>? _customerDevices;
LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>(); LinkedHashMap<int, ExercisePlanDetail> _myExercisesPlanDetails = LinkedHashMap<int, ExercisePlanDetail>();
LinkedHashMap _tree = LinkedHashMap<String, WorkoutMenuTree>(); LinkedHashMap<String, WorkoutMenuTree> _tree = LinkedHashMap<String, WorkoutMenuTree>();
double _percentExercises = -1; double _percentExercises = -1;
Customer _trainee; Customer? _trainee;
List<Exercise> _exercisesTrainee; List<Exercise>? _exercisesTrainee;
ExercisePlan _traineeExercisePlan; ExercisePlan? _traineeExercisePlan;
LinkedHashMap<String, int> _badges = LinkedHashMap(); LinkedHashMap<String, int> _badges = LinkedHashMap();
List deviceLanguages; List? deviceLanguages;
String startPage = "home"; String startPage = "home";
String testEnvironment; late String testEnvironment;
bool liveServer = true; bool liveServer = true;
bool hasHardware = false; bool? hasHardware = false;
bool isExerciseLogSeen = false; bool? isExerciseLogSeen = false;
bool isMuscleDevelopmentSeen = false; bool? isMuscleDevelopmentSeen = false;
factory Cache() { factory Cache() {
return _singleton; return _singleton;
@ -186,11 +187,8 @@ class Cache with Logging {
DateFormat format = DateFormat("yyyy-MM-dd HH:mm:ss"); DateFormat format = DateFormat("yyyy-MM-dd HH:mm:ss");
DateTime savedPlanDate; DateTime savedPlanDate;
try {
savedPlanDate = format.parse(savedPlanDateString); savedPlanDate = format.parse(savedPlanDateString);
} on Exception catch (e) {
return;
}
final DateTime now = DateTime.now(); final DateTime now = DateTime.now();
final DateTime added = savedPlanDate.add(Duration(days: 1)); final DateTime added = savedPlanDate.add(Duration(days: 1));
@ -198,13 +196,13 @@ class Cache with Logging {
return; return;
} }
String exercisePlanJson = sharedPreferences.getString(Cache.activeExercisePlanKey); String? exercisePlanJson = sharedPreferences.getString(Cache.activeExercisePlanKey);
if (exercisePlanJson != null) { if (exercisePlanJson != null) {
final Map<String, dynamic> map = JsonDecoder().convert(exercisePlanJson); final Map<String, dynamic> map = JsonDecoder().convert(exercisePlanJson);
this.activeExercisePlan = ExercisePlan.fromJson(map); this.activeExercisePlan = ExercisePlan.fromJson(map);
} }
String detailsJson = sharedPreferences.getString(Cache.activeExercisePlanDetailsKey); String? detailsJson = sharedPreferences.getString(Cache.activeExercisePlanDetailsKey);
if (detailsJson != null) { if (detailsJson != null) {
print("Details $detailsJson"); print("Details $detailsJson");
Iterable json = jsonDecode(detailsJson); Iterable json = jsonDecode(detailsJson);
@ -225,7 +223,7 @@ class Cache with Logging {
} }
void getHardware(SharedPreferences prefs) { void getHardware(SharedPreferences prefs) {
final bool hasHardware = prefs.getBool(Cache.hardwareKey); final bool? hasHardware = prefs.getBool(Cache.hardwareKey);
this.hasHardware = hasHardware; this.hasHardware = hasHardware;
if (hasHardware == null) { if (hasHardware == null) {
this.hasHardware = false; this.hasHardware = false;
@ -236,7 +234,7 @@ class Cache with Logging {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
final bool selectedHardware = sharedPreferences.getBool(Cache.hardwareKey); final bool? selectedHardware = sharedPreferences.getBool(Cache.hardwareKey);
return selectedHardware == null; return selectedHardware == null;
} }
@ -254,7 +252,7 @@ class Cache with Logging {
print("TestEnv $baseUrl"); print("TestEnv $baseUrl");
return; return;
} }
final bool live = prefs.getBool(Cache.serverKey); final bool? live = prefs.getBool(Cache.serverKey);
if (live == null) { if (live == null) {
baseUrl = 'http://aitrainer.app:8888/api/'; baseUrl = 'http://aitrainer.app:8888/api/';
print("Live Env $baseUrl"); print("Live Env $baseUrl");
@ -274,7 +272,7 @@ class Cache with Logging {
Future<void> setLoginTypeFromPrefs() async { Future<void> setLoginTypeFromPrefs() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
final String loginType = sharedPreferences.getString(Cache.loginTypeKey); final String? loginType = sharedPreferences.getString(Cache.loginTypeKey);
LoginType type = LoginType.email; LoginType type = LoginType.email;
if (loginType == LoginType.apple.toString()) { if (loginType == LoginType.apple.toString()) {
type = LoginType.apple; type = LoginType.apple;
@ -289,7 +287,7 @@ class Cache with Logging {
Cache().setLoginType(type); Cache().setLoginType(type);
} }
static String getToken(SharedPreferences prefs) { static String? getToken(SharedPreferences prefs) {
return prefs.getString(authTokenKey); return prefs.getString(authTokenKey);
} }
@ -305,10 +303,10 @@ class Cache with Logging {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
userLoggedIn = customer; userLoggedIn = customer;
final String uid = Cache().firebaseUid; final String uid = Cache().firebaseUid!;
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString());
await setPreferences(prefs, SharePrefsChange.registration, customer.customerId, uid); await setPreferences(prefs, SharePrefsChange.registration, customer.customerId!, uid);
} }
afterLogin(Customer customer) async { afterLogin(Customer customer) async {
@ -317,21 +315,21 @@ class Cache with Logging {
userLoggedIn = customer; userLoggedIn = customer;
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString());
await setPreferences(prefs, SharePrefsChange.login, customer.customerId, Cache().firebaseUid); await setPreferences(prefs, SharePrefsChange.login, customer.customerId!, Cache().firebaseUid!);
} }
afterFirebaseLogin() async { afterFirebaseLogin() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString());
await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn!.customerId!, Cache().firebaseUid!);
} }
afterFacebookLogin() async { afterFacebookLogin() async {
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
SharedPreferences sharedPreferences = await prefs; SharedPreferences sharedPreferences = await prefs;
sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString()); sharedPreferences.setString(Cache.loginTypeKey, Cache().getLoginType().toString());
await setPreferences(prefs, SharePrefsChange.login, userLoggedIn.customerId, Cache().firebaseUid); await setPreferences(prefs, SharePrefsChange.login, userLoggedIn!.customerId!, Cache().firebaseUid!);
} }
logout() async { logout() async {
@ -345,7 +343,7 @@ class Cache with Logging {
_percentExercises = -1; _percentExercises = -1;
_exercisesTrainee = null; _exercisesTrainee = null;
_traineeExercisePlan = null; _traineeExercisePlan = null;
_exercises = List(); _exercises = [];
_myExercisesPlanDetails = LinkedHashMap(); _myExercisesPlanDetails = LinkedHashMap();
log("Trainees is null? " + (_trainee == null).toString()); log("Trainees is null? " + (_trainee == null).toString());
Future<SharedPreferences> prefs = SharedPreferences.getInstance(); Future<SharedPreferences> prefs = SharedPreferences.getInstance();
@ -372,7 +370,7 @@ class Cache with Logging {
} else if (type == SharePrefsChange.logout) { } else if (type == SharePrefsChange.logout) {
sharedPreferences.setBool(Cache.isLoggedInKey, false); sharedPreferences.setBool(Cache.isLoggedInKey, false);
sharedPreferences.setInt(Cache.customerIdKey, 0); sharedPreferences.setInt(Cache.customerIdKey, 0);
sharedPreferences.setString(Cache.firebaseUidKey, null); sharedPreferences.setString(Cache.firebaseUidKey, "");
sharedPreferences.setString(authTokenKey, ""); sharedPreferences.setString(authTokenKey, "");
} }
initBadges(); initBadges();
@ -396,23 +394,25 @@ class Cache with Logging {
this._tree = tree; this._tree = tree;
} }
List<ExerciseType> getExerciseTypes() => this._exerciseTypes; List<ExerciseType>? getExerciseTypes() => this._exerciseTypes;
ExerciseType getExerciseTypeById(int exerciseTypeId) { ExerciseType? getExerciseTypeById(int exerciseTypeId) {
ExerciseType exerciseType; ExerciseType? exerciseType;
this._exerciseTypes.forEach((element) { if (_exerciseTypes != null) {
if (element.exerciseTypeId == exerciseTypeId) { this._exerciseTypes!.forEach((element) {
exerciseType = element; if (element.exerciseTypeId == exerciseTypeId) {
} exerciseType = element;
}); }
});
}
return exerciseType; return exerciseType;
} }
List<ExerciseTree> getExerciseTree() => this._exerciseTree; List<ExerciseTree>? getExerciseTree() => this._exerciseTree;
List<Exercise> getExercises() => this._exercises; List<Exercise>? getExercises() => this._exercises;
List<Exercise> getExercisesTrainee() => this._exercisesTrainee; List<Exercise>? getExercisesTrainee() => this._exercisesTrainee;
LinkedHashMap<String, WorkoutMenuTree> getWorkoutMenuTree() => this._tree; LinkedHashMap<String, WorkoutMenuTree> getWorkoutMenuTree() => this._tree;
@ -420,21 +420,21 @@ class Cache with Logging {
double getPercentExercises() => this._percentExercises; double getPercentExercises() => this._percentExercises;
void addExercise(Exercise exercise) => _exercises.add(exercise); void addExercise(Exercise exercise) => _exercises!.add(exercise);
void addExerciseTrainee(Exercise exercise) => _exercisesTrainee.add(exercise); void addExerciseTrainee(Exercise exercise) => _exercisesTrainee!.add(exercise);
Customer getTrainee() => this._trainee; Customer? getTrainee() => this._trainee;
void setTrainee(Customer trainee) => _trainee = trainee; void setTrainee(Customer trainee) => _trainee = trainee;
void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan; void setTraineeExercisePlan(ExercisePlan exercisePlan) => this._traineeExercisePlan = exercisePlan;
ExercisePlan getTraineesExercisePlan() => this._traineeExercisePlan; ExercisePlan? getTraineesExercisePlan() => this._traineeExercisePlan;
void setMyExercisePlan(ExercisePlan exercisePlan) => _myExercisePlan = exercisePlan; void setMyExercisePlan(ExercisePlan exercisePlan) => _myExercisePlan = exercisePlan;
ExercisePlan getMyExercisePlan() => _myExercisePlan; ExercisePlan? getMyExercisePlan() => _myExercisePlan;
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) => void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) =>
_myExercisesPlanDetails = listExercisePlanDetail; _myExercisesPlanDetails = listExercisePlanDetail;
@ -452,30 +452,30 @@ class Cache with Logging {
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId); void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) => void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
this._myExercisesPlanDetails[detail.exerciseTypeId].change = ModelChange.deleted; this._myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted;
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) { void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
this._myExercisesPlanDetails[exerciseTypeId].change = ModelChange.delete; this._myExercisesPlanDetails[exerciseTypeId]!.change = ModelChange.delete;
} }
void setProperties(List<Property> properties) => this._properties = properties; void setProperties(List<Property> properties) => this._properties = properties;
List<Property> getProperties() => _properties; List<Property>? getProperties() => _properties;
void setDevices(List<ExerciseDevice> devices) => this._devices = devices; void setDevices(List<ExerciseDevice> devices) => this._devices = devices;
List<ExerciseDevice> getDevices() => this._devices; List<ExerciseDevice>? getDevices() => this._devices;
void setCustomerDevices(List<CustomerExerciseDevice> devices) => this._customerDevices = devices; void setCustomerDevices(List<CustomerExerciseDevice> devices) => this._customerDevices = devices;
List<CustomerExerciseDevice> getCustomerDevices() => this._customerDevices; List<CustomerExerciseDevice>? getCustomerDevices() => this._customerDevices;
LinkedHashMap getBadges() => _badges; LinkedHashMap getBadges() => _badges;
void setBadge(String key, bool inc) { void setBadge(String key, bool inc) {
if (inc) { if (inc) {
if (_badges[key] != null) { if (_badges[key] != null) {
_badges[key]++; _badges[key] = _badges[key]! + 1;
} else { } else {
_badges[key] = 1; _badges[key] = 1;
} }
@ -484,7 +484,7 @@ class Cache with Logging {
if (_badges[key] == 1) { if (_badges[key] == 1) {
_badges.remove(key); _badges.remove(key);
} else { } else {
_badges[key]--; _badges[key] = _badges[key]! - 1;
} }
} }
} }
@ -492,31 +492,34 @@ class Cache with Logging {
void setBadgeNr(String key, int counter) { void setBadgeNr(String key, int counter) {
if (_badges[key] != null) { if (_badges[key] != null) {
_badges[key] += counter; _badges[key] = _badges[key]! + counter;
} else { } else {
_badges[key] = counter; _badges[key] = counter;
} }
} }
void initBadges() async { void initBadges() {
CustomerRepository customerRepository = CustomerRepository(); CustomerRepository customerRepository = CustomerRepository();
_badges = LinkedHashMap(); _badges = LinkedHashMap();
customerRepository.setCustomer(userLoggedIn); if (userLoggedIn == null) {
return;
}
customerRepository.setCustomer(userLoggedIn!);
int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt(); int _ecto = customerRepository.getCustomerPropertyValue(PropertyEnum.Ectomorph.toStr()).toInt();
int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt(); int _mezo = customerRepository.getCustomerPropertyValue(PropertyEnum.Mesomorph.toStr()).toInt();
int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt(); int _endo = customerRepository.getCustomerPropertyValue(PropertyEnum.Endomorph.toStr()).toInt();
//print("endo " + _endo.toString() + " mezo " + _mezo.toString()); //print("endo " + _endo.toString() + " mezo " + _mezo.toString());
if (this.userLoggedIn != null) { if (this.userLoggedIn != null) {
if (this.userLoggedIn.birthYear == null || this.userLoggedIn.birthYear == 0) { if (this.userLoggedIn!.birthYear == null || this.userLoggedIn!.birthYear == 0) {
setBadge("personalData", true); setBadge("personalData", true);
setBadge("account", true); setBadge("account", true);
} }
if (this._customerDevices == null || this._customerDevices.isEmpty) { if (this._customerDevices == null || this._customerDevices!.isEmpty) {
setBadge("customerDevice", true); setBadge("customerDevice", true);
setBadge("account", true); setBadge("account", true);
} }
if (userLoggedIn.properties == null || userLoggedIn.properties.isEmpty) { if (userLoggedIn!.properties.isEmpty) {
setBadge("personalData", true); setBadge("personalData", true);
setBadge("bodyType", true); setBadge("bodyType", true);
setBadge("Sizes", true); setBadge("Sizes", true);
@ -534,7 +537,7 @@ class Cache with Logging {
setBadge("account", true); setBadge("account", true);
setBadge("bodyType", true); setBadge("bodyType", true);
} }
if (this._exercises == null || this._exercises.length == 0) { if (this._exercises == null || this._exercises!.isEmpty) {
setBadge("home", true); setBadge("home", true);
setBadge("Muscle Build / Shape Toning", true); setBadge("Muscle Build / Shape Toning", true);
setBadge("Cardio", true); setBadge("Cardio", true);
@ -545,20 +548,20 @@ class Cache with Logging {
setBadge("My Body", true); setBadge("My Body", true);
setBadgeNr("home", 1); setBadgeNr("home", 1);
} }
if (userLoggedIn.goal == null) { if (userLoggedIn!.goal == null) {
setBadge("Goal", true); setBadge("Goal", true);
setBadge("account", true); setBadge("account", true);
} }
if (userLoggedIn.fitnessLevel == null) { if (userLoggedIn!.fitnessLevel == null) {
setBadge("FitnessLevel", true); setBadge("FitnessLevel", true);
setBadge("account", true); setBadge("account", true);
} }
if (this._exercises != null && this._exercises.isNotEmpty) { if (this._exercises != null && this._exercises!.isNotEmpty) {
if (!isExerciseLogSeen) { if (!isExerciseLogSeen!) {
setBadge("exerciseLog", true); setBadge("exerciseLog", true);
setBadge("development", true); setBadge("development", true);
} }
if (!isMuscleDevelopmentSeen) { if (!isMuscleDevelopmentSeen!) {
setBadge("muscleDevelopment", true); setBadge("muscleDevelopment", true);
setBadge("development", true); setBadge("development", true);
} }
@ -567,14 +570,16 @@ class Cache with Logging {
log("Badges: " + _badges.toString()); log("Badges: " + _badges.toString());
} }
List get products => _products; List<Product>? get products => _products;
void setProducts(List value) => _products = value; void setProducts(List<wt_product.Product> value) => _products = value;
List get purchases => _purchases; List<Purchase> get purchases => _purchases;
setPurchases(List value) => _purchases = value; setPurchases(List<Purchase> value) => _purchases = value;
List get productTests => _productTests; // ignore: unnecessary_getters_setters
set productTests(List value) => _productTests = value; List<ProductTest>? get productTests => _productTests;
// ignore: unnecessary_getters_setters
set productTests(List<ProductTest>? value) => _productTests = value;
Future<void> initCustomer(int customerId) async { Future<void> initCustomer(int customerId) async {
log(" *** initCustomer"); log(" *** initCustomer");
@ -593,10 +598,10 @@ class Cache with Logging {
Cache().startPage = "home"; Cache().startPage = "home";
} }
AccessToken get getAccessTokenFacebook => accessTokenFacebook; AccessToken? get getAccessTokenFacebook => accessTokenFacebook;
set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook; set setAccessTokenFacebook(AccessToken accessTokenFacebook) => this.accessTokenFacebook = accessTokenFacebook;
LoginType getLoginType() => loginType; LoginType? getLoginType() => loginType;
void setLoginType(LoginType type) => this.loginType = type; void setLoginType(LoginType type) => this.loginType = type;
List get exercisePlanTemplates => this._exercisePlanTemplates; List get exercisePlanTemplates => this._exercisePlanTemplates;
@ -617,7 +622,7 @@ class Cache with Logging {
isExerciseLogSeen = false; isExerciseLogSeen = false;
} }
//print("ExerciseLogSeen $isExerciseLogSeen"); //print("ExerciseLogSeen $isExerciseLogSeen");
return isExerciseLogSeen; return isExerciseLogSeen!;
} }
setMuscleDevelopmentSeen() async { setMuscleDevelopmentSeen() async {
@ -634,6 +639,6 @@ class Cache with Logging {
if (isMuscleDevelopmentSeen == null) { if (isMuscleDevelopmentSeen == null) {
isMuscleDevelopmentSeen = false; isMuscleDevelopmentSeen = false;
} }
return isMuscleDevelopmentSeen; return isMuscleDevelopmentSeen!;
} }
} }

View File

@ -1,27 +1,27 @@
import 'dart:collection'; import 'dart:collection';
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:intl/intl.dart';
import 'customer_property.dart'; import 'customer_property.dart';
class Customer { class Customer {
String name; String? name;
String email; late String? email;
String firstname; String? firstname;
String sex; String? sex;
int age; int? age;
String active; String? active;
int customerId; int? customerId;
String password; String? password;
int birthYear; int? birthYear;
String goal; String? goal;
String fitnessLevel; String? fitnessLevel;
String bodyType; String? bodyType;
int admin; int? admin;
int trainer; int? trainer;
int dataPolicyAllowed; int? dataPolicyAllowed;
String firebaseUid; String? firebaseUid;
DateTime dateAdd; DateTime? dateAdd;
DateTime dateChange; DateTime? dateChange;
LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap(); LinkedHashMap<String, CustomerProperty> properties = LinkedHashMap();
@ -43,7 +43,10 @@ class Customer {
this.dataPolicyAllowed, this.dataPolicyAllowed,
this.firebaseUid, this.firebaseUid,
this.dateAdd, this.dateAdd,
this.dateChange}); this.dateChange}) {
dateAdd = DateTime.now();
dateChange = DateTime.now();
}
Customer.fromJson(Map json) { Customer.fromJson(Map json) {
this.customerId = json['customerId']; this.customerId = json['customerId'];
@ -81,19 +84,19 @@ class Customer {
"admin": admin, "admin": admin,
"trainer": trainer, "trainer": trainer,
"dataPolicyAllowed": dataPolicyAllowed, "dataPolicyAllowed": dataPolicyAllowed,
"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!),
}; };
double getProperty(String propertyName) { double getProperty(String propertyName) {
if (this.properties[propertyName] == null) { if (this.properties[propertyName] == null) {
return 0; return 0;
} else { } else {
return this.properties[propertyName].propertyValue; return this.properties[propertyName]!.propertyValue;
} }
} }
setProperty(String propertyName, double value) { setProperty(String propertyName, double value) {
this.properties[propertyName].propertyValue = value; this.properties[propertyName]!.propertyValue = value;
} }
} }

View File

@ -1,15 +1,15 @@
import 'package:flutter_form_bloc/flutter_form_bloc.dart'; import 'package:intl/intl.dart';
class CustomerExerciseDevice { class CustomerExerciseDevice {
int customerExerciseDeviceId; int? customerExerciseDeviceId;
int exerciseDeviceId; late int exerciseDeviceId;
int customerId; late int customerId;
bool favourite; late bool favourite;
DateTime dateAdd; late DateTime dateAdd;
String change; late String change;
CustomerExerciseDevice({this.exerciseDeviceId, this.customerId, this.favourite}) { CustomerExerciseDevice({required this.exerciseDeviceId, required this.customerId, required this.favourite}) {
dateAdd = DateTime.now(); dateAdd = DateTime.now();
} }

Some files were not shown because too many files have changed in this diff Show More