WT 1.1.5+2 remote images for menu
@ -45,7 +45,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.aitrainer.aitrainer_app"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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
|
||||
|
Before Width: | Height: | Size: 272 KiB |
Before Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 4.4 MiB |
Before Width: | Height: | Size: 2.4 MiB |
BIN
asset/image/WT_results_background.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 781 KiB |
BIN
asset/menu/1.1.aerob.jpg
Normal file
After Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 1.6 MiB |
BIN
asset/menu/1.2.anaerob.jpg
Normal file
After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 1.1 MiB |
BIN
asset/menu/1.cardio.jpg
Normal file
After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 1.1 MiB |
BIN
asset/menu/2.1.1.1RM.jpg
Normal file
After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.1.6.core.jpg
Normal file
After Width: | Height: | Size: 163 KiB |
Before Width: | Height: | Size: 1.3 MiB |
BIN
asset/menu/2.1.endurance.jpg
Normal file
After Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 1.3 MiB |
BIN
asset/menu/2.2.1.1.chest.jpg
Normal file
After Width: | Height: | Size: 179 KiB |
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.2.1.3.biceps.jpg
Normal file
After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 1.2 MiB |
BIN
asset/menu/2.2.1.4.triceps.jpg
Normal file
After Width: | Height: | Size: 175 KiB |
Before Width: | Height: | Size: 1.5 MiB |
BIN
asset/menu/2.2.1.5.shoulders.jpg
Normal file
After Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/2.2.1.6.thigh.jpg
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
asset/menu/2.2.1.7.back.jpg
Normal file
After Width: | Height: | Size: 126 KiB |
BIN
asset/menu/2.2.1.8.calf.jpg
Normal file
After Width: | Height: | Size: 126 KiB |
BIN
asset/menu/2.strength.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 988 KiB |
Before Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 1.4 MiB |
BIN
asset/menu/3.bcs1.jpg
Normal file
After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 217 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 177 KiB |
28
i18n/en.json
@ -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"
|
||||
}
|
49
i18n/hu.json
@ -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"
|
||||
}
|
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
163
lib/library/image_cache.dart
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 = [
|
||||
|
@ -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,
|
||||
),
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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()},
|
||||
|
@ -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");
|
||||
|
@ -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,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
],
|
||||
)),
|
||||
]))))));
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
),
|
||||
|
@ -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,
|
||||
|
@ -89,6 +89,5 @@ class _HomePageState extends State<AitrainerHome> with Logging {
|
||||
@override
|
||||
void dispose() async {
|
||||
super.dispose();
|
||||
//await PlatformPurchaseApi().close();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
68
pubspec.lock
@ -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:
|
||||
|
64
pubspec.yaml
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# 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
|
||||
|
||||
|