Compare commits
10 Commits
208ada4251
...
45cebbbdd2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
45cebbbdd2 | ||
![]() |
a8af8f7c7e | ||
![]() |
3f52d95bbf | ||
![]() |
98901f2770 | ||
![]() |
dbdcf2f239 | ||
![]() |
ba36a10790 | ||
![]() |
cbaa1a5b81 | ||
![]() |
6ef311286c | ||
![]() |
20c481298f | ||
![]() |
621d766335 |
@ -22,12 +22,12 @@
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1633186029325</id>
|
||||
<id>1666112134141</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
||||
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
||||
</matcher>
|
||||
</filter>
|
||||
</filteredResources>
|
||||
|
@ -33,8 +33,6 @@ if (keystorePropertiesFile.exists()) {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
@ -45,16 +43,16 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.aitrainer.aitrainer_app"
|
||||
minSdkVersion 20
|
||||
targetSdkVersion 30
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
ndk.abiFilters 'armeabi-v7a', 'arm64-v8a','x86_64'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@ -85,6 +83,9 @@ dependencies {
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
implementation 'com.google.firebase:firebase-messaging:20.1.0'
|
||||
implementation 'com.google.firebase:firebase-core:20.0.0'
|
||||
implementation('com.google.firebase:firebase-auth') {
|
||||
exclude module: "play-services-safetynet"
|
||||
}
|
||||
implementation 'com.google.firebase:firebase-inappmessaging-display:20.1.1'
|
||||
}
|
||||
sourceCompatibility = '1.8'
|
@ -8,7 +8,7 @@
|
||||
<application android:name="${applicationName}" android:label="WorkoutTest" android:icon="@mipmap/launcher_icon">
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />
|
||||
<meta-data android:name="com.facebook.sdk.ClientToken" android:value="@string/facebook_client_token"/>
|
||||
<activity android:name="io.flutter.embedding.android.FlutterActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:allowBackup="false" android:fullBackupContent="false">
|
||||
<activity android:name="io.flutter.embedding.android.FlutterActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:allowBackup="false" android:fullBackupContent="false" android:exported="true">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
@ -47,7 +47,7 @@
|
||||
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
|
||||
|
||||
<activity android:name="com.facebook.FacebookActivity" android:configChanges=
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" />
|
||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:label="@string/app_name" android:exported="false"/>
|
||||
<activity android:name="com.facebook.CustomTabActivity" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -56,8 +56,14 @@
|
||||
<data android:scheme="@string/fb_login_protocol_scheme" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<meta-data android:name="com.posthog.posthog.API_KEY" android:value="phc_ATsS8RRdgzDdKpDSPYEYpYxWjfZ4QPMHHnoLbSaTZ2Q" />
|
||||
<meta-data android:name="com.posthog.posthog.POSTHOG_HOST" android:value="https://posthog.workouttest.org" />
|
||||
<meta-data android:name="com.posthog.posthog.TRACK_APPLICATION_LIFECYCLE_EVENTS" android:value="true" />
|
||||
<meta-data android:name="com.posthog.posthog.DEBUG" android:value="true" />
|
||||
|
||||
</application>
|
||||
<queries>
|
||||
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" />
|
||||
<provider android:authorities="com.facebook.katana.provider.PlatformProvider" android:exported="false"/>
|
||||
</queries>
|
||||
</manifest>
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_adaptive_back"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_adaptive_fore"/>
|
||||
</adaptive-icon>
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 41 KiB |
@ -6,7 +6,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:4.0.2"
|
||||
classpath "com.android.tools.build:gradle:7.0.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.google.gms:google-services:4.3.4"
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
|
7216
android/my-logs.txt
Normal file
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 5.9 MiB |
Before Width: | Height: | Size: 307 KiB |
Before Width: | Height: | Size: 228 KiB |
BIN
asset/image/12w_fit_boost.jpg
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
asset/image/12w_fit_boost_q.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
asset/image/cardio_distance.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
asset/image/cardio_time.jpg
Normal file
After Width: | Height: | Size: 121 KiB |
430
ios/Podfile.lock
@ -1,218 +1,210 @@
|
||||
PODS:
|
||||
- AppAuth (1.5.0):
|
||||
- AppAuth/Core (= 1.5.0)
|
||||
- AppAuth/ExternalUserAgent (= 1.5.0)
|
||||
- AppAuth/Core (1.5.0)
|
||||
- AppAuth/ExternalUserAgent (1.5.0):
|
||||
- AppAuth (1.6.0):
|
||||
- AppAuth/Core (= 1.6.0)
|
||||
- AppAuth/ExternalUserAgent (= 1.6.0)
|
||||
- AppAuth/Core (1.6.0)
|
||||
- AppAuth/ExternalUserAgent (1.6.0):
|
||||
- AppAuth/Core
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- devicelocale (0.0.1):
|
||||
- Flutter
|
||||
- FBAEMKit (13.0.0):
|
||||
- FBSDKCoreKit_Basics (= 13.0.0)
|
||||
- FBSDKCoreKit (13.0.0):
|
||||
- FBAEMKit (= 13.0.0)
|
||||
- FBSDKCoreKit_Basics (= 13.0.0)
|
||||
- FBSDKCoreKit_Basics (13.0.0)
|
||||
- FBSDKLoginKit (13.0.0):
|
||||
- FBSDKCoreKit (= 13.0.0)
|
||||
- Firebase/Analytics (8.11.0):
|
||||
- FBAEMKit (14.1.0):
|
||||
- FBSDKCoreKit_Basics (= 14.1.0)
|
||||
- FBSDKCoreKit (14.1.0):
|
||||
- FBAEMKit (= 14.1.0)
|
||||
- FBSDKCoreKit_Basics (= 14.1.0)
|
||||
- FBSDKCoreKit_Basics (14.1.0)
|
||||
- FBSDKLoginKit (14.1.0):
|
||||
- FBSDKCoreKit (= 14.1.0)
|
||||
- Firebase/Analytics (10.0.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Auth (8.11.0):
|
||||
- Firebase/Auth (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAuth (~> 8.11.0)
|
||||
- Firebase/Core (8.11.0):
|
||||
- FirebaseAuth (~> 10.0.0)
|
||||
- Firebase/Core (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (~> 8.11.0)
|
||||
- Firebase/CoreOnly (8.11.0):
|
||||
- FirebaseCore (= 8.11.0)
|
||||
- Firebase/DynamicLinks (8.11.0):
|
||||
- FirebaseAnalytics (~> 10.0.0)
|
||||
- Firebase/CoreOnly (10.0.0):
|
||||
- FirebaseCore (= 10.0.0)
|
||||
- Firebase/DynamicLinks (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseDynamicLinks (~> 8.11.0)
|
||||
- Firebase/InAppMessaging (8.11.0):
|
||||
- FirebaseDynamicLinks (~> 10.0.0)
|
||||
- Firebase/InAppMessaging (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseInAppMessaging (~> 8.11.0-beta)
|
||||
- Firebase/Messaging (8.11.0):
|
||||
- FirebaseInAppMessaging (~> 10.0.0-beta)
|
||||
- Firebase/Messaging (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseMessaging (~> 8.11.0)
|
||||
- Firebase/RemoteConfig (8.11.0):
|
||||
- FirebaseMessaging (~> 10.0.0)
|
||||
- Firebase/RemoteConfig (10.0.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseRemoteConfig (~> 8.11.0)
|
||||
- firebase_analytics (9.1.2):
|
||||
- Firebase/Analytics (= 8.11.0)
|
||||
- FirebaseRemoteConfig (~> 10.0.0)
|
||||
- firebase_analytics (10.0.1):
|
||||
- Firebase/Analytics (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_auth (3.3.11):
|
||||
- Firebase/Auth (= 8.11.0)
|
||||
- firebase_auth (4.0.1):
|
||||
- Firebase/Auth (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_core (1.13.1):
|
||||
- Firebase/CoreOnly (= 8.11.0)
|
||||
- firebase_core (2.0.0):
|
||||
- Firebase/CoreOnly (= 10.0.0)
|
||||
- Flutter
|
||||
- firebase_dynamic_links (4.1.1):
|
||||
- Firebase/DynamicLinks (= 8.11.0)
|
||||
- firebase_dynamic_links (5.0.1):
|
||||
- Firebase/DynamicLinks (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_in_app_messaging (0.6.0-9):
|
||||
- Firebase/InAppMessaging (= 8.11.0)
|
||||
- firebase_in_app_messaging (0.7.0-1):
|
||||
- Firebase/InAppMessaging (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_messaging (11.2.11):
|
||||
- Firebase/Messaging (= 8.11.0)
|
||||
- firebase_messaging (14.0.1):
|
||||
- Firebase/Messaging (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- firebase_remote_config (2.0.2):
|
||||
- Firebase/RemoteConfig (= 8.11.0)
|
||||
- firebase_remote_config (3.0.1):
|
||||
- Firebase/RemoteConfig (= 10.0.0)
|
||||
- firebase_core
|
||||
- Flutter
|
||||
- FirebaseABTesting (8.14.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseAnalytics (8.11.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 8.11.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (8.11.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleAppMeasurement (= 8.11.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAuth (8.11.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- FirebaseCore (8.11.0):
|
||||
- FirebaseCoreDiagnostics (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- FirebaseCoreDiagnostics (8.14.0):
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseDynamicLinks (8.11.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInAppMessaging (8.11.0-beta):
|
||||
- FirebaseABTesting (~> 8.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseInstallations (8.14.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- FirebaseMessaging (8.11.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Reachability (~> 7.7)
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseRemoteConfig (8.11.0):
|
||||
- FirebaseABTesting (~> 8.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- FirebaseABTesting (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseAnalytics (10.0.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 10.0.0)
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Network (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleAppMeasurement (= 10.0.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Network (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseAuth (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GTMSessionFetcher/Core (~> 2.1)
|
||||
- FirebaseCore (10.0.0):
|
||||
- FirebaseCoreInternal (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/Logger (~> 7.8)
|
||||
- FirebaseCoreInternal (10.0.0):
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- FirebaseDynamicLinks (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInAppMessaging (10.0.0-beta):
|
||||
- FirebaseABTesting (~> 10.0)
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseInstallations (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/UserDefaults (~> 7.8)
|
||||
- PromisesObjC (~> 2.1)
|
||||
- FirebaseMessaging (10.0.0):
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleDataTransport (~> 9.2)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- GoogleUtilities/Reachability (~> 7.8)
|
||||
- GoogleUtilities/UserDefaults (~> 7.8)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- FirebaseRemoteConfig (10.0.0):
|
||||
- FirebaseABTesting (~> 10.0)
|
||||
- FirebaseCore (~> 10.0)
|
||||
- FirebaseInstallations (~> 10.0)
|
||||
- GoogleUtilities/Environment (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- Flutter (1.0.0)
|
||||
- flutter_app_badger (0.0.1):
|
||||
- Flutter
|
||||
- flutter_facebook_auth (4.1.2):
|
||||
- FBSDKCoreKit (~> 13.0.0)
|
||||
- FBSDKLoginKit (~> 13.0.0)
|
||||
- flutter_facebook_auth (4.4.1):
|
||||
- FBSDKLoginKit (= 14.1.0)
|
||||
- Flutter
|
||||
- flutter_secure_storage (3.3.1):
|
||||
- Flutter
|
||||
- flutter_smartlook (0.0.5):
|
||||
- google_sign_in_ios (0.0.1):
|
||||
- Flutter
|
||||
- flutter_uxcam (2.0.1):
|
||||
- Flutter
|
||||
- UXCam (~> 3.3.6)
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- google_sign_in (0.0.1):
|
||||
- Flutter
|
||||
- GoogleSignIn (~> 5.0)
|
||||
- GoogleAppMeasurement (8.11.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 8.11.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (8.11.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 8.11.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (8.11.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleDataTransport (9.1.2):
|
||||
- GoogleUtilities/Environment (~> 7.2)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleSignIn (~> 6.2)
|
||||
- GoogleAppMeasurement (10.0.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 10.0.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Network (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (10.0.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 10.0.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Network (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (10.0.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.8)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.8)
|
||||
- GoogleUtilities/Network (~> 7.8)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.8)"
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- GoogleDataTransport (9.2.0):
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleSignIn (5.0.2):
|
||||
- AppAuth (~> 1.2)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.7.0):
|
||||
- GoogleSignIn (6.2.4):
|
||||
- AppAuth (~> 1.5)
|
||||
- GTMAppAuth (~> 1.3)
|
||||
- GTMSessionFetcher/Core (< 3.0, >= 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.8.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (7.7.0):
|
||||
- GoogleUtilities/Environment (7.8.0):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Logger (7.7.0):
|
||||
- GoogleUtilities/Logger (7.8.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/MethodSwizzler (7.7.0):
|
||||
- GoogleUtilities/MethodSwizzler (7.8.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network (7.7.0):
|
||||
- GoogleUtilities/Network (7.8.0):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (7.7.0)"
|
||||
- GoogleUtilities/Reachability (7.7.0):
|
||||
- "GoogleUtilities/NSData+zlib (7.8.0)"
|
||||
- GoogleUtilities/Reachability (7.8.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (7.7.0):
|
||||
- GoogleUtilities/UserDefaults (7.8.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GTMAppAuth (1.2.3):
|
||||
- AppAuth/Core (~> 1.4)
|
||||
- GTMSessionFetcher/Core (~> 1.5)
|
||||
- GTMSessionFetcher/Core (1.7.1)
|
||||
- GTMAppAuth (1.3.1):
|
||||
- AppAuth/Core (~> 1.6)
|
||||
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
|
||||
- GTMSessionFetcher/Core (2.1.0)
|
||||
- modal_progress_hud_nsn (0.0.1):
|
||||
- Flutter
|
||||
- nanopb (2.30908.0):
|
||||
- nanopb/decode (= 2.30908.0)
|
||||
- nanopb/encode (= 2.30908.0)
|
||||
- nanopb/decode (2.30908.0)
|
||||
- nanopb/encode (2.30908.0)
|
||||
- nanopb (2.30909.0):
|
||||
- nanopb/decode (= 2.30909.0)
|
||||
- nanopb/encode (= 2.30909.0)
|
||||
- nanopb/decode (2.30909.0)
|
||||
- nanopb/encode (2.30909.0)
|
||||
- package_info (0.0.1):
|
||||
- Flutter
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_ios (0.0.1):
|
||||
- Flutter
|
||||
- PromisesObjC (2.1.0)
|
||||
- PostHog (1.4.4)
|
||||
- posthog_session (0.0.1):
|
||||
- Flutter
|
||||
- PostHog (~> 1.1)
|
||||
- PromisesObjC (2.1.1)
|
||||
- Purchases (3.13.2):
|
||||
- PurchasesCoreSwift (= 3.13.2)
|
||||
- purchases_flutter (3.9.5):
|
||||
@ -221,25 +213,21 @@ PODS:
|
||||
- PurchasesCoreSwift (3.13.2)
|
||||
- PurchasesHybridCommon (1.11.2):
|
||||
- Purchases (= 3.13.2)
|
||||
- Sentry (7.10.2):
|
||||
- Sentry/Core (= 7.10.2)
|
||||
- Sentry/Core (7.10.2)
|
||||
- Sentry (7.28.0):
|
||||
- Sentry/Core (= 7.28.0)
|
||||
- Sentry/Core (7.28.0)
|
||||
- sentry_flutter (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry (~> 7.10.1)
|
||||
- Sentry (~> 7.28.0)
|
||||
- share (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_ios (0.0.1):
|
||||
- Flutter
|
||||
- sign_in_with_apple (0.0.1):
|
||||
- Flutter
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- FMDB (>= 2.7.5)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- UXCam (3.3.9)
|
||||
- video_player_avfoundation (0.0.1):
|
||||
- Flutter
|
||||
- wakelock (0.0.1):
|
||||
@ -261,19 +249,17 @@ DEPENDENCIES:
|
||||
- flutter_app_badger (from `.symlinks/plugins/flutter_app_badger/ios`)
|
||||
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- flutter_smartlook (from `.symlinks/plugins/flutter_smartlook/ios`)
|
||||
- flutter_uxcam (from `.symlinks/plugins/flutter_uxcam/ios`)
|
||||
- google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
|
||||
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
|
||||
- modal_progress_hud_nsn (from `.symlinks/plugins/modal_progress_hud_nsn/ios`)
|
||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
- posthog_session (from `.symlinks/plugins/posthog_session/ios`)
|
||||
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
|
||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||
- share (from `.symlinks/plugins/share/ios`)
|
||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||
- sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/ios`)
|
||||
- wakelock (from `.symlinks/plugins/wakelock/ios`)
|
||||
@ -291,13 +277,12 @@ SPEC REPOS:
|
||||
- FirebaseAnalytics
|
||||
- FirebaseAuth
|
||||
- FirebaseCore
|
||||
- FirebaseCoreDiagnostics
|
||||
- FirebaseCoreInternal
|
||||
- FirebaseDynamicLinks
|
||||
- FirebaseInAppMessaging
|
||||
- FirebaseInstallations
|
||||
- FirebaseMessaging
|
||||
- FirebaseRemoteConfig
|
||||
- FMDB
|
||||
- GoogleAppMeasurement
|
||||
- GoogleDataTransport
|
||||
- GoogleSignIn
|
||||
@ -305,12 +290,12 @@ SPEC REPOS:
|
||||
- GTMAppAuth
|
||||
- GTMSessionFetcher
|
||||
- nanopb
|
||||
- PostHog
|
||||
- PromisesObjC
|
||||
- Purchases
|
||||
- PurchasesCoreSwift
|
||||
- PurchasesHybridCommon
|
||||
- Sentry
|
||||
- UXCam
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
device_info_plus:
|
||||
@ -339,12 +324,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
|
||||
flutter_secure_storage:
|
||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||
flutter_smartlook:
|
||||
:path: ".symlinks/plugins/flutter_smartlook/ios"
|
||||
flutter_uxcam:
|
||||
:path: ".symlinks/plugins/flutter_uxcam/ios"
|
||||
google_sign_in:
|
||||
:path: ".symlinks/plugins/google_sign_in/ios"
|
||||
google_sign_in_ios:
|
||||
:path: ".symlinks/plugins/google_sign_in_ios/ios"
|
||||
modal_progress_hud_nsn:
|
||||
:path: ".symlinks/plugins/modal_progress_hud_nsn/ios"
|
||||
package_info:
|
||||
@ -353,6 +334,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
path_provider_ios:
|
||||
:path: ".symlinks/plugins/path_provider_ios/ios"
|
||||
posthog_session:
|
||||
:path: ".symlinks/plugins/posthog_session/ios"
|
||||
purchases_flutter:
|
||||
:path: ".symlinks/plugins/purchases_flutter/ios"
|
||||
sentry_flutter:
|
||||
@ -363,8 +346,6 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||
sign_in_with_apple:
|
||||
:path: ".symlinks/plugins/sign_in_with_apple/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
video_player_avfoundation:
|
||||
@ -375,63 +356,60 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
AppAuth: 80317d99ac7ff2801a2f18ff86b48cd315ed465d
|
||||
AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
|
||||
device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed
|
||||
devicelocale: b22617f40038496deffba44747101255cee005b0
|
||||
FBAEMKit: 11a0bcdc7a88e26ed764bcf56372afc6cbbbdcd9
|
||||
FBSDKCoreKit: 00e1e751257e1005304fa29cb683d2dfe008f41a
|
||||
FBSDKCoreKit_Basics: 96ec2ddb67a032e54f0754ea3d59db6f84f42389
|
||||
FBSDKLoginKit: 66ff4ddf372d9c3fc360e65ae048a47a482c29b9
|
||||
Firebase: 44dd9724c84df18b486639e874f31436eaa9a20c
|
||||
firebase_analytics: 20841ef6a705a412c737deb2fe98290e9242d323
|
||||
firebase_auth: bdfbd5b10da1db6d5eb6ae7dbda5d81365b9cc9d
|
||||
firebase_core: 08f6a85f62060111de5e98d6a214810d11365de9
|
||||
firebase_dynamic_links: 1b6e3aeb743c0a0df1dab3543bd9dec6aab4de58
|
||||
firebase_in_app_messaging: 5937abf8acacbe3d35123a4c845ccf9d1669d7ed
|
||||
firebase_messaging: 4a993bb4aa1a83349988d853c637fbb0494dab15
|
||||
firebase_remote_config: 588bafe2eff61076e53b018758ec1fa96893e3c3
|
||||
FirebaseABTesting: aaa0e096c9fc9972ce6806d596e8fcc077d4371f
|
||||
FirebaseAnalytics: 4e4b13031034e6561ed3bd1d47b6fdabbd6487c6
|
||||
FirebaseAuth: d96d73aba85d192d7a7aa0b86dd6d7f8ec170b4b
|
||||
FirebaseCore: 2f4f85b453cc8fea4bb2b37e370007d2bcafe3f0
|
||||
FirebaseCoreDiagnostics: fd0c8490f34287229c1d6c103d3a55f81ec85712
|
||||
FirebaseDynamicLinks: f506c83eb7eba0f9861f84cd6b65c38b3bd5ff6f
|
||||
FirebaseInAppMessaging: 68586d72d5411b2dfaeb02461c2cd8d9f96a771a
|
||||
FirebaseInstallations: 7d1d967a307c12f1aadd76844fc321cef699b1ce
|
||||
FirebaseMessaging: 02e248e8997f71fa8cc9d78e9d49ec1a701ba14a
|
||||
FirebaseRemoteConfig: a6a1ce9dabf404817ae2a44e8421d276660d9091
|
||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||
FBAEMKit: a899515e45476027f73aef377b5cffadcd56ca3a
|
||||
FBSDKCoreKit: 24f8bc8d3b5b2a8c5c656a1329492a12e8efa792
|
||||
FBSDKCoreKit_Basics: 6e578c9bdc7aa1365dbbbde633c9ebb536bcaa98
|
||||
FBSDKLoginKit: 787de205d524c3a4b17d527916f1d066e4361660
|
||||
Firebase: 1b810f3d0c0532e27a48f1961f8c0400a668a2cf
|
||||
firebase_analytics: 8f6874ecf36f61797835ed99d7a792d3a212b026
|
||||
firebase_auth: 62015b6cbfccf40521d7f777c804d19f9bc6f922
|
||||
firebase_core: f9febc855bab615ea02dc9a75b6932364edb1225
|
||||
firebase_dynamic_links: 37282d0148b844b34d09a9aba54bfa72eada9377
|
||||
firebase_in_app_messaging: 3ec946b7cf90c3fb0257e1e8155180d6dbf644f7
|
||||
firebase_messaging: a39df674ecaffd962658a9de3182d735b6cee0d7
|
||||
firebase_remote_config: 11eee0656374e6ef595f36e49d904ddc209b4523
|
||||
FirebaseABTesting: 5a08a4d3060b7fb5638f60698bc2cb57996bcc73
|
||||
FirebaseAnalytics: 9921a52739f4ab66099da31b6e0243db78a3ac0a
|
||||
FirebaseAuth: 493382cf533cc45e2862b00e9aa4cfe4c98daf71
|
||||
FirebaseCore: 97f48a3a567a72b8d4daa0f03c3aadb78df4e995
|
||||
FirebaseCoreInternal: 5eb3960335da5ea30115d57d39db6988c4ad06f3
|
||||
FirebaseDynamicLinks: 37dcd9f082b9c5ea9eb5826e82aef58bbd6fd5c1
|
||||
FirebaseInAppMessaging: 07aafacbb74228af034fb1c8885d25045a25d510
|
||||
FirebaseInstallations: 7f1c9ae6bd9df6abe9c74124b38fa8740aba5df4
|
||||
FirebaseMessaging: 8916bf5edb1dbfac74665a181e4d1ab3a78a08a2
|
||||
FirebaseRemoteConfig: e4431ddba74ddf705e2aabd7d356a23d5b802853
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_app_badger: 65de4d6f0c34a891df49e6cfb8a1c0496426fa68
|
||||
flutter_facebook_auth: c0a8473f857cf44b0a27bfe752facf1d5fedd863
|
||||
flutter_facebook_auth: 361ac7a57263ebf327f26089507ead0d66558ee8
|
||||
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||
flutter_smartlook: 2aa304f6a38fc22b741ca750e0078606582525ae
|
||||
flutter_uxcam: 32e4e8b4355be6bf9d512ad36aed6d86c98a5cdf
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
google_sign_in: f669f45933dad48cd218dc3e189726bced3d19f4
|
||||
GoogleAppMeasurement: aa3cb422fab2b05d2efac543a5720d1a85b9dea5
|
||||
GoogleDataTransport: 629c20a4d363167143f30ea78320d5a7eb8bd940
|
||||
GoogleSignIn: 7137d297ddc022a7e0aa4619c86d72c909fa7213
|
||||
GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
|
||||
GTMAppAuth: 987526d41b07efb1bedda5e936fe0cb718a03113
|
||||
GTMSessionFetcher: 4577a4cc914a5a07c40a8a0ad0acc22080418c2d
|
||||
google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c
|
||||
GoogleAppMeasurement: 7e48a3249792ac35d6f18f107f63f199a7e9d0ce
|
||||
GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f
|
||||
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
|
||||
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7
|
||||
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
|
||||
GTMSessionFetcher: ffbb25ec00ebcb5201adab0a56d808f6f1902d9f
|
||||
modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
|
||||
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
|
||||
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
|
||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||
PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72
|
||||
PostHog: 4b6321b521569092d4ef3a02238d9435dbaeb99f
|
||||
posthog_session: 24d7e00a2ebd7586c8e7a1789b987f3f8d6cd10a
|
||||
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
|
||||
Purchases: 03200de9288724e77de435000d1828601e6b8e00
|
||||
purchases_flutter: cf2b742f12b7ffef6f618c7f1ba1961e652825b1
|
||||
PurchasesCoreSwift: 2ea4b33e5cece5c8a0751594ef7c6cbfcbd747a9
|
||||
PurchasesHybridCommon: 56ef42d85c3e930d49aff4ac5fa027373d2e1bb8
|
||||
Sentry: 7bf9bfe713692cf87812e55f0999260494ba7982
|
||||
sentry_flutter: 77ccdac346608b8ce7e428e7284e7a3e4e7f4a02
|
||||
Sentry: 2c6053e4cfe6dea6608135dea1928ffbb4ecfba5
|
||||
sentry_flutter: fad3ef0917dc1afa7d242af0743696ed9a9a8864
|
||||
share: 0b2c3e82132f5888bccca3351c504d0003b3b410
|
||||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
||||
sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
||||
UXCam: fb294bf954e708fc308a645ae65bb967cac0760e
|
||||
video_player_avfoundation: e489aac24ef5cf7af82702979ed16f2a5ef84cff
|
||||
wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
|
||||
webview_flutter_wkwebview: 005fbd90c888a42c5690919a1527ecc6649e1162
|
||||
|
@ -160,7 +160,6 @@
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
EB0A62903CC30EC853FC7908 /* [CP] Embed Pods Frameworks */,
|
||||
C1BA2CB9D651F269CCBE06B3 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -270,23 +269,6 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
C1BA2CB9D651F269CCBE06B3 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
EB0A62903CC30EC853FC7908 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -388,6 +370,8 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -405,9 +389,10 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.26;
|
||||
MARKETING_VERSION = 1.1.27;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
@ -531,6 +516,8 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -548,9 +535,10 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.26;
|
||||
MARKETING_VERSION = 1.1.27;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@ -566,6 +554,8 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||
ENABLE_BITCODE = NO;
|
||||
@ -583,9 +573,10 @@
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MARKETING_VERSION = 1.1.26;
|
||||
MARKETING_VERSION = 1.1.27;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.aitrainer.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
|
@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
@ -38,10 +40,10 @@
|
||||
<string>TRUE</string>
|
||||
<key>FacebookAppID</key>
|
||||
<string>584181112271127</string>
|
||||
<key>FacebookClientToken</key>
|
||||
<string>60d565f451ce32de3d7eeb26274bbddd</string>
|
||||
<key>FacebookAutoLogAppEventsEnabled</key>
|
||||
<string>TRUE</string>
|
||||
<key>FacebookClientToken</key>
|
||||
<string>60d565f451ce32de3d7eeb26274bbddd</string>
|
||||
<key>FacebookDisplayName</key>
|
||||
<string>Workout Test</string>
|
||||
<key>FirebaseAppDelegateProxyEnabled</key>
|
||||
@ -98,5 +100,13 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
|
||||
<key>com.posthog.posthog.API_KEY</key>
|
||||
<string>phc_ATsS8RRdgzDdKpDSPYEYpYxWjfZ4QPMHHnoLbSaTZ2Q</string>
|
||||
<key>com.posthog.posthog.POSTHOG_HOST</key>
|
||||
<string>https://posthog.workouttest.org</string>
|
||||
<key>com.posthog.posthog.TRACK_APPLICATION_LIFECYCLE_EVENTS</key>
|
||||
<false/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -6,6 +6,8 @@ import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../../service/customer_service.dart';
|
||||
|
||||
part 'account_event.dart';
|
||||
part 'account_state.dart';
|
||||
|
||||
@ -21,6 +23,7 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
on<AccountLogout>(_onLogout);
|
||||
on<AccountGetTrainees>(_onGetTrainees);
|
||||
on<AccountSelectTrainee>(_onSelectTrainees);
|
||||
on<DeleteAccount>(_onDeleteAccount);
|
||||
}
|
||||
|
||||
void _load() {
|
||||
@ -56,6 +59,24 @@ class AccountBloc extends Bloc<AccountEvent, AccountState> {
|
||||
emit(AccountReady());
|
||||
}
|
||||
|
||||
void _onDeleteAccount(DeleteAccount event, Emitter<AccountState> emit) async {
|
||||
emit(AccountLoading());
|
||||
await Cache().logout();
|
||||
customerRepository.customer = event.customer;
|
||||
customerRepository.emptyTrainees();
|
||||
loggedIn = false;
|
||||
|
||||
//delete local store
|
||||
int customerId = customerRepository.customer!.customerId!;
|
||||
await Cache().deleteCustomerId(customerId);
|
||||
customerRepository.customer = null;
|
||||
|
||||
// deactivate user
|
||||
await CustomerApi().deactivateCustomer(customerId);
|
||||
|
||||
emit(AccountReady());
|
||||
}
|
||||
|
||||
void _onGetTrainees(AccountGetTrainees event, Emitter<AccountState> emit) async {
|
||||
emit(AccountLoading());
|
||||
await customerRepository.getTrainees();
|
||||
|
@ -20,6 +20,14 @@ class AccountLogin extends AccountEvent {
|
||||
const AccountLogin();
|
||||
}
|
||||
|
||||
class DeleteAccount extends AccountEvent {
|
||||
final Customer customer;
|
||||
|
||||
const DeleteAccount ({required this.customer});
|
||||
@override
|
||||
List<Object> get props => [customer];
|
||||
}
|
||||
|
||||
class AccountLogInFinished extends AccountEvent {
|
||||
final Customer customer;
|
||||
|
||||
|
@ -133,25 +133,28 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
void _onSaveFitness(CustomerSaveFitness event, Emitter<CustomerChangeState> emit) {
|
||||
emit(CustomerChangeLoading());
|
||||
if (customerRepository.customer!.fitnessLevel == null) {
|
||||
throw Exception("Please select your fitness level");
|
||||
emit(CustomerSaveError(message: "Please select your fitness level"));
|
||||
} else {
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
|
||||
void _onSaveGoal(CustomerSaveGoal event, Emitter<CustomerChangeState> emit) {
|
||||
emit(CustomerChangeLoading());
|
||||
if (customerRepository.customer!.goal == null) {
|
||||
throw Exception("Please select your goal");
|
||||
emit(CustomerSaveError(message: "Please select your goal"));
|
||||
} else {
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
|
||||
void _onSaveSex(CustomerSaveSex event, Emitter<CustomerChangeState> emit) {
|
||||
emit(CustomerChangeLoading());
|
||||
if (customerRepository.customer!.sex == null) {
|
||||
throw Exception("Please select your biologial gender");
|
||||
emit(CustomerSaveError(message: "Please select your biological gender"));
|
||||
} else {
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
emit(CustomerSaveSuccess());
|
||||
}
|
||||
|
||||
void _onSaveWeight(CustomerSaveWeight event, Emitter<CustomerChangeState> emit) {
|
||||
@ -166,25 +169,29 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
|
||||
void _onSave(CustomerSave event, Emitter<CustomerChangeState> emit) async {
|
||||
emit(CustomerSaving());
|
||||
if (validation()) {
|
||||
if (selectedFitnessItem != null) {
|
||||
customerRepository.setFitnessLevel(selectedFitnessItem!);
|
||||
}
|
||||
if (selectedSport != null) {
|
||||
customerRepository.customer!.sportId = selectedSport!.sportId;
|
||||
}
|
||||
try {
|
||||
if (validation()) {
|
||||
if (selectedFitnessItem != null) {
|
||||
customerRepository.setFitnessLevel(selectedFitnessItem!);
|
||||
}
|
||||
if (selectedSport != null) {
|
||||
customerRepository.customer!.sportId = selectedSport!.sportId;
|
||||
}
|
||||
|
||||
if (customerRepository.customer!.lang == null) {
|
||||
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
|
||||
}
|
||||
if (customerRepository.customer!.lang == null) {
|
||||
customerRepository.customer!.lang = AppLanguage().appLocal.languageCode;
|
||||
}
|
||||
|
||||
await customerRepository.saveCustomer();
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticDataChange();
|
||||
Cache().initBadges();
|
||||
emit(CustomerSaveSuccess());
|
||||
} else {
|
||||
emit(CustomerSaveError(message: "Please provide the necessary information"));
|
||||
await customerRepository.saveCustomer();
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticDataChange();
|
||||
Cache().initBadges();
|
||||
emit(CustomerSaveSuccess());
|
||||
} else {
|
||||
emit(CustomerSaveError(message: "Please provide the necessary information"));
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
emit(CustomerSaveError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:aitrainer_app/repository/mautic_repository.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:aitrainer_app/main.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
@ -174,15 +174,15 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
|
||||
}
|
||||
|
||||
exerciseRepository.end = DateTime.now();
|
||||
await exerciseRepository.addExercise();
|
||||
if (!isInDebugMode) {
|
||||
exerciseRepository.addExercise();
|
||||
if (kReleaseMode) {
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticExercise();
|
||||
mauticRepository.sendMauticExercise();
|
||||
}
|
||||
menuBloc.add(MenuTreeDown(parent: 0));
|
||||
Cache().initBadges();
|
||||
Track().track(TrackingEvent.exercise_new, eventValue: exerciseRepository.exerciseType!.name);
|
||||
emit(ExerciseNewReady());
|
||||
emit(ExerciseNewSaved());
|
||||
}
|
||||
|
||||
void _onSubmitNoRegistration(ExerciseNewSubmitNoRegistration event, Emitter<ExerciseNewState> emit) async {
|
||||
@ -190,7 +190,7 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
|
||||
exerciseRepository.addExerciseNoRegistration();
|
||||
menuBloc.add(MenuTreeDown(parent: 0));
|
||||
Track().track(TrackingEvent.exercise_new_no_registration, eventValue: exerciseRepository.exerciseType!.name);
|
||||
emit(ExerciseNewReady());
|
||||
emit(ExerciseNewSaved());
|
||||
}
|
||||
|
||||
void _onBMIAnimate(ExerciseNewBMIAnimate event, Emitter<ExerciseNewState> emit) async {
|
||||
@ -220,7 +220,12 @@ class ExerciseNewBloc extends Bloc<ExerciseNewEvent, ExerciseNewState> with Logg
|
||||
|
||||
double getBMR() {
|
||||
var date = DateTime.now();
|
||||
if (weight == null || height == null || height == 0 || weight == 0) {
|
||||
if (weight == null ||
|
||||
height == null ||
|
||||
height == 0 ||
|
||||
weight == 0 ||
|
||||
customerRepository.customer == null ||
|
||||
customerRepository.customer!.birthYear == null) {
|
||||
this.bmi = 0;
|
||||
return 0;
|
||||
}
|
||||
|
@ -93,10 +93,10 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
Track().track(TrackingEvent.login, eventValue: "email");
|
||||
Cache().setLoginType(LoginType.email);
|
||||
} on Exception catch(e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
} finally {
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
print("Login error: $e" );
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,10 +107,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
||||
await userRepository.getUserByFB();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
Track().track(TrackingEvent.login, eventValue: "FB");
|
||||
} on Exception catch(e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
} finally {
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,11 +120,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
||||
await userRepository.getUserByGoogle();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
Track().track(TrackingEvent.login, eventValue: "Google");
|
||||
|
||||
} on Exception catch(e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
} finally {
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,56 +133,77 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
||||
await userRepository.getUserByApple();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
Track().track(TrackingEvent.login, eventValue: "Apple");
|
||||
} on Exception catch(e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
} finally {
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onRegistrationSubmit(RegistrationSubmit event, Emitter<LoginState> emit) async {
|
||||
emit(LoginLoading());
|
||||
final String? validationError = this.validate();
|
||||
if (validationError != null) {
|
||||
emit(LoginError(message: validationError));
|
||||
} else {
|
||||
await userRepository.addUser();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("email");
|
||||
Cache().setLoginType(LoginType.email);
|
||||
try {
|
||||
final String? validationError = this.validate();
|
||||
if (validationError != null) {
|
||||
emit(LoginError(message: validationError));
|
||||
} else {
|
||||
await userRepository.addUser();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("email");
|
||||
Cache().setLoginType(LoginType.email);
|
||||
emit(LoginSuccess());
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
return;
|
||||
}
|
||||
emit(LoginSuccess());
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _onRegistrationFB(RegistrationFB event, Emitter<LoginState> emit) async {
|
||||
emit(LoginLoading());
|
||||
Cache().setLoginType(LoginType.fb);
|
||||
await userRepository.addUserFB();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("FB");
|
||||
emit(LoginSuccess());
|
||||
try {
|
||||
Cache().setLoginType(LoginType.fb);
|
||||
await userRepository.addUserFB();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("FB");
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _onRegistrationGoogle(RegistrationGoogle event, Emitter<LoginState> emit) async {
|
||||
emit(LoginLoading());
|
||||
Cache().setLoginType(LoginType.google);
|
||||
await userRepository.addUserGoogle();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("Google");
|
||||
emit(LoginSuccess());
|
||||
try {
|
||||
Cache().setLoginType(LoginType.google);
|
||||
await userRepository.addUserGoogle();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("Google");
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void _onRegistrationApple(RegistrationApple event, Emitter<LoginState> emit) async {
|
||||
emit(LoginLoading());
|
||||
Cache().setLoginType(LoginType.apple);
|
||||
await userRepository.addUserApple();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("Apple");
|
||||
emit(LoginSuccess());
|
||||
try {
|
||||
Cache().setLoginType(LoginType.apple);
|
||||
await userRepository.addUserApple();
|
||||
accountBloc.add(AccountLogInFinished(customer: Cache().userLoggedIn!));
|
||||
customerRepository!.customer!.emailSubscription = emailSubscription == true ? 1 : 0;
|
||||
await afterRegistration("Apple");
|
||||
emit(LoginSuccess());
|
||||
} on Exception catch (e) {
|
||||
emit(LoginError(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void _onDataProtectionClicked(DataProtectionClicked event, Emitter<LoginState> emit) async {
|
||||
|
@ -113,103 +113,6 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/* @override
|
||||
Stream<MenuState> mapEventToState(
|
||||
MenuEvent event,
|
||||
) async* {
|
||||
try {
|
||||
if (event is MenuCreate) {
|
||||
yield MenuLoading();
|
||||
//await menuTreeRepository.createTree();
|
||||
//menuTreeRepository.getBranch(this.parent);
|
||||
//setMenuInfo();
|
||||
if (Cache().getDevices() != null) {
|
||||
exerciseDeviceRepository.setDevices(Cache().getDevices()!);
|
||||
}
|
||||
yield MenuReady();
|
||||
} else if (event is MenuRecreateTree) {
|
||||
yield MenuLoading();
|
||||
// ie. at language changes
|
||||
menuTreeRepository.createTree();
|
||||
yield MenuReady();
|
||||
} else if (event is MenuTreeDown) {
|
||||
yield MenuLoading();
|
||||
parent = event.parent;
|
||||
workoutItem = event.item;
|
||||
|
||||
if (workoutItem != null) {
|
||||
setAbility(workoutItem!.internalName);
|
||||
}
|
||||
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent);
|
||||
|
||||
await getImages(branch);
|
||||
yield MenuReady();
|
||||
} else if (event is MenuTreeUp) {
|
||||
yield MenuLoading();
|
||||
// get parent menus or exercises
|
||||
parent = event.parent;
|
||||
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||
|
||||
LinkedHashMap<String, WorkoutMenuTree> branch;
|
||||
if (workoutItem != null) {
|
||||
setAbility(workoutItem!.internalName);
|
||||
branch = menuTreeRepository.getBranch(workoutItem!.parent);
|
||||
await getImages(branch);
|
||||
}
|
||||
|
||||
yield MenuReady();
|
||||
} else if (event is MenuTreeJump) {
|
||||
yield MenuLoading();
|
||||
parent = event.parent;
|
||||
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||
|
||||
if (workoutItem != null) {
|
||||
setAbility(workoutItem!.internalName);
|
||||
}
|
||||
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem!.parent);
|
||||
await getImages(branch);
|
||||
|
||||
yield MenuReady();
|
||||
} else if (event is MenuClickExercise) {
|
||||
yield MenuLoading();
|
||||
// get exercise page
|
||||
yield MenuReady();
|
||||
} else if (event is MenuFilterExerciseType) {
|
||||
yield MenuLoading();
|
||||
final int deviceId = event.deviceId;
|
||||
if (selectedDevice(deviceId)) {
|
||||
listFilterDevice.add(deviceId);
|
||||
} else {
|
||||
listFilterDevice.remove(deviceId);
|
||||
}
|
||||
yield MenuReady();
|
||||
} else if (event is MenuStartTrial) {
|
||||
yield MenuLoading();
|
||||
final DateTime start = event.start;
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
customerRepository.customer!.trialDate = start;
|
||||
Cache().userLoggedIn!.trialDate = start;
|
||||
|
||||
customerRepository.saveCustomer();
|
||||
|
||||
if (DateTime.now().difference(start).inHours < 1) {
|
||||
Cache().hasPurchased = true;
|
||||
log("Trial mode on!");
|
||||
Track().track(TrackingEvent.trial, eventValue: DateFormat('yyyy-MM-dd HH:mm:ss').format(start));
|
||||
|
||||
if (!isInDebugMode) {
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticTrial();
|
||||
}
|
||||
}
|
||||
yield MenuReady();
|
||||
}
|
||||
} on Exception catch (ex) {
|
||||
yield MenuError(message: ex.toString());
|
||||
}
|
||||
} */
|
||||
|
||||
void setAbility(String name) {
|
||||
switch (name) {
|
||||
case "one_rep_max":
|
||||
|
@ -15,7 +15,10 @@ import 'package:aitrainer_app/util/purchases.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:purchases_flutter/errors.dart';
|
||||
import 'package:purchases_flutter/models/offering_wrapper.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
part 'sales_event.dart';
|
||||
part 'sales_state.dart';
|
||||
@ -50,25 +53,46 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
||||
final int productId = event.productId;
|
||||
log("Requesting purchase for: " + productId.toString());
|
||||
Track().track(TrackingEvent.purchase_request);
|
||||
final Product? selectedProduct = this.getSelectedProduct(productId);
|
||||
log("SelectedProduct for purchase $selectedProduct");
|
||||
if (selectedProduct != null) {
|
||||
await RevenueCatPurchases().makePurchase(selectedProduct);
|
||||
if (Cache().hasPurchased) {
|
||||
Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
|
||||
purchase.dateAdd = DateTime.now();
|
||||
purchase.purchaseSum = 0;
|
||||
purchase.currency = "EUR";
|
||||
await PurchaseApi().savePurchase(purchase);
|
||||
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticPurchase();
|
||||
try {
|
||||
final Product? selectedProduct = this.getSelectedProduct(productId);
|
||||
|
||||
log("SelectedProduct for purchase $selectedProduct");
|
||||
if (selectedProduct != null) {
|
||||
await RevenueCatPurchases().makePurchase(selectedProduct);
|
||||
if (Cache().hasPurchased) {
|
||||
Purchase purchase = Purchase(customerId: Cache().userLoggedIn!.customerId!, productId: productId);
|
||||
purchase.dateAdd = DateTime.now();
|
||||
purchase.purchaseSum = 0;
|
||||
purchase.currency = "EUR";
|
||||
await PurchaseApi().savePurchase(purchase);
|
||||
Track().track(TrackingEvent.purchase_successful, eventValue: selectedProduct.localizedPrice.toString());
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
await mauticRepository.sendMauticPurchase();
|
||||
}
|
||||
emit(SalesSuccessful());
|
||||
} else {
|
||||
emit(SalesError(message: "No selected product"));
|
||||
}
|
||||
emit(SalesSuccessful());
|
||||
} else {
|
||||
emit(SalesError(message: "No selected product"));
|
||||
} on PlatformException catch (e) {
|
||||
await Sentry.captureException(e);
|
||||
var errorCode = PurchasesErrorHelper.getErrorCode(e);
|
||||
if (errorCode == PurchasesErrorCode.invalidReceiptError) {
|
||||
log("iOS Sandbox invalid receipt");
|
||||
Cache().hasPurchased = true;
|
||||
log(" -- Purchased -- ");
|
||||
return;
|
||||
}
|
||||
log(e.toString());
|
||||
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
|
||||
emit(SalesError(message: "Purchase was cancelled"));
|
||||
} else {
|
||||
emit(SalesError(message: "Purchase was not successful"));
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
log(e.toString());
|
||||
emit(SalesError(message: "Purchase was not successful"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,10 +185,10 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
||||
return;
|
||||
}
|
||||
|
||||
String productSetString = splitTestRepository.getSplitTestValue("product_set_5");
|
||||
log("ProductSetString: $productSetString");
|
||||
//String productSetString = splitTestRepository.getSplitTestValue("product_set_5");
|
||||
//log("ProductSetString: $productSetString");
|
||||
try {
|
||||
productSet = int.parse(productSetString);
|
||||
productSet = 5;
|
||||
} on Exception catch (e) {
|
||||
log("Define the right productset! $e");
|
||||
productSet = 2;
|
||||
|
@ -7,6 +7,7 @@ import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/session.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:upgrader/upgrader.dart';
|
||||
|
||||
part 'session_event.dart';
|
||||
part 'session_state.dart';
|
||||
@ -24,13 +25,22 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
||||
log(" -------- Session starting...");
|
||||
emit(SessionLoading());
|
||||
|
||||
this.settingsBloc = event.settingsBloc;
|
||||
await session.fetchSessionAndNavigate();
|
||||
FirebaseApi().setupRemoteConfig();
|
||||
String lang = AppLanguage().appLocal.languageCode;
|
||||
log("Change lang to $lang");
|
||||
settingsBloc!.add(SettingsChangeLanguage(language: lang));
|
||||
emit(SessionReady());
|
||||
try {
|
||||
this.settingsBloc = event.settingsBloc;
|
||||
await session.fetchSessionAndNavigate();
|
||||
FirebaseApi().setupRemoteConfig();
|
||||
String lang = AppLanguage().appLocal.languageCode;
|
||||
log("Change lang to $lang");
|
||||
settingsBloc!.add(SettingsChangeLanguage(language: lang));
|
||||
final iTunes = ITunesSearchAPI();
|
||||
final resultsFuture = iTunes.lookupByBundleId('com.aitrainer.app');
|
||||
resultsFuture.then((results) {
|
||||
print('iTunes results: $results');
|
||||
});
|
||||
emit(SessionReady());
|
||||
} on Exception catch (e) {
|
||||
emit(SessionFailure(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:aitrainer_app/main.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
@ -61,7 +61,7 @@ class TestSetNewBloc extends Bloc<TestSetNewEvent, TestSetNewState> {
|
||||
exerciseRepository.end = DateTime.now();
|
||||
await exerciseRepository.addExercise();
|
||||
executeBloc.add(TestSetExecuteExerciseFinished(exerciseTypeId: exerciseType.exerciseTypeId, quantity: quantity, unitQuantity: unitQuantity));
|
||||
if (!isInDebugMode) {
|
||||
if (kReleaseMode) {
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
|
@ -17,7 +17,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
final String day;
|
||||
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) {
|
||||
_load();
|
||||
//on<TrainingEvaluationLoad>(_onLoad);
|
||||
on<TrainingEvaluationLoad>(_onLoad);
|
||||
}
|
||||
|
||||
String duration = "-";
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/main.dart';
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer_training_plan.dart';
|
||||
@ -23,6 +22,7 @@ import 'package:aitrainer_app/widgets/exercise_save.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
part 'training_plan_event.dart';
|
||||
part 'training_plan_state.dart';
|
||||
@ -174,7 +174,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> with C
|
||||
await Cache().saveMyTrainingPlan();
|
||||
}
|
||||
|
||||
if (!isInDebugMode) {
|
||||
if (kReleaseMode) {
|
||||
CustomerRepository customerRepository = CustomerRepository();
|
||||
customerRepository.customer = Cache().userLoggedIn;
|
||||
MauticRepository mauticRepository = MauticRepository(customerRepository: customerRepository);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
//import 'dart:io';
|
||||
/*
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
class DB {
|
||||
@ -35,3 +35,4 @@ class DB {
|
||||
|
||||
Database getDB() => this._db;
|
||||
}
|
||||
*/
|
@ -121,7 +121,7 @@ class AnimatedButton extends StatefulWidget {
|
||||
this.borderWidth = 1,
|
||||
this.blurColor = Colors.black,
|
||||
this.shadowColor,
|
||||
}) : super(key: key);
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AnimatedButtonState createState() => _AnimatedButtonState(
|
||||
@ -145,7 +145,7 @@ class _AnimatedButtonState extends State<AnimatedButton> {
|
||||
_AnimatedButtonState({
|
||||
this.type,
|
||||
this.color,
|
||||
this.shadowColor,
|
||||
//this.shadowColor,
|
||||
this.borderColor,
|
||||
this.blurColor,
|
||||
});
|
||||
@ -159,14 +159,14 @@ class _AnimatedButtonState extends State<AnimatedButton> {
|
||||
int index = type!.index;
|
||||
setState(() {
|
||||
color = definedColors[index]["color"];
|
||||
shadowColor = definedColors[index]["shadowColor"];
|
||||
//shadowColor = definedColors[index]["shadowColor"];
|
||||
blurColor = definedColors[index]["blurColor"];
|
||||
borderColor = definedColors[index]["borderColor"];
|
||||
});
|
||||
} else {
|
||||
setState(() {
|
||||
color = widget.color;
|
||||
shadowColor = widget.shadowColor;
|
||||
//shadowColor = widget.shadowColor;
|
||||
blurColor = widget.blurColor;
|
||||
borderColor = widget.borderColor;
|
||||
});
|
||||
|
@ -40,19 +40,12 @@ class ImageCache with Logging {
|
||||
final String imageKey = generateMd5(url + "_" + id.toString());
|
||||
|
||||
// get from storage
|
||||
final String imageString = (await getImageAs64BaseString(id, url))!;
|
||||
final String? imageString = await getImageAs64BaseString(id, url);
|
||||
|
||||
_images[imageKey] = imageString;
|
||||
_imageMap[imageKey] = true;
|
||||
|
||||
/* final String imageString = await getImageAs64BaseString(id, url);
|
||||
if (imageString != null) {
|
||||
_imageMap[imageKey] = imageString;
|
||||
_imageDown[imageKey] = true;
|
||||
}
|
||||
if (imageString != null) {
|
||||
_images[imageKey] = imageString;
|
||||
_imageMap[imageKey] = true;
|
||||
}
|
||||
_images[imageKey] = imageString;
|
||||
_imageMap[imageKey] = true; */
|
||||
}
|
||||
|
||||
Future<void> saveImageToPrefs(String key, String value) async {
|
||||
@ -102,14 +95,14 @@ class ImageCache with Logging {
|
||||
return image;
|
||||
}
|
||||
|
||||
Future<String?> getImageAs64BaseString(int id, String name) async {
|
||||
Future<String?>? getImageAs64BaseString(int id, String name) async {
|
||||
final String imageKey = generateMd5(name + "_" + id.toString());
|
||||
String? imageString;
|
||||
if (await storage.containsKey(key: imageKey)) {
|
||||
//log(" .. get from storage");
|
||||
imageString = await storage.read(key: imageKey);
|
||||
} else {
|
||||
imageString = (await downloadAndSaveImage(id, name))!;
|
||||
imageString = await downloadAndSaveImage(id, name);
|
||||
//log(" .. downloaded");
|
||||
}
|
||||
return imageString;
|
||||
|
@ -1,7 +1,6 @@
|
||||
library network_image_to_byte;
|
||||
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
|
@ -76,7 +76,7 @@ class __TreeViewDataState extends State<_TreeViewData> {
|
||||
super.initState();
|
||||
|
||||
/// 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;
|
||||
subscription = stream.listen((value) {
|
||||
if (value) {
|
||||
|
170
lib/main.dart
@ -1,5 +1,3 @@
|
||||
// ignore_for_file: must_be_immutable
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
|
||||
@ -48,17 +46,17 @@ import 'package:aitrainer_app/widgets/development_diagram.dart';
|
||||
import 'package:aitrainer_app/widgets/home.dart';
|
||||
import 'package:aitrainer_app/library/facebook_app_events/facebook_app_events.dart';
|
||||
import 'package:firebase_analytics/firebase_analytics.dart';
|
||||
//import 'package:flurry_data/flurry_data.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
//import 'package:flutter_uxcam/flutter_uxcam.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:matomo_tracker/matomo_tracker.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
//import 'package:flutter_smartlook/flutter_smartlook.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:posthog_session/posthog_session.dart';
|
||||
import 'package:upgrader/upgrader.dart';
|
||||
import 'bloc/account/account_bloc.dart';
|
||||
import 'bloc/body_development/body_development_bloc.dart';
|
||||
@ -72,18 +70,7 @@ import 'model/cache.dart';
|
||||
import 'view/training_evaluation_page.dart';
|
||||
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
|
||||
|
||||
const dsn = 'https://0f635b7225564abc9089f8106f25eb5c@sentry.aitrainer.app/1';
|
||||
|
||||
/// Whether the VM is running in debug mode.
|
||||
///
|
||||
/// This is useful to decide whether a report should be sent to sentry. Usually
|
||||
/// reports from dev mode are not very useful, as these happen on developers'
|
||||
/// workspaces rather than on users' devices in production.
|
||||
bool get isInDebugMode {
|
||||
bool inDebugMode = false;
|
||||
assert(inDebugMode = true);
|
||||
return inDebugMode;
|
||||
}
|
||||
const dsn = 'https://2309523cf2374c089fa1143d19209bc1@glitch.workouttest.org/2';
|
||||
|
||||
/// Reports [error] along with its [stackTrace] to Sentry.io.
|
||||
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
|
||||
@ -92,38 +79,51 @@ Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
|
||||
// Errors thrown in development mode are unlikely to be interesting. You can
|
||||
// check if you are running in dev mode using an assertion and omit sending
|
||||
// the report.
|
||||
if (isInDebugMode) {
|
||||
if (!kReleaseMode) {
|
||||
print(stackTrace);
|
||||
print('In dev mode. Not sending report to Sentry.io.');
|
||||
return;
|
||||
}
|
||||
|
||||
print('Reporting to Sentry.io...');
|
||||
final String customerId = Cache().userLoggedIn != null ? Cache().userLoggedIn!.customerId.toString() : "0";
|
||||
Sentry.configureScope(
|
||||
(scope) => scope.user = SentryUser(id: customerId),
|
||||
);
|
||||
final String platform = Platform.isAndroid ? "Android" : "iOS";
|
||||
final String version = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : "";
|
||||
final sentryId =
|
||||
await Sentry.captureException(error, stackTrace: stackTrace, hint: "Platform: $platform, Version: $version, User: $customerId");
|
||||
|
||||
final sentryId = await Sentry.captureException(error, stackTrace: stackTrace);
|
||||
print('Capture exception result : SentryId : $sentryId');
|
||||
MatomoTracker.instance.trackEvent(eventCategory: "error", action: error.toString());
|
||||
print('Track error to Matomo');
|
||||
}
|
||||
|
||||
Future<Null> main() async {
|
||||
|
||||
// This captures errors reported by the Flutter framework.
|
||||
FlutterError.onError = (FlutterErrorDetails details) async {
|
||||
if (isInDebugMode) {
|
||||
if (!kReleaseMode) {
|
||||
// In development mode simply print to console.
|
||||
FlutterError.dumpErrorToConsole(details);
|
||||
} else {
|
||||
//} else {
|
||||
// In production mode report to the application zone to report to
|
||||
// Sentry.
|
||||
Zone.current.handleUncaughtError(details.exception, details.stack!);
|
||||
}
|
||||
};
|
||||
|
||||
Future<void> initThirdParty() async {
|
||||
if (kReleaseMode) {
|
||||
await MatomoTracker.instance.initialize(
|
||||
siteId: 3,
|
||||
url: 'https://matomo.workouttest.org/matomo.php',
|
||||
);
|
||||
}
|
||||
|
||||
Posthog().setContext({
|
||||
'token':'v1.1.26'
|
||||
});
|
||||
Posthog().identify(userId: 0, properties: {
|
||||
'token':'v1.1.26'
|
||||
});
|
||||
print(" -- FireBase init..");
|
||||
await FirebaseApi().initializeFlutterFire();
|
||||
}
|
||||
|
||||
// This creates a [Zone] that contains the Flutter application and stablishes
|
||||
// an error handler that captures errors and reports them.
|
||||
//
|
||||
@ -136,80 +136,51 @@ Future<Null> main() async {
|
||||
// - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
|
||||
// - https://www.dartlang.org/articles/libraries/zones
|
||||
runZonedGuarded<Future<Null>>(() async {
|
||||
if (!isInDebugMode) {
|
||||
await SentryFlutter.init(
|
||||
(options) {
|
||||
options.dsn = dsn;
|
||||
options.release = Cache().packageInfo != null ? Cache().packageInfo!.version + "+" + Cache().packageInfo!.buildNumber : "";
|
||||
options.enableAutoSessionTracking = true;
|
||||
},
|
||||
);
|
||||
}
|
||||
Future<void> initThirdParty() async {
|
||||
if (!isInDebugMode) {
|
||||
//await FlurryData.initialize(androidKey: "JNYCTCWBT34FM3J8TV36", iosKey: "3QBG7BSMGPDH24S8TRQP", enableLog: true);
|
||||
await MatomoTracker.instance.initialize(
|
||||
siteId: 3,
|
||||
url: 'https://matomo.workouttest.com/matomo.php',
|
||||
//visitorId: 'customer_1',
|
||||
);
|
||||
//FlutterUxcam.optIntoSchematicRecordings();
|
||||
}
|
||||
await FirebaseApi().initializeFlutterFire();
|
||||
}
|
||||
|
||||
final WorkoutTreeRepository menuTreeRepository = WorkoutTreeRepository();
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
if (!isInDebugMode) {
|
||||
//FlutterUxcam.startWithKey("wvdstyoml4tiwfd");
|
||||
|
||||
//SetupOptions options = (new SetupOptionsBuilder('682883e5cd71a46160c4f6ed070530ee593f49c6')).build();
|
||||
//Smartlook.setupAndStartRecording(options);
|
||||
//Smartlook.setEventTrackingMode(EventTrackingMode.FULL_TRACKING);
|
||||
}
|
||||
await initThirdParty();
|
||||
final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
|
||||
|
||||
print(" -- FireBase init..");
|
||||
|
||||
runApp(MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<SessionBloc>(
|
||||
create: (BuildContext context) => SessionBloc(session: Session()),
|
||||
),
|
||||
BlocProvider<MenuBloc>(
|
||||
create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<SettingsBloc>(
|
||||
create: (BuildContext context) => SettingsBloc(context: context),
|
||||
),
|
||||
BlocProvider<AccountBloc>(
|
||||
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
|
||||
),
|
||||
BlocProvider<ExercisePlanBloc>(
|
||||
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<DevelopmentByMuscleBloc>(
|
||||
create: (BuildContext context) => DevelopmentByMuscleBloc(workoutTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<BodyDevelopmentBloc>(
|
||||
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<TimerBloc>(
|
||||
create: (BuildContext context) => TimerBloc(),
|
||||
),
|
||||
BlocProvider<TestSetExecuteBloc>(
|
||||
create: (BuildContext context) => TestSetExecuteBloc(),
|
||||
),
|
||||
BlocProvider<TutorialBloc>(
|
||||
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
|
||||
BlocProvider<TrainingPlanBloc>(create: (context) {
|
||||
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
|
||||
}),
|
||||
],
|
||||
child: WorkoutTestApp(analytics: analytics),
|
||||
));
|
||||
await SentryFlutter.init((options) => options..dsn = dsn,
|
||||
appRunner: () => runApp(MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<SessionBloc>(
|
||||
create: (BuildContext context) => SessionBloc(session: Session()),
|
||||
),
|
||||
BlocProvider<MenuBloc>(
|
||||
create: (BuildContext context) => MenuBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<SettingsBloc>(
|
||||
create: (BuildContext context) => SettingsBloc(context: context),
|
||||
),
|
||||
BlocProvider<AccountBloc>(
|
||||
create: (BuildContext context) => AccountBloc(customerRepository: CustomerRepository()),
|
||||
),
|
||||
BlocProvider<ExercisePlanBloc>(
|
||||
create: (BuildContext context) => ExercisePlanBloc(menuTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<DevelopmentByMuscleBloc>(
|
||||
create: (BuildContext context) => DevelopmentByMuscleBloc(workoutTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<BodyDevelopmentBloc>(
|
||||
create: (BuildContext context) => BodyDevelopmentBloc(workoutTreeRepository: menuTreeRepository),
|
||||
),
|
||||
BlocProvider<TimerBloc>(
|
||||
create: (BuildContext context) => TimerBloc(),
|
||||
),
|
||||
BlocProvider<TestSetExecuteBloc>(
|
||||
create: (BuildContext context) => TestSetExecuteBloc(),
|
||||
),
|
||||
BlocProvider<TutorialBloc>(
|
||||
create: (BuildContext context) => TutorialBloc(tutorialName: ActivityDone.tutorialExecuteFirstTest.toStr())),
|
||||
BlocProvider<TrainingPlanBloc>(create: (context) {
|
||||
final MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
return TrainingPlanBloc(menuBloc: menuBloc, trainingPlanRepository: TrainingPlanRepository());
|
||||
}),
|
||||
],
|
||||
child: WorkoutTestApp(analytics: analytics),
|
||||
)));
|
||||
}, (error, stackTrace) async {
|
||||
await _reportError(error, stackTrace);
|
||||
});
|
||||
@ -227,7 +198,7 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
Upgrader().installAppStoreListingURL(Platform.isAndroid
|
||||
? "https://play.google.com/store/apps/details?id=com.aitrainer.aitrainer_app"
|
||||
: "https://apps.apple.com/hu/app/workouttest/id1515271425");
|
||||
//Upgrader().installAppStoreVersion("1.1.19");
|
||||
Upgrader().installAppStoreVersion("1.1.26");
|
||||
// On iOS, the default behavior will be to use the App Store version of
|
||||
// the app, so update the Bundle Identifier in example/ios/Runner with a
|
||||
// valid identifier already in the App Store.
|
||||
@ -305,13 +276,12 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
title: 'WorkoutTest',
|
||||
theme: ThemeData(
|
||||
brightness: Brightness.light,
|
||||
//primarySwatch: Colors.transparent,
|
||||
//fontFamily: 'Arial',
|
||||
textTheme: TextTheme(
|
||||
bodyText1: GoogleFonts.inter(textStyle: TextStyle(fontSize: 14.0)),
|
||||
)),
|
||||
navigatorObservers: [
|
||||
FirebaseAnalyticsObserver(analytics: analytics),
|
||||
PosthogObserver(),
|
||||
],
|
||||
home: AitrainerHome(),
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/customer_activity.dart';
|
||||
import 'package:aitrainer_app/model/customer_property.dart';
|
||||
@ -27,20 +28,17 @@ import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/service/firebase_api.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/service/package_service.dart';
|
||||
import 'package:aitrainer_app/main.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/env.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:firebase_remote_config/firebase_remote_config.dart';
|
||||
//import 'package:flurry_data/flurry_data.dart';
|
||||
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
|
||||
//import 'package:flutter_uxcam/flutter_uxcam.dart';
|
||||
import 'package:matomo_tracker/matomo_tracker.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
import 'package:posthog_session/posthog_session.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
//import 'package:flutter_smartlook/flutter_smartlook.dart';
|
||||
|
||||
import 'customer_exercise_device.dart';
|
||||
import 'exercise_device.dart';
|
||||
@ -117,10 +115,10 @@ class Cache with Logging {
|
||||
static final String activeExercisePlanDetailsKey = "active_exercise_details_plan";
|
||||
static final String myTrainingPlanKey = "myTrainingPlan";
|
||||
|
||||
static String baseUrlLive = 'https://aitrainer.info:8943/api/';
|
||||
static String baseUrlTest = 'https://aitrainer.info:8843/api/';
|
||||
static String baseUrlLive = 'https://api.workouttest.org/api/';
|
||||
static String baseUrlTest = 'https://apitest.workouttest.org/api/';
|
||||
late String baseUrl;
|
||||
static final String mediaUrl = 'https://admin.aitrainer.app/media/';
|
||||
static final String mediaUrl = 'https://admin.workouttest.org/media/';
|
||||
static final String username = 'bosi';
|
||||
static final String password = 'andio2009';
|
||||
|
||||
@ -214,6 +212,12 @@ class Cache with Logging {
|
||||
return this.authToken;
|
||||
}
|
||||
|
||||
Future<void> deleteCustomerId(int customerId) async {
|
||||
Future<SharedPreferences> prefs = SharedPreferences.getInstance();
|
||||
SharedPreferences sharedPreferences = await prefs;
|
||||
sharedPreferences.remove(Cache.customerIdKey);
|
||||
}
|
||||
|
||||
Future<void> saveActiveExercisePlan(ExercisePlan exercisePlan, List<ExercisePlanDetail> exercisePlanDetails) async {
|
||||
this.activeExercisePlan = exercisePlan;
|
||||
this.activeExercisePlanDetails = exercisePlanDetails;
|
||||
@ -695,15 +699,17 @@ class Cache with Logging {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isInDebugMode) {
|
||||
if (kReleaseMode) {
|
||||
//FlurryData.setUserId(customerId.toString());
|
||||
//FlutterUxcam.setUserProperty("username", customerId.toString());
|
||||
//FlutterUxcam.setUserIdentity(customerId.toString());
|
||||
//Smartlook.setUserIdentifier(customerId.toString());
|
||||
//Smartlook.instance.
|
||||
Track().track(TrackingEvent.enter);
|
||||
MatomoTracker.instance
|
||||
.trackEvent(eventName: TrackingEvent.enter.enumToString(), eventCategory: "", action: TrackingEvent.enter.enumToString(), eventValue: customerId);
|
||||
MatomoTracker.instance.setVisitorUserId(customerId.toString());
|
||||
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: TrackingEvent.enter.enumToString());
|
||||
Posthog().identify(userId: customerId.toString());
|
||||
Posthog().capture(eventName: TrackingEvent.enter.enumToString());
|
||||
}
|
||||
|
||||
await Future.forEach(ActivityDone.values, (element) async {
|
||||
|
@ -94,7 +94,7 @@ class CustomerTrainingPlanDetails {
|
||||
|
||||
this.exerciseType = Cache().getExerciseTypeById(exerciseTypeId!);
|
||||
|
||||
this.baseOneRepMax = json['baseOneRepMax'];
|
||||
this.baseOneRepMax = json['baseOneRepMax'] == null ? 0 : json['baseOneRepMax'];
|
||||
}
|
||||
|
||||
ExerciseType? getExerciseType() => exerciseType;
|
||||
|
@ -23,7 +23,7 @@ class CustomerRepository with Logging {
|
||||
Customer? _trainee;
|
||||
List<Customer>? _trainees;
|
||||
List<CustomerProperty>? _properties;
|
||||
List<CustomerProperty>? _allCustomerProperties;
|
||||
//List<CustomerProperty>? _allCustomerProperties;
|
||||
final PropertyRepository propertyRepository = PropertyRepository();
|
||||
final List<Property> womanSizes = [];
|
||||
final List<Property> manSizes = [];
|
||||
@ -45,7 +45,7 @@ class CustomerRepository with Logging {
|
||||
isMan = (Cache().userLoggedIn!.sex == "m");
|
||||
}
|
||||
|
||||
_allCustomerProperties = Cache().getCustomerPropertyAll();
|
||||
//_allCustomerProperties = Cache().getCustomerPropertyAll();
|
||||
}
|
||||
|
||||
String? getGenderByName(String name) {
|
||||
|
@ -204,12 +204,15 @@ class UserRepository with Logging {
|
||||
Future<void> getUser() async {
|
||||
final User modelUser = this.user;
|
||||
String rc = await FirebaseApi().signInEmail(modelUser.email, modelUser.password);
|
||||
|
||||
if (rc == FirebaseApi.SIGN_IN_OK) {
|
||||
await CustomerApi().getUserByEmail(modelUser.email!);
|
||||
await Cache().afterFirebaseLogin();
|
||||
} else {
|
||||
log("Exception: user not found or password is wrong");
|
||||
try {
|
||||
if (rc == FirebaseApi.SIGN_IN_OK) {
|
||||
await CustomerApi().getUserByEmail(modelUser.email!);
|
||||
await Cache().afterFirebaseLogin();
|
||||
} else {
|
||||
log("Exception: user not found or password is wrong");
|
||||
throw Exception("Customer does not exist or the password is wrong");
|
||||
}
|
||||
} on NotFoundException catch (_) {
|
||||
throw Exception("Customer does not exist or the password is wrong");
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
class APIClient with Common, Logging {
|
||||
static final APIClient _singleton = APIClient._internal();
|
||||
@ -45,12 +46,18 @@ class APIClient with Common, Logging {
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
if (result.statusCode != 200) {
|
||||
trace("authentication response: ${result.statusCode}");
|
||||
throw Exception("Network error, try again later!");
|
||||
trace("authentication response: ${result.statusCode} with URL: $url");
|
||||
throw Exception("Authentication error: ${result.statusCode}");
|
||||
}
|
||||
return jsonDecode(await result.transform(utf8.decoder).join());
|
||||
} catch (exception) {
|
||||
print(exception.toString());
|
||||
try {
|
||||
await Sentry.captureException(exception);
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
throw Exception("Network error, try again later!");
|
||||
}
|
||||
}
|
||||
@ -85,39 +92,49 @@ class APIClient with Common, Logging {
|
||||
} else {
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
} on NotFoundException catch(e) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} on Exception catch (e) {
|
||||
print("Post Exception: $e");
|
||||
await Sentry.captureException(e);
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> get(String endPoint, String param) async {
|
||||
final url = Cache().getBaseUrl() + endPoint + param;
|
||||
try {
|
||||
trace("-------- API get " + url);
|
||||
String authToken = Cache().getAuthToken();
|
||||
if (authToken.length == 0) {
|
||||
var responseJson = await this.authenticateUser(Cache.username, Cache.password);
|
||||
authToken = responseJson['token'];
|
||||
Cache().authToken = authToken;
|
||||
}
|
||||
var uri = Uri.parse(url);
|
||||
|
||||
trace("-------- API get " + url);
|
||||
String authToken = Cache().getAuthToken();
|
||||
if (authToken.length == 0) {
|
||||
var responseJson = await this.authenticateUser(Cache.username, Cache.password);
|
||||
authToken = responseJson['token'];
|
||||
Cache().authToken = authToken;
|
||||
}
|
||||
var uri = Uri.parse(url);
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
|
||||
|
||||
client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true);
|
||||
|
||||
final HttpClientRequest request = await client.getUrl(uri);
|
||||
request.headers.set('Content-Type', 'application/json');
|
||||
request.headers.set('Authorization', 'Bearer $authToken');
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
trace(" ------------get response code: " + result.statusCode.toString());
|
||||
if (result.statusCode == 200) {
|
||||
return await result.transform(utf8.decoder).join();
|
||||
} else if (result.statusCode == 404) {
|
||||
final HttpClientRequest request = await client.getUrl(uri);
|
||||
request.headers.set('Content-Type', 'application/json');
|
||||
request.headers.set('Authorization', 'Bearer $authToken');
|
||||
HttpClientResponse result = await request.close();
|
||||
client.close();
|
||||
trace(" ------------get response code: " + result.statusCode.toString());
|
||||
if (result.statusCode == 200) {
|
||||
return await result.transform(utf8.decoder).join();
|
||||
} else if (result.statusCode == 404) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
} on NotFoundException catch(e) {
|
||||
throw NotFoundException(message: "Not Found");
|
||||
} else {
|
||||
} on Exception catch (e) {
|
||||
print("Post Exception: $e");
|
||||
await Sentry.captureException(e);
|
||||
throw Exception("Network Error, please try again later");
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ class CustomerApi with Logging {
|
||||
await _client.post("customers/update_firebase_uid/" + customerId.toString(), uid);
|
||||
}
|
||||
|
||||
Future<void> deactivateCustomer(int customerId) async {
|
||||
log(" ===== deactivate : $customerId");
|
||||
await _client.post("customers/deactivate/$customerId", "");
|
||||
}
|
||||
|
||||
Future<void> addCustomer(Customer customer) async {
|
||||
customer.dateAdd = DateTime.now();
|
||||
customer.dateChange = DateTime.now();
|
||||
|
@ -2,7 +2,8 @@ import 'dart:math' as math;
|
||||
import 'dart:convert';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart' as logging;
|
||||
import 'package:aitrainer_app/service/logging.dart' as logger;
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
@ -11,7 +12,7 @@ import 'package:firebase_remote_config/firebase_remote_config.dart';
|
||||
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';
|
||||
import 'package:google_sign_in/google_sign_in.dart';
|
||||
|
||||
class FirebaseApi with logging.Logging {
|
||||
class FirebaseApi with logger.Logging {
|
||||
bool appleSignInAvailable = false;
|
||||
|
||||
static final FirebaseAuth auth = FirebaseAuth.instance;
|
||||
@ -37,25 +38,6 @@ class FirebaseApi with logging.Logging {
|
||||
|
||||
this.appleSignInAvailable = await SignInWithApple.isAvailable();
|
||||
|
||||
/* AwesomeNotifications().initialize(
|
||||
// set the icon to null if you want to use the default app icon
|
||||
null,
|
||||
[
|
||||
NotificationChannel(
|
||||
channelKey: 'basic_channel',
|
||||
channelName: 'Basic notifications',
|
||||
channelDescription: 'Notification channel for basic tests',
|
||||
defaultColor: Color(0xFF9D50DD),
|
||||
ledColor: Colors.white)
|
||||
]);
|
||||
|
||||
AwesomeNotifications().isNotificationAllowed().then((isAllowed) {
|
||||
if (!isAllowed) {
|
||||
// Insert here your friendly dialog box before call the request method
|
||||
// This is very important to not harm the user experience
|
||||
AwesomeNotifications().requestPermissionToSendNotifications();
|
||||
}
|
||||
}); */
|
||||
|
||||
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
|
||||
alert: true, // Required to display a heads up notification
|
||||
@ -75,9 +57,9 @@ class FirebaseApi with logging.Logging {
|
||||
print('Message also contained a notification: ${message.notification}');
|
||||
}
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
// Set `_error` state to true if Firebase initialization fails
|
||||
Sentry.captureException(e);
|
||||
log("Error initializing Firebase");
|
||||
}
|
||||
}
|
||||
@ -94,6 +76,7 @@ class FirebaseApi with logging.Logging {
|
||||
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
} on FirebaseAuthException catch (e) {
|
||||
Sentry.captureException(e);
|
||||
if (e.code == 'user-not-found') {
|
||||
log('No user found for that email.');
|
||||
rc = SIGN_IN_NOT_FOUND;
|
||||
@ -113,6 +96,7 @@ class FirebaseApi with logging.Logging {
|
||||
userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password);
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
} on FirebaseAuthException catch (e) {
|
||||
Sentry.captureException(e);
|
||||
if (e.code == 'weak-password') {
|
||||
log('The password provided is too weak.');
|
||||
rc = REGISTER_WEAK_PWD;
|
||||
@ -124,6 +108,7 @@ class FirebaseApi with logging.Logging {
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
Sentry.captureException(e);
|
||||
throw Exception(e.toString());
|
||||
}
|
||||
return rc;
|
||||
@ -145,26 +130,6 @@ class FirebaseApi with logging.Logging {
|
||||
Future<Map<String, dynamic>> signInWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
|
||||
/* final apple.AuthorizationResult result = await SignInWithApple.performRequests([
|
||||
apple.AppleIdRequest(requestedScopes: [apple.Scope.email, apple.Scope.fullName])
|
||||
]);
|
||||
switch (result.status) {
|
||||
case apple.AuthorizationStatus.authorized:
|
||||
print('User authorized');
|
||||
break;
|
||||
case apple.AuthorizationStatus.error:
|
||||
print('User error');
|
||||
throw Exception("Apple Sign-In failed");
|
||||
case apple.AuthorizationStatus.cancelled:
|
||||
print('User cancelled');
|
||||
throw Exception("Apple Sign-In cancelled");
|
||||
}
|
||||
|
||||
// Create an `OAuthCredential` from the credential returned by Apple.
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: String.fromCharCodes(result.credential.identityToken),
|
||||
accessToken: String.fromCharCodes(result.credential.authorizationCode!));
|
||||
*/
|
||||
// To prevent replay attacks with the credential returned from Apple, we
|
||||
// include a nonce in the credential request. When signing in with
|
||||
// Firebase, the nonce in the id token returned by Apple, is expected to
|
||||
@ -186,9 +151,15 @@ class FirebaseApi with logging.Logging {
|
||||
idToken: appleCredential.identityToken,
|
||||
rawNonce: rawNonce,
|
||||
);
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
UserCredential? userCredential;
|
||||
try {
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
} on FirebaseAuthException catch(e) {
|
||||
Sentry.captureException(e);
|
||||
throw Exception(e);
|
||||
}
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
log("userCredential: " + userCredential.toString());
|
||||
|
||||
@ -200,21 +171,7 @@ class FirebaseApi with logging.Logging {
|
||||
|
||||
Future<Map<String, dynamic>> registerWithApple() async {
|
||||
Map<String, dynamic> userData = Map();
|
||||
/* final apple.AuthorizationResult result = await apple.TheAppleSignIn.performRequests([
|
||||
apple.AppleIdRequest(requestedScopes: [apple.Scope.email, apple.Scope.fullName])
|
||||
]);
|
||||
switch (result.status) {
|
||||
case apple.AuthorizationStatus.authorized:
|
||||
print('Apple User authorized');
|
||||
break;
|
||||
case apple.AuthorizationStatus.error:
|
||||
print('Apple User error');
|
||||
throw Exception("Apple Sign-In failed");
|
||||
case apple.AuthorizationStatus.cancelled:
|
||||
print('User cancelled');
|
||||
throw Exception("Apple Sign-In cancelled");
|
||||
}
|
||||
*/
|
||||
|
||||
final rawNonce = generateNonce();
|
||||
final nonce = sha256ofString(rawNonce);
|
||||
|
||||
@ -232,14 +189,15 @@ class FirebaseApi with logging.Logging {
|
||||
rawNonce: rawNonce,
|
||||
);
|
||||
|
||||
/* // Create an `OAuthCredential` from the credential returned by Apple.
|
||||
final oauthCredential = OAuthProvider("apple.com").credential(
|
||||
idToken: String.fromCharCodes(result.credential.identityToken),
|
||||
accessToken: String.fromCharCodes(result.credential.authorizationCode));
|
||||
*/
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
UserCredential? userCredential;
|
||||
try {
|
||||
// Sign in the user with Firebase. If the nonce we generated earlier does
|
||||
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
|
||||
userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);
|
||||
} on FirebaseAuthException catch(e) {
|
||||
Sentry.captureException(e);
|
||||
throw Exception(e);
|
||||
}
|
||||
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
|
||||
@ -261,6 +219,7 @@ class FirebaseApi with logging.Logging {
|
||||
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
Sentry.captureException(new Exception("Google Sign In failed"));
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
@ -297,6 +256,7 @@ class FirebaseApi with logging.Logging {
|
||||
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
|
||||
|
||||
if (googleUser == null) {
|
||||
Sentry.captureException(new Exception("Google Sign In failed"));
|
||||
throw Exception("Google Sign In failed");
|
||||
}
|
||||
|
||||
@ -333,6 +293,7 @@ class FirebaseApi with logging.Logging {
|
||||
Cache().firebaseUid = userData['id'];
|
||||
log(userData.toString());
|
||||
} else {
|
||||
Sentry.captureException(new Exception(result.message));
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
@ -360,6 +321,7 @@ class FirebaseApi with logging.Logging {
|
||||
|
||||
Cache().firebaseUid = userCredential.user!.uid;
|
||||
} else {
|
||||
Sentry.captureException(new Exception(result.message));
|
||||
throw Exception("Facebook login was not successful");
|
||||
}
|
||||
|
||||
@ -381,11 +343,10 @@ class FirebaseApi with logging.Logging {
|
||||
|
||||
Future<void> setupRemoteConfig() async {
|
||||
//initializeFlutterFire();
|
||||
RemoteConfig? remoteConfig;
|
||||
FirebaseRemoteConfig? remoteConfig;
|
||||
try {
|
||||
remoteConfig = RemoteConfig.instance;
|
||||
await remoteConfig.setConfigSettings(
|
||||
RemoteConfigSettings(
|
||||
remoteConfig = FirebaseRemoteConfig.instance;
|
||||
await remoteConfig.setConfigSettings(RemoteConfigSettings(
|
||||
fetchTimeout: const Duration(seconds: 10),
|
||||
minimumFetchInterval: const Duration(seconds: 1),
|
||||
));
|
||||
|
@ -4,7 +4,7 @@ import 'package:aitrainer_app/model/mautic.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
|
||||
class MauticApi with Logging {
|
||||
final String mauticUrl = "https://mautic.aitrainer.app/form/submit?formId=";
|
||||
final String mauticUrl = "https://mautic.workouttest.org/form/submit?formId=";
|
||||
|
||||
Future<void> sendMauticForm(Mautic model) async {
|
||||
final String body = model.toForm();
|
||||
|
@ -145,6 +145,21 @@ mixin Common {
|
||||
return average;
|
||||
}
|
||||
|
||||
double getRepeatByOneRepMax(double oneRepMax, double weight) {
|
||||
double repeats = ( 80 * oneRepMax - 80 * weight ) / ( weight * ( 40 * 0.0333 + 1) );
|
||||
//print("getRepeatsByOneRepMax: $repeats");
|
||||
return repeats;
|
||||
}
|
||||
|
||||
int calculateRepeatBy1RMPercent(double oneRepMax, double weight, double percent) {
|
||||
return getRepeatByOneRepMax(oneRepMax , weight * percent).round();
|
||||
}
|
||||
|
||||
double calculate1RMPercentByRepeat(double oneRepMax, double weight, double repeat) {
|
||||
double percent = 80 * oneRepMax / (weight * ( repeat * ( 40 * 0.0333 + 1 ) + 80));
|
||||
return percent;
|
||||
}
|
||||
|
||||
static double get1RMPercent(int repeats) {
|
||||
double percent = 1;
|
||||
|
||||
@ -231,3 +246,5 @@ mixin Common {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
class CommonHoldingClass with Common {}
|
@ -53,6 +53,7 @@ enum TrackingEvent {
|
||||
tutorial_activate,
|
||||
terms_of_use,
|
||||
data_privacy,
|
||||
delete_account,
|
||||
faq,
|
||||
training_plan_open,
|
||||
training_plan_start,
|
||||
@ -60,7 +61,7 @@ enum TrackingEvent {
|
||||
training_plan_finished,
|
||||
training_plan_custom,
|
||||
trial,
|
||||
feedback_email
|
||||
feedback_email,
|
||||
}
|
||||
|
||||
T enumFromString<T>(Iterable<T> values, String value) {
|
||||
|
@ -50,6 +50,7 @@ class RevenueCatPurchases with Logging {
|
||||
log("Trial mode: $inTrial date: ${Cache().userLoggedIn!.trialDate}");
|
||||
if (Cache().userLoggedIn!.admin == 1 || inTrial || Cache().userLoggedIn!.lifeLong == 1) {
|
||||
Cache().hasPurchased = true;
|
||||
log(" -- Purchased -- ");
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,47 +75,34 @@ class RevenueCatPurchases with Logging {
|
||||
}
|
||||
|
||||
Future<void> makePurchase(wtproduct.Product product) async {
|
||||
try {
|
||||
if (_offering == null) {
|
||||
_offering = await getOfferings();
|
||||
}
|
||||
if (_offering != null) {
|
||||
String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
|
||||
Package? selectedPackage;
|
||||
log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId);
|
||||
for (var package in _offering!.availablePackages) {
|
||||
log("package to check " + package.product.identifier.toString());
|
||||
if (package.product.identifier == productId) {
|
||||
selectedPackage = package;
|
||||
log("**** Selected package to purchase" + package.product.identifier);
|
||||
break;
|
||||
}
|
||||
if (_offering == null) {
|
||||
_offering = await getOfferings();
|
||||
}
|
||||
if (_offering != null) {
|
||||
String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!;
|
||||
Package? selectedPackage;
|
||||
log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId);
|
||||
for (var package in _offering!.availablePackages) {
|
||||
log("package to check " + package.product.identifier.toString());
|
||||
if (package.product.identifier == productId) {
|
||||
selectedPackage = package;
|
||||
log("**** Selected package to purchase" + package.product.identifier);
|
||||
break;
|
||||
}
|
||||
if (selectedPackage != null) {
|
||||
PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
|
||||
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
|
||||
Cache().hasPurchased = true;
|
||||
}
|
||||
} else {
|
||||
log("!!!! No Selected package to purchase");
|
||||
throw Exception("Purchase was not successful");
|
||||
}
|
||||
if (selectedPackage != null) {
|
||||
PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage);
|
||||
if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) {
|
||||
Cache().hasPurchased = true;
|
||||
log(" -- Purchased -- ");
|
||||
}
|
||||
} else {
|
||||
log("!!!! No active offering");
|
||||
}
|
||||
} on PlatformException catch (e) {
|
||||
var errorCode = PurchasesErrorHelper.getErrorCode(e);
|
||||
if (errorCode == PurchasesErrorCode.invalidReceiptError) {
|
||||
log("iOS Sandbox invalid receipt");
|
||||
Cache().hasPurchased = true;
|
||||
return;
|
||||
}
|
||||
log(e.toString());
|
||||
if (errorCode == PurchasesErrorCode.purchaseCancelledError) {
|
||||
throw Exception("Purchase was cancelled");
|
||||
} else {
|
||||
throw Exception("Purchase was not successful");
|
||||
log("!!!! No Selected package to purchase");
|
||||
throw Exception("No Selected package to purchase");
|
||||
}
|
||||
} else {
|
||||
log("!!!! No active offering");
|
||||
throw Exception("No active offering");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:aitrainer_app/main.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/service/tracking_service.dart';
|
||||
@ -6,10 +5,9 @@ import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/model/tracking.dart' as model;
|
||||
import 'package:firebase_analytics/firebase_analytics.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
//import 'package:flurry_data/flurry_data.dart';
|
||||
//import 'package:flutter_uxcam/flutter_uxcam.dart';
|
||||
//import 'package:flutter_smartlook/flutter_smartlook.dart';
|
||||
import 'package:posthog_session/posthog_session.dart';
|
||||
import 'package:matomo_tracker/matomo_tracker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class Track with Logging {
|
||||
static final Track _singleton = Track._internal();
|
||||
@ -22,12 +20,9 @@ class Track with Logging {
|
||||
Track._internal();
|
||||
|
||||
void track(TrackingEvent event, {String eventValue = ""}) {
|
||||
if (!isInDebugMode) {
|
||||
//FlurryData.logEvent(event.enumToString());
|
||||
//Smartlook.setGlobalEventProperty(event.toString(), eventValue, false);
|
||||
//FlutterUxcam.logEventWithProperties(event.enumToString(), {"value": eventValue});
|
||||
model.Tracking tracking = model.Tracking();
|
||||
tracking.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
|
||||
model.Tracking tracking = model.Tracking();
|
||||
tracking.customerId = Cache().userLoggedIn == null ? 0 : Cache().userLoggedIn!.customerId!;
|
||||
if (kReleaseMode) {
|
||||
tracking.event = event.enumToString();
|
||||
if (eventValue.isNotEmpty) {
|
||||
tracking.eventValue = eventValue;
|
||||
@ -38,7 +33,21 @@ class Track with Logging {
|
||||
|
||||
FirebaseMessaging.instance.subscribeToTopic(event.enumToString());
|
||||
analytics.logEvent(name: event.enumToString(), parameters: {"value": eventValue});
|
||||
MatomoTracker.instance.trackEvent(eventName: event.enumToString(), eventCategory: "", action: eventValue, eventValue: tracking.customerId);
|
||||
|
||||
if (eventValue.isNotEmpty) {
|
||||
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: event.enumToString(), eventName: eventValue);
|
||||
} else {
|
||||
MatomoTracker.instance.trackEvent(eventCategory: "wt", action: event.enumToString());
|
||||
}
|
||||
Posthog().capture(
|
||||
eventName: event.enumToString(),
|
||||
properties: {
|
||||
'eventValue': eventValue,
|
||||
'customer': tracking.customerId,
|
||||
},
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
|
||||
|
||||
import '../util/enums.dart';
|
||||
import '../util/track.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AccountPage extends StatelessWidget with Trans {
|
||||
// ignore: close_sinks
|
||||
@ -73,7 +76,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
@ -94,7 +97,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
@ -116,7 +119,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
@ -134,7 +137,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t(bodyType), style: TextStyle(color: Colors.blue)),
|
||||
@ -152,6 +155,9 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
),
|
||||
devices(context, accountBloc),
|
||||
loginOut(context, accountBloc),
|
||||
Divider(),
|
||||
Divider(),
|
||||
deleteAccount(accountBloc),
|
||||
//messaging(),
|
||||
//getMyTrainees(context, accountBloc),
|
||||
]);
|
||||
@ -165,7 +171,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t("Available Devices"), style: TextStyle(color: Colors.blue)),
|
||||
@ -189,7 +195,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t("Trigger message"), style: TextStyle(color: Colors.purple)),
|
||||
@ -218,7 +224,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
title: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white38,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t(text), style: TextStyle(color: buttonColor)),
|
||||
@ -241,6 +247,29 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
return element;
|
||||
}
|
||||
|
||||
ListTile deleteAccount(AccountBloc accountBloc) {
|
||||
return ListTile(
|
||||
leading: Icon(Icons.delete_forever),
|
||||
title: TextButton(
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Text(t("Delete Account"), style: TextStyle(color: Color.fromARGB(255, 202, 10, 10))),
|
||||
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white70,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
if (accountBloc.loggedIn)
|
||||
{
|
||||
deleteAccountConfirmationDialog(accountBloc),
|
||||
}
|
||||
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getMyTrainees(BuildContext context, AccountBloc accountBloc) {
|
||||
if (accountBloc.customerRepository.customer == null || accountBloc.customerRepository.customer!.trainer == 0) {
|
||||
return ListTile(
|
||||
@ -253,7 +282,7 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
leading: Icon(Icons.people),
|
||||
title: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.white70,
|
||||
backgroundColor: Colors.white70,
|
||||
),
|
||||
onPressed: () => accountBloc.add(AccountGetTrainees()),
|
||||
child: Text("See my trainees"),
|
||||
@ -303,6 +332,35 @@ class AccountPage extends StatelessWidget with Trans {
|
||||
));
|
||||
}
|
||||
|
||||
void deleteAccountConfirmationDialog(AccountBloc accountBloc) {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (_) => CupertinoAlertDialog(
|
||||
title: Text(t("Are you sure to delete your account?")),
|
||||
content: Column(children: [
|
||||
Divider(),
|
||||
Text(t("Your training data, historical data, goals, 1RMs will be completly lost!")),
|
||||
]),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(t("No")),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
TextButton(
|
||||
child: Text(t("Yes")),
|
||||
onPressed: () => {
|
||||
if (accountBloc.customerRepository.customer != null && accountBloc.customerRepository.customer!.customerId != null) {
|
||||
Track().track(TrackingEvent.delete_account),
|
||||
accountBloc.add(DeleteAccount(customer: accountBloc.customerRepository.customer!)),
|
||||
},
|
||||
Navigator.pop(context),
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
void confirmationDialog(AccountBloc accountBloc) {
|
||||
showCupertinoDialog(
|
||||
useRootNavigator: true,
|
||||
|
@ -13,8 +13,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerFitnessPage extends StatefulWidget {
|
||||
late _CustomerFitnessPageState _state;
|
||||
|
@ -11,8 +11,6 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'package:syncfusion_flutter_gauges/gauges.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerHeightPage extends StatefulWidget {
|
||||
late _CustomerHeightPageState _state;
|
||||
|
@ -11,8 +11,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerSexPage extends StatefulWidget {
|
||||
late _CustomerSexPageState _state;
|
||||
|
@ -11,8 +11,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
|
||||
import '../bloc/customer_change/customer_change_bloc.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomerWeightPage extends StatefulWidget {
|
||||
late _CustomerWeightPageState _state;
|
||||
|
@ -59,10 +59,10 @@ class _CustomerWelcomePageState extends State<CustomerWelcomePage> with Trans {
|
||||
duration: Duration(seconds: 6),
|
||||
),
|
||||
SizedBox(
|
||||
height: 110,
|
||||
height: 40,
|
||||
),
|
||||
CircularPercentIndicator(
|
||||
radius: 250.0,
|
||||
radius: 200.0,
|
||||
animation: true,
|
||||
animationDuration: 4800,
|
||||
lineWidth: 20.0,
|
||||
|
@ -327,8 +327,8 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(0),
|
||||
primary: Colors.white,
|
||||
onSurface: Colors.blueAccent,
|
||||
foregroundColor: Colors.white,
|
||||
disabledForegroundColor: Colors.blueAccent,
|
||||
),
|
||||
onPressed: () {
|
||||
exerciseBloc.add(ExerciseControlSubmit(step: step));
|
||||
|
@ -47,7 +47,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
||||
}
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
BlocProvider.of<DevelopmentByMuscleBloc>(context).add(DevelopmentByMuscleLoad());
|
||||
});
|
||||
}
|
||||
|
@ -66,7 +66,10 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
text: t("My Training Logs"),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
image: "asset/image/edzesnaplom400400.jpg",
|
||||
left: 5,
|
||||
onTap: () => Navigator.of(context).pushNamed('mydevelopmentLog', arguments: args),
|
||||
@ -186,7 +189,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
onTap: () => {Navigator.of(context).pushNamed('mydevelopmentMusclePage', arguments: args)},
|
||||
isLocked: true,
|
||||
))),
|
||||
developmentWidget(imageWidth, t("Development of My Sizes"), "asset/image/sizes_q.jpg", TrackingEvent.my_size_development, args),
|
||||
developmentWidget(
|
||||
imageWidth, t("Development of My Sizes"), "asset/image/sizes_q.jpg", TrackingEvent.my_size_development, args),
|
||||
hiddenWidget(customerRepository, exerciseRepository),
|
||||
]),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@ -207,7 +211,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
textAlignment: Alignment.topLeft,
|
||||
text: t(title),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
image: imageUrl,
|
||||
onTap: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
@ -240,8 +245,8 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
return TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(20),
|
||||
primary: Colors.white,
|
||||
onSurface: Colors.blueAccent,
|
||||
backgroundColor: Colors.white,
|
||||
disabledForegroundColor: Colors.blueAccent,
|
||||
),
|
||||
onPressed: () => {
|
||||
if (Cache().getTrainee() != null)
|
||||
|
@ -43,8 +43,8 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
child: Form(
|
||||
child: BlocConsumer<SettingsBloc, SettingsState>(listener: (context, state) {
|
||||
if (state is SettingsError) {
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is SettingsReady) {
|
||||
menuBloc.add(MenuRecreateTree());
|
||||
Navigator.of(context).pushNamed("home");
|
||||
@ -193,7 +193,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white70,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
Track().track(TrackingEvent.terms_of_use),
|
||||
@ -220,7 +220,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white70,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
Track().track(TrackingEvent.data_privacy),
|
||||
@ -247,7 +247,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white70,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
Navigator.of(context).pushNamed("faqPage"),
|
||||
@ -290,7 +290,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
]),
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.white70,
|
||||
onSurface: Colors.grey,
|
||||
disabledForegroundColor: Colors.grey,
|
||||
),
|
||||
onPressed: () => {
|
||||
launchMailto(),
|
||||
@ -311,6 +311,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
// Use either Dart's string interpolation
|
||||
// or the toString() method.
|
||||
print("Mailto: $mailtoLink");
|
||||
await launch('$mailtoLink');
|
||||
final Uri _url = Uri.parse("$mailtoLink");
|
||||
await launchUrl(_url);
|
||||
}
|
||||
}
|
||||
|
@ -165,8 +165,8 @@ class TestSetControl extends StatelessWidget with Trans {
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
padding: EdgeInsets.all(0),
|
||||
primary: Colors.white,
|
||||
onSurface: Colors.blueAccent,
|
||||
foregroundColor: Colors.white,
|
||||
disabledForegroundColor: Colors.blueAccent,
|
||||
),
|
||||
onPressed: () => {
|
||||
bloc.add(TestSetControlSubmit()),
|
||||
|
@ -316,8 +316,8 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
getPlanDetails(plan, bloc, dayName),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
onPrimary: Colors.white,
|
||||
primary: restricted ? Colors.grey[600] : Colors.orange,
|
||||
foregroundColor: Colors.white,
|
||||
backgroundColor: restricted ? Colors.grey[600] : Colors.orange,
|
||||
),
|
||||
child: Text(t("Start")),
|
||||
onPressed: () {
|
||||
@ -476,7 +476,8 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
return DialogCommon(
|
||||
title: t("Dropset"),
|
||||
descriptions: t("A drop set is an advanced resistance training technique "),
|
||||
description2: t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
|
||||
description2:
|
||||
t(" in which you focus on completing a set until failure - or the inability to do another repetition."),
|
||||
text: "OK",
|
||||
onTap: () => {
|
||||
Navigator.of(context).pop(),
|
||||
@ -490,7 +491,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
headerGridLinesVisibility: GridLinesVisibility.both,
|
||||
gridLinesVisibility: GridLinesVisibility.both,
|
||||
columns: [
|
||||
GridTextColumn(
|
||||
GridColumn(
|
||||
columnWidthMode: ColumnWidthMode.lastColumnFill,
|
||||
maximumWidth: 130,
|
||||
columnName: 'exerciseImage',
|
||||
@ -507,7 +508,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
textAlign: TextAlign.start,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))),
|
||||
GridTextColumn(
|
||||
GridColumn(
|
||||
maximumWidth: 0,
|
||||
visible: false,
|
||||
columnName: 'exerciseName',
|
||||
@ -520,7 +521,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
textAlign: TextAlign.start,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))),
|
||||
GridTextColumn(
|
||||
GridColumn(
|
||||
maximumWidth: 60,
|
||||
columnName: 'Set',
|
||||
label: Container(
|
||||
@ -532,7 +533,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))),
|
||||
GridTextColumn(
|
||||
GridColumn(
|
||||
maximumWidth: 100,
|
||||
columnWidthMode: ColumnWidthMode.fill,
|
||||
columnName: 'Repeats',
|
||||
@ -545,7 +546,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
|
||||
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
))),
|
||||
GridTextColumn(
|
||||
GridColumn(
|
||||
maximumWidth: 60,
|
||||
columnName: 'Weight',
|
||||
label: Container(
|
||||
|
@ -297,7 +297,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
super.initState();
|
||||
@ -306,7 +306,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
@override
|
||||
void didUpdateWidget(ExerciseList page) {
|
||||
super.didUpdateWidget(page);
|
||||
WidgetsBinding.instance!.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
animate();
|
||||
});
|
||||
}
|
||||
@ -333,8 +333,8 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
String description2 = "";
|
||||
if (next.exerciseTypeId != detail.exerciseTypeId) {
|
||||
title = AppLocalizations.of(context)!.translate("Stop!");
|
||||
description =
|
||||
AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") + next.exerciseType!.nameTranslation;
|
||||
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") +
|
||||
next.exerciseType!.nameTranslation;
|
||||
} else {
|
||||
final HashMap args = HashMap();
|
||||
args['exerciseType'] = next.exerciseType;
|
||||
@ -388,7 +388,8 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
|
||||
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
|
||||
if (prev == null || (prev != null && prev!.exerciseTypeId != element.exerciseTypeId)) {
|
||||
tiles.add(GestureDetector(
|
||||
onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
|
||||
onTap: () =>
|
||||
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
|
||||
child: ExerciseTile(
|
||||
bloc: bloc,
|
||||
detail: element,
|
||||
@ -543,7 +544,8 @@ class ExerciseTile extends StatelessWidget with Trans {
|
||||
|
||||
List<Widget> getExerciseTiles(CustomerTrainingPlanDetails detail) {
|
||||
final List<Widget> list = [];
|
||||
if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null && bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
|
||||
if (bloc.alternatives[detail.customerTrainingPlanDetailsId] != null &&
|
||||
bloc.alternatives[detail.customerTrainingPlanDetailsId].length > 0) {
|
||||
int index = 0;
|
||||
for (CustomerTrainingPlanDetails alternative in bloc.alternatives[detail.customerTrainingPlanDetailsId]) {
|
||||
final Widget widget = getTile(alternative, index);
|
||||
@ -563,7 +565,10 @@ class ExerciseTile extends StatelessWidget with Trans {
|
||||
final int step = bloc.getStep(detail);
|
||||
final int highlightStep = bloc.getHighlightStep(detail);
|
||||
final bool hasLeftAlternative = detail.alternatives.length > 0 && index > 0;
|
||||
final bool hasRightAlternative = detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
|
||||
final bool hasRightAlternative =
|
||||
detail.alternatives.length > 0 && index + 1 < bloc.alternatives[detail.customerTrainingPlanDetailsId].length;
|
||||
|
||||
print("getTile Detail: $detail");
|
||||
|
||||
return Container(
|
||||
child: Stack(alignment: Alignment.centerRight, children: [
|
||||
@ -598,7 +603,8 @@ class ExerciseTile extends StatelessWidget with Trans {
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogHTML(
|
||||
title: detail.exerciseType!.nameTranslation, htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
|
||||
title: detail.exerciseType!.nameTranslation,
|
||||
htmlData: '<p>' + detail.exerciseType!.descriptionTranslation + '</p>');
|
||||
}),
|
||||
icon: Icon(
|
||||
Icons.info_outline,
|
||||
|
@ -86,7 +86,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
|
||||
getTrainingPlan(t("Training Plans of Celebrities"), "asset/menu/training_plans_q_celebrities.jpg", "celebrities"),
|
||||
getTrainingPlan(t("Training Plans for Gain Strength"), "asset/menu/training_plans_q_gain_strength.jpg", "gain_strength"),
|
||||
getTrainingPlan(t("Training Plans for Muscle Endurance"), "asset/menu/muscle_strength_q.jpg", "muscle_endurance"),
|
||||
getTrainingPlan(t("Physical Prepare Program for Footgolfers"), "asset/menu/FG_2_edz.jpg", "footgolf"),
|
||||
getTrainingPlan(t("12 Week Fit Boost Programm"), "asset/image/12w_fit_boost_q.jpg", "12w_fit_boost"),
|
||||
]),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
|
@ -38,7 +38,7 @@ class _BottomBarMultipleExercisesState extends State<BottomBarMultipleExercises>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
_controller = ScrollController();
|
||||
});
|
||||
}
|
||||
|
@ -209,12 +209,12 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
});
|
||||
}
|
||||
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
subscription = stream.listen((event) {
|
||||
//_controller1.text = ExerciseSaveStream().weight.toStringAsFixed(0);
|
||||
_controller2.text = ExerciseSaveStream().repeats.toStringAsFixed(0);
|
||||
});
|
||||
print("ExerciseSave weight ${widget.weight}");
|
||||
//print("ExerciseSave weight ${widget.weight}");
|
||||
_controller1.text = widget.weight == null || widget.weight == -1
|
||||
? "TEST"
|
||||
: widget.weight! % widget.weight!.round() == 0
|
||||
@ -229,19 +229,22 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
: widget.repeats!.toStringAsFixed(0);
|
||||
changable = (_controller2.text != "TEST" && _controller1.text != "TEST");
|
||||
if (widget.unitQuantityUnit != null && widget.tip != null && Cache().isActivityDone(widget.tip!) == false) {
|
||||
Timer(
|
||||
/*Timer(
|
||||
Duration(milliseconds: 2000),
|
||||
() => {
|
||||
TutorialWidget().explanation(
|
||||
context,
|
||||
ExplanationWidget(
|
||||
unitQuantityUnit: widget.unitQuantityUnit,
|
||||
unit: widget.unit,
|
||||
tip: widget.tip,
|
||||
weight: widget.weight,
|
||||
repeats: widget.repeats,
|
||||
)),
|
||||
});
|
||||
if (context != null)
|
||||
{
|
||||
TutorialWidget().explanation(
|
||||
context,
|
||||
ExplanationWidget(
|
||||
unitQuantityUnit: widget.unitQuantityUnit,
|
||||
unit: widget.unit,
|
||||
tip: widget.tip,
|
||||
weight: widget.weight,
|
||||
repeats: widget.repeats,
|
||||
)),
|
||||
}
|
||||
});*/
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -387,7 +390,7 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
leading: IconButton(
|
||||
iconSize: 30,
|
||||
onPressed: () => {
|
||||
if (widget.unitQuantityUnit != null)
|
||||
if (widget.unitQuantityUnit != null && context != null)
|
||||
{
|
||||
TutorialWidget().explanation(
|
||||
context,
|
||||
@ -633,7 +636,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
padding: const EdgeInsets.all(2),
|
||||
color: Colors.white70,
|
||||
onPressed: () async {
|
||||
stopWatchTimer.onExecute.add(StopWatchExecute.start);
|
||||
//stopWatchTimer.onExecute.add(StopWatchExecute.start);
|
||||
stopWatchTimer.onStartTimer();
|
||||
Wakelock.enable(); // prevent sleep the phone
|
||||
},
|
||||
icon: Icon(CustomIcon.play_1),
|
||||
@ -647,7 +651,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
iconSize: 40,
|
||||
color: Colors.white70,
|
||||
onPressed: () async {
|
||||
stopWatchTimer.onExecute.add(StopWatchExecute.stop);
|
||||
//stopWatchTimer.onExecute.add(StopWatchExecute.stop);
|
||||
stopWatchTimer.onStartTimer();
|
||||
Wakelock.disable();
|
||||
},
|
||||
icon: Icon(CustomIcon.stop),
|
||||
@ -660,7 +665,8 @@ class _ExerciseSaveState extends State<ExerciseSave> with Trans {
|
||||
iconSize: 40,
|
||||
color: Colors.white70,
|
||||
onPressed: () async {
|
||||
stopWatchTimer.onExecute.add(StopWatchExecute.reset);
|
||||
//stopWatchTimer.onExecute.add(StopWatchExecute.reset);
|
||||
stopWatchTimer.onResetTimer();
|
||||
},
|
||||
icon: Icon(CustomIcon.creative_commons_zero),
|
||||
),
|
||||
|
@ -12,6 +12,7 @@ import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:matomo_tracker/matomo_tracker.dart';
|
||||
import 'package:upgrader/upgrader.dart';
|
||||
import 'loading.dart';
|
||||
|
||||
@ -25,15 +26,21 @@ class AitrainerHome extends StatefulWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
||||
class _HomePageState extends State<AitrainerHome> with Logging, Trans, TraceableClientMixin {
|
||||
GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
String get traceName => 'Home';
|
||||
|
||||
@override
|
||||
String get traceTitle => this.widget.toString();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
runDelayedEvent();
|
||||
});
|
||||
|
||||
@ -65,12 +72,12 @@ class _HomePageState extends State<AitrainerHome> with Logging, Trans {
|
||||
setContext(context);
|
||||
final appcastURL = "https://raw.githubusercontent.com/bossanyit/appcast/main/android_rss.xml";
|
||||
final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
|
||||
print("Packageinfo ${Cache().packageInfo}");
|
||||
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
body: UpgradeAlert(
|
||||
upgrader: Upgrader(appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)),
|
||||
upgrader: Upgrader(
|
||||
countryCode: AppLanguage().appLocal.toString(), appcastConfig: cfg, messages: MyLocalizedUpgraderMessages(context: context)),
|
||||
child: BlocConsumer<SessionBloc, SessionState>(listener: (context, state) {
|
||||
if (state is SessionFailure) {
|
||||
showDialog(
|
||||
|
@ -174,8 +174,8 @@ class _InputDialogState<Event> extends State<InputDialog<Event>> with Trans {
|
||||
children: <Widget>[
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.black26,
|
||||
onSurface: Colors.white,
|
||||
backgroundColor: Colors.black26,
|
||||
disabledBackgroundColor: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
@ -187,8 +187,8 @@ class _InputDialogState<Event> extends State<InputDialog<Event>> with Trans {
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.orange[600],
|
||||
onSurface: Colors.white,
|
||||
backgroundColor: Colors.orange[600],
|
||||
disabledForegroundColor: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
widget.onChanged(this.inputValue);
|
||||
|
@ -5,7 +5,6 @@ import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
import 'package:aitrainer_app/repository/training_plan_repository.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_trial.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_image.dart';
|
||||
import 'package:aitrainer_app/widgets/menu_search_bar.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
@ -55,7 +54,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
}
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
menuBloc.add(MenuCreate());
|
||||
});
|
||||
|
||||
@ -112,7 +111,9 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
|
||||
return Stack(children: [
|
||||
CustomScrollView(
|
||||
controller: scrollController, scrollDirection: Axis.vertical, slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
|
||||
controller: scrollController,
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: buildMenuColumn(widget.parent!, context, menuBloc, cWidth, cHeight)),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -134,7 +135,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
padding: EdgeInsets.only(top: 15.0),
|
||||
child: Center(
|
||||
child: Stack(alignment: Alignment.bottomLeft, children: [
|
||||
Text(AppLocalizations.of(context)!.translate("All Exercises has been filtered out"), style: GoogleFonts.inter(color: Colors.white)),
|
||||
Text(AppLocalizations.of(context)!.translate("All Exercises has been filtered out"),
|
||||
style: GoogleFonts.inter(color: Colors.white)),
|
||||
]))));
|
||||
} else {
|
||||
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
|
||||
@ -395,8 +397,10 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
dynamic getShape(WorkoutMenuTree workoutTree) {
|
||||
bool base = workoutTree.base;
|
||||
dynamic returnCode = (base == true)
|
||||
? RoundedRectangleBorder(side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0)))
|
||||
: RoundedRectangleBorder(side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
|
||||
? RoundedRectangleBorder(
|
||||
side: BorderSide(width: 6, color: Colors.orangeAccent), borderRadius: BorderRadius.all(Radius.circular(24.0)))
|
||||
: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: Colors.transparent), borderRadius: BorderRadius.all(Radius.circular(8.0)));
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ class TutorialWidget with Trans, Logging {
|
||||
children: [
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.transparent,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () => {bloc.add(TutorialNext(text: bloc.checks[0]))},
|
||||
child: Text("« " + t(bloc.checks[0]),
|
||||
@ -186,7 +186,7 @@ class TutorialWidget with Trans, Logging {
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.transparent,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () => {bloc.add(TutorialNext(text: bloc.checks[1]))},
|
||||
child: Text(t(bloc.checks[1]) + " »",
|
||||
@ -196,7 +196,7 @@ class TutorialWidget with Trans, Logging {
|
||||
)
|
||||
: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.transparent,
|
||||
backgroundColor: Colors.transparent,
|
||||
),
|
||||
onPressed: () => {
|
||||
//tooltip!.rebuild(context),
|
||||
|
@ -16,7 +16,7 @@ class _VictoryConfettiState extends State<VictoryConfetti> {
|
||||
@override
|
||||
void initState() {
|
||||
_controllerBottomCenter = ConfettiController(duration: const Duration(seconds: 2));
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) {
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
Future.delayed(Duration(milliseconds: 500)).then((value) => _controllerBottomCenter.play());
|
||||
});
|
||||
super.initState();
|
||||
|
60
pubspec.lock
@ -176,6 +176,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -574,12 +581,12 @@ packages:
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct dev"
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.2"
|
||||
version: "0.10.0"
|
||||
flutter_layout_grid:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -811,7 +818,7 @@ packages:
|
||||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
version: "4.7.0"
|
||||
keyboard_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -867,7 +874,7 @@ packages:
|
||||
name: matomo_tracker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
version: "1.6.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1092,6 +1099,15 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
posthog_session:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "0db36d398cc23a7bfab09e0ddb6773525a92107b"
|
||||
url: "https://bossanyit@git.workouttest.org/bossanyit/posthog_session.git"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1321,20 +1337,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
sqflite:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0+1"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1426,13 +1428,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "20.3.50"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0+2"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1517,27 +1512,20 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
universal_platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: universal_platform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0+1"
|
||||
upgrader:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: upgrader
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.8.1"
|
||||
version: "4.11.1"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.6"
|
||||
version: "6.1.5"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1784,5 +1772,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.18.0-0 <3.0.0"
|
||||
flutter: ">=3.3.0-0"
|
||||
dart: ">=2.18.4 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
27
pubspec.yaml
@ -15,10 +15,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.26+107
|
||||
version: 1.1.28+117
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.9.0"
|
||||
sdk: ">=2.18.4 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
@ -54,6 +54,7 @@ dependencies:
|
||||
flutter_fancy_tree_view: ^0.5.1+1
|
||||
flutter_facebook_auth: ^4.4.1+1
|
||||
flutter_fadein: ^2.0.0
|
||||
flutter_launcher_icons: ^0.10.0
|
||||
flutter_lints: ^2.0.1
|
||||
flutter_radar_chart: ^0.2.1
|
||||
flutter_secure_storage: ^5.0.2
|
||||
@ -67,19 +68,20 @@ dependencies:
|
||||
keyboard_actions: ^3.4.0
|
||||
|
||||
mailto: ^2.0.0
|
||||
matomo_tracker: ^1.5.0
|
||||
matomo_tracker: ^1.6.0
|
||||
mockito: ^5.3.2
|
||||
modal_progress_hud_nsn: ^0.3.0
|
||||
|
||||
package_info: ^2.0.2
|
||||
percent_indicator: ^4.0.0
|
||||
#posthog_flutter: ^2.0.3
|
||||
purchases_flutter: ^3.9.5
|
||||
|
||||
rainbow_color: ^2.0.1
|
||||
|
||||
sentry_flutter: ^6.13.0
|
||||
sentry_flutter: ^6.9.1
|
||||
sign_in_with_apple: ^4.1.0
|
||||
sqflite: ^2.1.0+1
|
||||
#sqflite: ^2.1.0+1
|
||||
stop_watch_timer: ^2.0.0
|
||||
|
||||
syncfusion_flutter_gauges: ^20.3.50
|
||||
@ -91,13 +93,14 @@ dependencies:
|
||||
timeline_tile: ^2.0.0
|
||||
toggle_switch: ^2.0.1
|
||||
|
||||
upgrader: ^4.8.1
|
||||
upgrader: ^4.11.1
|
||||
url_launcher: ^6.0.9
|
||||
|
||||
wakelock: ^0.6.2
|
||||
web_browser: ^0.5.0
|
||||
|
||||
|
||||
posthog_session:
|
||||
git: https://bossanyit@git.workouttest.org/bossanyit/posthog_session.git
|
||||
#fl_chart: ^0.50.0
|
||||
#location: ^3.2.4
|
||||
#flurry_data: ^0.0.1
|
||||
@ -122,11 +125,10 @@ dev_dependencies:
|
||||
intl: ^0.17.0
|
||||
shared_preferences: ^2.0.5
|
||||
|
||||
flutter_launcher_icons: ^0.9.0
|
||||
|
||||
flutter_icons:
|
||||
android: "launcher_icon"
|
||||
image_path: "asset/icon/icon.png"
|
||||
ios: true
|
||||
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
@ -177,14 +179,19 @@ flutter:
|
||||
- asset/image/WT_cup_victory400.png
|
||||
- asset/image/WT_zold.jpg
|
||||
|
||||
- asset/image/12w_fit_boost_q.jpg
|
||||
- asset/image/12w_fit_boost.jpg
|
||||
- asset/image/alternatives_arrow.png
|
||||
- asset/image/add_test.png
|
||||
- asset/image/button_fb.png
|
||||
- asset/image/button_apple.png
|
||||
- asset/image/button_google.png
|
||||
- asset/image/cardio_distance.jpg
|
||||
- asset/image/cardio_time.jpg
|
||||
- asset/image/Congrats_N1.jpg
|
||||
- asset/image/continue.png
|
||||
- asset/image/drop_set.png
|
||||
- asset/image/lock.png
|
||||
- asset/image/add_test.png
|
||||
- asset/image/testemfejl400x400.jpg
|
||||
- asset/image/izomcsop400400.jpg
|
||||
- asset/image/edzesnaplom400400.jpg
|
||||
|
@ -1,10 +1,10 @@
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
/*import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan.dart';
|
||||
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
|
||||
import 'package:aitrainer_app/model/model_change.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'mocks.dart';
|
||||
|
||||
import 'mocks.dart';*/
|
||||
/*
|
||||
main() {
|
||||
late SimExercisePlanRepository _exercisePlanRepository;
|
||||
late int _customerId;
|
||||
@ -141,3 +141,5 @@ main() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
66
test/onerepmax.dart
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() {
|
||||
late CommonHoldingClass commonClass;
|
||||
setUp(() {
|
||||
commonClass = CommonHoldingClass();
|
||||
});
|
||||
|
||||
group('OneRepMax', () {
|
||||
test('test OneRepMax', () async {
|
||||
double weight = 60.0;
|
||||
double repeats = 10;
|
||||
double oneRepMax = commonClass.calculate1RM(weight, repeats);
|
||||
//print("1RM: $oneRepMax");
|
||||
print("1RM 100%: 1");
|
||||
int repeat95 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.95);
|
||||
print("1RM 95%: $repeat95");
|
||||
int repeat90 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.9);
|
||||
print("1RM 90%: $repeat90");
|
||||
int repeat85 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.85);
|
||||
print("1RM 85%: $repeat85");
|
||||
int repeat83 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.82);
|
||||
print("1RM 82%: $repeat83");
|
||||
int repeat80 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.8);
|
||||
print("1RM 80%: $repeat80");
|
||||
int repeat77 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.775);
|
||||
print("1RM 77,5%: $repeat77");
|
||||
int repeat75 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.75);
|
||||
print("1RM 75%: $repeat75");
|
||||
int repeat74 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.74);
|
||||
print("1RM 74%: $repeat74");
|
||||
int repeat71 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.71);
|
||||
print("1RM 71%: $repeat71");
|
||||
int repeat70 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.7);
|
||||
print("1RM 70%: $repeat70");
|
||||
int repeat68 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.685);
|
||||
print("1RM 68,5%: $repeat68");
|
||||
int repeat65 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.65);
|
||||
print("1RM 65%: $repeat65");
|
||||
int repeat62 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.628);
|
||||
print("1RM 62,8%: $repeat62");
|
||||
int repeat60 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.6);
|
||||
print("1RM 60%: $repeat60");
|
||||
int repeat59 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.59);
|
||||
print("1RM 59%: $repeat59");
|
||||
int repeat53 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.535);
|
||||
print("1RM 53,5%: $repeat53");
|
||||
int repeat50 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.5);
|
||||
print("1RM 50%: $repeat50");
|
||||
int repeat49 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.495);
|
||||
print("1RM 49,5%: $repeat49");
|
||||
int repeat46 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.46);
|
||||
print("1RM 45%: $repeat46");
|
||||
int repeat40 = commonClass.calculateRepeatBy1RMPercent(oneRepMax, oneRepMax, 0.405);
|
||||
print("1RM 40,5%: $repeat40");
|
||||
|
||||
expect(repeat90, 4);
|
||||
expect(repeat50, 34);
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
@ -17,10 +17,11 @@ import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_localizations/flutter_localizations.dart'; */
|
||||
import 'package:aitrainer_app/helper/database.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
//import 'package:aitrainer_app/helper/database.dart';
|
||||
//import 'package:flutter_test/flutter_test.dart';
|
||||
//import 'package:mockito/mockito.dart';
|
||||
|
||||
/*
|
||||
void main() {
|
||||
group('SQFLite', () {
|
||||
setUp(() async {
|
||||
@ -39,3 +40,4 @@ void main() {
|
||||
});
|
||||
});
|
||||
}
|
||||
*/
|
@ -6,7 +6,7 @@
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
//import 'package:aitrainer_app/bloc/login_form_bloc.dart';
|
||||
import 'package:aitrainer_app/helper/database.dart';
|
||||
//import 'package:aitrainer_app/helper/database.dart';
|
||||
import 'package:aitrainer_app/library_keys.dart';
|
||||
import 'package:aitrainer_app/util/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/user.dart';
|
||||
@ -52,7 +52,7 @@ void main() {
|
||||
late MockCommon common;
|
||||
|
||||
setUp(() async {
|
||||
await DB().initDb();
|
||||
//await DB().initDb();
|
||||
common = MockCommon();
|
||||
|
||||
loginWidget = MaterialApp(home: LoginPage(), localizationsDelegates: [
|
||||
|
@ -1,9 +1,10 @@
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import '../../lib/helper/database.dart';
|
||||
|
||||
//import 'package:aitrainer_app/model/customer.dart';
|
||||
//import '../../lib/helper/database.dart';
|
||||
/*
|
||||
class CustomerApi {
|
||||
Future<void> addCustomer(Customer customer) async {
|
||||
//print(" ===== add new customer: " + customer.toSQL().toString();
|
||||
await DB().getDB().insert("customer", customer.toJson());
|
||||
}
|
||||
}
|
||||
*/
|