WT 1.1.5+2 remote images for menu

This commit is contained in:
bossanyit 2021-01-31 12:59:52 +01:00
parent 71efd3f349
commit c1a57dd10e
88 changed files with 743 additions and 316 deletions

View File

@ -2,5 +2,5 @@
The WorkoutTest Mobile Application
live 1.1.3
live 1.1.5

View File

@ -45,7 +45,7 @@ android {
defaultConfig {
applicationId "com.aitrainer.aitrainer_app"
minSdkVersion 16
minSdkVersion 18
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName

View File

@ -14,6 +14,30 @@
}
},
"oauth_client": [
{
"client_id": "926782702216-237m2fsnnl6e9kufvommqlig6kh0306v.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.aitrainer.aitrainer_app",
"certificate_hash": "48a14ac298aea01f57a4b1fa85b62b4214529697"
}
},
{
"client_id": "926782702216-2f57akehq02uup6sbnuobbu4pth2a5do.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.aitrainer.aitrainer_app",
"certificate_hash": "35571ad544a6ac0d062eed92a6d2d40f0cb63116"
}
},
{
"client_id": "926782702216-4hfe454mnu2bv28m8cqbguvjg3mom3fd.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.aitrainer.aitrainer_app",
"certificate_hash": "0bed1641af363cf58750d95595f4521e596827f2"
}
},
{
"client_id": "926782702216-al3vjap51m6pgpa066d1oni0bdjpu7pr.apps.googleusercontent.com",
"client_type": 3
@ -30,6 +54,14 @@
{
"client_id": "926782702216-al3vjap51m6pgpa066d1oni0bdjpu7pr.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "926782702216-2nsi7d9at3pc5ts8gkobt5697v590kb9.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.aitrainer.app",
"app_store_id": "1515271425"
}
}
]
}

View File

@ -16,7 +16,9 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:allowBackup="false"
android:fullBackupContent="false">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 KiB

BIN
asset/menu/1.1.aerob.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

BIN
asset/menu/1.2.anaerob.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

BIN
asset/menu/1.cardio.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

BIN
asset/menu/2.1.1.1RM.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

BIN
asset/menu/2.1.6.core.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

BIN
asset/menu/2.2.1.7.back.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
asset/menu/2.2.1.8.calf.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

BIN
asset/menu/2.strength.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 988 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

BIN
asset/menu/3.bcs1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

View File

@ -102,7 +102,7 @@
"OR": "OR",
"Password (Leave empty if no change)":"Password (Leave empty if no change)",
"First Name": "First Name",
"Birth Year": "Birty Year",
"Birth Year": "Birth Year",
"Weight": "Weight",
"Gender": "Gender",
"Man": "Man",
@ -114,7 +114,7 @@
"Gain Muscle": "Gain Muscle",
"Loose Weight": "Loose Weight",
"Your Fitness State": "Your Fitness State",
"Fitness level": "Fizikai állapot",
"Fitness level": "Fitness level",
"Fitness Activity":"Fitness Activity",
"Beginner": "Beginner",
"I am beginner": "I am beginner",
@ -244,6 +244,7 @@
"Exception: Facebook login was not successful":"Facebook login was not successful",
"Exception: Facebook login cancelled":"Facebook login cancelled",
"Exception: Facebook login failed":"Facebook login failed",
"Exception: The account exists with different credential": "The account exists with different credential",
"More »": "More »",
@ -258,6 +259,7 @@
"goal":"goal",
"Basal Metabolic Rate":"Basal Metabolic Rate",
"Resting Metabolic Rate":"Resting Metabolic Rate",
"Resting metabolic rate is the rate at which your body burns energy when it is at complete rest.":"Resting metabolic rate is the rate at which your body burns energy when it is at complete rest.",
"Based on your weight, height and activity your BMR value":"Based on your bodyweight, height and activity this is your daily calory demand.",
"Your Sizes":"Your Sizes",
"Size Of Your":"Size Of Your",
@ -297,10 +299,11 @@
"The": "The",
"the first":"the first",
"the second":"the second",
"the third":"the third",
"Go Premium":"Go Premium",
"Unleash your potential with WorkoutTest Premium!":"Unleash your potential with WorkoutTest Premium!",
"feature is reachable after you finished":"feature is reachable after you finished",
"100% test circles":"100% test circles",
"100% test circles":"100% test rounds",
"Keep testing":"Keep Testing",
"Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.":"Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.",
@ -312,5 +315,22 @@
"Exception: Purchase was not successful":"Purchase was not successful",
"Exception: Purchase was cancelled":"Purchase was cancelled",
"Successful Purchase": "Successful Purchase",
"Now you can use the premium features of WorkoutTest!":"Now you can use the premium features of WorkoutTest!"
"Now you can use the premium features of WorkoutTest!":"Now you can use the premium features of WorkoutTest!",
"Progressindicator for the tests":"Where do you stand achieving your tests?",
"Progressindicator_desc":"<p>It shows which muscle group test did your achieved already.</p><h2>When do you reach the 100% test round?</h2><br/><p>If you have sucessfully tested one of the <strong>base</strong> exercises of each muscle group</p>",
"Unleash Your Development Now!":"Unleash Your Development Now!",
"Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.":"Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.",
"Subscription Conditions":"Subscription Conditions",
"Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hours before the end of the current period":"Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hours before the end of the current period",
"Account will be charged for renewal within 24 hours prior to the end of the current period":"Account will be charged for renewal within 24 hours prior to the end of the current period",
"Montly":"Montly",
"Annual":"Annual",
"Predictions with Artificial Intelligence":"Predictions with Artificial Intelligence",
"14% discount":"14% discount",
"2 months free":"2 months free",
"Development programs":"Development programs",
"Suggestions based on your actual status":"Suggestions based on your actual status",
"Special customized training plans":"Special customized training plans"
}

View File

@ -43,6 +43,7 @@
"Exception: Apple Sign-In failed":"Apple bejelentkezés sikertelen",
"Exception: Apple Sign-In cancelled":"Apple bejelentkezés megszakítva",
"Exception: Apple Sign In failure: email address is necessary": "Apple bejelentkezés sikertelen: email cím szükséges.",
"Exception: The account exists with different credential": "A felhasználói fiók már létezik más névvel",
"Please select an exercise": "Válassz ki egy gyakorlatot",
"There is an error: during registration:": "Hiba lépett fel a regisztráció során:",
@ -91,7 +92,7 @@
"Yes": "Igen",
"No": "Nem",
"with": "",
"Do you save this exercise with these parameters?":"Elmented a gyakorlatot ezekkel az adatokkal?",
"Do you save this exercise with these parameters?":"Elmented a gyakorlatot?",
"repeat": "ismétlés",
@ -143,7 +144,7 @@
"Make your first test": "Végezd el az első tesztet",
"finished": "végrehajtva",
"Why do you need Exercise Control?": "Miért szükséges a tesztgyakorlat?",
"Your 1RM:":"Maxerőd:",
"Your 1RM:":"Maxerőd (1RM):",
"Your Real 1RM:":"Ellenőrzött maxerő:",
"Check":"Ellenőrzés",
@ -169,7 +170,7 @@
"8. Calf": "8. Vádli",
"Execute My Selected Training Plan": "Edzésterv végrehajtása",
"Edit My Custom Plan": "Egyéni edzésterv létrehozása",
"Edit My Custom Plan": "Edzésterv létrehozása",
"Suggested Training Plan": "Javasolt edzésterv",
"My Special Plan": "Speciális edzésterv",
"Training Programs":"Edzés programok",
@ -183,7 +184,7 @@
"My Trainee's Exercise Logs": "Kliensem edzésnaplőja",
"My Development By Muscle": "Izomcsoportok fejlődése",
"Here you see you development in the last period." : "Itt az izomcsoportok fejlődését látod az elmúlt időszakban. A pontos képhez három diagram közül választhatsz: 'Gyakorlat össztömeg', 'Maxerő' és 'Százalékos fejlődés', illetv választhatsz 4 különböző időszaki bontásból is: 'Részletes', 'Heti', 'Havi', 'Éves",
"Here you see you development in the last period." : "A bevitt adatok alapján itt láthatod az izmaid fejlődését. Láthatod az össz megmozgatott súly, maxerő és a százalékos fejlődési diagramokat különböző időszaki bontásban.",
"Sum Of Mass":"Össztömeg",
"Percent": "Százalék",
@ -201,22 +202,22 @@
"Execute your active Exercise Plan!": "Hajtsd végre az aktív edzéstervedet",
"Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.": "Válaszd ki az izomcsoporton belül a gyakorlatot, és a következő oldalon add meg a súlyt és az ismétlés számot.",
"Custom Exercise Plan": "Egyedi edzésterv",
"Select manually the exercises what you would like to have in your plan. At the end don't forget to save.": "Válaszd ki a gyakorlatokat, amelyeket szeretnél végrehajtani a tervedben. Utána ne felejtsd el elmenteni.",
"Select manually the exercises what you would like to have in your plan. At the end don't forget to save.": "Állítsd össze a kívánt edzésedet! Add meg a gyakorlatot, a kívánt sorozat, ismétlés és a súly mennyiségét. Ha nem vagy biztos bennük, tesztelj! Sorozatok után vidd be a valós adatokat! Jó edzést!",
"In this list you will find all your executed exercises grouped by the date.": "Ebben a listában találod az eddig végrehajtott gyakorlataid dátum szerint csoportosítva.",
"Persistence!": "Kitartás!",
"Greetings!": "Üdvözöllek!",
"The purpose is to measure you physical condition": "A cél a jelenlegi fizikai kondíciód felmérése. Az első célod az összes izomcsoport tesztelése egy 'base' gyakorlattal.",
"The purpose is to measure you physical condition": "A cél a jelenlegi fizikai állapotod felmérése. Az első feladatod az összes izomcsoport tesztelése egy 'alap' gyakorlattal.",
"The suggested order of the exercises: chest - biceps - triceps - back - shoulders - core - tigh - calf.": "A gyakorlatok javasolt végrehajtási sorrendje: mell - bicepsz - tricepsz - hát - váll - has - comb - vádli.",
"Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.": "Menj a menüben az Erő - Max Erő - Mell menüpontba, és válaszd ki a kedvenc gyakorlatod.",
"Please continue your tests with a": "Kérlek folytasd a gyakorlatokat egy",
"Please continue your tests with a": "Kérlek folytasd tesztelést egy",
"I suggest begin your tests with a": "Azt javaslom, kezdd a teszteket egy 'mell' gyakorlattal",
"Nice! This is a good start": "Nagyon jó! Ez egy kitűnő start a teszthez",
"Go on!":"Gyerünk tovább!",
"You are on track": "Jó úton haladsz",
"Not so much left": "Már nincs sok hátra",
"Almost!": "Majdnem a végén vagy!",
"You have only 1-2 exercise left to finish!": "Már csak 1-2 gyakorlat van a végéig!",
"You have only 1-2 exercise left to finish!": "Már csak 1-2 gyakorlat van a hátra!",
"exercise!": "gyakorlattal!",
"Chest": "mell",
"Back": "hát",
@ -247,13 +248,14 @@
"Actual Height":"Magasság",
"Actual Weight":"Testtömeg",
"Bodyweight":"Testtömeg",
"Based on your weight and height your goal for BMI and weight:":"A jelenlegi testtömeged és magasságod alapján kiszámoltuk, hogy mennyi legyen a célod a BMI (testtömegindex) és tömeg elérésben:",
"Based on your weight and height your goal for BMI and weight:":"A jelenlegi adataid alapján kiszámoltuk Neked, hogy az ideális cél elérése érdekében az első lépést kell mihamarabb teljesítened. El tudod érni! Sok sikert!",
"Body Mass Index":"Testtömegindex",
"first step":"első lépés",
"goal":"cél",
"Basal Metabolic Rate":"Alapanyagcsere érték",
"Resting Metabolic Rate":"Minimum energiaszükséglet",
"Based on your weight, height and activity your BMR value":"A testtömeged, magasságod és aktivitásod alapján megközelítőleg ennyi a napi kalóriaszükségleted.",
"Basal Metabolic Rate":"Minimum energiaszükséglet",
"Resting metabolic rate is the rate at which your body burns energy when it is at complete rest.":"",
"Resting Metabolic Rate":"Alapanyagcsere",
"Based on your weight, height and activity your BMR value":"A megadott adataid és aktivitásod alapján megközelítőleg ennyi a napi kalóriaszükségleted.",
"Your Sizes":"Méreteid",
"Size Of Your":"Testméret:",
"Please type the following data:":"Kérlek írd be a következő adatot:",
@ -263,8 +265,8 @@
"Available Equipments":"Elérhető eszközök",
"select your places by tapping":"kattints az edzéshelyszínre",
"Available Training Places":"Elérhető edzéshelyszínek",
"Please take a relative bigger weight and repeat 12-20 times":"Vegyél egy relatív nagyobb súlyt és végezz el 12-20 ismétlést",
"Please take a medium weight and repeat 20-30 times": "Vegyél egy közepes súlyt és végezz el 20-30 ismétlést",
"Please take a relative bigger weight and repeat 12-20 times":"Válassz egy relatív nagyobb súlyt, amivel maximum 12-20 közötti ismétlésre vagy képes",
"Please take a medium weight and repeat 20-30 times": "Válassz egy közepes súlyt, amivel maximum 20-30 közötti ismétlésre vagy képes",
"Equipment Filter":"Eszköz szűrő",
"Live-Server":"Live-Server",
"Test-Server":"Test-Server",
@ -293,6 +295,7 @@
"The": "A",
"the first":"az első",
"the second":"a második",
"the third":"a harmadik",
"Go Premium":"Válts Prémiumra",
"Unleash your potential with WorkoutTest Premium!":"Bontakoztasd ki az erősségeidet WorkoutTest Prémiummal!",
"feature is reachable after you finished":"funkció elérhető számodra, miután teljesítetted",
@ -308,6 +311,22 @@
"Exception: Purchase was not successful":"A vásárlás sikertelen volt",
"Exception: Purchase was cancelled":"A vásárlás megszakadt",
"Successful Purchase": "Sikeres vásárlás!",
"Now you can use the premium features of WorkoutTest!":"Most már eléred a WorkoutTest prémium tartalmait."
"Now you can use the premium features of WorkoutTest!":"Most már eléred a WorkoutTest prémium tartalmait.",
"Progressindicator for the tests":"Hol tartasz a tesztek végrehajtásában?",
"Progressindicator_desc":"<p>Az előrehaladás jelző megmutatja, hogy hány százalékon állsz a tesztek végrehajtásában.</p><h2>Mikor éred el a 100%-os tesztkört?</h2><br/><p>Ha <strong>minden</strong> izomcsoportnál legalább egy <strong>alapgyakorlatot</strong> teljesítesz.<p>Az alapgyakorlatokat a menüponton narancssárgya <strong>alap</strong> pecséttel jelöltük</p>",
"Unleash Your Development Now!":"Indítsd el a fejlődésed most!",
"Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.":"Kövesd nyomon a fejlődésed, élvezd a mesterséges intelligenciával támogatott javaslatokat és előrejelzéseket.",
"Subscription Conditions":"Előfizetési feltételek",
"Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hours before the end of the current period":"A számládat megterheljük az adott összeggel. Az előfizetés automatikusan meghosszabodik, hacsak nem kapcsolod ki az automatikus megújítást legkésőbb 24 órával a meghosszabbítás előtt.",
"Account will be charged for renewal within 24 hours prior to the end of the current period":"Az előfizetési periódus végén a számládat megterheljuk 24 órával a lejárat előtt.",
"Montly":"Havi",
"Annual":"Éves",
"Predictions with Artificial Intelligence":"Mesterséges Intelligencia előrejelzések",
"14% discount":"14% kedvezmény",
"2 months free":"2 hónap ingyen",
"Development programs":"Fejlesztési programok",
"Suggestions based on your actual status":"Intelligens javaslatok az állapotod alapján",
"Special customized training plans":"Speciális testreszabott edzéstervek"
}

View File

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

View File

@ -8,16 +8,16 @@ PODS:
- Flutter
- devicelocale (0.0.1):
- Flutter
- FBSDKCoreKit (8.2.0):
- FBSDKCoreKit/Basics (= 8.2.0)
- FBSDKCoreKit/Core (= 8.2.0)
- FBSDKCoreKit/Basics (8.2.0)
- FBSDKCoreKit/Core (8.2.0):
- FBSDKCoreKit (9.0.0):
- FBSDKCoreKit/Basics (= 9.0.0)
- FBSDKCoreKit/Core (= 9.0.0)
- FBSDKCoreKit/Basics (9.0.0)
- FBSDKCoreKit/Core (9.0.0):
- FBSDKCoreKit/Basics
- FBSDKLoginKit (8.2.0):
- FBSDKLoginKit/Login (= 8.2.0)
- FBSDKLoginKit/Login (8.2.0):
- FBSDKCoreKit (~> 8.2.0)
- FBSDKLoginKit (9.0.0):
- FBSDKLoginKit/Login (= 9.0.0)
- FBSDKLoginKit/Login (9.0.0):
- FBSDKCoreKit (~> 9.0.0)
- Firebase/Analytics (6.33.0):
- Firebase/Core
- Firebase/Auth (6.33.0):
@ -93,14 +93,16 @@ PODS:
- flurry (0.0.4):
- Flurry-iOS-SDK/FlurrySDK
- Flutter
- Flurry-iOS-SDK/FlurrySDK (11.1.1)
- Flurry-iOS-SDK/FlurrySDK (11.2.0)
- Flutter (1.0.0)
- flutter_facebook_auth (1.0.0):
- FBSDKCoreKit (~> 8.2.0)
- FBSDKLoginKit (~> 8.2.0)
- FBSDKCoreKit (~> 9.0.0)
- FBSDKLoginKit (~> 9.0.0)
- Flutter
- flutter_keyboard_visibility (0.0.1):
- Flutter
- flutter_secure_storage (3.3.1):
- Flutter
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
@ -153,11 +155,11 @@ PODS:
- nanopb/encode (1.30906.0)
- path_provider (0.0.1):
- Flutter
- PromisesObjC (1.2.11)
- Protobuf (3.13.0)
- PromisesObjC (1.2.12)
- Protobuf (3.14.0)
- Purchases (3.9.2):
- PurchasesCoreSwift (= 3.9.2)
- purchases_flutter (2.0.0):
- purchases_flutter (2.0.2):
- Flutter
- PurchasesHybridCommon (= 1.5.0)
- PurchasesCoreSwift (3.9.2)
@ -186,6 +188,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`)
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
@ -244,6 +247,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
flutter_keyboard_visibility:
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
google_sign_in:
:path: ".symlinks/plugins/google_sign_in/ios"
path_provider:
@ -265,8 +270,8 @@ SPEC CHECKSUMS:
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
FBSDKCoreKit: 4afd6ff53d8133a433dbcda44451c9498f8c6ce4
FBSDKLoginKit: 7181765f2524d7ebf82d9629066c8e6caafc99d0
FBSDKCoreKit: ac6cc500b8e104bb9a4dd20b1527b5d199123c2e
FBSDKLoginKit: e9b6542fdee322333502ab497f628b011dce7d78
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_analytics: 36a619088c46224900829f14f4daa71585693a6f
firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a
@ -280,10 +285,11 @@ SPEC CHECKSUMS:
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad
Flurry-iOS-SDK: 8f3f7fce27177002f15f145eede88dc1b9ac0cd0
Flurry-iOS-SDK: 6636d30c30f12010e7c7c71d84b443416a168efc
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
flutter_facebook_auth: bad08a3d465e7b7ba9d8468a9dc7df3f69c136b8
flutter_facebook_auth: d952ca599c6a76439c54472b0b225004e1b880c4
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
@ -294,10 +300,10 @@ SPEC CHECKSUMS:
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
Protobuf: 0cde852566359049847168e51bd1c690e0f70056
Purchases: d8a798c9c7552fe66b550bf314a143e94ffa70c8
purchases_flutter: 27f87080055c0fd2cd124c247b10cae75b46e7e1
purchases_flutter: f97230b7edf32be4155b3dcce8e790a77df3fab1
PurchasesCoreSwift: ea4eabae180416e580ac60366f41aa1fefec0693
PurchasesHybridCommon: d9bfb34309db4c9ba82a6f7f3a6275c13befdca7
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
@ -306,6 +312,6 @@ SPEC CHECKSUMS:
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
PODFILE CHECKSUM: 28226b39c1afd238c6168e31e2bd3829c3d67530
PODFILE CHECKSUM: ac11fc852a681d8d7d22e344055d0c36b734cfc2
COCOAPODS: 1.10.0

View File

@ -388,7 +388,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -410,7 +410,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
@ -531,7 +531,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -554,7 +554,7 @@
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@ -566,7 +566,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = SFJJBDCU6Z;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
@ -588,7 +588,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;

View File

@ -4,6 +4,8 @@ import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:bloc/bloc.dart';
@ -22,7 +24,12 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
final bool isRegistration;
bool dataPolicyAllowed = false;
bool obscure = true;
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial());
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial()) {
if (isRegistration) {
ExerciseTreeApi().getExerciseTree();
ExerciseTypeApi().getExerciseTypes();
}
}
@override
Stream<LoginState> mapEventToState(
@ -119,7 +126,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
this.dataPolicyAllowed = !dataPolicyAllowed;
yield LoginReady();
} else if (event is LoginPasswordChangeObscure) {
yield LoginLoading();
this.obscure = !this.obscure;
yield LoginReady();
}
} on Exception catch (e) {
yield LoginError(message: e.toString());

View File

@ -13,6 +13,7 @@ import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:meta/meta.dart';
import 'package:aitrainer_app/library/image_cache.dart' as wt;
part 'menu_event.dart';
part 'menu_state.dart';
@ -21,9 +22,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
final WorkoutTreeRepository menuTreeRepository;
final ExerciseRepository exerciseRepository = ExerciseRepository();
ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository();
int parent;
int parent = 0;
WorkoutMenuTree workoutItem;
List<int> listFilterDevice = List();
final List<int> listFilterDevice = List();
String infoTitle = "";
String infoText = "";
@ -95,25 +96,27 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
if (event is MenuCreate) {
yield MenuLoading();
//await menuTreeRepository.createTree();
//menuTreeRepository.getBranch(this.parent);
setMenuInfo();
exerciseDeviceRepository.setDevices(Cache().getDevices());
/* exerciseDeviceRepository.getGymDevices().forEach((element) {
listFilterDevice.add(element.exerciseDeviceId);
}); */
yield MenuReady();
} else if (event is MenuRecreateTree) {
yield MenuLoading();
// ie. at language changes
await menuTreeRepository.createTree();
yield MenuReady();
} else if (event is MenuTreeDown) {
// get child menus or exercises
yield MenuLoading();
parent = event.parent;
workoutItem = event.item;
if (workoutItem != null) {
setAbility(workoutItem.nameEnglish);
}
menuTreeRepository.getBranch(event.parent);
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(event.parent);
await getImages(branch);
//await Future.delayed(Duration(seconds: 2));
yield MenuReady();
} else if (event is MenuTreeUp) {
yield MenuLoading();
@ -121,10 +124,13 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
parent = event.parent;
workoutItem = menuTreeRepository.getParentItem(parent);
LinkedHashMap<String, WorkoutMenuTree> branch;
if (workoutItem != null) {
menuTreeRepository.getBranch(workoutItem.parent);
setAbility(workoutItem.nameEnglish);
branch = menuTreeRepository.getBranch(workoutItem.parent);
await getImages(branch);
}
yield MenuReady();
} else if (event is MenuTreeJump) {
yield MenuLoading();
@ -132,9 +138,12 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
workoutItem = menuTreeRepository.getParentItem(parent);
if (workoutItem != null) {
menuTreeRepository.getBranch(workoutItem.parent);
setAbility(workoutItem.nameEnglish);
}
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem.parent);
if (branch != null) {
await getImages(branch);
}
yield MenuReady();
} else if (event is MenuClickExercise) {
yield MenuLoading();
@ -171,6 +180,29 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
log("Ability: " + ability.toString() + " name:" + name);
}
Future<void> getImages(LinkedHashMap<String, WorkoutMenuTree> branch) async {
wt.ImageCache().clearImageList();
await putBranchImageToHash(branch);
log("downloaded image size in KB: " + wt.ImageCache().downloadSize.toString());
}
Future<void> putBranchImageToHash(LinkedHashMap<String, WorkoutMenuTree> branch) async {
await Future.forEach(branch.keys, (key) async {
final WorkoutMenuTree value = branch[key];
if (!value.imageName.contains("asset")) {
await wt.ImageCache().putImageToList(value.id, value.imageName);
}
});
}
String getImage(int id, String name) {
String imageString;
if (name.contains("http")) {
imageString = wt.ImageCache().getImageString(id, name);
}
return imageString;
}
bool selectedDevice(int deviceId) {
return !listFilterDevice.contains(deviceId);
}

View File

@ -2,6 +2,8 @@ import 'dart:async';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/localization/app_language.dart';
import 'package:aitrainer_app/service/exercise_tree_service.dart';
import 'package:aitrainer_app/service/exercisetype_service.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/session.dart';
import 'package:bloc/bloc.dart';
@ -41,7 +43,6 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
@override
Future<void> close() async {
await this.close();
//PlatformPurchaseApi().close();
super.close();
}
}

View File

@ -0,0 +1,163 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/not_found_exception.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:network_image_to_byte/network_image_to_byte.dart';
import 'dart:collection';
class ImageCache with Logging {
static final ImageCache _singleton = ImageCache._internal();
final LinkedHashMap<String, String> _images = LinkedHashMap();
final LinkedHashMap<String, bool> _imageMap = LinkedHashMap();
var downloadSize = 0;
// Create storage
final storage = FlutterSecureStorage();
factory ImageCache() {
return _singleton;
}
ImageCache._internal();
LinkedHashMap getImageList() => _images;
void clearImageList() => _images.clear();
bool existsImageInMap(int id, String url) {
final String imageKey = generateMd5(url + "_" + id.toString());
return _imageMap[imageKey] != null && _imageMap[imageKey] == true;
}
String getImageString(int id, String url) {
final String imageKey = generateMd5(url + "_" + id.toString());
return _images[imageKey];
}
Future<void> putImageToList(int id, String url) async {
final String imageKey = generateMd5(url + "_" + id.toString());
// get from storage
final String imageString = await getImageAs64BaseString(id, url);
if (imageString != null) {
_images[imageKey] = imageString;
_imageMap[imageKey] = true;
}
/* final String imageString = await getImageAs64BaseString(id, url);
if (imageString != null) {
_imageMap[imageKey] = imageString;
_imageDown[imageKey] = true;
}
}
_images[imageKey] = imageString;
_imageMap[imageKey] = true; */
}
Future<void> saveImageToPrefs(String key, String value) async {
//log(" save the key " + key);
await storage.write(key: key, value: value);
return;
}
Future<void> emptyPrefs() async {
await storage.deleteAll();
return;
}
Future<String> loadImageFromPrefs(String key) async {
String value = await storage.read(key: key);
return value;
}
Future<bool> existImageInPrefs(String key) async {
return await storage.containsKey(key: key);
}
// encodes bytes list as string
static String base64String(Uint8List data) {
return base64Encode(data);
}
// decode bytes from a string
Image imageFrom64BaseString(String base64String) {
if (base64String == null) {
return null;
}
return Image.memory(
base64Decode(base64String),
fit: BoxFit.fill,
);
}
Future<Image> getImage(int id, String name) async {
if (storage == null) {
return null;
}
if (name == null || name.length == 0) {
return null;
}
final String imageKey = generateMd5(name + "_" + id.toString());
final String imageString = await storage.read(key: imageKey);
final Image image = imageFrom64BaseString(imageString);
return image;
}
Future<String> getImageAs64BaseString(int id, String name) async {
if (name == null) {
return null;
}
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);
//log(" .. downloaded");
}
return imageString;
}
Future<String> downloadAndSaveImage(int id, String url) async {
final String imageKey = generateMd5(url + "_" + id.toString());
if (!await existImageInPrefs(imageKey)) {
try {
if (url.contains("http")) {
log(" ... direct download " + url);
Uint8List byteImage = await networkImageToByte(url);
this.downloadSize += byteImage.length;
final String imageAsString = base64String(byteImage);
ImageCache().saveImageToPrefs(imageKey, imageAsString);
return imageAsString;
}
} on NotFoundException catch (_) {
print(url + " not found");
} on Exception catch (e) {
print(e);
}
} else {
//log(" .. from storage");
final String storageString = await storage.read(key: imageKey);
if (storageString != null) {
//log(" .. storage String: " + storageString);
} else {
// log(" .. storage String is NULL");
}
}
return null;
}
String generateMd5(String input) {
String converted = input.replaceAll(RegExp(r'\.'), 'a');
converted = converted.replaceAll(RegExp(r'\/'), 'b');
converted = converted.replaceAll(RegExp(r':'), 'c');
//print("key: " + converted);
return converted;
}
}

View File

@ -1,11 +1,30 @@
/// Tree view widget library
library tree_view;
import 'dart:async';
import 'package:aitrainer_app/util/common.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class TreeViewStream {
static final TreeViewStream _singleton = TreeViewStream._internal();
final StreamController<bool> streamController = StreamController<bool>.broadcast();
double positionY = 0;
Stream get stream => streamController.stream;
StreamController getStreamController() => streamController;
factory TreeViewStream() => _singleton;
TreeViewStream._internal();
void dispose() {
streamController.close();
}
}
class TreeView extends InheritedWidget {
final List<Widget> children;
final bool startExpanded;
@ -24,33 +43,77 @@ class TreeView extends InheritedWidget {
);
static TreeView of(BuildContext context) {
//return context.inheritFromWidgetOfExactType(TreeView);
return context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
}
@override
bool updateShouldNotify(TreeView oldWidget) {
if (oldWidget.children == this.children &&
oldWidget.startExpanded == this.startExpanded) {
if (oldWidget.children == this.children && oldWidget.startExpanded == this.startExpanded) {
return false;
}
return true;
}
}
class _TreeViewData extends StatelessWidget {
class _TreeViewData extends StatefulWidget {
final List<Widget> children;
_TreeViewData({
this.children,
});
@override
__TreeViewDataState createState() => __TreeViewDataState();
}
class __TreeViewDataState extends State<_TreeViewData> {
final ScrollController _controller = ScrollController();
final Stream stream = TreeViewStream().stream;
var subscription;
@override
void initState() {
super.initState();
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance.addPostFrameCallback((_) {
final double cHeight = MediaQuery.of(context).size.height;
subscription = stream.listen((value) {
if (value) {
final double positionY = TreeViewStream().positionY;
print("pos " +
positionY.toString() +
" height: " +
cHeight.toString() +
" controller offset " +
_controller.offset.toString() +
" controller initial " +
_controller.initialScrollOffset.toString());
if (positionY > cHeight - 190) {
final double offset = positionY + 40;
print("antimateTo " + offset.toString());
_controller.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
}
});
});
}
@override
void dispose() {
_controller.dispose();
subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: children.length,
scrollDirection: Axis.vertical,
controller: _controller,
itemCount: widget.children.length,
itemBuilder: (context, index) {
return children.elementAt(index);
return widget.children.elementAt(index);
},
);
}
@ -92,14 +155,9 @@ class TreeViewChild extends StatefulWidget {
}
}
class TreeViewChildState extends State<TreeViewChild> with Common, SingleTickerProviderStateMixin {
class TreeViewChildState extends State<TreeViewChild> with Common {
bool isExpanded;
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
Color _color;
double _opacity = 0;
AnimationController _controller;
Animation<double> sizeAnimation;
@override
void initState() {
@ -115,7 +173,8 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
@override
Widget build(BuildContext context) {
return Column(
return (Column(
key: listKey,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
@ -124,27 +183,35 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
),
Flexible(
child: Container(
child:
AnimatedSwitcher(
duration: Duration(milliseconds:200),
reverseDuration: Duration(milliseconds:200),
switchInCurve: Curves.easeIn,
child: isExpanded ? Column(
mainAxisSize: MainAxisSize.min,
children: widget.children,
) : Offstage(),
),
child: AnimatedSwitcher(
duration: Duration(milliseconds: 200),
reverseDuration: Duration(milliseconds: 200),
switchInCurve: Curves.easeIn,
child: isExpanded
? Column(
mainAxisSize: MainAxisSize.min,
children: widget.children,
)
: Offstage(),
),
),
)
],
);
));
}
void toggleExpanded() {
setState(() {
this.isExpanded = !this.isExpanded;
_color = isExpanded ? Colors.black12 : Colors.transparent;
_opacity = isExpanded ? 1 : 0;
TreeViewStream().positionY = getPosition();
TreeViewStream().getStreamController().add(this.isExpanded);
});
}
double getPosition() {
RenderBox box = listKey.currentContext.findRenderObject();
Offset position = box.localToGlobal(Offset.zero); //this is global position
double y = position.dy;
return y;
}
}

View File

@ -439,8 +439,14 @@ class Cache with Logging {
Flurry.setUserId(customerId.toString());
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
Cache().setCustomerDevices(customerDevices);
await ExerciseTypeApi().getExerciseTypes();
await ExerciseTreeApi().getExerciseTree();
if (this._exerciseTree == null) {
await ExerciseTreeApi().getExerciseTree();
}
if (this._exerciseTypes == null) {
await ExerciseTypeApi().getExerciseTypes();
}
await ExerciseDeviceApi().getDevices();
ExerciseRepository exerciseRepository = ExerciseRepository();

View File

@ -11,7 +11,7 @@ class ExerciseTree {
ExerciseTree.fromJson(Map json) {
this.treeId = json['treeId'];
this.name = json['name'];
this.parentId = -1;
this.parentId = 0;
this.imageUrl = json['imageUrl'];
this.active = json['active'];
this.nameTranslation = json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['name'] : this.name;

View File

@ -62,7 +62,11 @@ class UserRepository with Logging {
} else if (e.code == 'weak-password') {
log('The password provided is too weak.');
throw Exception("Password too short");
} else if (e.code == 'account-exists-with-different-credential') {
log(e.code);
throw Exception("The account exists with different credential");
} else {
print(e.code);
throw Exception(e);
}
} on WorkoutTestException catch (ex) {

View File

@ -47,22 +47,12 @@ class WorkoutTreeRepository with Logging {
Antagonist.calf: Antagonist.calfNr
};
/* Future<String> _buildImage(String imageUrl) async {
String assetImage = 'asset/menu/' + imageUrl.substring(7);
//print("Loading image " + assetImage);
return rootBundle.load(assetImage).then((value) {
return assetImage;
}).catchError((_) {
String imagePath = assetImage.substring(10);
String url = Cache.mediaUrl + 'images' + imagePath;
//print("Exception: " + assetImage + " will be loaded from the network " + url);
return url;
});
} */
Future<void> createTree() async {
isEnglish = AppLanguage().appLocal == Locale('en');
log("** Start creating tree on lang: " + AppLanguage().appLocal.languageCode);
log("** Start creating tree on lang: " +
AppLanguage().appLocal.languageCode +
" tree length: " +
Cache().getExerciseTree().length.toString());
List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
if (exerciseTree == null || exerciseTree.length == 0) {

View File

@ -3,10 +3,11 @@ import 'dart:convert';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_tree.dart';
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:flutter/services.dart';
import 'api.dart';
class ExerciseTreeApi {
class ExerciseTreeApi with Logging {
final APIClient _client = new APIClient();
Future<List<ExerciseTree>> getExerciseTree() async {
@ -17,23 +18,24 @@ class ExerciseTreeApi {
exerciseTree = await getExerciseTreeParents(exerciseTree);
if (exerciseTree != null) {
exerciseTree.forEach((element) async {
element.imageUrl = await _buildImage(element.imageUrl);
await Future.forEach(exerciseTree, (element) async {
//exerciseTree.forEach((element) async {
element.imageUrl = await _buildImage(element.imageUrl, element.treeId);
});
log("ExerciseTree downloaded");
Cache().setExerciseTree(exerciseTree);
}
Cache().setExerciseTree(exerciseTree);
return exerciseTree;
}
Future<String> _buildImage(String imageUrl) async {
Future<String> _buildImage(String imageUrl, int treeId) async {
String assetImage = 'asset/menu/' + imageUrl.substring(7);
//print("Loading image " + assetImage);
return rootBundle.load(assetImage).then((value) {
return await rootBundle.load(assetImage).then((value) {
return assetImage;
}).catchError((_) {
String imagePath = assetImage.substring(10);
String url = Cache.mediaUrl + 'images' + imagePath;
//print("Exception: " + assetImage + " will be loaded from the network " + url);
return url;
});
}

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:aitrainer_app/library/image_cache.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/service/api.dart';
@ -14,14 +15,17 @@ class ExerciseTypeApi with Logging {
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
if (exerciseTypes != null) {
exerciseTypes.forEach((element) async {
element.imageUrl = await _buildImage(element.imageUrl);
element.imageUrl = await _buildImage(element.imageUrl, element.exerciseTypeId);
//ImageCache().downloadAndSaveImage(element.exerciseTypeId, element.imageUrl);
});
log("ExerciseTypes downloaded");
Cache().setExerciseTypes(exerciseTypes);
}
Cache().setExerciseTypes(exerciseTypes);
return exerciseTypes;
}
Future<String> _buildImage(String imageUrl) async {
Future<String> _buildImage(String imageUrl, int exerciseTypeId) async {
if (imageUrl.length > 8) {
String assetImage = 'asset/menu/' + imageUrl.substring(7);
return rootBundle.load(assetImage).then((value) {
@ -29,7 +33,6 @@ class ExerciseTypeApi with Logging {
}).catchError((_) {
String imagePath = assetImage.substring(10);
String url = Cache.mediaUrl + 'images' + imagePath;
//print("Exception: " + assetImage + " will be loaded from the network " + url);
return url;
});
} else {

View File

@ -267,7 +267,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
"times!",
);
String title = step.toString() + ". " + t("Control Exercise:");
String title = (step + 1).toString() + "/4 " + t("Control Exercise:");
LinkedHashMap args = LinkedHashMap();
List<Widget> listWidgets = [

View File

@ -195,7 +195,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
Text(
exerciseDescription,
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
maxLines: 4,
maxLines: 1,
overflow: TextOverflow.fade,
softWrap: true,
),
@ -231,10 +231,21 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
color: Colors.transparent,
),
columnQuantity(exerciseBloc),
Divider(),
Divider(
color: Colors.transparent,
),
Text(
t("Step" + ": " + "1/4"),
style: GoogleFonts.inter(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.bold,
),
maxLines: 3,
textAlign: TextAlign.center,
overflow: TextOverflow.fade,
softWrap: true,
),
Divider(
color: Colors.transparent,
),

View File

@ -1,4 +1,3 @@
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
@ -6,13 +5,10 @@ import 'package:aitrainer_app/widgets/bottom_nav.dart';
import 'package:aitrainer_app/widgets/menu_page_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore: must_be_immutable
class MenuPage extends StatefulWidget {
static const routeName = '/menu_page';
int parent;
MenuPage({this.parent});
@ -24,81 +20,35 @@ class _MenuPage extends State<MenuPage> {
// ignore: close_sinks
MenuBloc menuBloc;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
menuBloc = BlocProvider.of<MenuBloc>(context);
menuBloc.parent = widget.parent;
return Scaffold(
appBar: AppBarNav(isMenu: true,),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
appBar: AppBarNav(
isMenu: true,
),
child: BlocConsumer<MenuBloc, MenuState>(
listener: (context, state) {
if (state is MenuError) {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.orange,
content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if ( state is MenuLoading ) {
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_menu_dark.png'),
fit: BoxFit.fill,
alignment: Alignment.center,
),
),
child: BlocConsumer<MenuBloc, MenuState>(listener: (context, state) {
if (state is MenuError) {
Scaffold.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
}
}, builder: (context, state) {
return MenuPageWidget();
}
},
// ignore: missing_return
builder: (context, state) {
if ( state is MenuInitial ) {
return LoadingMenuDialog();
} else if (state is MenuReady ) {
return MenuPageWidget();
} else if ( state is MenuLoading ) {
return LoadingMenuDialog();
}
}
)
),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 0)
);
})),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 0));
}
}
class LoadingMenuDialog extends StatefulWidget {
LoadingMenuDialog({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => _LoadingMenuDialog();
}
class _LoadingMenuDialog extends State<LoadingMenuDialog> {
@override
void initState() {
super.initState();
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance.addPostFrameCallback((_) {
BlocProvider.of<MenuBloc>(context).add(MenuCreate());
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Center(
child: Card(
child: Container(
width: 80,
height: 80,
padding: EdgeInsets.all(12.0),
child: CircularProgressIndicator(),
color: Colors.transparent,
),
),
),
);
}
}

View File

@ -98,7 +98,7 @@ class _MyExercisePlanPage extends State<MyExercisePlanPage> with Trans, Logging
builder: (BuildContext context) {
return DialogPremium(
unlocked: Cache().hasPurchased,
unlockRound: 1,
unlockRound: 2,
function: "Suggested Training Plan",
unlockedText: null,
onTap: () => {Navigator.of(context).pop()},

View File

@ -149,7 +149,7 @@ class SalesPage extends StatelessWidget with Trans, Logging {
bloc.product2Display.forEach((element) {
final String title = element.sort == 3 ? t("Montly") : t("Annual");
final String desc4 = element.sort == 1 ? "" : t("AI driven predictions");
final String desc4 = element.sort == 1 ? "" : t("Predictions with Artificial Intelligence");
String badge;
if (element.sort == 2) {
badge = t("14% discount");

View File

@ -5,6 +5,7 @@ import 'package:aitrainer_app/localization/app_localization.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/common.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -12,6 +13,8 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:rainbow_color/rainbow_color.dart';
import 'dialog_html.dart';
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
final MenuBloc menuBloc;
final bool isMenu;
@ -146,6 +149,9 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
percent = 0;
}
}
if (percent == null) {
percent = 0;
}
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
if (sizeExerciseList == 0) {
String text = AppLocalizations.of(context).translate("Make your first test");
@ -155,29 +161,38 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
text,
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple, blurRadius: 15)]),
),
//TestProgress(animation: sizeAnim),
]);
} else {
return Stack(
alignment: Alignment.topLeft,
children: [
LinearPercentIndicator(
width: cWidth / 4,
lineHeight: 14.0,
percent: percent,
center: Text(
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
style: new TextStyle(fontSize: 10.0),
GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: AppLocalizations.of(context).translate("Progressindicator for the tests"),
htmlData: AppLocalizations.of(context).translate("Progressindicator_desc"),
);
}),
child: LinearPercentIndicator(
width: cWidth / 4,
lineHeight: 14.0,
percent: percent,
center: Text(
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
style: new TextStyle(fontSize: 10.0),
),
trailing: Icon(
percent > 0.6 ? Icons.mood : Icons.mood_bad,
color: colorAnim.value,
),
linearStrokeCap: LinearStrokeCap.roundAll,
backgroundColor: colorAnim.value,
progressColor: Color(0xff73e600),
animation: true,
),
trailing: Icon(
percent > 0.6 ? Icons.mood : Icons.mood_bad,
color: colorAnim.value,
),
linearStrokeCap: LinearStrokeCap.roundAll,
backgroundColor: colorAnim.value,
progressColor: Color(0xff73e600),
animation: true,
),
)
],
);
}

View File

@ -172,6 +172,13 @@ class _BMIState extends State<BMI> with Trans {
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.orange[200],
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
color: Colors.black54,
),
],
)),
Text(
t("Bodyweight") +
@ -183,16 +190,37 @@ class _BMIState extends State<BMI> with Trans {
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.orange[200],
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
color: Colors.black87,
),
],
)),
Text("BMI" + " " + t("goal") + ": " + widget.exerciseBloc.goalBMI.toStringAsFixed(1),
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.orange[500],
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
color: Colors.black87,
),
],
)),
Text(t("Bodyweight") + " " + t("goal") + ": " + widget.exerciseBloc.goalWeight.toStringAsFixed(0) + " kg",
style: GoogleFonts.archivoBlack(
fontSize: 20,
color: Colors.orange[500],
shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 5.0,
color: Colors.black54,
),
],
)),
]))))));
}

View File

@ -141,6 +141,17 @@ class _BMRState extends State<BMR> with Trans {
fontSize: 30,
color: Colors.orange[300],
)),
Container(
padding: EdgeInsets.only(left: 65, right: 65),
alignment: Alignment.center,
child:
Text(t("Resting metabolic rate is the rate at which your body burns energy when it is at complete rest."),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.yellow[200],
)),
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.only(left: 35, right: 35),
@ -189,7 +200,7 @@ class _BMRState extends State<BMR> with Trans {
child: TextFormField(
focusNode: _nodeText2,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
labelText: AppLocalizations.of(context).translate("Actual Height"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,
@ -216,7 +227,7 @@ class _BMRState extends State<BMR> with Trans {
child: TextFormField(
focusNode: _nodeText3,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
labelText: AppLocalizations.of(context).translate("Birth Year"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,
@ -338,7 +349,7 @@ class _BMRState extends State<BMR> with Trans {
child: TextFormField(
focusNode: _nodeText1,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
labelText: AppLocalizations.of(context).translate("Actual Weight"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
fillColor: Colors.black38,

View File

@ -40,7 +40,7 @@ class _DialogPremiumState extends State<DialogHTML> with Trans {
borderRadius: BorderRadius.circular(24),
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
image: DecorationImage(
image: AssetImage('asset/image/WT_black_G_background.png'),
image: AssetImage('asset/image/WT_results_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),

View File

@ -256,7 +256,11 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
list.add(TextSpan(text: t(" ")));
list.add(
TextSpan(
text: widget.unlockRound == 1 ? t("the first") : t("the second"),
text: widget.unlockRound == 1
? t("the first")
: widget.unlockRound == 2
? t("the second")
: t("the third"),
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,

View File

@ -89,6 +89,5 @@ class _HomePageState extends State<AitrainerHome> with Logging {
@override
void dispose() async {
super.dispose();
//await PlatformPurchaseApi().close();
}
}

View File

@ -1,4 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:ui';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
@ -10,12 +10,16 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/service/logging.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/dialog_common.dart';
import 'package:auto_animated/auto_animated.dart';
import 'package:badges/badges.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:transparent_image/transparent_image.dart';
import 'package:aitrainer_app/library/image_cache.dart' as wt;
import 'dialog_html.dart';
import 'menu_info_widget.dart';
@ -35,35 +39,33 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
final double baseHeight = 675.2;
bool isFirst = true;
bool wait = false;
Timer _timer, _waitTimer;
MenuBloc menuBloc;
final scrollController = ScrollController();
@override
void initState() {
isFirst = true;
_timer = Timer.periodic(
Duration(milliseconds: 800),
(Timer timer) => setState(() {
if (!wait) {
isFirst = !isFirst;
//wait = true;
}
}));
_waitTimer = Timer.periodic(
Duration(milliseconds: 5000),
(Timer timer) => setState(() {
wait = !wait;
}));
/// We require the initializers to run after the loading screen is rendered
SchedulerBinding.instance.addPostFrameCallback((_) {
menuBloc.add(MenuCreate());
});
super.initState();
}
@override
Widget build(BuildContext context) {
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
menuBloc = BlocProvider.of<MenuBloc>(context);
setContext(context);
double cWidth = MediaQuery.of(context).size.width;
double cHeight = MediaQuery.of(context).size.height;
return CustomScrollView(scrollDirection: Axis.vertical, slivers: buildMenuColumn(widget.parent, context, menuBloc, cWidth, cHeight));
return CustomScrollView(
// Must add scrollController to sliver root
controller: scrollController,
scrollDirection: Axis.vertical,
slivers: buildMenuColumn(widget.parent, context, menuBloc, cWidth, cHeight));
}
List<Widget> buildMenuColumn(int parent, BuildContext context, MenuBloc menuBloc, double cWidth, double cHeight) {
@ -90,8 +92,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
WorkoutMenuTree workoutTree = value;
_columnChildren.add(Container(
padding: EdgeInsets.only(top: 15.0, left: 15, right: 15),
height: 225, //cHeight / 3 * distortionHeight,
padding: EdgeInsets.only(top: 15.0, left: cWidth * 0.04, right: cWidth * 0.04),
height: (cHeight / 3) - cWidth * 0.16,
child: Badge(
padding: EdgeInsets.all(8),
position: BadgePosition.bottomEnd(end: 0),
@ -141,9 +143,16 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
])))));
});
}
SliverList sliverList = SliverList(
delegate: SliverChildListDelegate(_columnChildren),
//delegate: SliverChildListDelegate(_columnChildren),
LiveSliverList sliverList = LiveSliverList(
itemCount: _columnChildren.length,
reAnimateOnVisibility: false,
showItemDuration: Duration(milliseconds: 250),
itemBuilder: (BuildContext context, int index, Animation<double> animation) => FadeTransition(
opacity: animation,
child: _columnChildren[index],
),
controller: scrollController,
);
slivers.add(sliverList);
@ -332,33 +341,51 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
}
Widget _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
Widget image;
if (workoutTree.imageName.startsWith('https')) {
image = ClipRRect(
//print("_getButtonImage " + workoutTree.imageName);
String imageString = menuBloc.getImage(workoutTree.id, workoutTree.imageName);
Widget widget;
if (imageString != null) {
print(" -- get Image from MEMORY " + workoutTree.imageName);
widget = ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.black87,
color: Colors.transparent,
child: FadeInImage(
image: NetworkImage(workoutTree.imageName),
placeholder: AssetImage("asset/image/dots.gif"),
fadeInDuration: Duration(milliseconds: 100),
image: MemoryImage(base64Decode(imageString)),
placeholder: MemoryImage(kTransparentImage),
),
));
} else {
image = Container(
//width: cWidth - 30,
//height: 210.0,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: AssetImage(workoutTree.imageName),
),
borderRadius: BorderRadius.all(Radius.circular(24.0)),
),
);
if (workoutTree.imageName.contains("https")) {
if (!wt.ImageCache().existsImageInMap(workoutTree.id, workoutTree.imageName)) {
print(" -- get Image from network " + workoutTree.imageName);
widget = ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.transparent,
child: FadeInImage(
fadeInDuration: Duration(milliseconds: 500),
image: NetworkImage(workoutTree.imageName),
placeholder: MemoryImage(kTransparentImage),
),
));
}
} else {
//print(" -- get Image from asset " + workoutTree.imageName);
widget = ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.transparent,
child: FadeInImage(
fadeInDuration: Duration(milliseconds: 200),
image: AssetImage(workoutTree.imageName),
placeholder: MemoryImage(kTransparentImage),
),
));
}
}
return image;
return widget;
}
Widget badgedIcon(WorkoutMenuTree workoutMenuTree, double cWidth, double cHeight) {
@ -380,7 +407,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
)),
child: buttonImage == null
? Container(
color: Colors.red,
color: Colors.transparent,
)
: buttonImage,
);
@ -388,8 +415,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
@override
void dispose() {
_timer.cancel();
_waitTimer.cancel();
super.dispose();
}
}

View File

@ -50,6 +50,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.1"
auto_animated:
dependency: "direct main"
description:
name: auto_animated
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
badges:
dependency: "direct main"
description:
@ -112,7 +119,7 @@ packages:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.13"
version: "1.11.0"
build_runner_core:
dependency: transitive
description:
@ -161,7 +168,7 @@ packages:
name: chewie
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.1+1"
version: "0.12.2"
chewie_audio:
dependency: transitive
description:
@ -404,7 +411,7 @@ packages:
name: flutter_facebook_auth
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0+1"
version: "2.0.1"
flutter_facebook_auth_platform_interface:
dependency: transitive
description:
@ -419,6 +426,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.6"
flutter_fadein:
dependency: "direct main"
description:
name: flutter_fadein
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
flutter_form_bloc:
dependency: "direct main"
description:
@ -453,12 +467,19 @@ packages:
name: flutter_layout_grid
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.3"
version: "0.10.5"
flutter_localizations:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_secure_storage:
dependency: "direct main"
description:
name: flutter_secure_storage
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.5"
flutter_svg:
dependency: transitive
description:
@ -496,7 +517,7 @@ packages:
name: google_fonts
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
version: "1.1.2"
google_sign_in:
dependency: "direct main"
description:
@ -650,7 +671,7 @@ packages:
name: mockito
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.3"
version: "4.1.4"
modal_progress_hud:
dependency: "direct main"
description:
@ -665,6 +686,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
network_image_to_byte:
dependency: "direct main"
description:
name: network_image_to_byte
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1"
node_interop:
dependency: transitive
description:
@ -685,7 +713,7 @@ packages:
name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.12"
version: "1.4.13"
package_config:
dependency: transitive
description:
@ -804,7 +832,7 @@ packages:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.2+4"
version: "4.3.3"
pub_semver:
dependency: transitive
description:
@ -825,7 +853,7 @@ packages:
name: purchases_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.0.2"
quiver:
dependency: transitive
description:
@ -860,7 +888,7 @@ packages:
name: sentry
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.3"
version: "4.0.4"
shared_preferences:
dependency: "direct dev"
description:
@ -902,7 +930,7 @@ packages:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+3"
version: "0.0.2+2"
shelf:
dependency: transitive
description:
@ -984,7 +1012,7 @@ packages:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.0.3+1"
stack_trace:
dependency: transitive
description:
@ -1076,6 +1104,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.8"
transparent_image:
dependency: "direct main"
description:
name: transparent_image
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
typed_data:
dependency: transitive
description:
@ -1118,6 +1153,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4+1"
visibility_detector:
dependency: transitive
description:
name: visibility_detector
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
vm_service:
dependency: transitive
description:
@ -1159,7 +1201,7 @@ packages:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0"
webkit_inspection_protocol:
dependency: transitive
description:

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.1.5+48
version: 1.1.5+49
environment:
sdk: ">=2.7.0 <3.0.0"
@ -50,6 +50,7 @@ dependencies:
wakelock: ^0.2.1+1
timeline_tile: ^1.0.0
purchases_flutter: ^2.0.0
network_image_to_byte: ^0.0.1
firebase_core: ^0.5.0
@ -60,13 +61,17 @@ dependencies:
google_sign_in: ^4.5.9
apple_sign_in: ^0.1.0
crypto: ^2.1.5
transparent_image: ^1.0.0
flutter_fadein: ^1.1.1
auto_animated: ^2.1.0
flurry: ^0.0.7
animated_widgets: ^1.0.6
mockito: ^4.1.3
sqflite: ^1.3.0
sqflite: ^1.3.2+2
flutter_secure_storage: ^3.3.5
flutter_localizations:
sdk: flutter
@ -126,10 +131,7 @@ flutter:
- asset/image/WT_black_background.png
- asset/image/WT_black_G_background.png
- asset/image/WT_plainblack_background.png
- asset/image/WT_reg_light_background.png
- asset/image/WT_menu.png
- asset/image/WT_login.png
- asset/image/WT_OK.png
- asset/image/dots.gif
- asset/image/WT_long_logo.png
- asset/image/WT_light_background.png
@ -142,11 +144,11 @@ flutter:
- asset/image/WT_Results_for_runners.png
- asset/image/WT_Results_for_female.png
- asset/image/WT_Results_for_men.png
- asset/image/WT_results_background.jpg
- asset/image/button_fb.png
- asset/image/button_apple.png
- asset/image/button_google.png
- asset/image/lock.png
- asset/image/Congrats_N1.jpg
- asset/image/testemfejl400x400.jpg
- asset/image/izomcsop400400.jpg
- asset/image/edzesnaplom400400.jpg
@ -159,7 +161,6 @@ flutter:
- asset/image/man_sizes.png
- asset/image/woman_sizes.png
- asset/image/merleg.png
- asset/image/BMI_diagram_b.png
- asset/image/BMI_graph_c.png
- asset/image/BMI_mutato.png
- asset/image/equipment_specialshome.jpg
@ -201,38 +202,23 @@ flutter:
- asset/image/pict_time_h.png
- asset/image/pict_hypertrophy.png
- asset/image/pict_weight_volumen_tonna.png
- asset/menu/1.cardio.png
- asset/menu/1.1.aerob.png
- asset/menu/1.2.anaerob.png
- asset/menu/1.1.1.cooper.png
- asset/menu/1.2.1.300m.png
- asset/menu/1.2.2.400m.png
- asset/menu/2.strength.png
- asset/menu/2.1.endurance.png
- asset/menu/2.1.1.pull-ups.png
- asset/menu/2.1.2.pushup.png
- asset/menu/2.1.3.sit-ups.png
- asset/menu/2.1.4.squats.png
- asset/menu/2.1.5.timedpushup.png
- asset/menu/2.1.6.core.png
- asset/menu/2.2.1.1RM.png
- asset/menu/2.2.1.1.chestpress.png
- asset/menu/2.2.1.2.pullups.png
- asset/menu/2.2.1.3.biceps.png
- asset/menu/2.2.1.4.triceps.png
- asset/menu/2.2.1.5.shoulders.png
- asset/menu/3.bcs1.png
- asset/menu/3.1.BMI.png
- asset/menu/3.2.BMR.png
- asset/menu/3.3.sizes.png
- asset/menu/cable_triceps.png
- asset/menu/Back_pullup.png
- asset/menu/biceps.jpg
- asset/menu/calf.png
- asset/menu/legpress.jpg
- asset/menu/shoulder_press.png
- asset/menu/squat.jpg
- asset/menu/tricdip.jpg
- asset/menu/1.cardio.jpg
- asset/menu/1.1.aerob.jpg
- asset/menu/1.2.anaerob.jpg
- asset/menu/2.strength.jpg
- asset/menu/2.1.endurance.jpg
- asset/menu/2.1.6.core.jpg
- asset/menu/2.1.1.1RM.jpg
- asset/menu/2.2.1.1.chest.jpg
- asset/menu/2.2.1.3.biceps.jpg
- asset/menu/2.2.1.4.triceps.jpg
- asset/menu/2.2.1.5.shoulders.jpg
- asset/menu/2.2.1.6.thigh.jpg
- asset/menu/2.2.1.7.back.jpg
- asset/menu/2.2.1.8.calf.jpg
- asset/menu/3.bcs1.jpg
- i18n/en.json
- i18n/hu.json