WT 1.26
This commit is contained in:
parent
dfeac33176
commit
3b96d81a85
@ -33,7 +33,7 @@ if (keystorePropertiesFile.exists()) {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
compileSdkVersion 31
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
|
@ -5,8 +5,18 @@
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application android:name="io.flutter.app.FlutterApplication" android:label="WorkoutTest" android:icon="@mipmap/launcher_icon">
|
||||
<activity android:name="com.aitrainer.aitrainer_app.MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:allowBackup="false" android:fullBackupContent="false">
|
||||
<application
|
||||
android:name="${applicationName}"
|
||||
android:label="WorkoutTest"
|
||||
android:icon="@mipmap/launcher_icon">
|
||||
<activity android:name="io.flutter.embedding.android.FlutterActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:allowBackup="false"
|
||||
android:fullBackupContent="false">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
|
@ -1,5 +0,0 @@
|
||||
package com.aitrainer.aitrainer_app
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity()
|
@ -1,5 +1,5 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.4.21'
|
||||
ext.kotlin_version = "1.6.10"
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 648 KiB After Width: | Height: | Size: 109 KiB |
324
i18n/en.csv
324
i18n/en.csv
@ -1,324 +0,0 @@
|
||||
39;39;en;Apple Sign In failure: email address is necessary
|
||||
40;40;en;There is an error: during registration:
|
||||
41;41;en;Cardio
|
||||
42;42;en;400m
|
||||
43;43;en;300m
|
||||
44;44;en;Aerobic
|
||||
45;45;en;Anaerobic
|
||||
46;46;en;Cooper
|
||||
47;47;en;Strength
|
||||
48;48;en;Strength Endurance
|
||||
49;49;en;Pushups
|
||||
50;50;en;Timed Pushups
|
||||
51;51;en;Core
|
||||
52;52;en;Squats
|
||||
53;53;en;Sit-ups
|
||||
54;54;en;1RM
|
||||
55;55;en;Chest Press
|
||||
56;56;en;Pull Ups
|
||||
57;57;en;Biceps
|
||||
58;58;en;Triceps
|
||||
59;59;en;Shoulders
|
||||
60;60;en;Body Compositions
|
||||
61;61;en;BMI
|
||||
62;62;en;BMR
|
||||
63;63;en;Sizes
|
||||
64;64;en;Save Exercise of:
|
||||
65;65;en;Delete
|
||||
66;66;en;<p>The essence of the endurance test is also to suggest the right WEIGHT and number of REPETATIONS for you. It is very important to do the test properly with the requested repetition! If your goal is to maintain long-term strength or you are an athlete, be sure to complete our endurance module as well.</p><p><b>Why endurance?</b></p><p>It improves the oxygen and nutrients supply of the muscles therefore you will be able to move more weights on a longer distance (e.g.: push-ups or pull-ups). It has less weight gain effect, it rather results a more athletic and strong physique if you exercise in a long term.</p>
|
||||
67;67;en;<p>Knowing the maximum of one repetition which also known as 1RM, can be important to you in calculating the right WEIGHT and REPEAT for you. Execute the test correctly!</p><p>This way we can suggest the weights and repetitions that are best for you later. If building muscle or strength is your goal, it is essential to do the 1RM tests!</p><p><b>What is 1RM?</b></p><p>This is the weight what you are able to move at once properly. Upon the maximum weight exercise is performed correctly, we can derive the weight and number of repetitions which fits to your goals.</p>
|
||||
68;68;en;Name
|
||||
69;69;en;Exercise
|
||||
70;70;en;Quantity
|
||||
71;71;en;Unit
|
||||
72;72;en;Exercise date and time
|
||||
73;73;en;Please type the right quantity 0-10000
|
||||
74;74;en;Yes
|
||||
75;75;en;No
|
||||
76;76;en;with
|
||||
77;77;en;Do you save this exercise with these parameters?
|
||||
78;78;en;The number of the exercise
|
||||
79;79;en;The number of the exercise done with
|
||||
80;80;en;Please repeat with
|
||||
81;81;en;Execute the
|
||||
82;82;en;set!
|
||||
83;83;en;repeat
|
||||
84;84;en;meter
|
||||
85;85;en;percent
|
||||
86;86;en;kg
|
||||
87;87;en;kilogram
|
||||
88;88;en;lbs
|
||||
89;89;en;second
|
||||
90;90;en;Email
|
||||
91;91;en;Password
|
||||
92;92;en;OR
|
||||
93;93;en;Password (Leave empty if no change)
|
||||
94;94;en;First Name
|
||||
95;95;en;Birth Year
|
||||
96;96;en;Weight
|
||||
97;97;en;Gender
|
||||
98;98;en;Man
|
||||
99;99;en;Woman
|
||||
100;100;en;Next
|
||||
101;101;en;Select a gender
|
||||
102;102;en;Set Your Goals
|
||||
103;103;en;Gain Muscle
|
||||
104;104;en;Loose Weight
|
||||
105;105;en;Your Fitness State
|
||||
106;106;en;Fitness level
|
||||
107;107;en;Fitness Activity
|
||||
108;108;en;Beginner
|
||||
109;109;en;I am beginner
|
||||
110;110;en;Intermediate
|
||||
111;111;en;1-3 times a week
|
||||
112;112;en;Advanced
|
||||
113;113;en;4+ times a week
|
||||
114;114;en;Professional
|
||||
115;115;en;I am a professional
|
||||
116;116;en;No item selected
|
||||
117;117;en;Your Body Type
|
||||
118;118;en;Ectomorph
|
||||
119;119;en;Endomorph
|
||||
120;120;en;Mesomorph
|
||||
121;121;en;Ecto-Mesomorph
|
||||
122;122;en;Meso-Endomorph
|
||||
123;123;en;<p>Ectomorph is your body type if:<p><ul><li>You have basically a thin physique like a long-distance runner</li><li>Long limbs and narrow shoulders are typical of you</li><li>You have difficulties to build muscles</li><li>If your chest and waist are almost the same width</li><li>You lose muscle easily</li><li>You have a relatively low body fat percentage</li></ul><br/><br/><p>We can’t talk about 100% matching of course but this data is very important for personalization. It happens sometime that an ectomorph can has excess fat. In this case, the thinness of joints and the behaviour of muscles are the crucial aspect.</p>
|
||||
124;124;en;<p>This is your body type if you feel that your physique is the sharp opposite of ectomorph and:</p><ul><li>Despite of your strong-looking physique, your muscles are less visually outlined</li><li>Getting rid of excess fat is difficult for you</li><li>You get stronger very easily</li><li>Your rib cage is wide and large</li><li>You have thick and strong joints</li><li>If your hips are wide and strong</li></ul><p>We can’t talk about 100% matching here too of course but this data is very important for personalization. It can happen that an endomorph is difficult to distinguish from a mesomorph.</p><p>In this case, check the size of the rib cage and the waist. From a side view, a mesomorph may have a flatter chest and abdomen compared to an originally strong and fleshy endomorph. All apple and pear shape are considered as endomorph.</p>
|
||||
125;125;en;<p>This is your body type if:</p><ul><li>You have an athletic physique like a sprinter, swimmer or gymnast</li><li>Wide clavicles and shoulders are typical of you</li><li>Your body is symmetrical</li><li>You have narrow hips and sporty, narrow waist</li><li>You have basically thinner joints but strong bones</li><li>Mesomorphs are more muscular than ectomorphs</li><li>You get muscular quickly</li><li>A mesomorph person has thicker bones and joints than an ectomorph</li><li>Your chest is wide compared to your waist</li><li>You have stronger calves and forearms than an ectomorph</li></ul><p>We can’t talk about 100% matching here too of course but this data is very important for personalisation. A mesomorph person can also has excess fat. In this case, the hip/chest ratio and behaviour of muscles are the deciding factors.</p>
|
||||
126;126;en;Description
|
||||
127;127;en;Make your first test
|
||||
128;128;en;finished
|
||||
129;129;en;-
|
||||
130;130;en;Your 1RM:
|
||||
131;131;en;Your Real 1RM:
|
||||
132;132;en;Check
|
||||
133;133;en;Test Exercise:
|
||||
134;134;en;Summary of your test
|
||||
135;135;en;Test
|
||||
136;136;en;1st Test Exercise
|
||||
137;137;en;2nd Test Exercise
|
||||
138;138;en;3rd Test Exercise
|
||||
139;139;en;Development
|
||||
140;140;en;Training Plan
|
||||
141;141;en;Please add an exercise plan
|
||||
142;142;en;Serie
|
||||
143;143;en;Repeats
|
||||
144;144;en;Save The Exercise To The Exercise Plan
|
||||
145;145;en;The number of the serie done with
|
||||
146;146;en;The number of the repeats of one serie
|
||||
147;147;en;reps
|
||||
148;148;en;1. Chest
|
||||
149;149;en;2. Biceps
|
||||
150;150;en;3. Triceps
|
||||
151;151;en;4. Back
|
||||
152;152;en;5. Shoulders
|
||||
153;153;en;6. Core
|
||||
154;154;en;7. Thigh
|
||||
155;155;en;8. Calf
|
||||
156;156;en;Execute My Selected Training Plan
|
||||
157;157;en;Create My Custom Plan
|
||||
158;158;en;Suggested Training Plan
|
||||
159;159;en;My Special Plan
|
||||
160;160;en;Training Programs
|
||||
161;161;en;My Trainee's Plan
|
||||
162;162;en;Execute My Trainee's Training Plan
|
||||
163;163;en;My Exercise Logs
|
||||
164;164;en;My Whole Body Development
|
||||
165;165;en;Development Of Muscles
|
||||
166;166;en;Predictions
|
||||
167;167;en;My Trainee's Exercise Logs
|
||||
168;168;en;My Development By Muscle
|
||||
169;169;en;Here you see your development in the last period.
|
||||
170;170;en;Sum Of Mass
|
||||
171;171;en;Percent
|
||||
172;172;en;One Rep Max
|
||||
173;173;en;One Rep Max
|
||||
174;174;en;<p>Knowing the maximum of one repetition which also known as 1RM, can be important to you in calculating the right WEIGHT and REPEAT for you. Execute the test correctly!</p><p>This way we can suggest the weights and repetitions that are best for you later. If building muscle or strength is your goal, it is essential to do the 1RM tests!</p><p><b>What is 1RM?</b></p><p>This is the weight what you are able to move at once properly. Upon the maximum weight exercise is performed correctly, we can derive the weight and number of repetitions which fits to your goals.</p>
|
||||
175;175;en;Detailed
|
||||
176;176;en;Weekly
|
||||
177;177;en;Monthly
|
||||
178;178;en;Yearly
|
||||
179;179;en;times!
|
||||
180;180;en;Please repeat with
|
||||
181;181;en;max times!
|
||||
182;182;en;Execute your active Exercise Plan!
|
||||
183;183;en;Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.
|
||||
184;184;en;Custom Exercise Plan
|
||||
185;185;en;Select manually the exercises what you would like to have in your plan. At the end don't forget to save.
|
||||
186;186;en;In this list you can find all your completed exercises sorted by the date.
|
||||
187;187;en;Persistence!
|
||||
188;188;en;Greetings!
|
||||
189;189;en;The purpose is to measure your physical condition. Your first goal is to test all your muscle regions with a 'base' exercise.
|
||||
190;190;en;Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.
|
||||
191;191;en;Please continue your tests with a
|
||||
192;192;en;I suggest begin your tests with a 'chest' exercise
|
||||
193;193;en;Nice! This is a good start
|
||||
194;194;en;Go on!
|
||||
195;195;en;You are on track
|
||||
196;196;en;Not so much left
|
||||
197;197;en;Almost done!
|
||||
198;198;en;You have only 1-2 exercise left to finish!
|
||||
199;199;en;exercise!
|
||||
200;200;en;Chest
|
||||
201;201;en;Back
|
||||
202;202;en;Thigh
|
||||
203;203;en;Calf
|
||||
204;204;en;Bring me there
|
||||
205;205;en;My Body Development
|
||||
206;206;en;You see here your whole body development by muscle groups.
|
||||
207;207;en;Are you sure to logout?
|
||||
208;208;en;
|
||||
209;209;en;Are you sure to delete this exercise?
|
||||
210;210;en;I forgot the password
|
||||
211;211;en;Customer with the email not found. Please register or reset your password
|
||||
212;212;en;Customer does not exist or the password is wrong
|
||||
213;213;en;Customer does not exist or the password is wrong
|
||||
214;214;en;You have a previous Facebook login operation in progress
|
||||
215;215;en;Facebook login was not successful
|
||||
216;216;en;Facebook login cancelled
|
||||
217;217;en;Facebook login failed
|
||||
218;218;en;The account exists with different credential
|
||||
219;219;en;More »
|
||||
220;220;en;Done
|
||||
221;221;en;Height
|
||||
222;222;en;Height
|
||||
223;223;en;Bodyweight
|
||||
224;224;en;Bodyweight
|
||||
225;225;en;Based on your bodyweight and height your goal for BMI and weight:
|
||||
226;226;en;Body Mass Index
|
||||
227;227;en;first step
|
||||
228;228;en;Step
|
||||
229;229;en;goal
|
||||
230;230;en;Basal Metabolic Rate
|
||||
231;231;en;Resting Metabolic Rate
|
||||
232;232;en;Resting metabolic rate is the rate at which your body burns energy when it is at complete rest.
|
||||
233;233;en;Based on your bodyweight, height and activity this is your daily calory demand.
|
||||
234;234;en;Your Sizes
|
||||
235;235;en;Size Of Your
|
||||
236;236;en;Please type the following data:
|
||||
237;237;en;Cancel
|
||||
238;238;en;Available Devices
|
||||
239;239;en;select your equipments by tapping
|
||||
240;240;en;Available Equipments
|
||||
241;241;en;select your places by tapping
|
||||
242;242;en;Available Training Places
|
||||
243;243;en;Please take a relative bigger weight and repeat 12-30 times
|
||||
244;244;en;Please take a medium weight and repeat 20-30 times
|
||||
245;245;en;Equipment Filter
|
||||
246;246;en;Live-Server
|
||||
247;247;en;Test-Server
|
||||
248;248;en;All Exercises has been filtered out
|
||||
249;249;en;base
|
||||
250;250;en;Hypertrophy
|
||||
251;251;en;Gain Strength
|
||||
252;252;en;repeats
|
||||
253;253;en;minutes
|
||||
254;254;en;Rest time
|
||||
255;255;en;Suggestions based on your test
|
||||
256;256;en;Repeats volume
|
||||
257;257;en;Weight volume
|
||||
258;258;en;Calorie
|
||||
259;259;en;Max BPM
|
||||
260;260;en;Min BPM
|
||||
261;261;en;Average BPM
|
||||
262;262;en;Fatburn %
|
||||
263;263;en;Health Data Summary
|
||||
264;264;en;Congratulation!
|
||||
265;265;en;You have achieved to first 100% test round!
|
||||
266;266;en;Now you have unlocked: Development By Muscles and the Suggested Trainings Plan
|
||||
267;267;en;The
|
||||
268;268;en;the first
|
||||
269;269;en;the second
|
||||
270;270;en;the third
|
||||
271;271;en;Go Premium
|
||||
272;272;en;Unleash your potential with WorkoutTest Premium!
|
||||
273;273;en;feature is reachable after you finished
|
||||
274;274;en;100% test rounds
|
||||
275;275;en;Keep Testing
|
||||
276;276;en;Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.
|
||||
277;277;en;Please define your Exercise Plan
|
||||
278;278;en;Go to: 'Training Plan' - 'Edit My Custom Plan'
|
||||
279;279;en;Jump there »
|
||||
280;280;en;Purchase was not successful
|
||||
281;281;en;Purchase was cancelled
|
||||
282;282;en;Successful Purchase
|
||||
283;283;en;Now you can use the premium features of WorkoutTest!
|
||||
284;284;en;Where do you stand achieving your tests?
|
||||
285;285;en;<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>
|
||||
286;286;en;Unleash Your Development Now!
|
||||
287;287;en;Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.
|
||||
288;288;en;Subscription Conditions
|
||||
289;289;en;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
|
||||
290;290;en;Account will be charged for renewal within 24 hours prior to the end of the current period
|
||||
291;291;en;Montly
|
||||
292;292;en;Annual
|
||||
293;293;en;Predictions with Artificial Intelligence
|
||||
294;294;en;14% discount
|
||||
295;295;en;2 months free
|
||||
296;296;en;Development programs
|
||||
297;297;en;Suggestions based on your actual status
|
||||
298;298;en;Special customized training plans
|
||||
299;299;en;Or type the time manually
|
||||
300;300;en;sec
|
||||
301;301;en;min
|
||||
302;302;en;Edit Profile
|
||||
303;303;en;Activity
|
||||
304;304;en;Body Type
|
||||
305;305;en;Goal
|
||||
306;306;en;Gain Muscle
|
||||
307;307;en;Weight Loss
|
||||
308;308;en;Set your goal
|
||||
309;309;en;Set your fitness level
|
||||
310;310;en;Set your body type
|
||||
311;311;en;These equipments and devices are available
|
||||
312;312;en;Successful Registration
|
||||
313;313;en;Now we would like to know you better to lift the experience of the app.
|
||||
314;314;en;Please go through the pages, it will take couple of minutes!
|
||||
315;315;en;Body Type Analyser
|
||||
316;316;en;How likely is it true about you?
|
||||
317;317;en;Not True
|
||||
318;318;en;Maybe
|
||||
319;319;en;True
|
||||
320;320;en;« Back
|
||||
321;321;en;1. I have basically a thin and bony physique
|
||||
322;322;en;2. Long limbs and narrow shoulders are typical of me
|
||||
323;323;en;3. It is difficult for me to build muscle
|
||||
324;324;en;4. My chest and waist are nearly the same width
|
||||
325;325;en;5. ’Chopstick’ was my nickname in the kindergarten
|
||||
326;326;en;6. I easily lose the muscle I built up
|
||||
327;327;en;7. To my knowledge, my body fat percentage is low
|
||||
328;328;en;8. Basically, I have a sporty and athletic physique
|
||||
329;329;en;9. I have a wide collarbone and shoulders
|
||||
330;330;en;10. My hips are narrow and my waist is sporty
|
||||
331;331;en;11. I get muscular quickly
|
||||
332;332;en;12. My chest is wider than my waist
|
||||
333;333;en;13. I could be the statue of David
|
||||
334;334;en;14. I have a strong calf and forearm
|
||||
335;335;en;15. I have a wide rib cage
|
||||
336;336;en;16. I have thick and wide joints
|
||||
337;337;en;17. My bones are strong
|
||||
338;338;en;18. My body is muscular but a little fatter
|
||||
339;339;en;19. My hips are wider than my chest
|
||||
340;340;en;20. Tun’ could be my nickname too
|
||||
341;341;en;21. I lose weight hard and gain weight more easily
|
||||
342;342;en;22. I have a strong and chunky physique
|
||||
343;343;en;Your Bodytype result
|
||||
344;344;en;Change the weight to
|
||||
345;345;en;Search Exercises...
|
||||
346;346;en;No exercise found
|
||||
347;347;en;Edit Your Training Test Set
|
||||
348;348;en;Start training
|
||||
349;349;en;Enjoy the exercises, good luck with the testing!
|
||||
350;350;en;Please continue with the next exercise in the queue:
|
||||
351;351;en;Or, you can redifine this exercise queue in the Compact Test menu
|
||||
352;352;en;you are able to do 12-20 repeats with
|
||||
353;353;en;You have an active Test Set!
|
||||
354;354;en;Do you want to override it?
|
||||
355;355;en;Press OK to continue
|
||||
356;356;en;Continue
|
||||
357;357;en; your
|
||||
358;358;en;\nyour plan is available for 24 hours
|
||||
359;359;en;Start
|
||||
360;360;en;Compact Test
|
||||
361;361;en;Custom Test
|
||||
362;362;en;Set
|
|
@ -552,5 +552,8 @@
|
||||
"Exception: Please select your biologial gender": "Please select your biologial gender",
|
||||
"The found exercises are": "The found exercises are",
|
||||
"in green": "in green",
|
||||
"in your calendar": "in your calendar"
|
||||
"in your calendar": "in your calendar",
|
||||
"Development of My Sizes":"Development of My Sizes",
|
||||
"Date": "Date",
|
||||
"Muscle development":"Muscle development"
|
||||
}
|
340
i18n/hu.csv
340
i18n/hu.csv
@ -1,340 +0,0 @@
|
||||
363;1;hu;OK
|
||||
364;2;hu;Hálózati hiba, kérlek próbáld meg később
|
||||
365;3;hu;Főoldal
|
||||
366;4;hu;Ügyfelek
|
||||
367;5;hu;Gyakorlatok
|
||||
368;6;hu;Tesztek
|
||||
369;7;hu;EDZÉS!
|
||||
370;8;hu;Bejelentkezés
|
||||
371;9;hu;Kijelentkezés
|
||||
372;11;hu;Nyelv
|
||||
373;12;hu;A jelszó min. 9 karakterből álljon
|
||||
374;13;hu;Kérlek írj be egy email címet
|
||||
375;17;hu;Regisztráció
|
||||
376;18;hu;Regisztráció
|
||||
378;14;hu;Kérlek fogadd el az adatvédelmi szabályzatunkat
|
||||
379;15;hu;Kérlek fogadd el az adatvédelmi szabályzatunkat.
|
||||
380;16;hu;További információkért kattints az 'Adatkezelés' linkre.
|
||||
381;19;hu;Adatkezelés
|
||||
382;20;hu;Nyelvválasztás
|
||||
383;21;hu;Angol
|
||||
384;22;hu;Magyar
|
||||
385;23;hu;Események
|
||||
386;24;hu;Fiók
|
||||
387;25;hu;Beállítások
|
||||
388;26;hu;Személyes adatok
|
||||
389;27;hu;Választott nyelv
|
||||
390;28;hu;Kérlek jelentkezz be
|
||||
391;29;hu;Kérlek jelentkezz be
|
||||
393;30;hu;A felhasználó nem létezik vagy a jelszó rossz.
|
||||
397;34;hu;Kérlek írj be egy email címet
|
||||
398;35;hu;A jelszó min. 9 karakterből álljon
|
||||
399;37;hu;Az előző bejelentkezés még folyamatban van.
|
||||
400;38;hu;Facebook bejelentkezés megszakítva
|
||||
401;31;hu;Facebook bejelentkezés sikertelen
|
||||
402;33;hu;Ezzel email címmel már regisztráltak
|
||||
403;36;hu;Google bejelentkezés sikertelen
|
||||
404;37;hu;Apple bejelentkezés sikertelen
|
||||
405;38;hu;Apple bejelentkezés megszakítva
|
||||
406;39;hu;Apple bejelentkezés sikertelen: email cím szükséges.
|
||||
407;32;hu;A felhasználói fiók már létezik más névvel
|
||||
409;40;hu;Hiba lépett fel a regisztráció során:
|
||||
411;41;hu;Kardió
|
||||
412;42;hu;400m
|
||||
413;43;hu;300m
|
||||
414;44;hu;Aerob
|
||||
415;45;hu;Anaerob
|
||||
416;46;hu;Cooper teszt
|
||||
417;47;hu;Erő
|
||||
418;48;hu;Erő állóképesség
|
||||
419;49;hu;Fekvőtámasz
|
||||
420;50;hu;Fekvőtámasz időre
|
||||
421;51;hu;Core (plank)
|
||||
422;52;hu;Guggolás
|
||||
423;53;hu;Felülés
|
||||
424;54;hu;1RM - Maxerő
|
||||
425;55;hu;Fekvenyomás
|
||||
426;56;hu;Húzódszkodás
|
||||
427;57;hu;Bicepsz
|
||||
428;58;hu;Tricepsz
|
||||
429;59;hu;Vállak
|
||||
430;60;hu;Testformálás
|
||||
431;61;hu;Testtömegindex
|
||||
432;62;hu;Alapanyagcsere
|
||||
433;53;hu;Méretek
|
||||
434;64;hu;Gyakorlat mentése:
|
||||
436;65;hu;Törlés
|
||||
442;66;hu;<p>Erőállóképességi teszt lényege, ahogy az 1RM tesztnél is, hogy a Neked megfelelő SÚLY és ISMÉTLÉS számot tudjuk javasolni. </p><p>Nagyon fontos, hogy szabályosan és a kért ismétléssel dolgozz!</p><p> Ha a célod a hosszabb távú erő fenntartása, netán sportoló vagy, akkor feltétlen teszteld az erőállóképességi modulunkat is.</p><br/><h2>Miért az erőállóképesség?</h2><p>Javítja az izmok oxigén és tápanyagellátottságát és ezáltal képes leszel egyre nagyobb súlyok egyre hosszabbtávon való megmozgatására. Például egyre több fekvőtámaszra és húzódzkodásra. </p><p>Kevésbé tömegnövelő hatású, ámbár atlétikus és nagyon erős testalkatot kölcsönöz, ha hosszútávon gyakorlod.</p>
|
||||
443;67;hu;<p>Az egy ismétléses maximum, vagy más néven 1RM ismerete számodra fontos lehet a Neked megfelelő SÚLY és ISMÉTLÉS kiszámításában. <p>Végezd el szabályosan(!) a tesztet, hogy a Neked legmegfelelőbb súlyokat és ismétléseket tudjuk javasolni a későbbiekben.</p> <p>Ha a célod az izom, vagy az erőnövelés, akkor feltétlen csináld meg az 1RM teszteket!</p><br/><h2>Mi az 1RM?</h2><p>Az a súly, amit egyetlen egyszer lennél képes szabályosan megmozgatni. Az egyszer szabályosan végrehajtott maximális súlyú gyakorlatból származtatjuk a céloknak megfelelő súly és ismétlésszámokat.</p>
|
||||
444;68;hu;Vezetéknév
|
||||
445;69;hu;Gyakorlat
|
||||
446;70;hu;Mennyiség
|
||||
447;71;hu;Egység
|
||||
448;72;hu;A gyakorlat időpontja
|
||||
449;73;hu;Kérlek írj be egy helyes számot 0-10000 között
|
||||
450;74;hu;Igen
|
||||
451;75;hu;Nem
|
||||
452;76;hu;
|
||||
453;77;hu;Elmented a gyakorlatot?
|
||||
454;83;hu;ismétlés
|
||||
455;84;hu;méter
|
||||
456;85;hu;százalék
|
||||
457;86;hu;kg
|
||||
458;87;hu;kilogramm
|
||||
459;88;hu;lbs
|
||||
460;89;hu;másodperc
|
||||
461;90;hu;Email
|
||||
462;91;hu;Jelszó
|
||||
463;92;hu;VAGY
|
||||
464;93;hu;Jelszó (üres, ha nincs változás)
|
||||
465;94;hu;Keresztnév
|
||||
466;95;hu;Születési év
|
||||
467;96;hu;Tömeg
|
||||
468;97;hu;Nemed
|
||||
469;98;hu;Férfi
|
||||
470;99;hu;Nő
|
||||
471;100;hu;Tovább
|
||||
472;101;hu;Válaszd ki a nemet
|
||||
473;102;hu;Mi a célod?
|
||||
474;103;hu;Izomépítés
|
||||
475;104;hu;Fogyás
|
||||
476;105;hu;Milyen a fizikai állapotod?
|
||||
477;106;hu;Fizikai állapot
|
||||
478;107;hu;Fizikai aktivitás
|
||||
479;108;hu;Kezdő
|
||||
480;109;hu;Kezdő / Újrakezdő vagyok
|
||||
481;110;hu;Középhaladó
|
||||
482;111;hu;1-3-szor mozgok egy héten
|
||||
483;112;hu;Haladó
|
||||
484;113;hu;4+ alkalommal sportolok egy héten
|
||||
485;114;hu;Professzionális
|
||||
486;115;hu;Professzionális sportoló vagyok
|
||||
487;117;hu;Milyen a testtípusod?
|
||||
488;116;hu;Nincs kiválasztott elem
|
||||
489;118;hu;Ektomorf
|
||||
490;119;hu;Endomorf
|
||||
491;120;hu;Mezomorf
|
||||
492;121;hu;Ekto-Mesomorf
|
||||
493;122;hu;Mezo-Endomorf
|
||||
494;123;hu;<p>A Te testtípusod, ha:</p><ul><li>alapvetően vékony testalkat vagy, mint a hosszútávfutók</li><li>hosszú végtagok, keskenyebb vállak</li><li>nehezen tudsz izomtömeget növelni</li><li>Mellkas és a derék szinte egyforma szélességű</li><li>Könnyen elveszíted a felszedett izmot</li><li>Meglehetősen alacsony a testzsírszázalék jellemez</li></ul><p>Természetesen, mint a többi testtípusnál itt sem beszélhetünk 100%-os egyezésről, de fontos a választás a személyre szabottság érdekében. Előfordul, hogy egy ectomorph zsírfelesleggel is rendelkezik. Ekkor az ízületek vékonysága és az izomzat viselkedése a döntő szempont.</p>,
|
||||
495;124;hu;<p>A te testtípusod, ha úgy érzed, hogy a testalkatod az ektomorf szöges ellentéte.</p><ul><li>Ha az erős megjelenésű testalkatod ellenére kevésbé érvényesülnek vizuálisan az izmok.</li><li>Ha nehezen szabadulsz meg a fölöslegtől</li><li>Nagyon könnyen erősödsz</li><li>Széles nagy térfogatú a bordakosár</li><li>Vastag erős ízületeid vannak</li><li>Ha a csípőben vagy erősebb</li></ul><p>Itt sem beszélhetünk 100%-os egyezésről, de fontos a személyre szabottság miatt. Előfordul, hogy egy endomorf nehezen különböztethető meg a mezomorftól. Ekkor vedd figyelembe a bordakosár méretét és a derekat. Oldalról egy mezomorf laposabb mellkassal, hassal rendelkezhet az eredendően „erős” tömöttebb endomorfhoz képest. Minden alma és körte forma ide sorolható.</p>
|
||||
496;125;hu;<p>A testtípusod, ha</p><ul><li>Sportos testalkat vagy, mint egy sprinter, úszó vagy tornász</li><li>Széles kulcscsontok és vállak</li><li>Szimmetrikus felépítés</li><li>Keskeny csípő és sportos keskeny derék</li><li>alapvetően vékonyabb ízületek, de erős csontok jellemeznek</li><li>izmosabbak, mint az ektomorfok</li><li>Gyorsan izmosodsz</li><li>vastagabbak a csontok és az ízületek az ekromorfhoz képest</li><li>mellkas a derékhez képest széles</li><li>erősebb vádli és alkar</li></ul><p>Természetesen, mint a többi testtípusnál itt sem beszélhetünk 100%-os egyezésről, de fontos a személyre szabottság miatt. Előfordul, hogy egy mezomorf zsírfelesleggel is rendelkezik. Ekkor a csípőcsont/mellkas arány és az izomzat viselkedése a döntő szempont.</p>
|
||||
497;126;hu;Leírás
|
||||
498;127;hu;Végezd el az első tesztet
|
||||
499;128;hu;végrehajtva
|
||||
500;129;hu;Miért szükséges a tesztgyakorlat?
|
||||
501;130;hu;Maxerőd (1RM):
|
||||
502;131;hu;Ellenőrzött maxerő:
|
||||
503;132;hu;Ellenőrzés
|
||||
504;139;hu;Fejlődésem
|
||||
505;140;hu;Edzéstervem
|
||||
506;141;hu;Kérlek add meg az edzéstervet a gyakorlathoz
|
||||
507;142;hu;Sorozat
|
||||
508;143;hu;Ismétlés
|
||||
509;144;hu;Gyakorlat mentése az edzéstervhez
|
||||
510;145;hu;Mennyi szériát csinálsz
|
||||
511;146;hu;Hány ismétlést csinálsz egy gyakorlaton belül
|
||||
512;148;hu;1. Mell
|
||||
513;149;hu;2. Bicepsz
|
||||
514;150;hu;3. Tricepsz
|
||||
515;151;hu;4. Hát
|
||||
516;152;hu;5. Váll
|
||||
517;152;hu;6. Has
|
||||
518;154;hu;7. Comb
|
||||
519;155;hu;8. Vádli
|
||||
520;156;hu;Edzésterv végrehajtása
|
||||
521;157;hu;Edzésterv létrehozása
|
||||
522;158;hu;Javasolt edzésterv
|
||||
523;159;hu;Speciális edzésterv
|
||||
524;160;hu;Edzés programok
|
||||
525;162;hu;Kliensem edzéstervének végrehajtása
|
||||
526;163;hu;Edzésnaplóm
|
||||
527;164;hu;Testem fejlődése
|
||||
528;165;hu;Izomcsoportok fejlődése
|
||||
529;166;hu;Előrejelzések
|
||||
530;167;hu;Kliensem edzésnaplőja
|
||||
531;168;hu;Izomcsoportok fejlődése
|
||||
532;169;hu;
|
||||
533;170;hu;Össztömeg
|
||||
534;171;hu;Százalék
|
||||
535;172;hu;Maxerő
|
||||
536;173;hu;Maxerő
|
||||
537;175;hu;Részletes
|
||||
538;176;hu;Heti
|
||||
539;177;hu;Havi
|
||||
540;178;hu;Éves
|
||||
541;179;hu;ismétléssel!
|
||||
542;180;hu;Kérlek ismételd meg
|
||||
543;181;hu; max. számú ismétléssel!
|
||||
544;182;hu;Hajtsd végre az aktív edzéstervedet
|
||||
545;183;hu;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.
|
||||
546;184;hu;Egyedi edzésterv
|
||||
547;185;hu;Á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!
|
||||
548;186;hu;Ebben a listában találod az eddig végrehajtott gyakorlataid dátum szerint csoportosítva.
|
||||
549;187;hu;Kitartás!
|
||||
550;188;hu;Üdvözöllek!
|
||||
551;189;hu;A cél a jelenlegi fizikai állapotod felmérése. Az első feladatod az összes izomcsoport tesztelése egy 'alap' gyakorlattal.
|
||||
553;190;hu;Menj a menüben az Erő - Max Erő - Mell menüpontba, és válaszd ki a kedvenc gyakorlatod.
|
||||
554;191;hu;Kérlek folytasd tesztelést egy
|
||||
555;192;hu;Azt javaslom, kezdd a teszteket egy 'mell' gyakorlattal
|
||||
556;193;hu;Nagyon jó! Ez egy kitűnő start a teszthez
|
||||
557;194;hu;Gyerünk tovább!
|
||||
558;195;hu;Jó úton haladsz
|
||||
559;196;hu;Már nincs sok hátra
|
||||
560;197;hu;Majdnem a végén vagy!
|
||||
561;198;hu;Már csak 1-2 gyakorlat van a hátra!
|
||||
562;199;hu;gyakorlattal!
|
||||
563;200;hu;mell
|
||||
564;201;hu;hát
|
||||
565;202;hu;comb
|
||||
566;203;hu;vádli
|
||||
567;204;hu;Vigyél oda
|
||||
568;205;hu;Testem fejlődése
|
||||
569;206;hu;Itt láthatod a tested fejlődését izomcsoportonként
|
||||
570;207;hu;Biztos, hogy kijelentkezel?
|
||||
571;208;hu; -mal
|
||||
579;209;hu;Biztos, hogy törlöd a gyakorlatot?
|
||||
580;210;hu;Elfelejtett jelszó
|
||||
581;212;hu;Ezzel az email címmel nem található felhasználó. Kérlek regisztálj vagy kérj jelszóemlékeztetőt
|
||||
582;219;hu;Részletek »
|
||||
583;220;hu;Kész
|
||||
584;221;hu;Magasság
|
||||
585;222;hu;Magasság
|
||||
586;223;hu;Testtömeg
|
||||
587;224;hu;Testtömeg
|
||||
588;225;hu;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!
|
||||
589;226;hu;Testtömegindex
|
||||
590;227;hu;első lépés
|
||||
591;229;hu;cél
|
||||
592;230;hu;Minimum energiaszükséglet
|
||||
593;231;hu;
|
||||
594;232;hu;Alapanyagcsere
|
||||
595;233;hu;A megadott adataid és aktivitásod alapján megközelítőleg ennyi a napi kalóriaszükségleted.
|
||||
596;234;hu;Méreteid
|
||||
597;235;hu;Testméret:
|
||||
598;236;hu;Kérlek írd be a következő adatot:
|
||||
599;237;hu;Mégsem
|
||||
600;238;hu;Edzés eszközök
|
||||
601;239;hu;válaszd ki az eszközeidet, kattints a képre
|
||||
602;240;hu;Elérhető eszközök
|
||||
603;241;hu;kattints az edzéshelyszínre
|
||||
604;242;hu;Elérhető edzéshelyszínek
|
||||
605;243;hu;Válassz egy relatív nagyobb súlyt, amivel maximum 12-20 közötti ismétlésre vagy képes
|
||||
606;245;hu;Eszköz szűrő
|
||||
607;246;hu;Live-Server
|
||||
608;247;hu;Test-Server
|
||||
609;248;hu;Az összes gyakorlatot kiszűrted
|
||||
610;249;hu;alap
|
||||
611;250;hu;Izomnövelés
|
||||
612;251;hu;Erőnövelés
|
||||
613;252;hu;ismétlés
|
||||
614;254;hu;Pihenőidő
|
||||
615;253;hu;perc
|
||||
616;255;hu;Javaslatok a teszted alapján
|
||||
617;256;hu;Össz. ismétlés
|
||||
618;257;hu;Össztömeg
|
||||
619;258;hu;Kalória
|
||||
620;258;hu;Max pulzus
|
||||
621;260;hu;Min pulzus
|
||||
622;261;hu;Átl pulzus
|
||||
623;262;hu;Zsírégetés %
|
||||
624;263;hu;Egészségadatok összefoglalás
|
||||
626;264;hu;Gratulálok!
|
||||
627;265;hu;Teljesítetted az első 100%-os tesztköröd!
|
||||
628;266;hu;Mostantól elérheted az 'Izomcsoportok fejlődése' és a 'Javasolt edzésterv' kategóriákat.
|
||||
629;267;hu;A
|
||||
630;268;hu;az első
|
||||
631;269;hu;a második
|
||||
632;270;hu;a harmadik
|
||||
633;271;hu;Válts Prémiumra
|
||||
634;272;hu;Bontakoztasd ki az erősségeidet WorkoutTest Prémiummal!
|
||||
635;273;hu;funkció elérhető számodra, miután teljesítetted
|
||||
636;274;hu;100%-os teszt-köröd
|
||||
637;275;hu;Folytasd a tesztelést
|
||||
638;276;hu;Élvezd ezt a prémium funkciót is, amely megjeleníti a korábbi gyakorlatok teljes kiértékelését
|
||||
639;277;hu;Kérlek készíts edzéstervet!
|
||||
640;278;hu;Menj a 'Edzéstervem' - 'Egyéni edzésterv' menübe
|
||||
641;279;hu;Vigyél oda »
|
||||
642;280;hu;A vásárlás sikertelen volt
|
||||
643;281;hu;A vásárlás megszakadt
|
||||
644;282;hu;Sikeres vásárlás!
|
||||
645;283;hu;Most már eléred a WorkoutTest prémium tartalmait.
|
||||
646;284;hu;Hol tartasz a tesztek végrehajtásában?
|
||||
647;285;hu;<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>
|
||||
648;286;hu;Indítsd el a fejlődésed most!
|
||||
649;287;hu;Kövesd nyomon a fejlődésed, élvezd a mesterséges intelligenciával támogatott javaslatokat és előrejelzéseket.
|
||||
650;288;hu;Előfizetési feltételek
|
||||
651;289;hu;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.
|
||||
652;290;hu;Az előfizetési periódus végén a számládat megterheljuk 24 órával a lejárat előtt.
|
||||
653;291;hu;Havi
|
||||
654;292;hu;Éves
|
||||
655;293;hu;Mesterséges Intelligencia előrejelzések
|
||||
656;294;hu;14% kedvezmény
|
||||
657;295;hu;2 hónap ingyen
|
||||
658;296;hu;Fejlesztési programok
|
||||
659;297;hu;Intelligens javaslatok az állapotod alapján
|
||||
660;298;hu;Speciális testreszabott edzéstervek
|
||||
662;299;hu;Vagy jelöld ki az időt kézzel
|
||||
663;300;hu;mp
|
||||
664;301;hu;perc
|
||||
665;302;hu;Profil szerkesztése
|
||||
666;303;hu;Fizikai állapot
|
||||
667;304;hu;Testtípus
|
||||
668;305;hu;Cél
|
||||
669;306;hu;Izomépítés
|
||||
670;307;hu;Fogyás
|
||||
671;308;hu;Mi a célod?
|
||||
672;309;hu;Milyen a fizikai állapotod?
|
||||
673;310;hu;Milyen a testtípusod?
|
||||
674;311;hu;Ezek az eszközök állnak a rendelkezésedre
|
||||
675;312;hu;Sikeres regisztráció
|
||||
676;313;hu;Most meg szeretnénk téged jobban ismerni, hogy az applikáció jobban illeszkedjen hozzád.
|
||||
677;314;hu;Kérlek menj át a következő oldalakon, néhány percet vesz csak igénybe!
|
||||
678;315;hu;Testtípus analizátor
|
||||
679;316;hu;Mennyire igaz rád az állítás?
|
||||
680;317;hu;Biztos nem
|
||||
681;318;hu;Talán
|
||||
682;319;hu;Biztosan
|
||||
683;320;hu;« Vissza
|
||||
684;321;hu;1. Alapvetően vékony, csontos testalkat vagyok
|
||||
685;322;hu;2. Hosszú végtagok, keskeny vállak jellemzőek rám
|
||||
686;323;hu;3. Nehezen tudok izmot növelni
|
||||
687;324;hu;4. Mellkasom, derekam közel egyforma szélességű
|
||||
688;325;hu;5. Pálcika volt a becenevem az oviban
|
||||
689;326;hu;6. Könnyen elveszítem a felszedett izmot
|
||||
690;327;hu;7. Tudtommal alacsony a testzsírom
|
||||
691;328;hu;8. Alapvetően sportos, atletikus testalkat vagyok
|
||||
692;329;hu;9. Széles kulcscsontom és vállam van
|
||||
693;330;hu;10. Keskeny a csípőm és sportos a derekam
|
||||
694;331;hu;11. Gyorsan izmosodok
|
||||
695;332;hu;12. Szélesebb a mellkasom a derekamnál
|
||||
696;333;hu;13. Akár lehetnék én a Dávid szobor
|
||||
697;334;hu;14. Erős vádli és alkar jellemez
|
||||
698;335;hu;15. Széles bordakosaram van
|
||||
699;336;hu;16. Vastag, széles ízületeim vannak
|
||||
700;337;hu;17. Erős a csontozatom
|
||||
701;338;hu;18. Zsírosabb, de izmos vagyok
|
||||
702;339;hu;19. Szélesebb a csípőm a mellkasomnál
|
||||
703;340;hu;20. Hordó is lehetne a becenevem
|
||||
704;341;hu;21. Nehezen fogyok, könnyebben hízok
|
||||
705;342;hu;22. Erős, vaskos testalkat vagyok
|
||||
706;343;hu;Testtípus eredményed
|
||||
707;344;hu;Súly változtatása
|
||||
708;345;hu;Gyakorlat keresése...
|
||||
709;346;hu;Nincs ilyen gyakorlat
|
||||
710;347;hu;Válaszd ki a gyakorlatokat
|
||||
711;348;hu;Edzés kezdése
|
||||
712;349;hu;Élvezd a gyakorlatokat, sok sikert a teszteléshez!
|
||||
713;350;hu;Kérlek folytasd a következő gyakorlattal:
|
||||
714;351;hu;Vagy változtatsd meg a gyakorlatokat a Tesztközpontban
|
||||
715;352;hu;amivel képes vagy 12-20 ismétlésre
|
||||
716;353;hu;Van egy aktiv tesztköröd!
|
||||
717;354;hu;Felülírod?
|
||||
718;355;hu;Nyomd meg az OK-t a folytatáshoz
|
||||
719;356;hu;Folytatsd
|
||||
720;357;hu;
|
||||
721;358;hu;\na teszt 24 óráig aktív
|
||||
722;359;hu;Kezdd el
|
||||
723;360;hu;Kompakt teszt
|
||||
724;361;hu;Egyedi teszt
|
||||
725;362;hu;Széria
|
|
@ -552,5 +552,9 @@
|
||||
"Exception: Please select your biologial gender": "Kérlek válaszd ki a biológiai nemed",
|
||||
"The found exercises are": "A keresett gyakorlatot",
|
||||
"in green": "zölddel",
|
||||
"in your calendar": "jelöltük a naptárban"
|
||||
"in your calendar": "jelöltük a naptárban",
|
||||
"Development of My Sizes":"Méretek fejlődése",
|
||||
"Date": "Dátum",
|
||||
"Muscle development":"Izom fejlődése"
|
||||
|
||||
}
|
362
i18n/key.csv
362
i18n/key.csv
@ -1,362 +0,0 @@
|
||||
1;OK;;0
|
||||
2;Network Error, please try again later;;0
|
||||
3;Home;;0
|
||||
4;Customers;;0
|
||||
5;Exercises;;0
|
||||
6;TRAINING!;;0
|
||||
7;Login;;0
|
||||
8;Logout;;0
|
||||
9;SignUp with Email;;0
|
||||
10;Tests;;0
|
||||
11;Change Language;;0
|
||||
12;Password too short;;0
|
||||
13;Please type an email address;;0
|
||||
14;"Exception; Please accept our data policy";;0
|
||||
15;Please accept our data protection policy.;;0
|
||||
16;For more information please click on 'Privacy';;0
|
||||
17;SignUp;;0
|
||||
18;SignUpLink;;0
|
||||
19;Privacy;;0
|
||||
20;Change App Language;;0
|
||||
21;English;;0
|
||||
22;Hungarian;;0
|
||||
23;Events;;0
|
||||
24;Account;;0
|
||||
25;Settings;;0
|
||||
26;Profile;;0
|
||||
27;Selected Language;;0
|
||||
28;Please log in;;0
|
||||
29;Exception: Please log in;;0
|
||||
30;Exception. Customer does not exist or the password is wrong;;0
|
||||
31;Exception: Facebook signup was not successful. Please try another method;;0
|
||||
32;Exception: Customer exists;;0
|
||||
33;Exception: The email address has been registered already;;0
|
||||
34;Exception: Please type an email address;;0
|
||||
35;Exception: Password too short;;0
|
||||
36;Exception: Google Sign In failed;;0
|
||||
37;Exception: Apple Sign-In failed;;0
|
||||
38;Exception: Apple Sign-In cancelled;;0
|
||||
39;"Exception: Apple Sign In failure; email address is necessary";;0
|
||||
40;There is an error: during registration:;;0
|
||||
41;Cardio;;0
|
||||
42;400m;;0
|
||||
43;300m;;0
|
||||
44;Aerobic;;0
|
||||
45;Anaerobic;;0
|
||||
46;Cooper;;0
|
||||
47;Strength;;0
|
||||
48;Endurance;;0
|
||||
49;Pushups;;0
|
||||
50;Timed Pushups;;0
|
||||
51;Core;;0
|
||||
52;Squats;;0
|
||||
53;Sit-ups;;0
|
||||
54;1RM;;0
|
||||
55;Chest Press;;0
|
||||
56;Pull Ups;;0
|
||||
57;Biceps;;0
|
||||
58;Triceps;;0
|
||||
59;Shoulders;;0
|
||||
60;Body Compositions;;0
|
||||
61;BMI;;0
|
||||
62;BMR;;0
|
||||
63;Sizes;;0
|
||||
64;Save Exercise;;0
|
||||
65;Delete;;0
|
||||
66;Endurance_desc;;0
|
||||
67;OneRepMax_desc;;0
|
||||
68;Name;;0
|
||||
69;Exercise;;0
|
||||
70;Quantity;;0
|
||||
71;Unit;;0
|
||||
72;Exercise date and time;;0
|
||||
73;Please type the right quantity 0-1000;;0
|
||||
74;Yes;;0
|
||||
75;No;;0
|
||||
76;with;;0
|
||||
77;Do you save this exercise with these parameters?;;0
|
||||
78;The number of the exercise;;0
|
||||
79;The number of the exercise done with;;0
|
||||
80;Please repeat with;;0
|
||||
81;Execute the;;0
|
||||
82;set!;;0
|
||||
83;repeat;;0
|
||||
84;meter;;0
|
||||
85;percent;;0
|
||||
86;kg;;0
|
||||
87;kilogram;;0
|
||||
88;lbs;;0
|
||||
89;second;;0
|
||||
90;Email;;0
|
||||
91;Password;;0
|
||||
92;OR;;0
|
||||
93;Password (Leave empty if no change);;0
|
||||
94;First Name;;0
|
||||
95;Birth Year;;0
|
||||
96;Weight;;0
|
||||
97;Gender;;0
|
||||
98;Man;;0
|
||||
99;Woman;;0
|
||||
100;Next;;0
|
||||
101;Select a gender;;0
|
||||
102;Set Your Goals;;0
|
||||
103;Gain Muscle;;0
|
||||
104;Loose Weight;;0
|
||||
105;Your Fitness State;;0
|
||||
106;Fitness level;;0
|
||||
107;Fitness Activity;;0
|
||||
108;Beginner;;0
|
||||
109;I am beginner;;0
|
||||
110;Intermediate;;0
|
||||
111;I am intermediate;;0
|
||||
112;Advanced;;0
|
||||
113;I am advanced;;0
|
||||
114;Professional;;0
|
||||
115;I am professional;;0
|
||||
116;No item selected;;0
|
||||
117;Your Body Type;;0
|
||||
118;Ectomorph;;0
|
||||
119;Endomorph;;0
|
||||
120;Mesomorph;;0
|
||||
121;Ecto-Mesomorph;;0
|
||||
122;Meso-Endomorph;;0
|
||||
123;Ectomorph_desc;;0
|
||||
124;Endomorph_desc;;0
|
||||
125;Mesomorph_desc;;0
|
||||
126;Description;;0
|
||||
127;Make your first test;;0
|
||||
128;finished;;0
|
||||
129;Why do you need Exercise Control? ;;0
|
||||
130;"Your 1RM;";;0
|
||||
131;"Your Real 1RM;";;0
|
||||
132;Check;;0
|
||||
133;"Control Exercise;";;0
|
||||
134;Summary of your test;;0
|
||||
135;Test;;0
|
||||
136;1st Control;;0
|
||||
137;2nd Control;;0
|
||||
138;3rd Control;;0
|
||||
139;My Development;;0
|
||||
140;My Training Plan;;0
|
||||
141;Please add an exercise plan;;0
|
||||
142;Serie;;0
|
||||
143;Repeats;;0
|
||||
144;Save The Exercise To The Exercise Plan;;0
|
||||
145;The number of the serie done with;;0
|
||||
146;The number of the repeats of one serie;;0
|
||||
147;reps;;0
|
||||
148;1. Chest;;0
|
||||
149;2. Biceps;;0
|
||||
150;3. Triceps;;0
|
||||
151;4. Back;;0
|
||||
152;5. Shoulders;;0
|
||||
153;6. Core;;0
|
||||
154;7. Thigh;;0
|
||||
155;8. Calf;;0
|
||||
156;Execute My Selected Training Plan;;0
|
||||
157;Edit My Custom Plan;;0
|
||||
158;Suggested Training Plan;;0
|
||||
159;My Special Plan;;0
|
||||
160;Training Programs;;0
|
||||
161;My Trainee's Plan;;0
|
||||
162;Execute My Trainee's Training Plan;;0
|
||||
163;My Exercise Logs;;0
|
||||
164;My Whole Body Development;;0
|
||||
165;Development Of Muscles;;0
|
||||
166;Predictions;;0
|
||||
167;My Trainee's Exercise Logs;;0
|
||||
168;My Development By Muscle;;0
|
||||
169;Here you see you development in the last period. ;;0
|
||||
170;Sum Of Mass;;0
|
||||
171;Percent;;0
|
||||
172;One Rep Max;;0
|
||||
173;OneRepMax;;0
|
||||
174;onerepmax_desc;;0
|
||||
175;Detailed;;0
|
||||
176;Weekly;;0
|
||||
177;Monthly;;0
|
||||
178;Yearly;;0
|
||||
179;times!;;0
|
||||
180;Please repeat with ;;0
|
||||
181;max times!;;0
|
||||
182;Execute your active Exercise Plan!;;0
|
||||
183;Select the muscle type and tap on the exercise. One the next page enter the weight and repeat.;;0
|
||||
184;Custom Exercise Plan;;0
|
||||
185;Select manually the exercises what you would like to have in your plan. At the end don't forget to save.;;0
|
||||
186;In this list you will find all your executed exercises grouped by the date.;;0
|
||||
187;Persistence!;;0
|
||||
188;Greetings!;;0
|
||||
189;The purpose is to measure you physical condition;;0
|
||||
190;Go to the menu Strength - One Rep Max - Chest, and select your favourite exercise.;;0
|
||||
191;Please continue your tests with a;;0
|
||||
192;I suggest begin your tests with a;;0
|
||||
193;Nice! This is a good start;;0
|
||||
194;Go on!;;0
|
||||
195;You are on track;;0
|
||||
196;Not so much left;;0
|
||||
197;Almost!;;0
|
||||
198;You have only 1-2 exercise left to finish!;;0
|
||||
199;exercise!;;0
|
||||
200;Chest;;0
|
||||
201;Back;;0
|
||||
202;Thigh;;0
|
||||
203;Calf;;0
|
||||
204;Bring me there;;0
|
||||
205;My Body Development;;0
|
||||
206;You see here your whole body development by muscle groups.;;0
|
||||
207;Are you sure to logout?;;0
|
||||
208;hu_with;;0
|
||||
209;Are you sure to delete this exercise?;;0
|
||||
210;I forgot the password;;0
|
||||
211;"Exception; Instance of 'NotFoundException'";;0
|
||||
212;Customer does not exist or the password is wrong;;0
|
||||
213;The email does not exist or the password is wrong;;0
|
||||
214;"Exception; You have a previous Facebook login operation in progress";;0
|
||||
215;"Exception; Facebook login was not successful";;0
|
||||
216;"Exception; Facebook login cancelled";;0
|
||||
217;"Exception; Facebook login failed";;0
|
||||
218;"Exception; The account exists with different credential";;0
|
||||
219;More »;;0
|
||||
220;Done;;0
|
||||
221;Height;;0
|
||||
222;Actual Height;;0
|
||||
223;Actual Weight;;0
|
||||
224;Bodyweight;;0
|
||||
225;"Based on your weight and height your goal for BMI and weight;";;0
|
||||
226;Body Mass Index;;0
|
||||
227;first step;;0
|
||||
228;Step;;0
|
||||
229;goal;;0
|
||||
230;Basal Metabolic Rate;;0
|
||||
231;Resting Metabolic Rate;;0
|
||||
232;Resting metabolic rate is the rate at which your body burns energy when it is at complete rest.;;0
|
||||
233;Based on your weight, height and activity your BMR value;;0
|
||||
234;Your Sizes;;0
|
||||
235;Size Of Your;;0
|
||||
236;"Please type the following data;";;0
|
||||
237;Cancel;;0
|
||||
238;Available Devices;;0
|
||||
239;select your equipments by tapping;;0
|
||||
240;Available Equipments;;0
|
||||
241;select your places by tapping;;0
|
||||
242;Available Training Places;;0
|
||||
243;Please take a relative bigger weight and repeat 12-30 times;;0
|
||||
244;Please take a medium weight and repeat 20-30 times;;0
|
||||
245;Equipment Filter;;0
|
||||
246;Live-Server;;0
|
||||
247;Test-Server;;0
|
||||
248;All Exercises has been filtered out;;0
|
||||
249;base;;0
|
||||
250;Hypertrophy;;0
|
||||
251;Gain Strength;;0
|
||||
252;repeats;;0
|
||||
253;minutes;;0
|
||||
254;Rest time;;0
|
||||
255;Suggestions based on your test;;0
|
||||
256;Repeats volume;;0
|
||||
257;Weight volume;;0
|
||||
258;Calorie;;0
|
||||
259;Max BPM;;0
|
||||
260;Min BPM;;0
|
||||
261;Average BPM;;0
|
||||
262;Fatburn %;;0
|
||||
263;Health Data Summary;;0
|
||||
264;Congratulation!;;0
|
||||
265;You have achieved to first 100% test-round!;;0
|
||||
266;"Now you unlocked; Development By Muscles and the Suggested Trainings Plan";;0
|
||||
267;The;;0
|
||||
268;the first;;0
|
||||
269;the second;;0
|
||||
270;the third;;0
|
||||
271;Go Premium;;0
|
||||
272;Unleash your potential with WorkoutTest Premium!;;0
|
||||
273;feature is reachable after you finished;;0
|
||||
274;100% test circles;;0
|
||||
275;Keep testing;;0
|
||||
276;Enjoy also this premium fetaure to show all old evaluation data of your successful exercises.;;0
|
||||
277;Please define your Exercise Plan;;0
|
||||
278;"Go to; 'Training Plan' - 'Edit My Custom Plan'";;0
|
||||
279;Jump there »;;0
|
||||
280;"Exception; Purchase was not successful";;0
|
||||
281;"Exception; Purchase was cancelled";;0
|
||||
282;Successful Purchase;;0
|
||||
283;Now you can use the premium features of WorkoutTest!;;0
|
||||
284;Progressindicator for the tests;;0
|
||||
285;Progressindicator_desc;;0
|
||||
286;Unleash Your Development Now!;;0
|
||||
287;Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.;;0
|
||||
288;Subscription Conditions;;0
|
||||
289;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;;0
|
||||
290;Account will be charged for renewal within 24 hours prior to the end of the current period;;0
|
||||
291;Montly;;0
|
||||
292;Annual;;0
|
||||
293;Predictions with Artificial Intelligence;;0
|
||||
294;14% discount;;0
|
||||
295;2 months free;;0
|
||||
296;Development programs;;0
|
||||
297;Suggestions based on your actual status;;0
|
||||
298;Special customized training plans;;0
|
||||
299;"Or type the time manually;";;0
|
||||
300;sec;;0
|
||||
301;min;;0
|
||||
302;Edit Profile;;0
|
||||
303;Activity;;0
|
||||
304;Body Type;;0
|
||||
305;Goal;;0
|
||||
306;gain_muscle;;0
|
||||
307;weight_loss;;0
|
||||
308;Set your goal;;0
|
||||
309;Set your fitness level;;0
|
||||
310;Set your body type;;0
|
||||
311;These equipments and devices are available;;0
|
||||
312;Successful Registration;;0
|
||||
313;Now we would like to know you better to lift the experience of the app.;;0
|
||||
314;Please go through the pages, it will take couple of minutes!;;0
|
||||
315;Body Type Analyser;;0
|
||||
316;How likely is it true about you?;;0
|
||||
317;Very unlikely;;0
|
||||
318;Maybe;;0
|
||||
319;Very likely;;0
|
||||
320;« Back;;0
|
||||
321;1. Basicly I am skinny and bonny;;0
|
||||
322;2. question;;0
|
||||
323;3. question;;0
|
||||
324;4. question;;0
|
||||
325;5. question;;0
|
||||
326;6. question;;0
|
||||
327;7. question;;0
|
||||
328;8. question;;0
|
||||
329;9. question;;0
|
||||
330;10. question;;0
|
||||
331;11. question;;0
|
||||
332;12. question;;0
|
||||
333;13. question;;0
|
||||
334;14. question;;0
|
||||
335;15. question;;0
|
||||
336;16. question;;0
|
||||
337;17. question;;0
|
||||
338;18. question;;0
|
||||
339;19. question;;0
|
||||
340;20. question;;0
|
||||
341;21. question;;0
|
||||
342;22. question;;0
|
||||
343;Your Bodytype result;;0
|
||||
344;Change the weight to;;0
|
||||
345;Search Exercises...;;0
|
||||
346;No exercise found;;0
|
||||
347;Edit Your Training Test Set;;0
|
||||
348;Start training;;0
|
||||
349;Enjoy the exercises, good luck with the testing!;;0
|
||||
350;"Please continue with the next exercise in the queue;";;0
|
||||
351;Or, you can redifine this exercise queue in the Compact Test menu;;0
|
||||
352;you are able to do 12-20 repeats with;;0
|
||||
353;You have an active Test Set!;;0
|
||||
354;Do you want to override it?;;0
|
||||
355;Press OK to continue;;0
|
||||
356;Continue;;0
|
||||
357; your ;;0
|
||||
358;\nyour plan is available for 24 hours;;0
|
||||
359;Start;;0
|
||||
360;Compact Test;;0
|
||||
361;Custom Test;;0
|
||||
362;Set;;0
|
|
@ -119,15 +119,9 @@ class CustomerChangeBloc extends Bloc<CustomerChangeEvent, CustomerChangeState>
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveWeight) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.getProperty("Weight") == null) {
|
||||
throw Exception("Please select your weight");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSaveHeight) {
|
||||
yield CustomerChangeLoading();
|
||||
if (customerRepository.customer!.getProperty("Height") == null) {
|
||||
throw Exception("Please select your height");
|
||||
}
|
||||
yield CustomerSaveSuccess();
|
||||
} else if (event is CustomerSave) {
|
||||
yield CustomerSaving();
|
||||
|
@ -1,28 +1,142 @@
|
||||
import 'package:intl/intl.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/calculate.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/group_data.dart';
|
||||
import 'package:aitrainer_app/util/diagram_data.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
|
||||
part 'development_by_muscle_event.dart';
|
||||
|
||||
part 'development_by_muscle_state.dart';
|
||||
|
||||
enum DiagramType { sumMass, oneRepMax, percent }
|
||||
enum DiagramDateType { daily, weekly, monthly, yearly }
|
||||
|
||||
class GroupDate extends GroupData with Common {
|
||||
final List<Exercise> inputList;
|
||||
final List<DiagramData> outputList;
|
||||
|
||||
String? _origDatePart;
|
||||
late int _origExerciseTypeId;
|
||||
late Exercise _origExercise;
|
||||
|
||||
late double _sumQuantity;
|
||||
late double _maxQuantity;
|
||||
late int _countExercises;
|
||||
|
||||
late DiagramType diagramType;
|
||||
late DiagramDateType dateRate;
|
||||
|
||||
GroupDate({required this.inputList, required this.outputList});
|
||||
|
||||
double getQuantityByDate(Exercise exercise) {
|
||||
double sum = 0;
|
||||
if (this.diagramType == DiagramType.sumMass) {
|
||||
if (exercise.unitQuantity != null) {
|
||||
sum = exercise.quantity! * exercise.unitQuantity!;
|
||||
} else {
|
||||
sum = exercise.quantity!;
|
||||
}
|
||||
} else if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
|
||||
if (exercise.unitQuantity != null) {
|
||||
sum = calculate1RM(exercise.quantity!, exercise.unitQuantity!);
|
||||
} else {
|
||||
sum = exercise.quantity!;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@override
|
||||
void addTempData(Exercise exercise) {
|
||||
double newQuantity = getQuantityByDate(exercise);
|
||||
_sumQuantity = _sumQuantity + newQuantity;
|
||||
if (_maxQuantity < newQuantity) {
|
||||
_maxQuantity = newQuantity;
|
||||
}
|
||||
_countExercises = _countExercises + 1;
|
||||
_origDatePart = getDatePart(exercise.dateAdd!, dateRate);
|
||||
_origExerciseTypeId = exercise.exerciseTypeId!;
|
||||
_origExercise = exercise;
|
||||
}
|
||||
|
||||
@override
|
||||
bool checkNewType(Exercise exercise) {
|
||||
String exerciseDatePart = getDatePart(exercise.dateAdd!, dateRate);
|
||||
return _origDatePart == null || _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
|
||||
}
|
||||
|
||||
String getDatePart(DateTime date, DiagramDateType dateRate) {
|
||||
String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
if (dateRate == DiagramDateType.weekly) {
|
||||
datePart = weekNumber(date).toString();
|
||||
} else if (dateRate == DiagramDateType.monthly) {
|
||||
datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DiagramDateType.yearly) {
|
||||
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DiagramDateType.daily) {
|
||||
datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
}
|
||||
return datePart;
|
||||
}
|
||||
|
||||
@override
|
||||
void iteration() {
|
||||
this.resetTemp();
|
||||
Exercise? tempExercise;
|
||||
inputList.forEach((element) {
|
||||
tempExercise = element;
|
||||
if (this.checkNewType(element)) {
|
||||
if (_origDatePart == null) {
|
||||
this.addTempData(element);
|
||||
} else {
|
||||
this.temp2Output(_origExercise);
|
||||
this.resetTemp();
|
||||
this.addTempData(element);
|
||||
}
|
||||
} else {
|
||||
this.addTempData(element);
|
||||
}
|
||||
});
|
||||
if (tempExercise != null) {
|
||||
this.temp2Output(tempExercise!);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void temp2Output(Exercise exercise) {
|
||||
if (exercise.unitQuantity == null) {
|
||||
return;
|
||||
}
|
||||
Exercise newExercise = exercise.copy();
|
||||
newExercise.datePart = _origDatePart;
|
||||
if (this.diagramType == DiagramType.oneRepMax || this.diagramType == DiagramType.percent) {
|
||||
newExercise.calculated = _maxQuantity;
|
||||
} else {
|
||||
newExercise.calculated = _sumQuantity / _countExercises;
|
||||
}
|
||||
DiagramData data = DiagramData(newExercise.datePart!, newExercise.calculated);
|
||||
outputList.add(data);
|
||||
}
|
||||
|
||||
@override
|
||||
void resetTemp() {
|
||||
_countExercises = 0;
|
||||
_sumQuantity = 0;
|
||||
_maxQuantity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
class DiagramType {
|
||||
static String sumMass = "sumMass";
|
||||
static String oneRepMax = "oneRepMax";
|
||||
@ -33,7 +147,7 @@ class DiagramType {
|
||||
=========== GROUPDATE CLASS
|
||||
*/
|
||||
|
||||
class GroupDate extends GroupData with Calculate, Common {
|
||||
class GroupDate extends GroupData with Common {
|
||||
final List<Exercise> inputList;
|
||||
final List<Exercise> outputList;
|
||||
|
||||
@ -136,7 +250,7 @@ class GroupDate extends GroupData with Calculate, Common {
|
||||
/*
|
||||
=========== CHART DATA CLASS
|
||||
*/
|
||||
class GroupChart extends GroupData with Calculate {
|
||||
class GroupChart extends GroupData with Common {
|
||||
final List<dynamic> inputList;
|
||||
LinkedHashMap<int, ChartDataExtended> outputList = LinkedHashMap();
|
||||
|
||||
@ -186,9 +300,8 @@ class GroupChart extends GroupData with Calculate {
|
||||
_minData = diagramValue;
|
||||
}
|
||||
|
||||
BarChartGroupData data = BarChartGroupData(x: exercise.dateAdd!.millisecondsSinceEpoch, barRods: [
|
||||
BarChartRodData(y: diagramValue, width: 12, colors: [Colors.lightBlue, Colors.lightBlueAccent])
|
||||
]);
|
||||
BarChartGroupData data = BarChartGroupData(
|
||||
x: exercise.dateAdd!.millisecondsSinceEpoch, barRods: [BarChartRodData(toY: diagramValue, width: 12, color: Colors.lightBlue)]);
|
||||
_chartData.add(data);
|
||||
_origExerciseTypeId = exercise.exerciseTypeId!;
|
||||
}
|
||||
@ -262,7 +375,7 @@ class ChartDataExtended {
|
||||
element.barRods.forEach((rods) {
|
||||
var barChartData = {
|
||||
'x': element.x,
|
||||
'y': rods.y,
|
||||
'y': rods.toY,
|
||||
};
|
||||
listBarChartData.add(barChartData);
|
||||
});
|
||||
@ -274,20 +387,20 @@ class ChartDataExtended {
|
||||
};
|
||||
return chartData;
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Calculate, Logging {
|
||||
class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, DevelopmentByMuscleState> with Common, Logging {
|
||||
final WorkoutTreeRepository workoutTreeRepository;
|
||||
|
||||
final ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||
LinkedHashMap<int, ChartDataExtended> listChartData = LinkedHashMap();
|
||||
late List<BarChartGroupData> chartData;
|
||||
String diagramType = DiagramType.sumMass;
|
||||
String dateRate = DateRate.daily;
|
||||
double basePercent = 0;
|
||||
final List<DiagramData> diagramData = [];
|
||||
int actualExerciseType = 0;
|
||||
DiagramType diagramType = DiagramType.sumMass;
|
||||
DiagramDateType diagramDateType = DiagramDateType.monthly;
|
||||
|
||||
@override
|
||||
DevelopmentByMuscleBloc({required this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial());
|
||||
DevelopmentByMuscleBloc({required this.workoutTreeRepository}) : super(DevelopmentByMuscleStateInitial()) {
|
||||
on<DevelopmentByMuscleLoad>(_onLoad);
|
||||
}
|
||||
|
||||
Future<void> getData() async {
|
||||
workoutTreeRepository.sortedTree.clear();
|
||||
@ -299,93 +412,13 @@ class DevelopmentByMuscleBloc extends Bloc<DevelopmentByMuscleEvent, Development
|
||||
workoutTree.selected = false;
|
||||
});
|
||||
});
|
||||
|
||||
this.getChartData();
|
||||
}
|
||||
|
||||
void getChartData() {
|
||||
List<Exercise>? exercises = exerciseRepository.getExerciseList();
|
||||
|
||||
//print("-- Start calculate --- ");
|
||||
exercises = this.groupByDate(exercises);
|
||||
|
||||
exercises = sort(exercises, true);
|
||||
/* exercises.forEach((exercise) {
|
||||
print ("Chart exercise " + exercise.toJsonDatePart().toString());
|
||||
});*/
|
||||
|
||||
listChartData = LinkedHashMap();
|
||||
GroupChart groupChart = GroupChart(inputList: exercises, outputList: listChartData);
|
||||
groupChart.diagramType = this.diagramType;
|
||||
groupChart.iteration();
|
||||
listChartData = groupChart.outputList;
|
||||
|
||||
listChartData.forEach((key, value) {
|
||||
//trace("typeid " + key.toString() + " chardata " + value.toJson().toString());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
List<Exercise> groupByDate(List<Exercise>? exercises) {
|
||||
List<Exercise> groupedExercises = [];
|
||||
if (exercises != null) {
|
||||
exercises = sort(exercises, false);
|
||||
exercises.forEach((exercise) {
|
||||
//trace("Date exercise " + exercise.toJsonDatePart().toString());
|
||||
});
|
||||
|
||||
GroupDate groupDate = GroupDate(inputList: exercises, outputList: groupedExercises);
|
||||
groupDate.dateRate = this.dateRate;
|
||||
groupDate.diagramType = this.diagramType;
|
||||
groupDate.iteration();
|
||||
groupedExercises = groupDate.outputList;
|
||||
}
|
||||
|
||||
/* groupedExercises.forEach((element) {
|
||||
print("Grouped " + element.toJsonDatePart().toString());
|
||||
});*/
|
||||
|
||||
return groupedExercises;
|
||||
}
|
||||
|
||||
List<Exercise> sort(List<Exercise> exercises, bool asc) {
|
||||
exercises.sort((a, b) {
|
||||
var aDateId = a.exerciseTypeId.toString() + "_" + a.datePart.toString();
|
||||
var bDateId = b.exerciseTypeId.toString() + "_" + b.datePart.toString();
|
||||
|
||||
return asc ? aDateId.compareTo(bDateId) : bDateId.compareTo(aDateId);
|
||||
});
|
||||
return exercises;
|
||||
}
|
||||
|
||||
String getDateFormat(DateTime datetime) {
|
||||
return DateFormat('yMd', AppLanguage().appLocal.toString()).format(datetime);
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<DevelopmentByMuscleState> mapEventToState(DevelopmentByMuscleEvent event) async* {
|
||||
try {
|
||||
if (event is DevelopmentByMuscleLoad) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
Track().track(TrackingEvent.my_muscle_development);
|
||||
Cache().setActivityDonePrefs(ActivityDone.isMuscleDevelopmentSeen);
|
||||
await getData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
} else if (event is DevelopmentByMuscleDiagramTypeChange) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
String type = event.diagramType;
|
||||
this.diagramType = type;
|
||||
getChartData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
} else if (event is DevelopmentByMuscleDateRateChange) {
|
||||
yield DevelopmentByMuscleLoadingState();
|
||||
String dateRate = event.dateRate;
|
||||
this.dateRate = dateRate;
|
||||
getChartData();
|
||||
yield DevelopmentByMuscleReadyState();
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield DevelopmentByMuscleErrorState(message: e.toString());
|
||||
}
|
||||
void _onLoad(DevelopmentByMuscleLoad event, Emitter<DevelopmentByMuscleState> emit) async {
|
||||
emit(DevelopmentByMuscleLoadingState());
|
||||
Track().track(TrackingEvent.my_muscle_development);
|
||||
Cache().setActivityDonePrefs(ActivityDone.isMuscleDevelopmentSeen);
|
||||
await getData();
|
||||
emit(DevelopmentByMuscleReadyState());
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class DevelopmentByMuscleLoad extends DevelopmentByMuscleEvent {
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
|
||||
final String dateRate;
|
||||
final DiagramDateType dateRate;
|
||||
const DevelopmentByMuscleDateRateChange({required this.dateRate});
|
||||
|
||||
@override
|
||||
@ -21,7 +21,7 @@ class DevelopmentByMuscleDateRateChange extends DevelopmentByMuscleEvent {
|
||||
}
|
||||
|
||||
class DevelopmentByMuscleDiagramTypeChange extends DevelopmentByMuscleEvent {
|
||||
final String diagramType;
|
||||
final DiagramType diagramType;
|
||||
const DevelopmentByMuscleDiagramTypeChange({required this.diagramType});
|
||||
|
||||
@override
|
||||
|
319
lib/bloc/development_diagram/development_diagram_bloc.dart
Normal file
319
lib/bloc/development_diagram/development_diagram_bloc.dart
Normal file
@ -0,0 +1,319 @@
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/model/customer_property.dart';
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/diagram_data.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
part 'development_diagram_event.dart';
|
||||
part 'development_diagram_state.dart';
|
||||
|
||||
enum DiagramDataSource { customerProperty, exercise }
|
||||
|
||||
extension DiagramDataSourceExt on DiagramDataSource {
|
||||
String toStr() => this.toString().split(".").last;
|
||||
bool equalsTo(DiagramDataSource filter) => this.toString() == filter.toString();
|
||||
bool equalsStringTo(String filter) => this.toString() == filter;
|
||||
}
|
||||
|
||||
enum DiagramDateFilter { daily, monthly, weekly, yearly }
|
||||
|
||||
extension DiagramDateFilterExt on DiagramDateFilter {
|
||||
String toStr() => this.toString().split(".").last;
|
||||
bool equalsTo(DiagramDateFilter filter) => this.toString() == filter.toString();
|
||||
bool equalsStringTo(String filter) => this.toString() == filter;
|
||||
}
|
||||
|
||||
enum DiagramGroup { none, sumMass, oneRepMax, percent }
|
||||
|
||||
extension DiagramGroupExt on DiagramDateFilter {
|
||||
String toStr() => this.toString().split(".").last;
|
||||
bool equalsTo(DiagramGroup filter) => this.toString() == filter.toString();
|
||||
bool equalsStringTo(String filter) => this.toString() == filter;
|
||||
}
|
||||
|
||||
class DevelopmentDiagramBloc extends Bloc<DevelopmentDiagramEvent, DevelopmentDiagramState> with Common {
|
||||
DiagramDateFilter dateFilter = DiagramDateFilter.monthly;
|
||||
DiagramGroup group = DiagramGroup.sumMass;
|
||||
final List<DiagramData> diagramData = [];
|
||||
|
||||
CustomerRepository? customerRepository;
|
||||
ExerciseRepository? exerciseRepository;
|
||||
String? propertyName;
|
||||
int? exerciseTypeId;
|
||||
final String diagramTitle;
|
||||
bool isGroup = true;
|
||||
|
||||
DevelopmentDiagramBloc({required this.diagramTitle, this.customerRepository, this.exerciseRepository, this.propertyName, this.exerciseTypeId})
|
||||
: super(DevelopmentDiagramInitial()) {
|
||||
_init();
|
||||
on<DevelopmentDiagramLoad>(_onLoad);
|
||||
on<DevelopmentDiagramChangeDateFormat>(_onChangeDateFormat);
|
||||
on<DevelopmentDiagramChangeGroup>(_onChangeGroup);
|
||||
}
|
||||
|
||||
void _onLoad(DevelopmentDiagramLoad event, Emitter<DevelopmentDiagramState> emit) {
|
||||
emit(DevelopmentDiagramLoading());
|
||||
if (Cache().userLoggedIn == null) {
|
||||
emit(DevelopmentDiagramError(message: "Please log in"));
|
||||
return;
|
||||
}
|
||||
|
||||
emit(DevelopmentDiagramReady());
|
||||
}
|
||||
|
||||
void _init() {
|
||||
if (customerRepository != null) {
|
||||
final List<CustomerProperty> properties = this.customerRepository!.getAllCustomerPropertyByName(this.propertyName!);
|
||||
this.fillDataCustomerProperty(properties, this.dateFilter);
|
||||
this.isGroup = false;
|
||||
} else {
|
||||
this.isGroup = true;
|
||||
this.getExerciseData();
|
||||
}
|
||||
this.dateFilter = DiagramDateFilter.monthly;
|
||||
}
|
||||
|
||||
void _onChangeDateFormat(DevelopmentDiagramChangeDateFormat event, Emitter<DevelopmentDiagramState> emit) {
|
||||
emit(DevelopmentDiagramLoading());
|
||||
this.dateFilter = event.dateFilter;
|
||||
print("Filter: ${this.dateFilter} - property: ${this.propertyName}");
|
||||
if (customerRepository != null) {
|
||||
final List<CustomerProperty> properties = this.customerRepository!.getAllCustomerPropertyByName(this.propertyName!);
|
||||
this.fillDataCustomerProperty(properties, this.dateFilter);
|
||||
} else {
|
||||
this.getExerciseData();
|
||||
}
|
||||
|
||||
emit(DevelopmentDiagramReady());
|
||||
}
|
||||
|
||||
void _onChangeGroup(DevelopmentDiagramChangeGroup event, Emitter<DevelopmentDiagramState> emit) {
|
||||
emit(DevelopmentDiagramLoading());
|
||||
this.group = event.group;
|
||||
this.getExerciseData();
|
||||
emit(DevelopmentDiagramReady());
|
||||
}
|
||||
|
||||
void getExerciseData() {
|
||||
this.diagramData.clear();
|
||||
this.getChartData();
|
||||
}
|
||||
|
||||
List<DiagramData> getChartData() {
|
||||
List<Exercise>? exercises = exerciseRepository!.getExerciseList();
|
||||
List<Exercise> _exercises = [];
|
||||
if (this.exerciseTypeId != null) {
|
||||
exercises!.forEach((element) {
|
||||
if (element.exerciseTypeId == this.exerciseTypeId) {
|
||||
_exercises.add(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_exercises = sort(_exercises, true);
|
||||
|
||||
GroupDate groupDate = GroupDate(inputList: _exercises, outputList: this.diagramData);
|
||||
groupDate.dateRate = this.dateFilter;
|
||||
groupDate.diagramType = this.group;
|
||||
groupDate.iteration();
|
||||
|
||||
return this.diagramData;
|
||||
}
|
||||
|
||||
List<Exercise> sort(List<Exercise> _exercises, bool asc) {
|
||||
_exercises.sort((a, b) {
|
||||
var aDateId = a.exerciseTypeId.toString() + "_" + a.datePart.toString();
|
||||
var bDateId = b.exerciseTypeId.toString() + "_" + b.datePart.toString();
|
||||
|
||||
return asc ? aDateId.compareTo(bDateId) : bDateId.compareTo(aDateId);
|
||||
});
|
||||
return _exercises;
|
||||
}
|
||||
|
||||
void fillDataCustomerProperty(List<CustomerProperty> customerProperties, DiagramDateFilter filter) {
|
||||
this.diagramData.clear();
|
||||
this.dateFilter = filter;
|
||||
customerProperties.sort((a, b) => a.dateAdd!.compareTo(b.dateAdd!) > 0 ? 1 : -1);
|
||||
|
||||
double avg = 0;
|
||||
String? preFilter;
|
||||
if (this.dateFilter == DiagramDateFilter.daily) {
|
||||
preFilter = customerProperties[0].dateYmd;
|
||||
} else if (this.dateFilter == DiagramDateFilter.weekly) {
|
||||
preFilter = customerProperties[0].dateYmd;
|
||||
} else if (this.dateFilter == DiagramDateFilter.monthly) {
|
||||
preFilter = customerProperties[0].dateYm;
|
||||
} else if (this.dateFilter == DiagramDateFilter.yearly) {
|
||||
preFilter = customerProperties[0].dateY;
|
||||
}
|
||||
int counter = 0;
|
||||
customerProperties.forEach((element) {
|
||||
String? condition;
|
||||
if (this.dateFilter == DiagramDateFilter.daily) {
|
||||
condition = element.dateYmd;
|
||||
} else if (this.dateFilter == DiagramDateFilter.monthly) {
|
||||
condition = element.dateYm;
|
||||
} else if (this.dateFilter == DiagramDateFilter.weekly) {
|
||||
condition = element.dateYm;
|
||||
} else if (this.dateFilter == DiagramDateFilter.yearly) {
|
||||
condition = element.dateY;
|
||||
}
|
||||
|
||||
if (preFilter != condition) {
|
||||
int count = counter == 0 ? 1 : counter;
|
||||
DiagramData data = DiagramData(preFilter!, avg / count);
|
||||
//print("Sum: $avg count: $count Data: $data");
|
||||
diagramData.add(data);
|
||||
counter = 1;
|
||||
preFilter = condition;
|
||||
avg = element.propertyValue;
|
||||
} else {
|
||||
avg += element.propertyValue;
|
||||
counter++;
|
||||
}
|
||||
});
|
||||
int count = counter == 0 ? 1 : counter;
|
||||
if (preFilter != null) {
|
||||
DiagramData data = DiagramData(preFilter!, avg / count);
|
||||
diagramData.add(data);
|
||||
}
|
||||
print("Diagramdata: --- ${this.diagramData}");
|
||||
}
|
||||
}
|
||||
|
||||
class GroupDate extends GroupData with Common {
|
||||
final List<Exercise> inputList;
|
||||
final List<DiagramData> outputList;
|
||||
|
||||
String? _origDatePart;
|
||||
late int _origExerciseTypeId;
|
||||
late Exercise _origExercise;
|
||||
|
||||
late double _sumQuantity;
|
||||
late double _maxQuantity;
|
||||
late int _countExercises;
|
||||
double? _basePercent;
|
||||
|
||||
late DiagramGroup diagramType;
|
||||
late DiagramDateFilter dateRate;
|
||||
|
||||
GroupDate({required this.inputList, required this.outputList});
|
||||
|
||||
double getQuantityByDate(Exercise exercise) {
|
||||
double sum = 0;
|
||||
if (this.diagramType == DiagramGroup.sumMass) {
|
||||
if (exercise.unitQuantity != null) {
|
||||
sum = exercise.quantity! * exercise.unitQuantity!;
|
||||
} else {
|
||||
sum = exercise.quantity!;
|
||||
}
|
||||
} else if (this.diagramType == DiagramGroup.oneRepMax) {
|
||||
if (exercise.unitQuantity != null) {
|
||||
sum = calculate1RM(exercise.unitQuantity!, exercise.quantity!);
|
||||
} else {
|
||||
sum = exercise.quantity!;
|
||||
}
|
||||
} else if (this.diagramType == DiagramGroup.percent) {
|
||||
if (exercise.unitQuantity != null) {
|
||||
sum = calculate1RM(exercise.unitQuantity!, exercise.quantity!);
|
||||
if (_basePercent == null) {
|
||||
_basePercent = sum;
|
||||
}
|
||||
sum = (sum / this._basePercent!) * 100;
|
||||
} else {
|
||||
sum = exercise.quantity!;
|
||||
if (_basePercent == null) {
|
||||
_basePercent = sum;
|
||||
}
|
||||
sum = (sum / this._basePercent!) * 100;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@override
|
||||
void addTempData(Exercise exercise) {
|
||||
double newQuantity = getQuantityByDate(exercise);
|
||||
_sumQuantity = _sumQuantity + newQuantity;
|
||||
if (_maxQuantity < newQuantity) {
|
||||
_maxQuantity = newQuantity;
|
||||
}
|
||||
_countExercises = _countExercises + 1;
|
||||
_origDatePart = getDatePart(exercise.dateAdd!, dateRate);
|
||||
_origExerciseTypeId = exercise.exerciseTypeId!;
|
||||
_origExercise = exercise;
|
||||
}
|
||||
|
||||
@override
|
||||
bool checkNewType(Exercise exercise) {
|
||||
String exerciseDatePart = getDatePart(exercise.dateAdd!, dateRate);
|
||||
return _origDatePart == null || _origDatePart != exerciseDatePart || _origExerciseTypeId != exercise.exerciseTypeId;
|
||||
}
|
||||
|
||||
String getDatePart(DateTime date, DiagramDateFilter dateRate) {
|
||||
String datePart = DateFormat('yy.MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
if (dateRate == DiagramDateFilter.weekly) {
|
||||
datePart = weekNumber(date).toString();
|
||||
} else if (dateRate == DiagramDateFilter.monthly) {
|
||||
datePart = DateFormat('yy.MM', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DiagramDateFilter.yearly) {
|
||||
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DiagramDateFilter.daily) {
|
||||
datePart = DateFormat('yy.MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
}
|
||||
return datePart;
|
||||
}
|
||||
|
||||
@override
|
||||
void iteration() {
|
||||
this.resetTemp();
|
||||
Exercise? tempExercise;
|
||||
inputList.forEach((element) {
|
||||
tempExercise = element;
|
||||
if (this.checkNewType(element)) {
|
||||
if (_origDatePart == null) {
|
||||
this.addTempData(element);
|
||||
} else {
|
||||
this.temp2Output(_origExercise);
|
||||
this.resetTemp();
|
||||
this.addTempData(element);
|
||||
}
|
||||
} else {
|
||||
this.addTempData(element);
|
||||
}
|
||||
});
|
||||
if (tempExercise != null) {
|
||||
this.temp2Output(tempExercise!);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void temp2Output(Exercise exercise) {
|
||||
if (exercise.unitQuantity == null) {
|
||||
return;
|
||||
}
|
||||
Exercise newExercise = exercise.copy();
|
||||
newExercise.datePart = _origDatePart;
|
||||
if (this.diagramType == DiagramGroup.oneRepMax || this.diagramType == DiagramGroup.percent) {
|
||||
newExercise.calculated = _maxQuantity;
|
||||
} else {
|
||||
newExercise.calculated = _sumQuantity / _countExercises;
|
||||
}
|
||||
DiagramData data = DiagramData(newExercise.datePart!, newExercise.calculated);
|
||||
print("chart add $data");
|
||||
outputList.add(data);
|
||||
}
|
||||
|
||||
@override
|
||||
void resetTemp() {
|
||||
_countExercises = 0;
|
||||
_sumQuantity = 0;
|
||||
_maxQuantity = 0;
|
||||
}
|
||||
}
|
40
lib/bloc/development_diagram/development_diagram_event.dart
Normal file
40
lib/bloc/development_diagram/development_diagram_event.dart
Normal file
@ -0,0 +1,40 @@
|
||||
part of 'development_diagram_bloc.dart';
|
||||
|
||||
abstract class DevelopmentDiagramEvent extends Equatable {
|
||||
const DevelopmentDiagramEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DevelopmentDiagramLoad extends DevelopmentDiagramEvent {
|
||||
const DevelopmentDiagramLoad();
|
||||
}
|
||||
|
||||
class DevelopmentDiagramChangeDateFormat extends DevelopmentDiagramEvent {
|
||||
final DiagramDateFilter dateFilter;
|
||||
const DevelopmentDiagramChangeDateFormat({required this.dateFilter});
|
||||
}
|
||||
|
||||
class DevelopmentDiagramChangeGroup extends DevelopmentDiagramEvent {
|
||||
final DiagramGroup group;
|
||||
const DevelopmentDiagramChangeGroup({required this.group});
|
||||
}
|
||||
|
||||
class DevelopmentDiagramInitCustomerData extends DevelopmentDiagramEvent {
|
||||
final CustomerRepository customerRepository;
|
||||
final String propertyName;
|
||||
|
||||
const DevelopmentDiagramInitCustomerData({required this.customerRepository, required this.propertyName});
|
||||
@override
|
||||
List<Object> get props => [customerRepository, propertyName];
|
||||
}
|
||||
|
||||
class DevelopmentDiagramInitExerciseData extends DevelopmentDiagramEvent {
|
||||
final ExerciseRepository exerciseRepository;
|
||||
final int exerciseTypeId;
|
||||
|
||||
const DevelopmentDiagramInitExerciseData({required this.exerciseRepository, required this.exerciseTypeId});
|
||||
@override
|
||||
List<Object> get props => [exerciseRepository, exerciseTypeId];
|
||||
}
|
28
lib/bloc/development_diagram/development_diagram_state.dart
Normal file
28
lib/bloc/development_diagram/development_diagram_state.dart
Normal file
@ -0,0 +1,28 @@
|
||||
part of 'development_diagram_bloc.dart';
|
||||
|
||||
abstract class DevelopmentDiagramState extends Equatable {
|
||||
const DevelopmentDiagramState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DevelopmentDiagramInitial extends DevelopmentDiagramState {
|
||||
const DevelopmentDiagramInitial();
|
||||
}
|
||||
|
||||
class DevelopmentDiagramLoading extends DevelopmentDiagramState {
|
||||
const DevelopmentDiagramLoading();
|
||||
}
|
||||
|
||||
class DevelopmentDiagramReady extends DevelopmentDiagramState {
|
||||
const DevelopmentDiagramReady();
|
||||
}
|
||||
|
||||
class DevelopmentDiagramError extends DevelopmentDiagramState {
|
||||
final String message;
|
||||
const DevelopmentDiagramError({required this.message});
|
||||
|
||||
@override
|
||||
List<Object> get props => [this.message];
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
@ -11,22 +9,26 @@ part 'development_sizes_state.dart';
|
||||
class DevelopmentSizesBloc extends Bloc<DevelopmentSizesEvent, DevelopmentSizesState> {
|
||||
final CustomerRepository customerRepository;
|
||||
DevelopmentSizesBloc({required this.customerRepository}) : super(DevelopmentSizesInitial()) {
|
||||
isMan = Cache().userLoggedIn!.sex == "m";
|
||||
isMan = true;
|
||||
if ( Cache().userLoggedIn == null) {
|
||||
isMan = Cache().userLoggedIn!.sex == "m";
|
||||
}
|
||||
|
||||
on<DevelopmentSizesLoad>(_onLoad);
|
||||
}
|
||||
|
||||
late bool isMan;
|
||||
|
||||
@override
|
||||
Stream<DevelopmentSizesState> mapEventToState(
|
||||
DevelopmentSizesEvent event,
|
||||
) async* {
|
||||
try {
|
||||
if (state is DevelopmentSizesLoad) {
|
||||
yield DevelopmentSizesLoading();
|
||||
yield DevelopmentSizesReady();
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield DevelopmentSizesError(message: e.toString());
|
||||
void _onLoad(DevelopmentSizesLoad event, Emitter<DevelopmentSizesState> emit) {
|
||||
emit( DevelopmentSizesLoading());
|
||||
if ( Cache().userLoggedIn == null) {
|
||||
emit(DevelopmentSizesError(message: "Please log in" ));
|
||||
return;
|
||||
}
|
||||
customerRepository.customer = Cache().userLoggedIn!;
|
||||
emit( DevelopmentSizesReady());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import 'package:aitrainer_app/util/purchases.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:purchases_flutter/offering_wrapper.dart';
|
||||
import 'package:purchases_flutter/models/offering_wrapper.dart';
|
||||
|
||||
part 'sales_event.dart';
|
||||
part 'sales_state.dart';
|
||||
|
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
|
||||
part 'training_evaluation_event.dart';
|
||||
part 'training_evaluation_state.dart';
|
||||
|
||||
class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvaluationState> {
|
||||
class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvaluationState> with Common {
|
||||
final TrainingPlanBloc trainingPlanBloc;
|
||||
final String day;
|
||||
TrainingEvaluationBloc({required this.trainingPlanBloc, required this.day}) : super(TrainingEvaluationInitial()) {
|
||||
@ -42,32 +42,6 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@override
|
||||
Stream<TrainingEvaluationState> mapEventToState(
|
||||
TrainingEvaluationEvent event,
|
||||
) async* {
|
||||
try {
|
||||
if (event is TrainingEvaluationLoad) {
|
||||
//yield TrainingEvaluationLoading();
|
||||
await saveResult();
|
||||
getDuration();
|
||||
getTotalLift();
|
||||
getMaxRepeats();
|
||||
getTotalRepeats();
|
||||
createEvaluationData();
|
||||
getMaxLift();
|
||||
if (end == null || DateTime.now().difference(end!).inMinutes > 5) {
|
||||
yield TrainingEvaluationReady();
|
||||
} else {
|
||||
yield TrainingEvaluationVictoryReady();
|
||||
}
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
yield TrainingEvaluationError(message: e.toString());
|
||||
}
|
||||
} */
|
||||
|
||||
void createEvaluationData() {
|
||||
if (trainingPlanBloc.getMyPlan() == null || trainingPlanBloc.getMyPlan()!.days[day] == null) {
|
||||
return;
|
||||
@ -114,7 +88,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
exercise.trend = getTrendEvaluationRepeats(exercise);
|
||||
} else {
|
||||
exercise.type = TrainingEvaluationExerciseType.weightBased;
|
||||
exercise.oneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
exercise.oneRepMax = calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
exercise.max1RM = getMax1RMByExerciseType(detail.exerciseTypeId!);
|
||||
exercise.totalLift = getTotalLiftBySameExercise(detail.exerciseTypeId!);
|
||||
exercise.maxTotalLift = getMaxTotalLiftByExerciseType(detail.exerciseTypeId!);
|
||||
@ -300,7 +274,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
if (element.dateAdd != null) {
|
||||
final String formattedExerciseDate = formatter.format(element.dateAdd!);
|
||||
if (element.exerciseTypeId == exerciseTypeId && formattedToday != formattedExerciseDate) {
|
||||
final double oneRepMax = Common.calculate1RM(element.unitQuantity!, element.quantity!);
|
||||
final double oneRepMax = calculate1RM(element.unitQuantity!, element.quantity!);
|
||||
if (max1RM < oneRepMax) {
|
||||
max1RM = oneRepMax;
|
||||
}
|
||||
@ -330,7 +304,7 @@ class TrainingEvaluationBloc extends Bloc<TrainingEvaluationEvent, TrainingEvalu
|
||||
if (detail.weight == null) {
|
||||
return 0;
|
||||
}
|
||||
return Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
return calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
}
|
||||
|
||||
double getTotalLiftExercise(CustomerTrainingPlanDetails detail) {
|
||||
|
@ -27,7 +27,7 @@ import 'package:flutter/material.dart';
|
||||
part 'training_plan_event.dart';
|
||||
part 'training_plan_state.dart';
|
||||
|
||||
class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> with Common {
|
||||
final TrainingPlanRepository trainingPlanRepository;
|
||||
final MenuBloc menuBloc;
|
||||
TrainingPlanBloc({required this.trainingPlanRepository, required this.menuBloc}) : super(TrainingPlanInitial()) {
|
||||
@ -198,7 +198,6 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
|
||||
int baseCustomerTrainingPlanDetailsId = 0;
|
||||
if (eventDetail.exerciseType!.unitQuantity != null && eventDetail.weight! > 0) {
|
||||
double calculatedWeight = 0;
|
||||
for (var nextDetail in _myPlan!.details) {
|
||||
if (nextDetail.exerciseTypeId == eventDetail.exerciseTypeId) {
|
||||
if (id == 0 && nextDetail.customerTrainingPlanDetailsId == eventDetail.customerTrainingPlanDetailsId) {
|
||||
@ -214,7 +213,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
if (nextDetail.weight == -2 && nextDetail.customerTrainingPlanDetailsId != eventDetail.customerTrainingPlanDetailsId) {
|
||||
print("Nr 1. - recalculating -2 ${eventDetail.customerTrainingPlanDetailsId}");
|
||||
trainingPlanRepository.recalculateDetail(_myPlan!.trainingPlanId!, eventDetail, nextDetail);
|
||||
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
nextDetail.baseOneRepMax = calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
} /* else if (weightFromPlan == -1 && nextDetail.set! > 1 && nextDetail.exercises.length == 1) {
|
||||
print("Nr 2. recalculating -1 ${event.detail.customerTrainingPlanDetailsId}");
|
||||
nextDetail = trainingPlanRepository.recalculateDetailFixRepeats(_myPlan!.trainingPlanId!, nextDetail);
|
||||
@ -223,22 +222,21 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
else if (nextDetail.weight == -1 && nextDetail.set! == 1) {
|
||||
print("Nr 3. recalculating -1, set 1 ${eventDetail.customerTrainingPlanDetailsId}");
|
||||
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, eventDetail);
|
||||
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
nextDetail.baseOneRepMax = calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
} else if (eventDetail.set! == 1 &&
|
||||
(weightFromPlan == -2 || weightFromPlan == -1) &&
|
||||
nextDetail.customerTrainingPlanDetailsId! == id + 1 &&
|
||||
recalculate) {
|
||||
print("Nr 4. recalculating after the first exercise ${eventDetail.customerTrainingPlanDetailsId}");
|
||||
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, eventDetail);
|
||||
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
calculatedWeight = nextDetail.weight!;
|
||||
nextDetail.baseOneRepMax = calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
} else if (eventDetail.set! == 1 &&
|
||||
(weightFromPlan == -2 || weightFromPlan == -1) &&
|
||||
nextDetail.customerTrainingPlanDetailsId! > id + 1 &&
|
||||
recalculate) {
|
||||
print("Nr 5. recalculating after the second exercise ${eventDetail.customerTrainingPlanDetailsId}");
|
||||
nextDetail = trainingPlanRepository.recalculateDetailFixRepeatsSet1(_myPlan!.trainingPlanId!, nextDetail, eventDetail);
|
||||
nextDetail.baseOneRepMax = Common.calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
nextDetail.baseOneRepMax = calculate1RM(nextDetail.weight!, nextDetail.repeats!.toDouble());
|
||||
} else if (id != 0) {
|
||||
// calculate weight and repeat based on the first baseOneRepMax
|
||||
if (baseCustomerTrainingPlanDetailsId != 0) {
|
||||
@ -918,8 +916,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
if (_myDetail == null || _myDetail!.exerciseType == null) {
|
||||
return exerciseName;
|
||||
}
|
||||
exerciseName =
|
||||
AppLanguage().appLocal == Locale("en") ? getMyDetail()!.exerciseType!.name : getMyDetail()!.exerciseType!.nameTranslation;
|
||||
exerciseName = AppLanguage().appLocal == Locale("en") ? getMyDetail()!.exerciseType!.name : getMyDetail()!.exerciseType!.nameTranslation;
|
||||
return exerciseName;
|
||||
}
|
||||
|
||||
@ -1007,8 +1004,7 @@ class TrainingPlanBloc extends Bloc<TrainingPlanEvent, TrainingPlanState> {
|
||||
if (listDetail.exercises.length >= listDetail.set!) {
|
||||
listDetail.state = ExercisePlanDetailState.finished;
|
||||
}
|
||||
allFinished =
|
||||
allFinished && (listDetail.exercises.length >= listDetail.set! || listDetail.state.equalsTo(ExercisePlanDetailState.skipped));
|
||||
allFinished = allFinished && (listDetail.exercises.length >= listDetail.set! || listDetail.state.equalsTo(ExercisePlanDetailState.skipped));
|
||||
}
|
||||
//print("All finished: $allFinished for ${detail.exerciseTypeId}");
|
||||
return allFinished;
|
||||
|
@ -121,8 +121,7 @@ class AnimatedButton extends StatefulWidget {
|
||||
this.borderWidth = 1,
|
||||
this.blurColor = Colors.black,
|
||||
this.shadowColor,
|
||||
}) : assert(child != null),
|
||||
super(key: key);
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AnimatedButtonState createState() => _AnimatedButtonState(
|
||||
|
@ -258,7 +258,7 @@ class _BottomNavigationTile extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: item.title,
|
||||
child: Text(item.label!),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -288,7 +288,7 @@ class _BottomNavigationTile extends StatelessWidget {
|
||||
fontSize: _kActiveFontSize,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: item.title!,
|
||||
child: Text(item.label!),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -44,6 +44,7 @@ import 'package:aitrainer_app/view/test_set_execute.dart';
|
||||
import 'package:aitrainer_app/view/test_set_new.dart';
|
||||
import 'package:aitrainer_app/view/training_plan_activate_page.dart';
|
||||
import 'package:aitrainer_app/view/training_plan_exercise.dart';
|
||||
import 'package:aitrainer_app/widgets/development_diagram.dart';
|
||||
import 'package:aitrainer_app/widgets/home.dart';
|
||||
import 'package:aitrainer_app/library/facebook_app_events/facebook_app_events.dart';
|
||||
import 'package:firebase_analytics/firebase_analytics.dart';
|
||||
@ -282,6 +283,7 @@ class WorkoutTestApp extends StatelessWidget {
|
||||
'mydevelopmentMusclePage': (context) => MyDevelopmentMusclePage(),
|
||||
'mydevelopmentBodyPage': (context) => MyDevelopmentBodyPage(),
|
||||
'mydevelopmentSizesPage': (context) => SizesDevelopmentPage(),
|
||||
'developmentDiagramPage': (context) => DevelopmentDiagram(),
|
||||
'evaluationPage': (context) => EvaluationPage(),
|
||||
'salesPage': (context) => SalesPage(),
|
||||
'testSetEdit': (context) => TestSetEdit(),
|
||||
|
@ -2,6 +2,7 @@ import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'package:aitrainer_app/model/customer.dart';
|
||||
import 'package:aitrainer_app/model/customer_activity.dart';
|
||||
import 'package:aitrainer_app/model/customer_property.dart';
|
||||
import 'package:aitrainer_app/model/customer_training_plan.dart';
|
||||
import 'package:aitrainer_app/model/description.dart';
|
||||
import 'package:aitrainer_app/model/evaluation.dart';
|
||||
@ -158,6 +159,7 @@ class Cache with Logging {
|
||||
List<CustomerExerciseDevice>? _customerDevices;
|
||||
List<CustomerActivity>? _customerActivities;
|
||||
List<CustomerTrainingPlan>? _customerTrainingPlans;
|
||||
List<CustomerProperty>? _customerPropertyAll;
|
||||
|
||||
List<Tutorial>? _tutorials;
|
||||
List<Description>? _descriptions;
|
||||
@ -542,8 +544,7 @@ class Cache with Logging {
|
||||
|
||||
ExercisePlan? getMyExercisePlan() => _myExercisePlan;
|
||||
|
||||
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) =>
|
||||
_myExercisesPlanDetails = listExercisePlanDetail;
|
||||
void setMyExercisePlanDetails(LinkedHashMap<int, ExercisePlanDetail> listExercisePlanDetail) => _myExercisesPlanDetails = listExercisePlanDetail;
|
||||
|
||||
void addToMyExercisePlanDetails(ExercisePlanDetail detail) => _myExercisesPlanDetails[detail.exerciseTypeId] = detail;
|
||||
|
||||
@ -557,8 +558,7 @@ class Cache with Logging {
|
||||
|
||||
void deleteMyExercisePlanDetail(ExercisePlanDetail detail) => this.deleteMyExercisePlanDetailByExerciseTypeId(detail.exerciseTypeId);
|
||||
|
||||
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) =>
|
||||
this._myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted;
|
||||
void deletedMyExercisePlanDetail(ExercisePlanDetail detail) => this._myExercisesPlanDetails[detail.exerciseTypeId]!.change = ModelChange.deleted;
|
||||
|
||||
void deleteMyExercisePlanDetailByExerciseTypeId(int exerciseTypeId) {
|
||||
this._myExercisesPlanDetails[exerciseTypeId]!.change = ModelChange.delete;
|
||||
@ -772,10 +772,20 @@ class Cache with Logging {
|
||||
List<TrainingPlanDay> getTrainingPlanDays() => this._trainingPlanDays;
|
||||
setTrainingPlanDays(value) => this._trainingPlanDays = value;
|
||||
|
||||
List<CustomerProperty>? getCustomerPropertyAll() => this._customerPropertyAll;
|
||||
setCustomerPropertyAll(value) => this._customerPropertyAll = value;
|
||||
addCustomerProperty(CustomerProperty property) {
|
||||
if (this._customerPropertyAll == null) {
|
||||
this._customerPropertyAll = [];
|
||||
}
|
||||
this._customerPropertyAll!.add(property);
|
||||
}
|
||||
|
||||
bool canTrial() {
|
||||
bool can = true;
|
||||
if (Cache().userLoggedIn == null) {
|
||||
can = false;
|
||||
return can;
|
||||
}
|
||||
for (var element in _purchases) {
|
||||
if (element.customerId == Cache().userLoggedIn!.customerId) {
|
||||
|
@ -5,17 +5,33 @@ class CustomerProperty {
|
||||
late int propertyId;
|
||||
late int customerId;
|
||||
DateTime? dateAdd;
|
||||
String? dateYmd;
|
||||
String? dateYm;
|
||||
String? dateY;
|
||||
late double propertyValue;
|
||||
bool newData = false;
|
||||
|
||||
CustomerProperty({required this.propertyId, required this.customerId, required this.dateAdd, required this.propertyValue});
|
||||
CustomerProperty(
|
||||
{required this.propertyId,
|
||||
required this.customerId,
|
||||
required this.dateAdd,
|
||||
required this.propertyValue});
|
||||
|
||||
CustomerProperty.fromJson(Map json) {
|
||||
this.customerPropertyId = json['customerPropertyId'];
|
||||
this.propertyId = json['propertyId'];
|
||||
this.customerId = json['customerId'];
|
||||
this.dateAdd = json['dataAdd'] ?? DateTime.now();
|
||||
this.dateAdd = DateTime.parse(json['dateAdd']);
|
||||
|
||||
if (this.dateAdd != null) {
|
||||
dateYmd = DateFormat('yyyy-MM-dd').format(this.dateAdd!);
|
||||
dateYm = DateFormat('yyyy-MM').format(this.dateAdd!);
|
||||
dateY = DateFormat('yyyy').format(this.dateAdd!);
|
||||
}
|
||||
|
||||
this.propertyValue = json['propertyValue'];
|
||||
|
||||
print("Json $json, ${this.toString()}");
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
@ -36,4 +52,18 @@ class CustomerProperty {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
String toString() {
|
||||
Map<String, dynamic> json = {
|
||||
"customerPropertyId": this.customerPropertyId,
|
||||
"propertyId": this.propertyId,
|
||||
"customerId": this.customerId,
|
||||
"dateAdd": DateFormat('yyyy-MM-dd HH:mm:ss').format(this.dateAdd!),
|
||||
"propertyValue": this.propertyValue,
|
||||
"dateYmd": this.dateYmd,
|
||||
"dateYm": this.dateYm,
|
||||
"dateY": this.dateY,
|
||||
};
|
||||
return json.toString();
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,17 @@ class Property {
|
||||
this.propertyName = json['propertyName'];
|
||||
this.propertyUnit = json['propertyUnit'];
|
||||
this.propertyNameTranslation =
|
||||
json['translations'] != null && (json['translations']).length > 0 ? json['translations'][0]['propertyName'] : this.propertyName;
|
||||
json['translations'] != null && (json['translations']).length > 0
|
||||
? json['translations'][0]['propertyName']
|
||||
: this.propertyName;
|
||||
}
|
||||
|
||||
String toString() {
|
||||
Map<String, dynamic> json = {
|
||||
"propertyId": propertyId,
|
||||
"propertyName": propertyName,
|
||||
"propertyUnit": propertyUnit
|
||||
};
|
||||
return json.toString();
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ class CustomerRepository with Logging {
|
||||
Customer? customer;
|
||||
Customer? _trainee;
|
||||
List<Customer>? _trainees;
|
||||
List<CustomerProperty>? _allProperties;
|
||||
List<CustomerProperty>? _properties;
|
||||
List<CustomerProperty>? _allCustomerProperties;
|
||||
final PropertyRepository propertyRepository = PropertyRepository();
|
||||
final List<Property> womanSizes = [];
|
||||
final List<Property> manSizes = [];
|
||||
@ -43,6 +44,8 @@ class CustomerRepository with Logging {
|
||||
if (Cache().userLoggedIn != null) {
|
||||
isMan = (Cache().userLoggedIn!.sex == "m");
|
||||
}
|
||||
|
||||
_allCustomerProperties = Cache().getCustomerPropertyAll();
|
||||
}
|
||||
|
||||
String? getGenderByName(String name) {
|
||||
@ -164,7 +167,9 @@ class CustomerRepository with Logging {
|
||||
}
|
||||
|
||||
setCustomerProperty(String propertyName, double value, {id = 0}) {
|
||||
if (this.customer == null) throw Exception("Initialize the customer object");
|
||||
if (this.customer == null) {
|
||||
throw Exception("Initialize the customer object");
|
||||
}
|
||||
if (this.customer!.properties[propertyName] == null) {
|
||||
this.customer!.properties[propertyName] = CustomerProperty(
|
||||
propertyId: propertyRepository.getPropertyByName("Height")!.propertyId,
|
||||
@ -179,6 +184,7 @@ class CustomerRepository with Logging {
|
||||
if (id > 0) {
|
||||
this.customer!.properties[propertyName]!.customerPropertyId = id;
|
||||
}
|
||||
Cache().addCustomerProperty(this.customer!.properties[propertyName]!);
|
||||
}
|
||||
|
||||
double getWeight() {
|
||||
@ -277,7 +283,7 @@ class CustomerRepository with Logging {
|
||||
}
|
||||
|
||||
Future<void> savePropertyByName(String name) async {
|
||||
await Future.forEach(this._allProperties!, (element) async {
|
||||
await Future.forEach(this._properties!, (element) async {
|
||||
final CustomerProperty customerProperty = element as CustomerProperty;
|
||||
final Property? property = propertyRepository.getPropertyByName(name);
|
||||
if (property != null) {
|
||||
@ -303,12 +309,12 @@ class CustomerRepository with Logging {
|
||||
Future<List<CustomerProperty>> getAllCustomerProperties() async {
|
||||
int customerId = Cache().userLoggedIn!.customerId!;
|
||||
final results = await CustomerApi().getAllProperties(customerId);
|
||||
this._allProperties = results;
|
||||
this._properties = results;
|
||||
return results;
|
||||
}
|
||||
|
||||
List<CustomerProperty>? getAllProperties() {
|
||||
return this._allProperties;
|
||||
return this._properties;
|
||||
}
|
||||
|
||||
List<Customer>? getTraineesList() {
|
||||
@ -547,4 +553,21 @@ class CustomerRepository with Logging {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<CustomerProperty> getAllCustomerPropertyByName(String propertyName) {
|
||||
List<CustomerProperty> allProperties = [];
|
||||
|
||||
Property? property = propertyRepository.getPropertyByName(propertyName);
|
||||
print(property);
|
||||
if (property == null || Cache().getCustomerPropertyAll() == null) {
|
||||
return allProperties;
|
||||
}
|
||||
|
||||
Cache().getCustomerPropertyAll()!.forEach((element) {
|
||||
if (element.propertyId == property.propertyId) {
|
||||
allProperties.add(element);
|
||||
}
|
||||
});
|
||||
return allProperties;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import 'package:aitrainer_app/repository/training_plan_day_repository.dart';
|
||||
import 'package:aitrainer_app/util/app_language.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
|
||||
class TrainingPlanRepository {
|
||||
class TrainingPlanRepository with Common {
|
||||
ExerciseTree? parentTree;
|
||||
List<TrainingPlan> getPlansByParent(String parent) {
|
||||
final List<TrainingPlan> resultList = [];
|
||||
@ -165,7 +165,7 @@ class TrainingPlanRepository {
|
||||
|
||||
detail.state = ExercisePlanDetailState.start;
|
||||
if (detail.weight != null && detail.weight! > 0) {
|
||||
detail.baseOneRepMax = Common.calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
detail.baseOneRepMax = calculate1RM(detail.weight!, detail.repeats!.toDouble());
|
||||
}
|
||||
|
||||
// first repeat: 50% more
|
||||
@ -173,7 +173,7 @@ class TrainingPlanRepository {
|
||||
CustomerTrainingPlanDetails firstDetail = CustomerTrainingPlanDetails();
|
||||
firstDetail.copy(detail);
|
||||
firstDetail.repeats = (detail.repeats! * 1.5).round();
|
||||
firstDetail.baseOneRepMax = Common.calculate1RM(firstDetail.weight!, firstDetail.repeats!.toDouble());
|
||||
firstDetail.baseOneRepMax = calculate1RM(firstDetail.weight!, firstDetail.repeats!.toDouble());
|
||||
firstDetail.set = 1;
|
||||
detail.set = detail.set! - 1;
|
||||
if (detail.set! > 0) {
|
||||
@ -189,8 +189,7 @@ class TrainingPlanRepository {
|
||||
return list;
|
||||
}
|
||||
|
||||
CustomerTrainingPlanDetails isWeightCalculatedByExerciseType(
|
||||
int exerciseTypeId, CustomerTrainingPlanDetails detail, CustomerTrainingPlan plan) {
|
||||
CustomerTrainingPlanDetails isWeightCalculatedByExerciseType(int exerciseTypeId, CustomerTrainingPlanDetails detail, CustomerTrainingPlan plan) {
|
||||
CustomerTrainingPlanDetails calculated = detail;
|
||||
for (var element in plan.details) {
|
||||
if (element.exerciseTypeId == exerciseTypeId) {
|
||||
@ -290,7 +289,7 @@ class TrainingPlanRepository {
|
||||
actual.dateAdd!.year == exercise.dateAdd!.year &&
|
||||
actual.dateAdd!.month == exercise.dateAdd!.month &&
|
||||
actual.dateAdd!.day == exercise.dateAdd!.day) {
|
||||
double oneRepMax = Common.calculate1RM(exercise.unitQuantity!, exercise.quantity!);
|
||||
double oneRepMax = calculate1RM(exercise.unitQuantity!, exercise.quantity!);
|
||||
if (max1RM < oneRepMax) {
|
||||
max1RM = oneRepMax;
|
||||
}
|
||||
@ -350,16 +349,14 @@ class TrainingPlanRepository {
|
||||
}
|
||||
int originalRepeats = getOriginalRepeats(trainingPlanId, detail);
|
||||
|
||||
detail.weight =
|
||||
Common.calculateWeigthByChangedQuantity(detailWithData.weight!, detailWithData.repeats!.toDouble(), originalRepeats.toDouble());
|
||||
detail.weight = Common.calculateWeigthByChangedQuantity(detailWithData.weight!, detailWithData.repeats!.toDouble(), originalRepeats.toDouble());
|
||||
detail.weight = Common.roundWeight(detail.weight!);
|
||||
print("Recalculated weight: ${detail.weight}");
|
||||
detail.repeats = originalRepeats;
|
||||
return detail;
|
||||
}
|
||||
|
||||
CustomerTrainingPlanDetails recalculateDetail(
|
||||
int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) {
|
||||
CustomerTrainingPlanDetails recalculateDetail(int trainingPlanId, CustomerTrainingPlanDetails detail, CustomerTrainingPlanDetails nextDetail) {
|
||||
CustomerTrainingPlanDetails recalculatedDetail = nextDetail;
|
||||
|
||||
// 1. get original repeats
|
||||
@ -379,8 +376,7 @@ class TrainingPlanRepository {
|
||||
});
|
||||
|
||||
// 2 get recalculated repeats
|
||||
recalculatedDetail.weight =
|
||||
Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble());
|
||||
recalculatedDetail.weight = Common.calculateWeigthByChangedQuantity(detail.weight!, detail.repeats!.toDouble(), originalRepeats.toDouble());
|
||||
recalculatedDetail.weight = Common.roundWeight(recalculatedDetail.weight!);
|
||||
print("recalculated repeats for $originalRepeats: ${recalculatedDetail.weight}");
|
||||
//recalculatedDetail.repeats = originalRepeats;
|
||||
|
@ -44,44 +44,62 @@ class PackageApi {
|
||||
final List<String> headRecord = element.split("***");
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
if (headRecord[0] == "ExerciseDevice") {
|
||||
final List<ExerciseDevice> devices = json.map((device) => ExerciseDevice.fromJson(device)).toList();
|
||||
final List<ExerciseDevice> devices =
|
||||
json.map((device) => ExerciseDevice.fromJson(device)).toList();
|
||||
Cache().setDevices(devices);
|
||||
} else if (headRecord[0] == "Product") {
|
||||
final List<Product> products = json.map((product) => Product.fromJson(product)).toList();
|
||||
final List<Product> products =
|
||||
json.map((product) => Product.fromJson(product)).toList();
|
||||
Cache().setProducts(products);
|
||||
} else if (headRecord[0] == "Property") {
|
||||
final List<Property> properties = json.map((property) => Property.fromJson(property)).toList();
|
||||
final List<Property> properties =
|
||||
json.map((property) => Property.fromJson(property)).toList();
|
||||
Cache().setProperties(properties);
|
||||
} else if (headRecord[0] == "ExerciseTree") {
|
||||
exerciseTree = json.map((exerciseTree) => ExerciseTree.fromJson(exerciseTree)).toList();
|
||||
exerciseTree = json
|
||||
.map((exerciseTree) => ExerciseTree.fromJson(exerciseTree))
|
||||
.toList();
|
||||
} else if (headRecord[0] == "ExerciseType") {
|
||||
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
||||
final List<ExerciseType> exerciseTypes = json
|
||||
.map((exerciseType) => ExerciseType.fromJson(exerciseType))
|
||||
.toList();
|
||||
await Future.forEach(exerciseTypes, (elem) async {
|
||||
final ExerciseType exerciseType = elem as ExerciseType;
|
||||
exerciseType.imageUrl = await ExerciseTypeApi().buildImage(exerciseType.imageUrl, exerciseType.exerciseTypeId);
|
||||
exerciseType.imageUrl = await ExerciseTypeApi()
|
||||
.buildImage(exerciseType.imageUrl, exerciseType.exerciseTypeId);
|
||||
});
|
||||
Cache().setExerciseTypes(exerciseTypes);
|
||||
} else if (headRecord[0] == "ExerciseAbility") {
|
||||
} else if (headRecord[0] == "ExercisePlanTemplate") {
|
||||
final List<ExercisePlanTemplate> exercisePlanTemplates =
|
||||
json.map((exercisePlanTemplate) => ExercisePlanTemplate.fromJson(exercisePlanTemplate)).toList();
|
||||
final List<ExercisePlanTemplate> exercisePlanTemplates = json
|
||||
.map((exercisePlanTemplate) =>
|
||||
ExercisePlanTemplate.fromJson(exercisePlanTemplate))
|
||||
.toList();
|
||||
Cache().setExercisePlanTemplates(exercisePlanTemplates);
|
||||
} else if (headRecord[0] == "ExerciseTreeParents") {
|
||||
exerciseTreeParents = json.map((exerciseTreeParent) => ExerciseTreeParents.fromJson(exerciseTreeParent)).toList();
|
||||
exerciseTreeParents = json
|
||||
.map((exerciseTreeParent) =>
|
||||
ExerciseTreeParents.fromJson(exerciseTreeParent))
|
||||
.toList();
|
||||
} else if (headRecord[0] == "Evaluation") {
|
||||
final List<Evaluation> evaluations = json.map((evaluation) => Evaluation.fromJson(evaluation)).toList();
|
||||
final List<Evaluation> evaluations =
|
||||
json.map((evaluation) => Evaluation.fromJson(evaluation)).toList();
|
||||
Cache().evaluations = evaluations;
|
||||
} else if (headRecord[0] == "Sport") {
|
||||
final List<Sport> sports = json.map((sport) => Sport.fromJson(sport)).toList();
|
||||
final List<Sport> sports =
|
||||
json.map((sport) => Sport.fromJson(sport)).toList();
|
||||
Cache().setSports(sports);
|
||||
} else if (headRecord[0] == "Tutorial") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Tutorial> tutorials = json.map((tutorial) => Tutorial.fromJson(tutorial)).toList();
|
||||
final List<Tutorial> tutorials =
|
||||
json.map((tutorial) => Tutorial.fromJson(tutorial)).toList();
|
||||
|
||||
Cache().setTutorials(tutorials);
|
||||
} else if (headRecord[0] == "Description") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Description>? descriptions = json.map((description) => Description.fromJson(description)).toList();
|
||||
final List<Description>? descriptions = json
|
||||
.map((description) => Description.fromJson(description))
|
||||
.toList();
|
||||
//print("Description: $descriptions");
|
||||
Cache().setDescriptions(descriptions);
|
||||
} else if (headRecord[0] == "Faq") {
|
||||
@ -91,7 +109,8 @@ class PackageApi {
|
||||
Cache().setFaqs(faqs);
|
||||
} else if (headRecord[0] == "TrainingPlan") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<TrainingPlan>? plans = json.map((plan) => TrainingPlan.fromJson(plan)).toList();
|
||||
final List<TrainingPlan>? plans =
|
||||
json.map((plan) => TrainingPlan.fromJson(plan)).toList();
|
||||
|
||||
List<TrainingPlan> activePlans = [];
|
||||
if (plans != null) {
|
||||
@ -104,31 +123,38 @@ class PackageApi {
|
||||
Cache().setTrainingPlans(activePlans);
|
||||
} else if (headRecord[0] == "SplitTests") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<SplitTest>? tests = json.map((test) => SplitTest.fromJson(test)).toList();
|
||||
final List<SplitTest>? tests =
|
||||
json.map((test) => SplitTest.fromJson(test)).toList();
|
||||
//print("A/B tests: $tests");
|
||||
Cache().setSplitTests(tests);
|
||||
} else if (headRecord[0] == "TrainingPlanDay") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<TrainingPlanDay>? days = json.map((day) => TrainingPlanDay.fromJson(day)).toList();
|
||||
final List<TrainingPlanDay>? days =
|
||||
json.map((day) => TrainingPlanDay.fromJson(day)).toList();
|
||||
Cache().setTrainingPlanDays(days);
|
||||
}
|
||||
});
|
||||
|
||||
exerciseTree = this.getExerciseTreeParents(exerciseTree, exerciseTreeParents);
|
||||
exerciseTree =
|
||||
this.getExerciseTreeParents(exerciseTree, exerciseTreeParents);
|
||||
|
||||
await Future.forEach(exerciseTree, (element) async {
|
||||
ExerciseTree tree = element as ExerciseTree;
|
||||
tree.imageUrl = await ExerciseTreeApi().buildImage(tree.imageUrl, tree.treeId);
|
||||
tree.imageUrl =
|
||||
await ExerciseTreeApi().buildImage(tree.imageUrl, tree.treeId);
|
||||
});
|
||||
Cache().setExerciseTree(exerciseTree);
|
||||
|
||||
TrainingPlanDayRepository trainingPlanDayRepository = TrainingPlanDayRepository();
|
||||
TrainingPlanDayRepository trainingPlanDayRepository =
|
||||
TrainingPlanDayRepository();
|
||||
trainingPlanDayRepository.assignTrainingPlanDays();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
List<ExerciseTree> getExerciseTreeParents(final List<ExerciseTree> exerciseTree, final List<ExerciseTreeParents> exerciseTreeParents) {
|
||||
List<ExerciseTree> getExerciseTreeParents(
|
||||
final List<ExerciseTree> exerciseTree,
|
||||
final List<ExerciseTreeParents> exerciseTreeParents) {
|
||||
List<ExerciseTree> copyList = ExerciseTreeApi().copyList(exerciseTree);
|
||||
|
||||
int treeIndex = 0;
|
||||
@ -158,7 +184,8 @@ class PackageApi {
|
||||
|
||||
Future<void> getCustomerPackage(int customerId) async {
|
||||
try {
|
||||
final body = await _client.get("app_customer_package/" + customerId.toString(), "");
|
||||
final body = await _client.get(
|
||||
"app_customer_package/" + customerId.toString(), "");
|
||||
|
||||
final List<String> models = body.split("|||");
|
||||
await Future.forEach(models, (elem) async {
|
||||
@ -170,21 +197,35 @@ class PackageApi {
|
||||
Cache().userLoggedIn = customer;
|
||||
} else if (headRecord[0] == "CustomerExerciseDevice") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerExerciseDevice> devices = json.map((device) => CustomerExerciseDevice.fromJson(device)).toList();
|
||||
final List<CustomerExerciseDevice> devices = json
|
||||
.map((device) => CustomerExerciseDevice.fromJson(device))
|
||||
.toList();
|
||||
Cache().setCustomerDevices(devices);
|
||||
// ToDo
|
||||
} else if (headRecord[0] == "Exercises") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Exercise> exercises = json.map((exerciseType) => Exercise.fromJson(exerciseType)).toList();
|
||||
final List<Exercise> exercises = json
|
||||
.map((exerciseType) => Exercise.fromJson(exerciseType))
|
||||
.toList();
|
||||
Cache().setExercises(exercises);
|
||||
} else if (headRecord[0] == "Purchase") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<Purchase> purchases = json.map((purchase) => Purchase.fromJson(purchase)).toList();
|
||||
final List<Purchase> purchases =
|
||||
json.map((purchase) => Purchase.fromJson(purchase)).toList();
|
||||
Cache().setPurchases(purchases);
|
||||
} else if (headRecord[0] == "CustomerProperty") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerProperty> customerProperties = json.map((property) => CustomerProperty.fromJson(property)).toList();
|
||||
final List<CustomerProperty> customerProperties = json
|
||||
.map((property) => CustomerProperty.fromJson(property))
|
||||
.toList();
|
||||
CustomerApi().initProperties(customerProperties);
|
||||
} else if (headRecord[0] == "CustomerPropertyAll") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerProperty> allCustomerProperties = json
|
||||
.map((property) => CustomerProperty.fromJson(property))
|
||||
.toList();
|
||||
print(" All Properties ---- $allCustomerProperties");
|
||||
Cache().setCustomerPropertyAll(allCustomerProperties);
|
||||
} else if (headRecord[0] == "ExerciseResult") {
|
||||
/*final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<ExerciseResult> exerciseResults = json.map((exerciseResult) {
|
||||
@ -194,7 +235,9 @@ class PackageApi {
|
||||
// ToDo */
|
||||
} else if (headRecord[0] == "CustomerActivity") {
|
||||
final Iterable json = jsonDecode(headRecord[1]);
|
||||
final List<CustomerActivity> customerActivities = json.map((activity) => CustomerActivity.fromJson(activity)).toList();
|
||||
final List<CustomerActivity> customerActivities = json
|
||||
.map((activity) => CustomerActivity.fromJson(activity))
|
||||
.toList();
|
||||
Cache().setCustomerActivities(customerActivities);
|
||||
}
|
||||
});
|
||||
|
@ -1,15 +0,0 @@
|
||||
mixin Calculate {
|
||||
|
||||
double calculate1RM(double quantity, double unitQuantity) {
|
||||
double weight = unitQuantity;
|
||||
double repeat = quantity;
|
||||
if ( weight == 0 || repeat == 0) {
|
||||
return 0;
|
||||
}
|
||||
double rmWendler = weight * repeat * 0.0333 + weight;
|
||||
double rmOconner = weight * (1 + repeat / 40);
|
||||
double average = (rmWendler + rmOconner)/2;
|
||||
|
||||
return average;
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ mixin Common {
|
||||
String getDateLocale(DateTime datetime, bool timeDisplay) {
|
||||
var date = datetime;
|
||||
|
||||
String dateName = DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(date.toUtc());
|
||||
String dateName = DateFormat(DateFormat.YEAR_NUM_MONTH_DAY, AppLanguage().appLocal.toString()).format(date.toUtc());
|
||||
if (timeDisplay) {
|
||||
dateName += " " + DateFormat(DateFormat.HOUR_MINUTE, AppLanguage().appLocal.toString()).format(date.toUtc());
|
||||
}
|
||||
@ -82,20 +82,6 @@ mixin Common {
|
||||
return ((dayOfYear - date.weekday + 10) / 7).floor();
|
||||
}
|
||||
|
||||
String getDatePart(DateTime date, String dateRate) {
|
||||
String datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
if (dateRate == DateRate.weekly) {
|
||||
datePart = weekNumber(date).toString();
|
||||
} else if (dateRate == DateRate.monthly) {
|
||||
datePart = DateFormat('MMM', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DateRate.yearly) {
|
||||
datePart = DateFormat('y', AppLanguage().appLocal.toString()).format(date);
|
||||
} else if (dateRate == DateRate.daily) {
|
||||
datePart = DateFormat('MM.dd', AppLanguage().appLocal.toString()).format(date);
|
||||
}
|
||||
return datePart;
|
||||
}
|
||||
|
||||
static String? emailValidation(String? email) {
|
||||
final String error = "Please type an email address";
|
||||
if (email == null) {
|
||||
@ -146,7 +132,7 @@ mixin Common {
|
||||
return value;
|
||||
}
|
||||
|
||||
static double calculate1RM(double weight, double repeat) {
|
||||
double calculate1RM(double weight, double repeat) {
|
||||
if (weight == 0 || repeat == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -207,8 +193,7 @@ mixin Common {
|
||||
final double repeatWendler = (rmWendler - changedWeight) / 0.0333 / changedWeight;
|
||||
final double repeatOconner = (rmOconner / changedWeight - 1) * 40;
|
||||
final newRepeat = ((repeatOconner + repeatWendler) / 2).ceil();
|
||||
print(
|
||||
"Weight: $weight changedWeight: $changedWeight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat");
|
||||
print("Weight: $weight changedWeight: $changedWeight repeatWendler: $repeatWendler repeat Oconner: $repeatOconner. NEW REPEAT: $newRepeat");
|
||||
return newRepeat;
|
||||
}
|
||||
|
||||
|
26
lib/util/diagram_data.dart
Normal file
26
lib/util/diagram_data.dart
Normal file
@ -0,0 +1,26 @@
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
|
||||
abstract class GroupData {
|
||||
void iteration();
|
||||
|
||||
bool checkNewType(Exercise exercise);
|
||||
|
||||
void addTempData(Exercise element);
|
||||
|
||||
void temp2Output(Exercise exercise);
|
||||
|
||||
void resetTemp();
|
||||
}
|
||||
|
||||
class DiagramData {
|
||||
final String x;
|
||||
final double? y;
|
||||
DiagramData(this.x, this.y);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> json = {"x": this.x, "y": this.y};
|
||||
return json;
|
||||
}
|
||||
|
||||
String toString() => this.toJson().toString();
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import 'package:aitrainer_app/model/exercise.dart';
|
||||
|
||||
abstract class GroupData {
|
||||
|
||||
void iteration();
|
||||
|
||||
bool checkNewType(Exercise exercise);
|
||||
|
||||
void addTempData(Exercise element);
|
||||
|
||||
void temp2Output(Exercise exercise);
|
||||
|
||||
void resetTemp();
|
||||
|
||||
}
|
@ -207,9 +207,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white24,
|
||||
border: Border.all(color: Colors.black, width: 0.4),
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
color: Colors.white24, border: Border.all(color: Colors.black, width: 0.4), borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
child: Column(children: [
|
||||
Text(t("Birth Year"),
|
||||
style: GoogleFonts.inter(
|
||||
@ -257,8 +255,8 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
||||
orientation: LinearGaugeOrientation.horizontal,
|
||||
majorTickStyle: LinearTickStyle(length: 20),
|
||||
axisLabelStyle: TextStyle(fontSize: 12.0, color: Colors.black),
|
||||
axisTrackStyle: LinearAxisTrackStyle(
|
||||
color: Colors.cyan, edgeStyle: LinearEdgeStyle.bothFlat, thickness: 1.0, borderColor: Colors.grey)),
|
||||
axisTrackStyle:
|
||||
LinearAxisTrackStyle(color: Colors.cyan, edgeStyle: LinearEdgeStyle.bothFlat, thickness: 1.0, borderColor: Colors.grey)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
@ -270,9 +268,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white24,
|
||||
border: Border.all(color: Colors.black, width: 0.4),
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
color: Colors.white24, border: Border.all(color: Colors.black, width: 0.4), borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
child: Column(children: [
|
||||
Text(t("Weight"),
|
||||
style: GoogleFonts.inter(
|
||||
@ -300,9 +296,7 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white24,
|
||||
border: Border.all(color: Colors.black, width: 0.4),
|
||||
borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
color: Colors.white24, border: Border.all(color: Colors.black, width: 0.4), borderRadius: BorderRadius.all(Radius.circular(12))),
|
||||
child: Column(children: [
|
||||
Text(t("Height"),
|
||||
style: GoogleFonts.inter(
|
||||
@ -376,14 +370,15 @@ class CustomerModifyPage extends StatelessWidget with Trans {
|
||||
minHeight: 50.0,
|
||||
fontSize: 14.0,
|
||||
initialLabelIndex: customerBloc.customerRepository.customer!.sex == "m" ? 0 : 1,
|
||||
activeBgColor: Colors.indigo,
|
||||
activeBgColor: [Colors.indigo],
|
||||
activeFgColor: Colors.white,
|
||||
inactiveBgColor: Colors.white30,
|
||||
inactiveFgColor: Colors.grey[900],
|
||||
labels: [t('Man'), t('Woman')],
|
||||
onToggle: (index) {
|
||||
customerBloc.add(CustomerGenderChange(gender: index));
|
||||
customerBloc.add(CustomerGenderChange(gender: index!));
|
||||
},
|
||||
totalSwitches: 2,
|
||||
),
|
||||
Divider(),
|
||||
Divider(),
|
||||
|
@ -34,8 +34,8 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
|
||||
create: (context) => TrainingLogBloc()..add(TrainingLogLoad()),
|
||||
child: BlocConsumer<TrainingLogBloc, TrainingLogState>(listener: (context, state) {
|
||||
if (state is TrainingLogError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final bloc = BlocProvider.of<TrainingLogBloc>(context);
|
||||
@ -88,7 +88,14 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
|
||||
Widget getCalendar(TrainingLogBloc bloc) {
|
||||
return Expanded(
|
||||
child: SfCalendarTheme(
|
||||
data: SfCalendarThemeData(brightness: Brightness.dark, backgroundColor: Colors.transparent),
|
||||
data: SfCalendarThemeData(
|
||||
brightness: Brightness.dark,
|
||||
backgroundColor: Colors.transparent,
|
||||
agendaDayTextStyle: GoogleFonts.inter(color: Colors.white),
|
||||
agendaDateTextStyle: GoogleFonts.inter(color: Colors.white),
|
||||
weekNumberTextStyle: GoogleFonts.inter(color: Colors.white),
|
||||
viewHeaderDayTextStyle: GoogleFonts.inter(color: Colors.white),
|
||||
),
|
||||
child: SfCalendar(
|
||||
dataSource: TrainingDataSource(bloc.results),
|
||||
allowedViews: [
|
||||
@ -97,14 +104,22 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
|
||||
],
|
||||
view: CalendarView.month,
|
||||
monthViewSettings: MonthViewSettings(
|
||||
showAgenda: true,
|
||||
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
|
||||
showTrailingAndLeadingDates: true,
|
||||
appointmentDisplayCount: 12,
|
||||
),
|
||||
showAgenda: true,
|
||||
appointmentDisplayMode: MonthAppointmentDisplayMode.indicator,
|
||||
showTrailingAndLeadingDates: true,
|
||||
appointmentDisplayCount: 12,
|
||||
monthCellStyle: MonthCellStyle(
|
||||
textStyle: GoogleFonts.inter(color: Colors.white),
|
||||
leadingDatesTextStyle: GoogleFonts.inter(color: Colors.white54),
|
||||
trailingDatesTextStyle: GoogleFonts.inter(color: Colors.white54),
|
||||
)),
|
||||
appointmentTimeTextFormat: 'HH:mm',
|
||||
headerDateFormat: "y MMMM",
|
||||
headerStyle: CalendarHeaderStyle(
|
||||
textStyle: GoogleFonts.inter(color: Colors.white),
|
||||
),
|
||||
firstDayOfWeek: 1, // Monday
|
||||
cellBorderColor: Colors.white54,
|
||||
selectionDecoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
border: Border.all(color: Color(0xffb4f500), width: 2),
|
||||
@ -145,8 +160,7 @@ class MyDevelopmentLog extends StatelessWidget with Trans, Common {
|
||||
fit: FlexFit.tight,
|
||||
flex: 30,
|
||||
child: Text(result.eventName,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: result.isExercise ? 14 : 16, color: result.color, fontWeight: FontWeight.bold)),
|
||||
style: GoogleFonts.inter(fontSize: result.isExercise ? 14 : 16, color: result.color, fontWeight: FontWeight.bold)),
|
||||
),
|
||||
Visibility(
|
||||
visible: result.isExercise,
|
||||
|
@ -5,7 +5,6 @@ import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_premium.dart';
|
||||
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
|
||||
import 'package:fl_chart/fl_chart.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/bloc/development_by_muscle/development_by_muscle_bloc.dart';
|
||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
@ -21,7 +20,6 @@ class MyDevelopmentMusclePage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Common, Trans {
|
||||
// ignore: close_sinks
|
||||
late DevelopmentByMuscleBloc bloc;
|
||||
late double cWidth;
|
||||
|
||||
@ -88,7 +86,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
||||
} else {
|
||||
return TreeView(
|
||||
startExpanded: false,
|
||||
children: _getTreeChildren(bloc.workoutTreeRepository.sortedTree, bloc),
|
||||
children: _getTreeChildren(bloc),
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -98,9 +96,7 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _getTreeChildren(SplayTreeMap tree, DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> exerciseTypes = [];
|
||||
|
||||
Card getExplanation(DevelopmentByMuscleBloc bloc) {
|
||||
Card explanation = Card(
|
||||
color: Colors.white60,
|
||||
child: Container(
|
||||
@ -128,97 +124,27 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
||||
t("Here you see you development in the last period."),
|
||||
style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(
|
||||
Icons.bubble_chart,
|
||||
),
|
||||
label: Text(t('Sum Of Mass')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.sumMass,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.sumMass))},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.accessibility_new),
|
||||
label: Text(t('One Rep Max')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.oneRepMax,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.oneRepMax))},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.perm_device_information),
|
||||
label: Text(t('Percent')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.diagramType == DiagramType.percent,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDiagramTypeChange(diagramType: DiagramType.percent))},
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Detailed')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
disabledColor: Colors.black26,
|
||||
selectedColor: Colors.greenAccent,
|
||||
selected: bloc.dateRate == DateRate.daily,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.daily))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Weekly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white12,
|
||||
tooltip: "Heti bontás",
|
||||
selected: bloc.dateRate == DateRate.weekly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.weekly))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Monthly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.black26,
|
||||
selected: bloc.dateRate == DateRate.monthly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.monthly))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Yearly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white70,
|
||||
selected: bloc.dateRate == DateRate.yearly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentByMuscleDateRateChange(dateRate: DateRate.yearly))},
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
)));
|
||||
return explanation;
|
||||
}
|
||||
|
||||
List<Widget> _getTreeChildren(DevelopmentByMuscleBloc bloc) {
|
||||
List<Widget> exerciseTypes = [];
|
||||
|
||||
Card explanation = this.getExplanation(bloc);
|
||||
exerciseTypes.add(explanation);
|
||||
|
||||
LinkedHashMap<String, dynamic> rc = LinkedHashMap();
|
||||
tree.forEach((name, list) {
|
||||
bloc.workoutTreeRepository.sortedTree.forEach((name, list) {
|
||||
rc = _getChildList(list, bloc);
|
||||
final List<Widget> children = rc['list'];
|
||||
final bool hasNoData = rc['hasNoData'];
|
||||
exerciseTypes.add(Container(
|
||||
margin: const EdgeInsets.only(left: 4.0),
|
||||
margin: const EdgeInsets.only(left: 8.0),
|
||||
child: TreeViewChild(
|
||||
startExpanded: false,
|
||||
parent: _getExerciseWidget(exerciseTypeName: name, noData: hasNoData),
|
||||
parent: _getExerciseGroupWidget(exerciseTypeName: name, noData: hasNoData),
|
||||
children: children,
|
||||
)));
|
||||
});
|
||||
@ -226,104 +152,47 @@ class _MyDevelopmentMuscleState extends State<MyDevelopmentMusclePage> with Comm
|
||||
return exerciseTypes;
|
||||
}
|
||||
|
||||
Widget _getExerciseGroupWidget({required String exerciseTypeName, bool noData = false}) {
|
||||
return TreeviewParentWidget(
|
||||
text: exerciseTypeName,
|
||||
backgroundColor: !noData ? Colors.white38 : Colors.white12,
|
||||
color: !noData ? Colors.blue[800] : Colors.blue[100],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _getExerciseWidget({required String exerciseTypeName, bool noData = false}) {
|
||||
return TreeviewParentWidget(
|
||||
text: exerciseTypeName,
|
||||
backgroundColor: !noData ? Colors.white38 : Colors.white12,
|
||||
color: !noData ? Colors.blue[800] : Colors.grey[400]);
|
||||
text: exerciseTypeName,
|
||||
backgroundColor: !noData ? Colors.white38 : Colors.white12,
|
||||
color: !noData ? Colors.blue[700] : Colors.blue[100],
|
||||
fontSize: 16,
|
||||
);
|
||||
}
|
||||
|
||||
LinkedHashMap<String, dynamic> _getChildList(List<WorkoutMenuTree> listWorkoutTree, DevelopmentByMuscleBloc bloc) {
|
||||
LinkedHashMap<String, dynamic> rc = LinkedHashMap();
|
||||
List<Widget> list = [];
|
||||
bool hasSummaryNoData = true;
|
||||
listWorkoutTree.forEach((element) {
|
||||
final bool hasNoData = (bloc.listChartData[element.exerciseTypeId] == null);
|
||||
hasSummaryNoData = hasSummaryNoData && hasNoData;
|
||||
String unit = " kg";
|
||||
if (bloc.diagramType == DiagramType.percent) {
|
||||
unit = " %";
|
||||
}
|
||||
list.add(SizedBox(
|
||||
width: cWidth * 0.85,
|
||||
height: hasNoData ? 0 : 200,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 5, top: 5, right: 5, bottom: 5),
|
||||
color: Colors.white70,
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
hasNoData
|
||||
? Container()
|
||||
: Text(
|
||||
element.exerciseType!.nameTranslation,
|
||||
style: TextStyle(color: Colors.deepOrange),
|
||||
),
|
||||
hasNoData
|
||||
? Container(
|
||||
//child: Text("no data for " + element.exerciseType.nameTranslation),
|
||||
)
|
||||
: Expanded(
|
||||
//fit: FlexFit.loose,
|
||||
child: BarChart(
|
||||
BarChartData(
|
||||
alignment: BarChartAlignment.spaceAround,
|
||||
barTouchData: BarTouchData(
|
||||
touchTooltipData: BarTouchTooltipData(
|
||||
tooltipBgColor: Colors.white70,
|
||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||
return BarTooltipItem(
|
||||
rod.y.toStringAsFixed(0) + unit,
|
||||
TextStyle(color: Colors.black54, fontSize: 12, fontWeight: FontWeight.bold),
|
||||
);
|
||||
}),
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
show: true,
|
||||
bottomTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (_) => TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
getTitles: (double value) {
|
||||
var date = new DateTime.fromMillisecondsSinceEpoch(value.toInt());
|
||||
String strDate = getDatePart(date, bloc.dateRate);
|
||||
return strDate;
|
||||
},
|
||||
),
|
||||
leftTitles: SideTitles(
|
||||
showTitles: true,
|
||||
getTextStyles: (_) => TextStyle(fontSize: 8, color: Colors.blueGrey),
|
||||
interval: bloc.listChartData[element.exerciseTypeId] == null ||
|
||||
bloc.listChartData[element.exerciseTypeId]!.interval == 0
|
||||
? 100
|
||||
: bloc.listChartData[element.exerciseTypeId]!.interval,
|
||||
margin: 10,
|
||||
getTitles: (double value) {
|
||||
return value.toStringAsFixed(0) + unit;
|
||||
})),
|
||||
borderData: FlBorderData(
|
||||
show: false,
|
||||
),
|
||||
gridData: FlGridData(
|
||||
show: true,
|
||||
checkToShowHorizontalLine: (value) => value % bloc.listChartData[element.exerciseTypeId]!.gridInterval == 0,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.black26,
|
||||
strokeWidth: 0.5,
|
||||
);
|
||||
},
|
||||
),
|
||||
groupsSpace: 2,
|
||||
barGroups:
|
||||
bloc.listChartData[element.exerciseTypeId] == null ? [] : bloc.listChartData[element.exerciseTypeId]!.data,
|
||||
),
|
||||
swapAnimationDuration: Duration(milliseconds: 1200),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
));
|
||||
});
|
||||
rc['list'] = list;
|
||||
rc['hasNoData'] = hasSummaryNoData;
|
||||
rc['hasNoData'] = false;
|
||||
listWorkoutTree.forEach((element) {
|
||||
list.add(Container(
|
||||
margin: const EdgeInsets.only(left: 8.0),
|
||||
child: TreeViewChild(
|
||||
parent: _getExerciseWidget(exerciseTypeName: element.exerciseType!.nameTranslation),
|
||||
children: [],
|
||||
onTap: () => onPressed(bloc, element),
|
||||
)));
|
||||
});
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void onPressed(DevelopmentByMuscleBloc bloc, WorkoutMenuTree element) {
|
||||
HashMap<String, dynamic> args = HashMap();
|
||||
args['exerciseRepository'] = bloc.exerciseRepository;
|
||||
args['workoutTreeRepository'] = bloc.workoutTreeRepository;
|
||||
args['exerciseTypeId'] = element.exerciseTypeId;
|
||||
args['title'] = t("Muscle development") + ": " + "${element.exerciseType!.nameTranslation}";
|
||||
Navigator.of(context).pushNamed('developmentDiagramPage', arguments: args);
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,7 @@ import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/enums.dart';
|
||||
import 'package:aitrainer_app/util/track.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_premium.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
@ -68,10 +66,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
text: t("My Training Logs"),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
image: "asset/image/edzesnaplom400400.jpg",
|
||||
left: 5,
|
||||
onTap: () => Navigator.of(context).pushNamed('mydevelopmentLog', arguments: args),
|
||||
@ -110,10 +105,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
text: t("My Whole Body Development"),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||
fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4)),
|
||||
),
|
||||
image: "asset/image/testemfejl400x400.jpg",
|
||||
left: 5,
|
||||
@ -132,8 +124,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
warning: true,
|
||||
title: t("Warning"),
|
||||
descriptions: t("Please log in"),
|
||||
description2:
|
||||
t("because only that way can we show you the personalized development diagrams and analysises"),
|
||||
description2: t("because only that way can we show you the personalized development diagrams and analysises"),
|
||||
text: "OK",
|
||||
onTap: () => Navigator.of(context).popAndPushNamed("login"),
|
||||
onCancel: () => {
|
||||
@ -199,65 +190,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
onTap: () => {Navigator.of(context).pushNamed('mydevelopmentMusclePage', arguments: args)},
|
||||
isLocked: true,
|
||||
))),
|
||||
Badge(
|
||||
elevation: 0,
|
||||
padding: EdgeInsets.all(0),
|
||||
position: BadgePosition.topStart(top: -12, start: -12),
|
||||
animationDuration: Duration(milliseconds: 1500),
|
||||
animationType: BadgeAnimationType.fade,
|
||||
badgeColor: Colors.transparent,
|
||||
showBadge: Cache().hasPurchased,
|
||||
badgeContent: IconButton(
|
||||
iconSize: 36,
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
title: t("Premium function"),
|
||||
descriptions: Cache().canTrial()
|
||||
? t("This is a premium function, you can reach it outside of the trial period only with a valid subscription")
|
||||
: t("This is a premium function, you can reach it only with a valid subscription"),
|
||||
onCancel: () => Navigator.of(context).pop(),
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
text: '',
|
||||
);
|
||||
}),
|
||||
icon: Icon(
|
||||
Icons.star,
|
||||
color: Colors.orange[600],
|
||||
)),
|
||||
child: ImageButton(
|
||||
width: imageWidth,
|
||||
left: 5,
|
||||
textAlignment: Alignment.topLeft,
|
||||
text: t("Predictions"),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
image: "asset/image/predictions.jpg",
|
||||
onTap: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
{
|
||||
Track().track(TrackingEvent.prediction),
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogPremium(
|
||||
unlocked: Cache().hasPurchased,
|
||||
unlockRound: 12,
|
||||
function: "Predictions",
|
||||
unlockedText: null,
|
||||
onTap: () => {Navigator.of(context).pop()},
|
||||
);
|
||||
})
|
||||
}
|
||||
},
|
||||
isLocked: true,
|
||||
)),
|
||||
//developmentWidget(imageWidth, "Development Size", "asset/image/predictions.jpg", TrackingEvent.my_size_development, args),
|
||||
developmentWidget(imageWidth, t("Development of My Sizes"), "asset/image/sizes_q.jpg", TrackingEvent.my_size_development, args),
|
||||
hiddenWidget(customerRepository, exerciseRepository),
|
||||
]),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@ -278,15 +211,14 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
textAlignment: Alignment.topLeft,
|
||||
text: t(title),
|
||||
style: GoogleFonts.robotoMono(
|
||||
textStyle:
|
||||
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
textStyle: TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
|
||||
image: imageUrl,
|
||||
onTap: () => {
|
||||
if (Cache().userLoggedIn != null)
|
||||
{
|
||||
Track().track(trackingEvent),
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]),
|
||||
Future.delayed(Duration(seconds: 400)),
|
||||
//SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]),
|
||||
//Future.delayed(Duration(seconds: 400)),
|
||||
Navigator.of(context).pushNamed('mydevelopmentSizesPage', arguments: args),
|
||||
|
||||
/* showDialog(
|
||||
@ -302,7 +234,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
|
||||
}) */
|
||||
}
|
||||
},
|
||||
isLocked: true,
|
||||
isLocked: false,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/development_sizes/development_sizes_bloc.dart';
|
||||
import 'package:aitrainer_app/library/custom_icon_icons.dart';
|
||||
import 'package:aitrainer_app/model/property.dart';
|
||||
import 'package:aitrainer_app/repository/customer_repository.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
@ -7,7 +10,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import '../widgets/app_bar.dart';
|
||||
import '../widgets/input_dialog_widget.dart';
|
||||
|
||||
class SizesDevelopmentPage extends StatefulWidget {
|
||||
const SizesDevelopmentPage();
|
||||
@ -24,8 +26,8 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
create: (context) => DevelopmentSizesBloc(customerRepository: CustomerRepository())..add(DevelopmentSizesLoad()),
|
||||
child: BlocConsumer<DevelopmentSizesBloc, DevelopmentSizesState>(listener: (context, state) {
|
||||
if (state is DevelopmentSizesError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))));
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar((SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))));
|
||||
}
|
||||
}, builder: (context, state) {
|
||||
final bloc = BlocProvider.of<DevelopmentSizesBloc>(context);
|
||||
@ -41,30 +43,31 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
}
|
||||
|
||||
Widget getForm(DevelopmentSizesBloc bloc) {
|
||||
return Form(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBarNav(depth: 1),
|
||||
body: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_background.jpg'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
appBar: AppBarNav(depth: 1),
|
||||
body: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_background.jpg'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: getSizeFigure(bloc),
|
||||
)
|
||||
]))),
|
||||
)));
|
||||
getHeader(bloc),
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: getSizeFigure(bloc),
|
||||
)
|
||||
])))),
|
||||
));
|
||||
}
|
||||
|
||||
List<Widget> getSizeFigure(DevelopmentSizesBloc bloc) {
|
||||
@ -91,7 +94,6 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
top: bloc.customerRepository.getWeightCoordinate(bloc.isMan, isTop: true)!.toDouble(),
|
||||
left: bloc.customerRepository.getWeightCoordinate(bloc.isMan, isTop: false, isLeft: true)!.toDouble() - 45,
|
||||
child: GestureDetector(
|
||||
//onTap: () => onPressed(bloc.customerRepository.getPropertyByName("Weight")),
|
||||
child: Image.asset(
|
||||
"asset/image/merleg.png",
|
||||
height: 120,
|
||||
@ -101,30 +103,6 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
));
|
||||
|
||||
list.addAll(getSizeElements(bloc));
|
||||
list.add(
|
||||
Positioned(
|
||||
top: mediaHeight * .07,
|
||||
left: bloc.isMan ? mediaWidth * .62 : mediaWidth * .65,
|
||||
child: Stack(
|
||||
alignment: Alignment.topLeft,
|
||||
children: [
|
||||
SizedBox(height: 80, width: 100),
|
||||
Text(t("Your Size Diagrams"),
|
||||
maxLines: 2,
|
||||
style: GoogleFonts.archivoBlack(
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(5.0, 5.0),
|
||||
blurRadius: 3.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
fontSize: 20,
|
||||
color: Colors.orange[500],
|
||||
)),
|
||||
],
|
||||
)),
|
||||
);
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -139,21 +117,21 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
left: element.left!.toDouble(),
|
||||
child: element.value != 0
|
||||
? Container(
|
||||
width: 20,
|
||||
height: 20,
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: bloc.isMan ? Colors.green[800] : Color(0xFFEA776C),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(20),
|
||||
Radius.circular(40),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.trending_up, color: Colors.green),
|
||||
padding: EdgeInsets.zero,
|
||||
color: Colors.red[800],
|
||||
splashColor: Colors.amber,
|
||||
onPressed: () => onPressed(element),
|
||||
padding: EdgeInsets.only(left: 1, top: 1, right: 1, bottom: 1),
|
||||
child: TextButton(
|
||||
child: Text(
|
||||
bloc.customerRepository.getCustomerProperty(element.propertyName)!.propertyValue.toStringAsFixed(0),
|
||||
style: GoogleFonts.inter(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
onPressed: () => onPressed(element, bloc, element.propertyName),
|
||||
))
|
||||
: Container(
|
||||
width: 23,
|
||||
@ -166,11 +144,11 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
),
|
||||
),
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.trending_up, color: Colors.red),
|
||||
icon: Icon(CustomIcon.minus_circle, color: Colors.red),
|
||||
padding: EdgeInsets.zero,
|
||||
color: Colors.red[800],
|
||||
splashColor: Colors.amber,
|
||||
onPressed: () => onPressed(element),
|
||||
onPressed: () => onPressed(element, bloc, element.propertyName),
|
||||
))),
|
||||
);
|
||||
});
|
||||
@ -178,17 +156,53 @@ class _SizeState extends State<SizesDevelopmentPage> with Trans {
|
||||
return list;
|
||||
}
|
||||
|
||||
void onPressed(Property element) {
|
||||
print(element.propertyName);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => InputDialog(
|
||||
title: t("Size Of Your"),
|
||||
subtitle: element.propertyNameTranslation,
|
||||
initialValue: element.value!,
|
||||
onChanged: (value) {
|
||||
//widget.exerciseBloc.add(ExerciseNewSizeChange(propertyName: element.propertyName, value: value));
|
||||
},
|
||||
));
|
||||
void onPressed(Property element, DevelopmentSizesBloc bloc, String propertyName) {
|
||||
HashMap<String, dynamic> args = HashMap();
|
||||
args['customerRepository'] = bloc.customerRepository;
|
||||
args['property'] = element;
|
||||
args['title'] = t("Size development: ") + " " + propertyName;
|
||||
Navigator.of(context).pushNamed('developmentDiagramPage', arguments: args);
|
||||
}
|
||||
|
||||
Widget getHeader(DevelopmentSizesBloc bloc) {
|
||||
return Card(
|
||||
color: Colors.white60,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
|
||||
child: Column(children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Text(
|
||||
t("Red icon means you have not saved this size."),
|
||||
overflow: TextOverflow.clip,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
t("Tap on the green icon to see your development in a diagram"),
|
||||
overflow: TextOverflow.clip,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
child: Form(
|
||||
child: BlocConsumer<SettingsBloc, SettingsState>(listener: (context, state) {
|
||||
if (state is SettingsError) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||
} else if (state is SettingsReady) {
|
||||
menuBloc.add(MenuRecreateTree());
|
||||
Navigator.of(context).pushNamed("home");
|
||||
@ -110,7 +110,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
? 1
|
||||
: 0
|
||||
: 1,
|
||||
activeBgColor: Colors.indigo,
|
||||
activeBgColor: [Colors.indigo],
|
||||
activeFgColor: Colors.white,
|
||||
inactiveBgColor: Colors.white60,
|
||||
inactiveFgColor: Colors.grey[900],
|
||||
@ -120,6 +120,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
print("Server setting to: $live");
|
||||
settingsBloc.add(SettingsSetServer(live: index == 0));
|
||||
},
|
||||
totalSwitches: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -133,7 +134,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
minHeight: 30.0,
|
||||
fontSize: 14.0,
|
||||
initialLabelIndex: Cache().hasHardware! ? 0 : 1,
|
||||
activeBgColor: Colors.indigo,
|
||||
activeBgColor: [Colors.indigo],
|
||||
activeFgColor: Colors.white,
|
||||
inactiveBgColor: Colors.white60,
|
||||
inactiveFgColor: Colors.grey[900],
|
||||
@ -141,6 +142,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
onToggle: (index) {
|
||||
settingsBloc.add(SettingsSetHardware(hasHardware: index == 0));
|
||||
},
|
||||
totalSwitches: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -155,7 +157,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
minHeight: 30.0,
|
||||
fontSize: 14.0,
|
||||
initialLabelIndex: 0,
|
||||
activeBgColor: Colors.indigo,
|
||||
activeBgColor: [Colors.indigo],
|
||||
activeFgColor: Colors.white,
|
||||
inactiveBgColor: Colors.white60,
|
||||
inactiveFgColor: Colors.grey[900],
|
||||
@ -173,6 +175,7 @@ class SettingsPage extends StatelessWidget with Trans {
|
||||
tutorialBloc.add(TutorialStart());
|
||||
Track().track(TrackingEvent.tutorial_activate);
|
||||
},
|
||||
totalSwitches: 2,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
276
lib/widgets/development_diagram.dart
Normal file
276
lib/widgets/development_diagram.dart
Normal file
@ -0,0 +1,276 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:aitrainer_app/bloc/development_diagram/development_diagram_bloc.dart';
|
||||
import 'package:aitrainer_app/model/property.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/repository/workout_tree_repository.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/diagram_data.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/app_bar.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
import '../repository/customer_repository.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class DevelopmentDiagram extends StatelessWidget with Common, Trans {
|
||||
CustomerRepository? customerRepository;
|
||||
ExerciseRepository? exerciseRepository;
|
||||
WorkoutTreeRepository? workoutTreeRepository;
|
||||
int? exerciseTypeId;
|
||||
Property? property;
|
||||
late String title;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
setContext(context);
|
||||
final HashMap<String, dynamic> args = ModalRoute.of(context)!.settings.arguments as HashMap<String, dynamic>;
|
||||
this.customerRepository = args['customerRepository'];
|
||||
this.exerciseRepository = args['exerciseRepository'];
|
||||
this.exerciseTypeId = args['exerciseTypeId'];
|
||||
this.property = args['property'];
|
||||
this.title = args['title'];
|
||||
return Scaffold(
|
||||
appBar: AppBarNav(depth: 1),
|
||||
body: Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_plainblack_background.jpg'),
|
||||
fit: BoxFit.fill,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
),
|
||||
child: BlocProvider(
|
||||
create: (context) => customerRepository == null
|
||||
? DevelopmentDiagramBloc(diagramTitle: title, exerciseRepository: exerciseRepository, exerciseTypeId: exerciseTypeId)
|
||||
: DevelopmentDiagramBloc(
|
||||
diagramTitle: title,
|
||||
customerRepository: customerRepository,
|
||||
propertyName: property!.propertyName,
|
||||
),
|
||||
child: BlocConsumer<DevelopmentDiagramBloc, DevelopmentDiagramState>(
|
||||
listener: (context, state) {
|
||||
if (state is DevelopmentDiagramError) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogCommon(
|
||||
warning: true,
|
||||
title: t("Warning"),
|
||||
descriptions: t(state.message),
|
||||
text: "OK",
|
||||
onTap: () => Navigator.of(context).pop(),
|
||||
onCancel: () => {
|
||||
Navigator.of(context).pop(),
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
final DevelopmentDiagramBloc bloc = BlocProvider.of<DevelopmentDiagramBloc>(context);
|
||||
return ModalProgressHUD(
|
||||
child: getDiagramWidget(bloc),
|
||||
inAsyncCall: state is DevelopmentDiagramLoading,
|
||||
opacity: 0.5,
|
||||
color: Colors.black54,
|
||||
progressIndicator: CircularProgressIndicator(),
|
||||
);
|
||||
},
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
Widget getExplanation(DevelopmentDiagramBloc bloc) {
|
||||
return Container(
|
||||
color: Colors.white54,
|
||||
padding: EdgeInsets.all(5),
|
||||
child: Wrap(
|
||||
direction: Axis.horizontal,
|
||||
runSpacing: 5,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info,
|
||||
color: Colors.orangeAccent,
|
||||
),
|
||||
Text(" "),
|
||||
Text(
|
||||
bloc.diagramTitle,
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getFilterData(DevelopmentDiagramBloc bloc) {
|
||||
return bloc.isGroup
|
||||
? Container(
|
||||
color: Colors.transparent,
|
||||
// padding: EdgeInsets.all(5),
|
||||
child: Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 10,
|
||||
runSpacing: 5,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
avatar: Icon(
|
||||
Icons.bubble_chart,
|
||||
),
|
||||
label: Text(t('Sum Of Mass')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.group == DiagramGroup.sumMass,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeGroup(group: DiagramGroup.sumMass))},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.accessibility_new),
|
||||
label: Text(t('One Rep Max')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.group == DiagramGroup.oneRepMax,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeGroup(group: DiagramGroup.oneRepMax))},
|
||||
),
|
||||
ChoiceChip(
|
||||
avatar: Icon(Icons.perm_device_information),
|
||||
label: Text(t('Percent')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.lightBlueAccent,
|
||||
selected: bloc.group == DiagramGroup.percent,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeGroup(group: DiagramGroup.percent))},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: Offstage();
|
||||
}
|
||||
|
||||
Widget getGroupDate(DevelopmentDiagramBloc bloc) {
|
||||
return Container(
|
||||
color: Colors.transparent,
|
||||
//padding: EdgeInsets.all(5),
|
||||
child: Wrap(
|
||||
direction: Axis.horizontal,
|
||||
spacing: 10,
|
||||
runSpacing: 5,
|
||||
children: [
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Detailed')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
disabledColor: Colors.black26,
|
||||
selectedColor: Colors.greenAccent,
|
||||
selected: bloc.dateFilter == DiagramDateFilter.daily,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeDateFormat(dateFilter: DiagramDateFilter.daily))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Weekly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white12,
|
||||
selected: bloc.dateFilter == DiagramDateFilter.weekly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeDateFormat(dateFilter: DiagramDateFilter.weekly))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Monthly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.black26,
|
||||
selected: bloc.dateFilter == DiagramDateFilter.monthly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeDateFormat(dateFilter: DiagramDateFilter.monthly))},
|
||||
),
|
||||
ChoiceChip(
|
||||
labelPadding: EdgeInsets.only(right: 5),
|
||||
avatar: Icon(Icons.timer),
|
||||
label: Text(t('Yearly')),
|
||||
labelStyle: TextStyle(fontSize: 9, color: Colors.black),
|
||||
selectedColor: Colors.greenAccent,
|
||||
disabledColor: Colors.white70,
|
||||
selected: bloc.dateFilter == DiagramDateFilter.yearly,
|
||||
onSelected: (value) => {bloc.add(DevelopmentDiagramChangeDateFormat(dateFilter: DiagramDateFilter.yearly))},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getDiagramWidget(DevelopmentDiagramBloc bloc) {
|
||||
double cHeight = MediaQuery.of(context).size.height;
|
||||
return SingleChildScrollView(
|
||||
child: Column(children: [
|
||||
getExplanation(bloc),
|
||||
getFilterData(bloc),
|
||||
getGroupDate(bloc),
|
||||
Container(
|
||||
height: cHeight * .70,
|
||||
child: SfCartesianChart(
|
||||
/* title: ChartTitle(
|
||||
text: property.propertyNameTranslation,
|
||||
textStyle: TextStyle(color: Colors.white, fontFamily: 'Roboto', fontSize: 20, fontWeight: FontWeight.w800)), */
|
||||
plotAreaBorderColor: Colors.amber[50],
|
||||
primaryXAxis: CategoryAxis(
|
||||
borderColor: Colors.white12,
|
||||
axisLine: AxisLine(color: Colors.deepOrange, width: 2, dashArray: <double>[5, 5]),
|
||||
labelStyle:
|
||||
TextStyle(color: Colors.deepOrange, fontFamily: 'Roboto', fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500),
|
||||
//title: AxisTitle(text: t('Date'), textStyle: TextStyle(color: Colors.white, fontFamily: 'Roboto', fontSize: 20, fontWeight: FontWeight.w800))
|
||||
),
|
||||
primaryYAxis: CategoryAxis(
|
||||
borderColor: Colors.white12,
|
||||
labelStyle:
|
||||
TextStyle(color: Colors.deepOrange, fontFamily: 'Roboto', fontSize: 14, fontStyle: FontStyle.italic, fontWeight: FontWeight.w500),
|
||||
axisLine: AxisLine(color: Colors.deepOrange, width: 2, dashArray: <double>[15, 5]),
|
||||
),
|
||||
palette: <Color>[Colors.white, Colors.orange, Colors.yellow],
|
||||
zoomPanBehavior: ZoomPanBehavior(
|
||||
// Performs zooming on double tap
|
||||
|
||||
enableDoubleTapZooming: true),
|
||||
/* trackballBehavior: TrackballBehavior(
|
||||
// Enables the trackball
|
||||
enable: true,
|
||||
activationMode: ActivationMode.singleTap,
|
||||
tooltipSettings: InteractiveTooltip(
|
||||
enable: true,
|
||||
color: Colors.white,
|
||||
format: 'point.x : point.y',
|
||||
)), */
|
||||
annotations: <CartesianChartAnnotation>[
|
||||
/* CartesianChartAnnotation(
|
||||
coordinateUnit: CoordinateUnit.percentage,
|
||||
verticalAlignment: ChartAlignment.center,
|
||||
horizontalAlignment: ChartAlignment.center,
|
||||
widget: getExplanation(bloc),
|
||||
x: '50%',
|
||||
y: '3%'), */
|
||||
CartesianChartAnnotation(
|
||||
coordinateUnit: CoordinateUnit.percentage,
|
||||
verticalAlignment: ChartAlignment.center,
|
||||
horizontalAlignment: ChartAlignment.center,
|
||||
widget: Text(t("Double Tap: Zoom"), style: GoogleFonts.inter(color: Colors.yellow, fontSize: 12)),
|
||||
x: '55%',
|
||||
y: '85%')
|
||||
],
|
||||
series: <ChartSeries>[
|
||||
SplineSeries<DiagramData, String>(
|
||||
markerSettings: MarkerSettings(isVisible: true, shape: DataMarkerType.diamond),
|
||||
dataSource: bloc.diagramData,
|
||||
dataLabelSettings: DataLabelSettings(isVisible: true, color: Colors.white),
|
||||
xValueMapper: (DiagramData data, _) => data.x,
|
||||
yValueMapper: (DiagramData data, _) => data.y,
|
||||
dataLabelMapper: (DiagramData data, _) => data.y!.toStringAsFixed(1))
|
||||
],
|
||||
))
|
||||
]));
|
||||
}
|
||||
}
|
@ -82,7 +82,8 @@ class _SizeState extends State<SizeWidget> with Trans {
|
||||
45,
|
||||
child: GestureDetector(
|
||||
onTap: () => {
|
||||
if (widget.exerciseBloc.customerRepository.getPropertyByName("Weight") != null)
|
||||
|
||||
if (widget.exerciseBloc.customerRepository.getPropertyByName("Weight") != null)
|
||||
{
|
||||
onPressed(widget.exerciseBloc.customerRepository.getPropertyByName("Weight")!),
|
||||
}
|
||||
|
457
pubspec.lock
457
pubspec.lock
File diff suppressed because it is too large
Load Diff
48
pubspec.yaml
48
pubspec.yaml
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 1.1.25+104
|
||||
version: 1.1.26+106
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
@ -26,32 +26,31 @@ dependencies:
|
||||
|
||||
cupertino_icons: ^1.0.0
|
||||
google_fonts: ^2.1.0
|
||||
devicelocale: ^0.4.1
|
||||
sentry_flutter: ^5.1.0-beta.1
|
||||
devicelocale: ^0.5.0
|
||||
sentry_flutter: ^6.4.0
|
||||
flutter_bloc: ^7.3.3
|
||||
equatable: ^2.0.3
|
||||
|
||||
spider_chart: ^0.1.5
|
||||
radar_chart: ^2.1.0
|
||||
rainbow_color: ^2.0.1
|
||||
percent_indicator: ^ 3.3.0-nullsafety.1
|
||||
fl_chart: ^0.36.1
|
||||
percent_indicator: ^4.0.0
|
||||
fl_chart: ^0.50.0
|
||||
infinite_listview: ^1.1.0
|
||||
toggle_switch: ^0.1.9
|
||||
toggle_switch: ^1.4.0
|
||||
keyboard_actions: ^3.4.0
|
||||
badges: ^2.0.1
|
||||
#health: ^3.0.0
|
||||
stop_watch_timer: ^1.3.1
|
||||
#location: ^3.2.4
|
||||
modal_progress_hud_nsn: ^0.1.0-nullsafety-1
|
||||
flutter_html: ^2.0.0
|
||||
wakelock: ^ 0.5.6
|
||||
wakelock: ^0.6.1+2
|
||||
timeline_tile: ^2.0.0
|
||||
purchases_flutter: ^3.8.0
|
||||
package_info: ^2.0.0
|
||||
ezanimation: ^0.5.0
|
||||
confetti: ^0.6.0-nullsafety
|
||||
ezanimation: ^0.6.0
|
||||
confetti: ^0.6.0
|
||||
crypto: ^3.0.0
|
||||
carousel_slider: ^4.0.0-nullsafety.0
|
||||
carousel_slider: ^4.0.0
|
||||
convex_bottom_bar: ^3.0.0
|
||||
flutter_app_badger: ^1.2.0
|
||||
extended_tabs: ^2.2.0
|
||||
@ -62,28 +61,29 @@ dependencies:
|
||||
url_launcher: ^6.0.9
|
||||
|
||||
firebase_core: ^1.10.5
|
||||
firebase_analytics: ^9.0.3
|
||||
firebase_messaging: ^11.2.3
|
||||
firebase_analytics: ^9.1.2
|
||||
firebase_messaging: ^11.2.11
|
||||
firebase_auth: ^3.3.3
|
||||
firebase_remote_config: ^1.0.2
|
||||
firebase_dynamic_links: ^4.0.2
|
||||
firebase_remote_config: ^2.0.2
|
||||
firebase_dynamic_links: ^4.1.1
|
||||
firebase_in_app_messaging: ^0.6.0+4
|
||||
|
||||
syncfusion_flutter_gauges: ^19.3.48
|
||||
syncfusion_flutter_datagrid: ^19.1.63
|
||||
syncfusion_flutter_charts: ^19.2.60
|
||||
syncfusion_flutter_calendar: ^19.3.53
|
||||
syncfusion_localizations: ^19.3.54
|
||||
syncfusion_flutter_gauges: ^20.1.47
|
||||
syncfusion_flutter_datagrid: ^20.1.47
|
||||
syncfusion_flutter_charts: ^20.1.47
|
||||
syncfusion_flutter_calendar: ^20.1.47
|
||||
syncfusion_localizations: ^20.1.47
|
||||
|
||||
flutter_facebook_auth: ^3.5.7
|
||||
google_sign_in: ^5.2.1
|
||||
flutter_facebook_auth: ^4.1.2
|
||||
google_sign_in: ^5.2.4
|
||||
sign_in_with_apple: ^3.3.0
|
||||
|
||||
flutter_smartlook: ^3.0.4
|
||||
flutter_smartlook: ^3.0.9
|
||||
#flurry_data: ^0.0.1
|
||||
flutter_uxcam: ^2.0.1
|
||||
|
||||
animated_widgets: ^1.0.6
|
||||
flutter_fancy_tree_view: ^0.5.1+1
|
||||
|
||||
mockito: ^5.0.3
|
||||
sqflite: ^2.0.0+3
|
||||
|
Loading…
Reference in New Issue
Block a user