WT 1.1.5+2 remote images for menu
@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
The WorkoutTest Mobile Application
|
The WorkoutTest Mobile Application
|
||||||
|
|
||||||
live 1.1.3
|
live 1.1.5
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.aitrainer.aitrainer_app"
|
applicationId "com.aitrainer.aitrainer_app"
|
||||||
minSdkVersion 16
|
minSdkVersion 18
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
@ -14,6 +14,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"oauth_client": [
|
"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_id": "926782702216-al3vjap51m6pgpa066d1oni0bdjpu7pr.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"client_type": 3
|
||||||
@ -30,6 +54,14 @@
|
|||||||
{
|
{
|
||||||
"client_id": "926782702216-al3vjap51m6pgpa066d1oni0bdjpu7pr.apps.googleusercontent.com",
|
"client_id": "926782702216-al3vjap51m6pgpa066d1oni0bdjpu7pr.apps.googleusercontent.com",
|
||||||
"client_type": 3
|
"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:theme="@style/LaunchTheme"
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
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
|
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||||
the Android process has started. This theme is visible to the user
|
the Android process has started. This theme is visible to the user
|
||||||
while the Flutter UI initializes. After that, this theme continues
|
while the Flutter UI initializes. After that, this theme continues
|
||||||
|
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",
|
"OR": "OR",
|
||||||
"Password (Leave empty if no change)":"Password (Leave empty if no change)",
|
"Password (Leave empty if no change)":"Password (Leave empty if no change)",
|
||||||
"First Name": "First Name",
|
"First Name": "First Name",
|
||||||
"Birth Year": "Birty Year",
|
"Birth Year": "Birth Year",
|
||||||
"Weight": "Weight",
|
"Weight": "Weight",
|
||||||
"Gender": "Gender",
|
"Gender": "Gender",
|
||||||
"Man": "Man",
|
"Man": "Man",
|
||||||
@ -114,7 +114,7 @@
|
|||||||
"Gain Muscle": "Gain Muscle",
|
"Gain Muscle": "Gain Muscle",
|
||||||
"Loose Weight": "Loose Weight",
|
"Loose Weight": "Loose Weight",
|
||||||
"Your Fitness State": "Your Fitness State",
|
"Your Fitness State": "Your Fitness State",
|
||||||
"Fitness level": "Fizikai állapot",
|
"Fitness level": "Fitness level",
|
||||||
"Fitness Activity":"Fitness Activity",
|
"Fitness Activity":"Fitness Activity",
|
||||||
"Beginner": "Beginner",
|
"Beginner": "Beginner",
|
||||||
"I am beginner": "I am 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 was not successful":"Facebook login was not successful",
|
||||||
"Exception: Facebook login cancelled":"Facebook login cancelled",
|
"Exception: Facebook login cancelled":"Facebook login cancelled",
|
||||||
"Exception: Facebook login failed":"Facebook login failed",
|
"Exception: Facebook login failed":"Facebook login failed",
|
||||||
|
"Exception: The account exists with different credential": "The account exists with different credential",
|
||||||
|
|
||||||
|
|
||||||
"More »": "More »",
|
"More »": "More »",
|
||||||
@ -258,6 +259,7 @@
|
|||||||
"goal":"goal",
|
"goal":"goal",
|
||||||
"Basal Metabolic Rate":"Basal Metabolic Rate",
|
"Basal Metabolic Rate":"Basal Metabolic Rate",
|
||||||
"Resting Metabolic Rate":"Resting 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.",
|
"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",
|
"Your Sizes":"Your Sizes",
|
||||||
"Size Of Your":"Size Of Your",
|
"Size Of Your":"Size Of Your",
|
||||||
@ -297,10 +299,11 @@
|
|||||||
"The": "The",
|
"The": "The",
|
||||||
"the first":"the first",
|
"the first":"the first",
|
||||||
"the second":"the second",
|
"the second":"the second",
|
||||||
|
"the third":"the third",
|
||||||
"Go Premium":"Go Premium",
|
"Go Premium":"Go Premium",
|
||||||
"Unleash your potential with WorkoutTest Premium!":"Unleash your potential with WorkoutTest 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",
|
"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",
|
"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.",
|
"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 not successful":"Purchase was not successful",
|
||||||
"Exception: Purchase was cancelled":"Purchase was cancelled",
|
"Exception: Purchase was cancelled":"Purchase was cancelled",
|
||||||
"Successful Purchase": "Successful Purchase",
|
"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 failed":"Apple bejelentkezés sikertelen",
|
||||||
"Exception: Apple Sign-In cancelled":"Apple bejelentkezés megszakítva",
|
"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: 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",
|
"Please select an exercise": "Válassz ki egy gyakorlatot",
|
||||||
"There is an error: during registration:": "Hiba lépett fel a regisztráció során:",
|
"There is an error: during registration:": "Hiba lépett fel a regisztráció során:",
|
||||||
@ -91,7 +92,7 @@
|
|||||||
"Yes": "Igen",
|
"Yes": "Igen",
|
||||||
"No": "Nem",
|
"No": "Nem",
|
||||||
"with": "",
|
"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",
|
"repeat": "ismétlés",
|
||||||
@ -143,7 +144,7 @@
|
|||||||
"Make your first test": "Végezd el az első tesztet",
|
"Make your first test": "Végezd el az első tesztet",
|
||||||
"finished": "végrehajtva",
|
"finished": "végrehajtva",
|
||||||
"Why do you need Exercise Control?": "Miért szükséges a tesztgyakorlat?",
|
"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ő:",
|
"Your Real 1RM:":"Ellenőrzött maxerő:",
|
||||||
"Check":"Ellenőrzés",
|
"Check":"Ellenőrzés",
|
||||||
|
|
||||||
@ -169,7 +170,7 @@
|
|||||||
"8. Calf": "8. Vádli",
|
"8. Calf": "8. Vádli",
|
||||||
|
|
||||||
"Execute My Selected Training Plan": "Edzésterv végrehajtása",
|
"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",
|
"Suggested Training Plan": "Javasolt edzésterv",
|
||||||
"My Special Plan": "Speciális edzésterv",
|
"My Special Plan": "Speciális edzésterv",
|
||||||
"Training Programs":"Edzés programok",
|
"Training Programs":"Edzés programok",
|
||||||
@ -183,7 +184,7 @@
|
|||||||
"My Trainee's Exercise Logs": "Kliensem edzésnaplőja",
|
"My Trainee's Exercise Logs": "Kliensem edzésnaplőja",
|
||||||
|
|
||||||
"My Development By Muscle": "Izomcsoportok fejlődése",
|
"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",
|
"Sum Of Mass":"Össztömeg",
|
||||||
"Percent": "Százalék",
|
"Percent": "Százalék",
|
||||||
|
|
||||||
@ -201,22 +202,22 @@
|
|||||||
"Execute your active Exercise Plan!": "Hajtsd végre az aktív edzéstervedet",
|
"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.",
|
"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",
|
"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.",
|
"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!",
|
"Persistence!": "Kitartás!",
|
||||||
"Greetings!": "Üdvözöllek!",
|
"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.",
|
"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.",
|
"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",
|
"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",
|
"Nice! This is a good start": "Nagyon jó! Ez egy kitűnő start a teszthez",
|
||||||
"Go on!":"Gyerünk tovább!",
|
"Go on!":"Gyerünk tovább!",
|
||||||
"You are on track": "Jó úton haladsz",
|
"You are on track": "Jó úton haladsz",
|
||||||
"Not so much left": "Már nincs sok hátra",
|
"Not so much left": "Már nincs sok hátra",
|
||||||
"Almost!": "Majdnem a végén vagy!",
|
"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!",
|
"exercise!": "gyakorlattal!",
|
||||||
"Chest": "mell",
|
"Chest": "mell",
|
||||||
"Back": "hát",
|
"Back": "hát",
|
||||||
@ -247,13 +248,14 @@
|
|||||||
"Actual Height":"Magasság",
|
"Actual Height":"Magasság",
|
||||||
"Actual Weight":"Testtömeg",
|
"Actual Weight":"Testtömeg",
|
||||||
"Bodyweight":"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",
|
"Body Mass Index":"Testtömegindex",
|
||||||
"first step":"első lépés",
|
"first step":"első lépés",
|
||||||
"goal":"cél",
|
"goal":"cél",
|
||||||
"Basal Metabolic Rate":"Alapanyagcsere érték",
|
"Basal Metabolic Rate":"Minimum energiaszükséglet",
|
||||||
"Resting Metabolic Rate":"Minimum energiaszükséglet",
|
"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":"A testtömeged, magasságod és aktivitásod alapján megközelítőleg ennyi a napi kalóriaszükségleted.",
|
"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",
|
"Your Sizes":"Méreteid",
|
||||||
"Size Of Your":"Testméret:",
|
"Size Of Your":"Testméret:",
|
||||||
"Please type the following data:":"Kérlek írd be a következő adatot:",
|
"Please type the following data:":"Kérlek írd be a következő adatot:",
|
||||||
@ -263,8 +265,8 @@
|
|||||||
"Available Equipments":"Elérhető eszközök",
|
"Available Equipments":"Elérhető eszközök",
|
||||||
"select your places by tapping":"kattints az edzéshelyszínre",
|
"select your places by tapping":"kattints az edzéshelyszínre",
|
||||||
"Available Training Places":"Elérhető edzéshelyszínek",
|
"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 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": "Vegyél egy közepes súlyt és végezz el 20-30 ismétlést",
|
"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ő",
|
"Equipment Filter":"Eszköz szűrő",
|
||||||
"Live-Server":"Live-Server",
|
"Live-Server":"Live-Server",
|
||||||
"Test-Server":"Test-Server",
|
"Test-Server":"Test-Server",
|
||||||
@ -293,6 +295,7 @@
|
|||||||
"The": "A",
|
"The": "A",
|
||||||
"the first":"az első",
|
"the first":"az első",
|
||||||
"the second":"a második",
|
"the second":"a második",
|
||||||
|
"the third":"a harmadik",
|
||||||
"Go Premium":"Válts Prémiumra",
|
"Go Premium":"Válts Prémiumra",
|
||||||
"Unleash your potential with WorkoutTest Premium!":"Bontakoztasd ki az erősségeidet WorkoutTest Prémiummal!",
|
"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",
|
"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 not successful":"A vásárlás sikertelen volt",
|
||||||
"Exception: Purchase was cancelled":"A vásárlás megszakadt",
|
"Exception: Purchase was cancelled":"A vásárlás megszakadt",
|
||||||
"Successful Purchase": "Sikeres vásárlás!",
|
"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
|
# 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.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
@ -8,16 +8,16 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- devicelocale (0.0.1):
|
- devicelocale (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FBSDKCoreKit (8.2.0):
|
- FBSDKCoreKit (9.0.0):
|
||||||
- FBSDKCoreKit/Basics (= 8.2.0)
|
- FBSDKCoreKit/Basics (= 9.0.0)
|
||||||
- FBSDKCoreKit/Core (= 8.2.0)
|
- FBSDKCoreKit/Core (= 9.0.0)
|
||||||
- FBSDKCoreKit/Basics (8.2.0)
|
- FBSDKCoreKit/Basics (9.0.0)
|
||||||
- FBSDKCoreKit/Core (8.2.0):
|
- FBSDKCoreKit/Core (9.0.0):
|
||||||
- FBSDKCoreKit/Basics
|
- FBSDKCoreKit/Basics
|
||||||
- FBSDKLoginKit (8.2.0):
|
- FBSDKLoginKit (9.0.0):
|
||||||
- FBSDKLoginKit/Login (= 8.2.0)
|
- FBSDKLoginKit/Login (= 9.0.0)
|
||||||
- FBSDKLoginKit/Login (8.2.0):
|
- FBSDKLoginKit/Login (9.0.0):
|
||||||
- FBSDKCoreKit (~> 8.2.0)
|
- FBSDKCoreKit (~> 9.0.0)
|
||||||
- Firebase/Analytics (6.33.0):
|
- Firebase/Analytics (6.33.0):
|
||||||
- Firebase/Core
|
- Firebase/Core
|
||||||
- Firebase/Auth (6.33.0):
|
- Firebase/Auth (6.33.0):
|
||||||
@ -93,14 +93,16 @@ PODS:
|
|||||||
- flurry (0.0.4):
|
- flurry (0.0.4):
|
||||||
- Flurry-iOS-SDK/FlurrySDK
|
- Flurry-iOS-SDK/FlurrySDK
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flurry-iOS-SDK/FlurrySDK (11.1.1)
|
- Flurry-iOS-SDK/FlurrySDK (11.2.0)
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- flutter_facebook_auth (1.0.0):
|
- flutter_facebook_auth (1.0.0):
|
||||||
- FBSDKCoreKit (~> 8.2.0)
|
- FBSDKCoreKit (~> 9.0.0)
|
||||||
- FBSDKLoginKit (~> 8.2.0)
|
- FBSDKLoginKit (~> 9.0.0)
|
||||||
- Flutter
|
- Flutter
|
||||||
- flutter_keyboard_visibility (0.0.1):
|
- flutter_keyboard_visibility (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- flutter_secure_storage (3.3.1):
|
||||||
|
- Flutter
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
@ -153,11 +155,11 @@ PODS:
|
|||||||
- nanopb/encode (1.30906.0)
|
- nanopb/encode (1.30906.0)
|
||||||
- path_provider (0.0.1):
|
- path_provider (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- PromisesObjC (1.2.11)
|
- PromisesObjC (1.2.12)
|
||||||
- Protobuf (3.13.0)
|
- Protobuf (3.14.0)
|
||||||
- Purchases (3.9.2):
|
- Purchases (3.9.2):
|
||||||
- PurchasesCoreSwift (= 3.9.2)
|
- PurchasesCoreSwift (= 3.9.2)
|
||||||
- purchases_flutter (2.0.0):
|
- purchases_flutter (2.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- PurchasesHybridCommon (= 1.5.0)
|
- PurchasesHybridCommon (= 1.5.0)
|
||||||
- PurchasesCoreSwift (3.9.2)
|
- PurchasesCoreSwift (3.9.2)
|
||||||
@ -186,6 +188,7 @@ DEPENDENCIES:
|
|||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
|
- flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
|
||||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
- flutter_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`)
|
- google_sign_in (from `.symlinks/plugins/google_sign_in/ios`)
|
||||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
|
- purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`)
|
||||||
@ -244,6 +247,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
|
:path: ".symlinks/plugins/flutter_facebook_auth/ios"
|
||||||
flutter_keyboard_visibility:
|
flutter_keyboard_visibility:
|
||||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||||
|
flutter_secure_storage:
|
||||||
|
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||||
google_sign_in:
|
google_sign_in:
|
||||||
:path: ".symlinks/plugins/google_sign_in/ios"
|
:path: ".symlinks/plugins/google_sign_in/ios"
|
||||||
path_provider:
|
path_provider:
|
||||||
@ -265,8 +270,8 @@ SPEC CHECKSUMS:
|
|||||||
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
AppAuth: 31bcec809a638d7bd2f86ea8a52bd45f6e81e7c7
|
||||||
apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
|
apple_sign_in: 7716c7ddfa195aeab7dec0dc374ef4ff45d1adb4
|
||||||
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
|
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
|
||||||
FBSDKCoreKit: 4afd6ff53d8133a433dbcda44451c9498f8c6ce4
|
FBSDKCoreKit: ac6cc500b8e104bb9a4dd20b1527b5d199123c2e
|
||||||
FBSDKLoginKit: 7181765f2524d7ebf82d9629066c8e6caafc99d0
|
FBSDKLoginKit: e9b6542fdee322333502ab497f628b011dce7d78
|
||||||
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
|
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
|
||||||
firebase_analytics: 36a619088c46224900829f14f4daa71585693a6f
|
firebase_analytics: 36a619088c46224900829f14f4daa71585693a6f
|
||||||
firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a
|
firebase_auth: d5159db3873478d1ac839af7b10d2f831516136a
|
||||||
@ -280,10 +285,11 @@ SPEC CHECKSUMS:
|
|||||||
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
|
FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1
|
||||||
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
|
FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a
|
||||||
flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad
|
flurry: 15b01f664ab1367c62b50291541ea7f78ca85aad
|
||||||
Flurry-iOS-SDK: 8f3f7fce27177002f15f145eede88dc1b9ac0cd0
|
Flurry-iOS-SDK: 6636d30c30f12010e7c7c71d84b443416a168efc
|
||||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||||
flutter_facebook_auth: bad08a3d465e7b7ba9d8468a9dc7df3f69c136b8
|
flutter_facebook_auth: d952ca599c6a76439c54472b0b225004e1b880c4
|
||||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||||
|
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
|
google_sign_in: 6bd214b9c154f881422f5fe27b66aaa7bbd580cc
|
||||||
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
|
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
|
||||||
@ -294,10 +300,10 @@ SPEC CHECKSUMS:
|
|||||||
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
|
GTMSessionFetcher: b3503b20a988c4e20cc189aa798fd18220133f52
|
||||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
|
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
||||||
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
|
Protobuf: 0cde852566359049847168e51bd1c690e0f70056
|
||||||
Purchases: d8a798c9c7552fe66b550bf314a143e94ffa70c8
|
Purchases: d8a798c9c7552fe66b550bf314a143e94ffa70c8
|
||||||
purchases_flutter: 27f87080055c0fd2cd124c247b10cae75b46e7e1
|
purchases_flutter: f97230b7edf32be4155b3dcce8e790a77df3fab1
|
||||||
PurchasesCoreSwift: ea4eabae180416e580ac60366f41aa1fefec0693
|
PurchasesCoreSwift: ea4eabae180416e580ac60366f41aa1fefec0693
|
||||||
PurchasesHybridCommon: d9bfb34309db4c9ba82a6f7f3a6275c13befdca7
|
PurchasesHybridCommon: d9bfb34309db4c9ba82a6f7f3a6275c13befdca7
|
||||||
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||||
@ -306,6 +312,6 @@ SPEC CHECKSUMS:
|
|||||||
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
|
wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
|
||||||
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
|
webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96
|
||||||
|
|
||||||
PODFILE CHECKSUM: 28226b39c1afd238c6168e31e2bd3829c3d67530
|
PODFILE CHECKSUM: ac11fc852a681d8d7d22e344055d0c36b734cfc2
|
||||||
|
|
||||||
COCOAPODS: 1.10.0
|
COCOAPODS: 1.10.0
|
||||||
|
@ -388,7 +388,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -410,7 +410,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
@ -531,7 +531,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -554,7 +554,7 @@
|
|||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@ -566,7 +566,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 2;
|
||||||
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
DEVELOPMENT_TEAM = SFJJBDCU6Z;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -588,7 +588,7 @@
|
|||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = 1;
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
name = Release;
|
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/model/cache.dart';
|
||||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||||
import 'package:aitrainer_app/repository/user_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/common.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
@ -22,7 +24,12 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
|||||||
final bool isRegistration;
|
final bool isRegistration;
|
||||||
bool dataPolicyAllowed = false;
|
bool dataPolicyAllowed = false;
|
||||||
bool obscure = true;
|
bool obscure = true;
|
||||||
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial());
|
LoginBloc({this.accountBloc, this.userRepository, this.context, this.isRegistration}) : super(LoginInitial()) {
|
||||||
|
if (isRegistration) {
|
||||||
|
ExerciseTreeApi().getExerciseTree();
|
||||||
|
ExerciseTypeApi().getExerciseTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<LoginState> mapEventToState(
|
Stream<LoginState> mapEventToState(
|
||||||
@ -119,7 +126,9 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> with Trans {
|
|||||||
this.dataPolicyAllowed = !dataPolicyAllowed;
|
this.dataPolicyAllowed = !dataPolicyAllowed;
|
||||||
yield LoginReady();
|
yield LoginReady();
|
||||||
} else if (event is LoginPasswordChangeObscure) {
|
} else if (event is LoginPasswordChangeObscure) {
|
||||||
|
yield LoginLoading();
|
||||||
this.obscure = !this.obscure;
|
this.obscure = !this.obscure;
|
||||||
|
yield LoginReady();
|
||||||
}
|
}
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
yield LoginError(message: e.toString());
|
yield LoginError(message: e.toString());
|
||||||
|
@ -13,6 +13,7 @@ import 'package:bloc/bloc.dart';
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||||
|
|
||||||
part 'menu_event.dart';
|
part 'menu_event.dart';
|
||||||
part 'menu_state.dart';
|
part 'menu_state.dart';
|
||||||
@ -21,9 +22,9 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
final WorkoutTreeRepository menuTreeRepository;
|
final WorkoutTreeRepository menuTreeRepository;
|
||||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository();
|
ExerciseDeviceRepository exerciseDeviceRepository = ExerciseDeviceRepository();
|
||||||
int parent;
|
int parent = 0;
|
||||||
WorkoutMenuTree workoutItem;
|
WorkoutMenuTree workoutItem;
|
||||||
List<int> listFilterDevice = List();
|
final List<int> listFilterDevice = List();
|
||||||
|
|
||||||
String infoTitle = "";
|
String infoTitle = "";
|
||||||
String infoText = "";
|
String infoText = "";
|
||||||
@ -95,25 +96,27 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
if (event is MenuCreate) {
|
if (event is MenuCreate) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
//await menuTreeRepository.createTree();
|
//await menuTreeRepository.createTree();
|
||||||
|
//menuTreeRepository.getBranch(this.parent);
|
||||||
setMenuInfo();
|
setMenuInfo();
|
||||||
exerciseDeviceRepository.setDevices(Cache().getDevices());
|
exerciseDeviceRepository.setDevices(Cache().getDevices());
|
||||||
/* exerciseDeviceRepository.getGymDevices().forEach((element) {
|
|
||||||
listFilterDevice.add(element.exerciseDeviceId);
|
|
||||||
}); */
|
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuRecreateTree) {
|
} else if (event is MenuRecreateTree) {
|
||||||
|
yield MenuLoading();
|
||||||
// ie. at language changes
|
// ie. at language changes
|
||||||
await menuTreeRepository.createTree();
|
await menuTreeRepository.createTree();
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuTreeDown) {
|
} else if (event is MenuTreeDown) {
|
||||||
// get child menus or exercises
|
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
parent = event.parent;
|
parent = event.parent;
|
||||||
workoutItem = event.item;
|
workoutItem = event.item;
|
||||||
|
|
||||||
if (workoutItem != null) {
|
if (workoutItem != null) {
|
||||||
setAbility(workoutItem.nameEnglish);
|
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();
|
yield MenuReady();
|
||||||
} else if (event is MenuTreeUp) {
|
} else if (event is MenuTreeUp) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
@ -121,10 +124,13 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
parent = event.parent;
|
parent = event.parent;
|
||||||
workoutItem = menuTreeRepository.getParentItem(parent);
|
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||||
|
|
||||||
|
LinkedHashMap<String, WorkoutMenuTree> branch;
|
||||||
if (workoutItem != null) {
|
if (workoutItem != null) {
|
||||||
menuTreeRepository.getBranch(workoutItem.parent);
|
|
||||||
setAbility(workoutItem.nameEnglish);
|
setAbility(workoutItem.nameEnglish);
|
||||||
|
branch = menuTreeRepository.getBranch(workoutItem.parent);
|
||||||
|
await getImages(branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuTreeJump) {
|
} else if (event is MenuTreeJump) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
@ -132,9 +138,12 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
workoutItem = menuTreeRepository.getParentItem(parent);
|
workoutItem = menuTreeRepository.getParentItem(parent);
|
||||||
|
|
||||||
if (workoutItem != null) {
|
if (workoutItem != null) {
|
||||||
menuTreeRepository.getBranch(workoutItem.parent);
|
|
||||||
setAbility(workoutItem.nameEnglish);
|
setAbility(workoutItem.nameEnglish);
|
||||||
}
|
}
|
||||||
|
final LinkedHashMap<String, WorkoutMenuTree> branch = menuTreeRepository.getBranch(workoutItem.parent);
|
||||||
|
if (branch != null) {
|
||||||
|
await getImages(branch);
|
||||||
|
}
|
||||||
yield MenuReady();
|
yield MenuReady();
|
||||||
} else if (event is MenuClickExercise) {
|
} else if (event is MenuClickExercise) {
|
||||||
yield MenuLoading();
|
yield MenuLoading();
|
||||||
@ -171,6 +180,29 @@ class MenuBloc extends Bloc<MenuEvent, MenuState> with Trans, Logging {
|
|||||||
log("Ability: " + ability.toString() + " name:" + name);
|
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) {
|
bool selectedDevice(int deviceId) {
|
||||||
return !listFilterDevice.contains(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/bloc/settings/settings_bloc.dart';
|
||||||
import 'package:aitrainer_app/localization/app_language.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/service/logging.dart';
|
||||||
import 'package:aitrainer_app/util/session.dart';
|
import 'package:aitrainer_app/util/session.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
@ -41,7 +43,6 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
|||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await this.close();
|
await this.close();
|
||||||
//PlatformPurchaseApi().close();
|
|
||||||
super.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
|
/// Tree view widget library
|
||||||
library tree_view;
|
library tree_view;
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
|
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 {
|
class TreeView extends InheritedWidget {
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
final bool startExpanded;
|
final bool startExpanded;
|
||||||
@ -24,33 +43,77 @@ class TreeView extends InheritedWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
static TreeView of(BuildContext context) {
|
static TreeView of(BuildContext context) {
|
||||||
//return context.inheritFromWidgetOfExactType(TreeView);
|
|
||||||
return context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
|
return context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool updateShouldNotify(TreeView oldWidget) {
|
bool updateShouldNotify(TreeView oldWidget) {
|
||||||
if (oldWidget.children == this.children &&
|
if (oldWidget.children == this.children && oldWidget.startExpanded == this.startExpanded) {
|
||||||
oldWidget.startExpanded == this.startExpanded) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TreeViewData extends StatelessWidget {
|
class _TreeViewData extends StatefulWidget {
|
||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
|
|
||||||
_TreeViewData({
|
_TreeViewData({
|
||||||
this.children,
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
itemCount: children.length,
|
scrollDirection: Axis.vertical,
|
||||||
|
controller: _controller,
|
||||||
|
itemCount: widget.children.length,
|
||||||
itemBuilder: (context, index) {
|
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;
|
bool isExpanded;
|
||||||
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
|
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
|
||||||
Color _color;
|
|
||||||
double _opacity = 0;
|
|
||||||
|
|
||||||
AnimationController _controller;
|
|
||||||
Animation<double> sizeAnimation;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -115,7 +173,8 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return (Column(
|
||||||
|
key: listKey,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
@ -124,27 +183,35 @@ class TreeViewChildState extends State<TreeViewChild> with Common, SingleTicker
|
|||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child:
|
child: AnimatedSwitcher(
|
||||||
AnimatedSwitcher(
|
|
||||||
duration: Duration(milliseconds: 200),
|
duration: Duration(milliseconds: 200),
|
||||||
reverseDuration: Duration(milliseconds: 200),
|
reverseDuration: Duration(milliseconds: 200),
|
||||||
switchInCurve: Curves.easeIn,
|
switchInCurve: Curves.easeIn,
|
||||||
child: isExpanded ? Column(
|
child: isExpanded
|
||||||
|
? Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: widget.children,
|
children: widget.children,
|
||||||
) : Offstage(),
|
)
|
||||||
|
: Offstage(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void toggleExpanded() {
|
void toggleExpanded() {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.isExpanded = !this.isExpanded;
|
this.isExpanded = !this.isExpanded;
|
||||||
_color = isExpanded ? Colors.black12 : Colors.transparent;
|
TreeViewStream().positionY = getPosition();
|
||||||
_opacity = isExpanded ? 1 : 0;
|
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());
|
Flurry.setUserId(customerId.toString());
|
||||||
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
|
final customerDevices = await CustomerExerciseDeviceApi().getDevices(customerId);
|
||||||
Cache().setCustomerDevices(customerDevices);
|
Cache().setCustomerDevices(customerDevices);
|
||||||
await ExerciseTypeApi().getExerciseTypes();
|
|
||||||
|
if (this._exerciseTree == null) {
|
||||||
await ExerciseTreeApi().getExerciseTree();
|
await ExerciseTreeApi().getExerciseTree();
|
||||||
|
}
|
||||||
|
if (this._exerciseTypes == null) {
|
||||||
|
await ExerciseTypeApi().getExerciseTypes();
|
||||||
|
}
|
||||||
|
|
||||||
await ExerciseDeviceApi().getDevices();
|
await ExerciseDeviceApi().getDevices();
|
||||||
|
|
||||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
|
@ -11,7 +11,7 @@ class ExerciseTree {
|
|||||||
ExerciseTree.fromJson(Map json) {
|
ExerciseTree.fromJson(Map json) {
|
||||||
this.treeId = json['treeId'];
|
this.treeId = json['treeId'];
|
||||||
this.name = json['name'];
|
this.name = json['name'];
|
||||||
this.parentId = -1;
|
this.parentId = 0;
|
||||||
this.imageUrl = json['imageUrl'];
|
this.imageUrl = json['imageUrl'];
|
||||||
this.active = json['active'];
|
this.active = json['active'];
|
||||||
this.nameTranslation = json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['name'] : this.name;
|
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') {
|
} else if (e.code == 'weak-password') {
|
||||||
log('The password provided is too weak.');
|
log('The password provided is too weak.');
|
||||||
throw Exception("Password too short");
|
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 {
|
} else {
|
||||||
|
print(e.code);
|
||||||
throw Exception(e);
|
throw Exception(e);
|
||||||
}
|
}
|
||||||
} on WorkoutTestException catch (ex) {
|
} on WorkoutTestException catch (ex) {
|
||||||
|
@ -47,22 +47,12 @@ class WorkoutTreeRepository with Logging {
|
|||||||
Antagonist.calf: Antagonist.calfNr
|
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 {
|
Future<void> createTree() async {
|
||||||
isEnglish = AppLanguage().appLocal == Locale('en');
|
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();
|
List<ExerciseTree> exerciseTree = Cache().getExerciseTree();
|
||||||
if (exerciseTree == null || exerciseTree.length == 0) {
|
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/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
|
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
|
||||||
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
|
|
||||||
class ExerciseTreeApi {
|
class ExerciseTreeApi with Logging {
|
||||||
final APIClient _client = new APIClient();
|
final APIClient _client = new APIClient();
|
||||||
|
|
||||||
Future<List<ExerciseTree>> getExerciseTree() async {
|
Future<List<ExerciseTree>> getExerciseTree() async {
|
||||||
@ -17,23 +18,24 @@ class ExerciseTreeApi {
|
|||||||
exerciseTree = await getExerciseTreeParents(exerciseTree);
|
exerciseTree = await getExerciseTreeParents(exerciseTree);
|
||||||
|
|
||||||
if (exerciseTree != null) {
|
if (exerciseTree != null) {
|
||||||
exerciseTree.forEach((element) async {
|
await Future.forEach(exerciseTree, (element) async {
|
||||||
element.imageUrl = await _buildImage(element.imageUrl);
|
//exerciseTree.forEach((element) async {
|
||||||
|
element.imageUrl = await _buildImage(element.imageUrl, element.treeId);
|
||||||
});
|
});
|
||||||
}
|
log("ExerciseTree downloaded");
|
||||||
Cache().setExerciseTree(exerciseTree);
|
Cache().setExerciseTree(exerciseTree);
|
||||||
|
}
|
||||||
|
|
||||||
return exerciseTree;
|
return exerciseTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _buildImage(String imageUrl) async {
|
Future<String> _buildImage(String imageUrl, int treeId) async {
|
||||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
//print("Loading image " + assetImage);
|
return await rootBundle.load(assetImage).then((value) {
|
||||||
return rootBundle.load(assetImage).then((value) {
|
|
||||||
return assetImage;
|
return assetImage;
|
||||||
}).catchError((_) {
|
}).catchError((_) {
|
||||||
String imagePath = assetImage.substring(10);
|
String imagePath = assetImage.substring(10);
|
||||||
String url = Cache.mediaUrl + 'images' + imagePath;
|
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||||
//print("Exception: " + assetImage + " will be loaded from the network " + url);
|
|
||||||
return url;
|
return url;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:aitrainer_app/library/image_cache.dart';
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/service/api.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();
|
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
||||||
if (exerciseTypes != null) {
|
if (exerciseTypes != null) {
|
||||||
exerciseTypes.forEach((element) async {
|
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;
|
return exerciseTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> _buildImage(String imageUrl) async {
|
Future<String> _buildImage(String imageUrl, int exerciseTypeId) async {
|
||||||
if (imageUrl.length > 8) {
|
if (imageUrl.length > 8) {
|
||||||
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
return rootBundle.load(assetImage).then((value) {
|
return rootBundle.load(assetImage).then((value) {
|
||||||
@ -29,7 +33,6 @@ class ExerciseTypeApi with Logging {
|
|||||||
}).catchError((_) {
|
}).catchError((_) {
|
||||||
String imagePath = assetImage.substring(10);
|
String imagePath = assetImage.substring(10);
|
||||||
String url = Cache.mediaUrl + 'images' + imagePath;
|
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||||
//print("Exception: " + assetImage + " will be loaded from the network " + url);
|
|
||||||
return url;
|
return url;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -267,7 +267,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
|
|||||||
"times!",
|
"times!",
|
||||||
);
|
);
|
||||||
|
|
||||||
String title = step.toString() + ". " + t("Control Exercise:");
|
String title = (step + 1).toString() + "/4 " + t("Control Exercise:");
|
||||||
LinkedHashMap args = LinkedHashMap();
|
LinkedHashMap args = LinkedHashMap();
|
||||||
|
|
||||||
List<Widget> listWidgets = [
|
List<Widget> listWidgets = [
|
||||||
|
@ -195,7 +195,7 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
|
|||||||
Text(
|
Text(
|
||||||
exerciseDescription,
|
exerciseDescription,
|
||||||
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
|
style: GoogleFonts.inter(fontSize: 12, color: Colors.yellow[300]),
|
||||||
maxLines: 4,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
),
|
),
|
||||||
@ -231,10 +231,21 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
|
|||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
),
|
),
|
||||||
columnQuantity(exerciseBloc),
|
columnQuantity(exerciseBloc),
|
||||||
Divider(),
|
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.transparent,
|
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(
|
Divider(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
),
|
),
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||||
|
|
||||||
import 'package:aitrainer_app/widgets/app_bar.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:aitrainer_app/widgets/menu_page_widget.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class MenuPage extends StatefulWidget {
|
class MenuPage extends StatefulWidget {
|
||||||
static const routeName = '/menu_page';
|
|
||||||
int parent;
|
int parent;
|
||||||
|
|
||||||
MenuPage({this.parent});
|
MenuPage({this.parent});
|
||||||
@ -24,12 +20,19 @@ class _MenuPage extends State<MenuPage> {
|
|||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
MenuBloc menuBloc;
|
MenuBloc menuBloc;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
menuBloc.parent = widget.parent;
|
menuBloc.parent = widget.parent;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBarNav(isMenu: true,),
|
appBar: AppBarNav(
|
||||||
|
isMenu: true,
|
||||||
|
),
|
||||||
body: Container(
|
body: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
@ -38,67 +41,14 @@ class _MenuPage extends State<MenuPage> {
|
|||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: BlocConsumer<MenuBloc, MenuState>(
|
child: BlocConsumer<MenuBloc, MenuState>(listener: (context, state) {
|
||||||
listener: (context, state) {
|
|
||||||
if (state is MenuError) {
|
if (state is MenuError) {
|
||||||
Scaffold.of(context).showSnackBar(SnackBar(
|
Scaffold.of(context).showSnackBar(
|
||||||
backgroundColor: Colors.orange,
|
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||||
content: Text(state.message, style: TextStyle(color: Colors.white))));
|
}
|
||||||
} else if ( state is MenuLoading ) {
|
}, builder: (context, state) {
|
||||||
return MenuPageWidget();
|
return MenuPageWidget();
|
||||||
}
|
})),
|
||||||
},
|
bottomNavigationBar: BottomNavigator(bottomNavIndex: 0));
|
||||||
// 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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
builder: (BuildContext context) {
|
||||||
return DialogPremium(
|
return DialogPremium(
|
||||||
unlocked: Cache().hasPurchased,
|
unlocked: Cache().hasPurchased,
|
||||||
unlockRound: 1,
|
unlockRound: 2,
|
||||||
function: "Suggested Training Plan",
|
function: "Suggested Training Plan",
|
||||||
unlockedText: null,
|
unlockedText: null,
|
||||||
onTap: () => {Navigator.of(context).pop()},
|
onTap: () => {Navigator.of(context).pop()},
|
||||||
|
@ -149,7 +149,7 @@ class SalesPage extends StatelessWidget with Trans, Logging {
|
|||||||
|
|
||||||
bloc.product2Display.forEach((element) {
|
bloc.product2Display.forEach((element) {
|
||||||
final String title = element.sort == 3 ? t("Montly") : t("Annual");
|
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;
|
String badge;
|
||||||
if (element.sort == 2) {
|
if (element.sort == 2) {
|
||||||
badge = t("14% discount");
|
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/model/cache.dart';
|
||||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||||
import 'package:aitrainer_app/util/common.dart';
|
import 'package:aitrainer_app/util/common.dart';
|
||||||
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@ -12,6 +13,8 @@ import 'package:google_fonts/google_fonts.dart';
|
|||||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||||
import 'package:rainbow_color/rainbow_color.dart';
|
import 'package:rainbow_color/rainbow_color.dart';
|
||||||
|
|
||||||
|
import 'dialog_html.dart';
|
||||||
|
|
||||||
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
||||||
final MenuBloc menuBloc;
|
final MenuBloc menuBloc;
|
||||||
final bool isMenu;
|
final bool isMenu;
|
||||||
@ -146,6 +149,9 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
|||||||
percent = 0;
|
percent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (percent == null) {
|
||||||
|
percent = 0;
|
||||||
|
}
|
||||||
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
|
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
|
||||||
if (sizeExerciseList == 0) {
|
if (sizeExerciseList == 0) {
|
||||||
String text = AppLocalizations.of(context).translate("Make your first test");
|
String text = AppLocalizations.of(context).translate("Make your first test");
|
||||||
@ -155,13 +161,21 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
|||||||
text,
|
text,
|
||||||
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple, blurRadius: 15)]),
|
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple, blurRadius: 15)]),
|
||||||
),
|
),
|
||||||
//TestProgress(animation: sizeAnim),
|
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.topLeft,
|
alignment: Alignment.topLeft,
|
||||||
children: [
|
children: [
|
||||||
LinearPercentIndicator(
|
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,
|
width: cWidth / 4,
|
||||||
lineHeight: 14.0,
|
lineHeight: 14.0,
|
||||||
percent: percent,
|
percent: percent,
|
||||||
@ -178,6 +192,7 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
|||||||
progressColor: Color(0xff73e600),
|
progressColor: Color(0xff73e600),
|
||||||
animation: true,
|
animation: true,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,13 @@ class _BMIState extends State<BMI> with Trans {
|
|||||||
style: GoogleFonts.archivoBlack(
|
style: GoogleFonts.archivoBlack(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.orange[200],
|
color: Colors.orange[200],
|
||||||
|
shadows: <Shadow>[
|
||||||
|
Shadow(
|
||||||
|
offset: Offset(2.0, 2.0),
|
||||||
|
blurRadius: 5.0,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
],
|
||||||
)),
|
)),
|
||||||
Text(
|
Text(
|
||||||
t("Bodyweight") +
|
t("Bodyweight") +
|
||||||
@ -183,16 +190,37 @@ class _BMIState extends State<BMI> with Trans {
|
|||||||
style: GoogleFonts.archivoBlack(
|
style: GoogleFonts.archivoBlack(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.orange[200],
|
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),
|
Text("BMI" + " " + t("goal") + ": " + widget.exerciseBloc.goalBMI.toStringAsFixed(1),
|
||||||
style: GoogleFonts.archivoBlack(
|
style: GoogleFonts.archivoBlack(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.orange[500],
|
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",
|
Text(t("Bodyweight") + " " + t("goal") + ": " + widget.exerciseBloc.goalWeight.toStringAsFixed(0) + " kg",
|
||||||
style: GoogleFonts.archivoBlack(
|
style: GoogleFonts.archivoBlack(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: Colors.orange[500],
|
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,
|
fontSize: 30,
|
||||||
color: Colors.orange[300],
|
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),
|
SizedBox(height: 20),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(left: 35, right: 35),
|
padding: EdgeInsets.only(left: 35, right: 35),
|
||||||
@ -189,7 +200,7 @@ class _BMRState extends State<BMR> with Trans {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
focusNode: _nodeText2,
|
focusNode: _nodeText2,
|
||||||
decoration: InputDecoration(
|
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"),
|
labelText: AppLocalizations.of(context).translate("Actual Height"),
|
||||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||||
fillColor: Colors.black38,
|
fillColor: Colors.black38,
|
||||||
@ -216,7 +227,7 @@ class _BMRState extends State<BMR> with Trans {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
focusNode: _nodeText3,
|
focusNode: _nodeText3,
|
||||||
decoration: InputDecoration(
|
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"),
|
labelText: AppLocalizations.of(context).translate("Birth Year"),
|
||||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||||
fillColor: Colors.black38,
|
fillColor: Colors.black38,
|
||||||
@ -338,7 +349,7 @@ class _BMRState extends State<BMR> with Trans {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
focusNode: _nodeText1,
|
focusNode: _nodeText1,
|
||||||
decoration: InputDecoration(
|
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"),
|
labelText: AppLocalizations.of(context).translate("Actual Weight"),
|
||||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||||
fillColor: Colors.black38,
|
fillColor: Colors.black38,
|
||||||
|
@ -40,7 +40,7 @@ class _DialogPremiumState extends State<DialogHTML> with Trans {
|
|||||||
borderRadius: BorderRadius.circular(24),
|
borderRadius: BorderRadius.circular(24),
|
||||||
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
|
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: AssetImage('asset/image/WT_black_G_background.png'),
|
image: AssetImage('asset/image/WT_results_background.jpg'),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
),
|
),
|
||||||
|
@ -256,7 +256,11 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
|||||||
list.add(TextSpan(text: t(" ")));
|
list.add(TextSpan(text: t(" ")));
|
||||||
list.add(
|
list.add(
|
||||||
TextSpan(
|
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(
|
style: GoogleFonts.inter(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
@ -89,6 +89,5 @@ class _HomePageState extends State<AitrainerHome> with Logging {
|
|||||||
@override
|
@override
|
||||||
void dispose() async {
|
void dispose() async {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
//await PlatformPurchaseApi().close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'dart:async';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
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/service/logging.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||||
|
import 'package:auto_animated/auto_animated.dart';
|
||||||
import 'package:badges/badges.dart';
|
import 'package:badges/badges.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:transparent_image/transparent_image.dart';
|
||||||
|
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||||
|
|
||||||
import 'dialog_html.dart';
|
import 'dialog_html.dart';
|
||||||
import 'menu_info_widget.dart';
|
import 'menu_info_widget.dart';
|
||||||
@ -35,35 +39,33 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
final double baseHeight = 675.2;
|
final double baseHeight = 675.2;
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
bool wait = false;
|
bool wait = false;
|
||||||
Timer _timer, _waitTimer;
|
MenuBloc menuBloc;
|
||||||
|
final scrollController = ScrollController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
isFirst = true;
|
isFirst = true;
|
||||||
_timer = Timer.periodic(
|
|
||||||
Duration(milliseconds: 800),
|
/// We require the initializers to run after the loading screen is rendered
|
||||||
(Timer timer) => setState(() {
|
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||||
if (!wait) {
|
menuBloc.add(MenuCreate());
|
||||||
isFirst = !isFirst;
|
});
|
||||||
//wait = true;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
_waitTimer = Timer.periodic(
|
|
||||||
Duration(milliseconds: 5000),
|
|
||||||
(Timer timer) => setState(() {
|
|
||||||
wait = !wait;
|
|
||||||
}));
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||||
setContext(context);
|
setContext(context);
|
||||||
double cWidth = MediaQuery.of(context).size.width;
|
double cWidth = MediaQuery.of(context).size.width;
|
||||||
double cHeight = MediaQuery.of(context).size.height;
|
double cHeight = MediaQuery.of(context).size.height;
|
||||||
|
|
||||||
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) {
|
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) {
|
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
|
||||||
WorkoutMenuTree workoutTree = value;
|
WorkoutMenuTree workoutTree = value;
|
||||||
_columnChildren.add(Container(
|
_columnChildren.add(Container(
|
||||||
padding: EdgeInsets.only(top: 15.0, left: 15, right: 15),
|
padding: EdgeInsets.only(top: 15.0, left: cWidth * 0.04, right: cWidth * 0.04),
|
||||||
height: 225, //cHeight / 3 * distortionHeight,
|
height: (cHeight / 3) - cWidth * 0.16,
|
||||||
child: Badge(
|
child: Badge(
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
position: BadgePosition.bottomEnd(end: 0),
|
position: BadgePosition.bottomEnd(end: 0),
|
||||||
@ -141,9 +143,16 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
])))));
|
])))));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//delegate: SliverChildListDelegate(_columnChildren),
|
||||||
SliverList sliverList = SliverList(
|
LiveSliverList sliverList = LiveSliverList(
|
||||||
delegate: SliverChildListDelegate(_columnChildren),
|
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);
|
slivers.add(sliverList);
|
||||||
@ -332,33 +341,51 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
|
Widget _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
|
||||||
Widget image;
|
//print("_getButtonImage " + workoutTree.imageName);
|
||||||
|
String imageString = menuBloc.getImage(workoutTree.id, workoutTree.imageName);
|
||||||
if (workoutTree.imageName.startsWith('https')) {
|
Widget widget;
|
||||||
image = ClipRRect(
|
if (imageString != null) {
|
||||||
|
print(" -- get Image from MEMORY " + workoutTree.imageName);
|
||||||
|
widget = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(24.0),
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.black87,
|
color: Colors.transparent,
|
||||||
child: FadeInImage(
|
child: FadeInImage(
|
||||||
image: NetworkImage(workoutTree.imageName),
|
fadeInDuration: Duration(milliseconds: 100),
|
||||||
placeholder: AssetImage("asset/image/dots.gif"),
|
image: MemoryImage(base64Decode(imageString)),
|
||||||
|
placeholder: MemoryImage(kTransparentImage),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
image = Container(
|
if (workoutTree.imageName.contains("https")) {
|
||||||
//width: cWidth - 30,
|
if (!wt.ImageCache().existsImageInMap(workoutTree.id, workoutTree.imageName)) {
|
||||||
//height: 210.0,
|
print(" -- get Image from network " + workoutTree.imageName);
|
||||||
decoration: BoxDecoration(
|
widget = ClipRRect(
|
||||||
image: DecorationImage(
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
fit: BoxFit.cover,
|
child: Container(
|
||||||
image: AssetImage(workoutTree.imageName),
|
color: Colors.transparent,
|
||||||
|
child: FadeInImage(
|
||||||
|
fadeInDuration: Duration(milliseconds: 500),
|
||||||
|
image: NetworkImage(workoutTree.imageName),
|
||||||
|
placeholder: MemoryImage(kTransparentImage),
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.all(Radius.circular(24.0)),
|
));
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return image;
|
//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 widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget badgedIcon(WorkoutMenuTree workoutMenuTree, double cWidth, double cHeight) {
|
Widget badgedIcon(WorkoutMenuTree workoutMenuTree, double cWidth, double cHeight) {
|
||||||
@ -380,7 +407,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
)),
|
)),
|
||||||
child: buttonImage == null
|
child: buttonImage == null
|
||||||
? Container(
|
? Container(
|
||||||
color: Colors.red,
|
color: Colors.transparent,
|
||||||
)
|
)
|
||||||
: buttonImage,
|
: buttonImage,
|
||||||
);
|
);
|
||||||
@ -388,8 +415,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_timer.cancel();
|
|
||||||
_waitTimer.cancel();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
68
pubspec.lock
@ -50,6 +50,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0-nullsafety.1"
|
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:
|
badges:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -112,7 +119,7 @@ packages:
|
|||||||
name: build_runner
|
name: build_runner
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.13"
|
version: "1.11.0"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -161,7 +168,7 @@ packages:
|
|||||||
name: chewie
|
name: chewie
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.1+1"
|
version: "0.12.2"
|
||||||
chewie_audio:
|
chewie_audio:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -404,7 +411,7 @@ packages:
|
|||||||
name: flutter_facebook_auth
|
name: flutter_facebook_auth
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0+1"
|
version: "2.0.1"
|
||||||
flutter_facebook_auth_platform_interface:
|
flutter_facebook_auth_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -419,6 +426,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
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:
|
flutter_form_bloc:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -453,12 +467,19 @@ packages:
|
|||||||
name: flutter_layout_grid
|
name: flutter_layout_grid
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.3"
|
version: "0.10.5"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
flutter_svg:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -496,7 +517,7 @@ packages:
|
|||||||
name: google_fonts
|
name: google_fonts
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.2"
|
||||||
google_sign_in:
|
google_sign_in:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -650,7 +671,7 @@ packages:
|
|||||||
name: mockito
|
name: mockito
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.3"
|
version: "4.1.4"
|
||||||
modal_progress_hud:
|
modal_progress_hud:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -665,6 +686,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4"
|
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:
|
node_interop:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -685,7 +713,7 @@ packages:
|
|||||||
name: node_preamble
|
name: node_preamble
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.12"
|
version: "1.4.13"
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -804,7 +832,7 @@ packages:
|
|||||||
name: provider
|
name: provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.2+4"
|
version: "4.3.3"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -825,7 +853,7 @@ packages:
|
|||||||
name: purchases_flutter
|
name: purchases_flutter
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.2"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -860,7 +888,7 @@ packages:
|
|||||||
name: sentry
|
name: sentry
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.3"
|
version: "4.0.4"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -902,7 +930,7 @@ packages:
|
|||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1+3"
|
version: "0.0.2+2"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -984,7 +1012,7 @@ packages:
|
|||||||
name: sqflite_common
|
name: sqflite_common
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "1.0.3+1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1076,6 +1104,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.8"
|
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:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1118,6 +1153,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.4+1"
|
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:
|
vm_service:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -1159,7 +1201,7 @@ packages:
|
|||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.0"
|
||||||
webkit_inspection_protocol:
|
webkit_inspection_protocol:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
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.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.1.5+48
|
version: 1.1.5+49
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
@ -50,6 +50,7 @@ dependencies:
|
|||||||
wakelock: ^0.2.1+1
|
wakelock: ^0.2.1+1
|
||||||
timeline_tile: ^1.0.0
|
timeline_tile: ^1.0.0
|
||||||
purchases_flutter: ^2.0.0
|
purchases_flutter: ^2.0.0
|
||||||
|
network_image_to_byte: ^0.0.1
|
||||||
|
|
||||||
|
|
||||||
firebase_core: ^0.5.0
|
firebase_core: ^0.5.0
|
||||||
@ -60,13 +61,17 @@ dependencies:
|
|||||||
google_sign_in: ^4.5.9
|
google_sign_in: ^4.5.9
|
||||||
apple_sign_in: ^0.1.0
|
apple_sign_in: ^0.1.0
|
||||||
crypto: ^2.1.5
|
crypto: ^2.1.5
|
||||||
|
transparent_image: ^1.0.0
|
||||||
|
flutter_fadein: ^1.1.1
|
||||||
|
auto_animated: ^2.1.0
|
||||||
|
|
||||||
flurry: ^0.0.7
|
flurry: ^0.0.7
|
||||||
|
|
||||||
animated_widgets: ^1.0.6
|
animated_widgets: ^1.0.6
|
||||||
|
|
||||||
mockito: ^4.1.3
|
mockito: ^4.1.3
|
||||||
sqflite: ^1.3.0
|
sqflite: ^1.3.2+2
|
||||||
|
flutter_secure_storage: ^3.3.5
|
||||||
|
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
@ -126,10 +131,7 @@ flutter:
|
|||||||
- asset/image/WT_black_background.png
|
- asset/image/WT_black_background.png
|
||||||
- asset/image/WT_black_G_background.png
|
- asset/image/WT_black_G_background.png
|
||||||
- asset/image/WT_plainblack_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_login.png
|
||||||
- asset/image/WT_OK.png
|
|
||||||
- asset/image/dots.gif
|
- asset/image/dots.gif
|
||||||
- asset/image/WT_long_logo.png
|
- asset/image/WT_long_logo.png
|
||||||
- asset/image/WT_light_background.png
|
- asset/image/WT_light_background.png
|
||||||
@ -142,11 +144,11 @@ flutter:
|
|||||||
- asset/image/WT_Results_for_runners.png
|
- asset/image/WT_Results_for_runners.png
|
||||||
- asset/image/WT_Results_for_female.png
|
- asset/image/WT_Results_for_female.png
|
||||||
- asset/image/WT_Results_for_men.png
|
- asset/image/WT_Results_for_men.png
|
||||||
|
- asset/image/WT_results_background.jpg
|
||||||
- asset/image/button_fb.png
|
- asset/image/button_fb.png
|
||||||
- asset/image/button_apple.png
|
- asset/image/button_apple.png
|
||||||
- asset/image/button_google.png
|
- asset/image/button_google.png
|
||||||
- asset/image/lock.png
|
- asset/image/lock.png
|
||||||
- asset/image/Congrats_N1.jpg
|
|
||||||
- asset/image/testemfejl400x400.jpg
|
- asset/image/testemfejl400x400.jpg
|
||||||
- asset/image/izomcsop400400.jpg
|
- asset/image/izomcsop400400.jpg
|
||||||
- asset/image/edzesnaplom400400.jpg
|
- asset/image/edzesnaplom400400.jpg
|
||||||
@ -159,7 +161,6 @@ flutter:
|
|||||||
- asset/image/man_sizes.png
|
- asset/image/man_sizes.png
|
||||||
- asset/image/woman_sizes.png
|
- asset/image/woman_sizes.png
|
||||||
- asset/image/merleg.png
|
- asset/image/merleg.png
|
||||||
- asset/image/BMI_diagram_b.png
|
|
||||||
- asset/image/BMI_graph_c.png
|
- asset/image/BMI_graph_c.png
|
||||||
- asset/image/BMI_mutato.png
|
- asset/image/BMI_mutato.png
|
||||||
- asset/image/equipment_specialshome.jpg
|
- asset/image/equipment_specialshome.jpg
|
||||||
@ -201,38 +202,23 @@ flutter:
|
|||||||
- asset/image/pict_time_h.png
|
- asset/image/pict_time_h.png
|
||||||
- asset/image/pict_hypertrophy.png
|
- asset/image/pict_hypertrophy.png
|
||||||
- asset/image/pict_weight_volumen_tonna.png
|
- asset/image/pict_weight_volumen_tonna.png
|
||||||
- asset/menu/1.cardio.png
|
|
||||||
- asset/menu/1.1.aerob.png
|
- asset/menu/1.cardio.jpg
|
||||||
- asset/menu/1.2.anaerob.png
|
- asset/menu/1.1.aerob.jpg
|
||||||
- asset/menu/1.1.1.cooper.png
|
- asset/menu/1.2.anaerob.jpg
|
||||||
- asset/menu/1.2.1.300m.png
|
- asset/menu/2.strength.jpg
|
||||||
- asset/menu/1.2.2.400m.png
|
- asset/menu/2.1.endurance.jpg
|
||||||
- asset/menu/2.strength.png
|
- asset/menu/2.1.6.core.jpg
|
||||||
- asset/menu/2.1.endurance.png
|
- asset/menu/2.1.1.1RM.jpg
|
||||||
- asset/menu/2.1.1.pull-ups.png
|
- asset/menu/2.2.1.1.chest.jpg
|
||||||
- asset/menu/2.1.2.pushup.png
|
- asset/menu/2.2.1.3.biceps.jpg
|
||||||
- asset/menu/2.1.3.sit-ups.png
|
- asset/menu/2.2.1.4.triceps.jpg
|
||||||
- asset/menu/2.1.4.squats.png
|
- asset/menu/2.2.1.5.shoulders.jpg
|
||||||
- asset/menu/2.1.5.timedpushup.png
|
- asset/menu/2.2.1.6.thigh.jpg
|
||||||
- asset/menu/2.1.6.core.png
|
- asset/menu/2.2.1.7.back.jpg
|
||||||
- asset/menu/2.2.1.1RM.png
|
- asset/menu/2.2.1.8.calf.jpg
|
||||||
- asset/menu/2.2.1.1.chestpress.png
|
- asset/menu/3.bcs1.jpg
|
||||||
- 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
|
|
||||||
- i18n/en.json
|
- i18n/en.json
|
||||||
- i18n/hu.json
|
- i18n/hu.json
|
||||||
|
|
||||||
|