1.1.22+3 corrections

This commit is contained in:
bossanyit
2021-09-05 07:47:15 +02:00
parent cebd83648b
commit e34add8185
57 changed files with 1577 additions and 1490 deletions
+2 -2
View File
@@ -65,7 +65,7 @@ class AccountPage extends StatelessWidget with Trans {
return ListView(padding: EdgeInsets.only(top: 35), children: <Widget>[
ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.perm_identity, "personalData"), //Icon(Icons.perm_identity),
subtitle: Text(t("Profile")),
subtitle: Text(t("Profile") + " " + t("and") + " " + t("Sport")),
title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(customerName, style: TextStyle(color: Colors.blue)),
@@ -108,7 +108,7 @@ class AccountPage extends StatelessWidget with Trans {
),
ListTile(
leading: Common.badgedIcon(Colors.grey, Icons.perm_contact_cal, "FitnessLevel"), //Icon(Icons.perm_contact_cal),
subtitle: Text(t("Activity") + " " + t("and") + " " + t("Sport")),
subtitle: Text(t("Activity")),
title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text(fitnessLevel, style: TextStyle(color: Colors.blue)),
+6 -1
View File
@@ -7,6 +7,7 @@ import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:aitrainer_app/widgets/dialog_html.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -34,9 +35,13 @@ class _CustomerBodyTypeAnimationPageState extends State<CustomerBodyTypeAnimatio
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
}
PreferredSizeWidget _bar = AppBarMin(
back: true,
);
setContext(context);
return Scaffold(
appBar: AppBarNav(depth: 0),
appBar: _bar,
body: Container(
height: double.infinity,
width: double.infinity,
+8 -127
View File
@@ -2,8 +2,6 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/sport.dart';
import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/model/fitness_state.dart';
@@ -18,7 +16,6 @@ import 'package:google_fonts/google_fonts.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import '../bloc/customer_change/customer_change_bloc.dart';
import '../library/dropdown_search/dropdown_search.dart';
// ignore: must_be_immutable
class CustomerFitnessPage extends StatefulWidget {
@@ -76,8 +73,11 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pop();
Navigator.of(context).pushNamed("customerSexPage", arguments: changeBloc.customerRepository);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).popAndPushNamed("customerSexPage", arguments: changeBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -103,15 +103,15 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
changeBloc.add(CustomerSave()),
}
},
backgroundColor: Color(0xffb4f500),
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
color: Colors.black,
color: Colors.white,
size: 26,
),
label: Text(
fulldata ? t("Save") : t("Next"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),
),
),
);
@@ -141,46 +141,19 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
SizedBox(
height: h,
),
getButton("Beginner", "I am beginner", FitnessState.beginner),
SizedBox(
height: h,
),
getButton("Intermediate", "I am intermediate", FitnessState.intermediate),
SizedBox(
height: h,
),
getButton("Advanced", "I am advanced", FitnessState.advanced),
SizedBox(
height: h,
),
getButton("Professional", "I am professional", FitnessState.professional),
/* Divider(),
Text(
t("Your Primary Sport") + ":",
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
color: Colors.orange,
fontSize: 20,
),
), */
//getSport(changeBloc),
/* Divider(),
ElevatedButton(
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
primary: Colors.orange,
),
child: Text(fulldata ? t("Save") : t("Next")),
onPressed: () => {
changeBloc.add(CustomerSave()),
Navigator.of(context).pop(),
if (!fulldata) {Navigator.of(context).pushNamed("customerBodyTypePage", arguments: customerRepository)}
},
) */
],
),
);
@@ -233,98 +206,6 @@ class _CustomerFitnessPageState extends State<CustomerFitnessPage> with Trans {
side: BorderSide(width: 4, color: Colors.white24),
borderRadius: BorderRadius.circular(12),
);
//return
return returnCode;
}
Widget getSport(CustomerChangeBloc bloc) {
Sport? selected = bloc.selectedSport;
return Container(
padding: EdgeInsets.only(left: 65, right: 65),
child: DropdownSearch<Sport>(
dropdownSearchDecoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: t("Sport"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.indigo),
//fillColor: Colors.black38,
filled: false,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.blue, width: 0.4),
),
),
mode: Mode.MENU,
compareFn: (Sport? i, Sport? s) {
if (i == null || s == null) {
return false;
} else {
return i.sportId == s.sportId;
}
},
showSelectedItem: true,
selectedItem: selected,
itemAsString: (data) => t(data!.sportNameTranslation),
onChanged: (data) {
bloc.add(CustomerSportChange(sport: data!));
},
dropdownBuilder: _customDropDownItem,
popupItemBuilder: _customMenuBuilder,
popupBarrierColor: Colors.white10,
//popupBackgroundColor: Colors.yellow,
items: Cache().getSports(),
dropDownButton: Icon(
Icons.arrow_drop_down,
color: Colors.indigo,
),
));
//items: FitnessItem().toList()));
}
Widget _customMenuBuilder(BuildContext context, Sport? sport, bool isSelected) {
return Container(
decoration: !isSelected
? BoxDecoration(color: Colors.grey[300])
: BoxDecoration(
border: Border.all(color: Colors.blue),
borderRadius: BorderRadius.circular(12),
color: Colors.grey[100],
),
child: ListTile(
selected: isSelected,
title: Text(
t(sport!.sportNameTranslation),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.blue[600]),
),
subtitle: Text(
t(sport.name),
style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[600]),
),
),
);
}
Widget _customDropDownItem(BuildContext context, Sport? item, String itemDesignation) {
return Container(
child: (item == null)
? ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
t("No item selected"),
style: GoogleFonts.inter(fontSize: 14, color: Colors.blue[600]),
),
)
: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
t(item.sportNameTranslation),
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.blue[600]),
),
subtitle: Text(
t(item.name),
style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[600]),
),
),
);
}
}
+9 -5
View File
@@ -81,7 +81,7 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
customerRepository = CustomerRepository();
}
PreferredSizeWidget _bar = AppBarMin(
back: false,
back: true,
);
if (!fulldata) {
_bar = AppBarProgress(max: 14, min: 0);
@@ -107,7 +107,11 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pushNamed("customerFitnessPage", arguments: changeBloc.customerRepository);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).popAndPushNamed("customerFitnessPage", arguments: changeBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -136,15 +140,15 @@ class _CustomerGoalPage extends State<CustomerGoalPage> with Trans {
changeBloc.add(CustomerSave()),
}
},
backgroundColor: Color(0xffb4f500),
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
color: Colors.black,
color: Colors.white,
size: 26,
),
label: Text(
fulldata ? t("Save") : t("Next"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),
),
),
);
+8 -5
View File
@@ -64,8 +64,11 @@ class _CustomerHeightPageState extends State<CustomerHeightPage> with Trans {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pop();
Navigator.of(context).pushNamed("registration", arguments: changeBloc.customerRepository);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).popAndPushNamed("registration", arguments: changeBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -76,15 +79,15 @@ class _CustomerHeightPageState extends State<CustomerHeightPage> with Trans {
)),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => changeBloc.add(CustomerSaveHeight()),
backgroundColor: Color(0xffb4f500),
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
color: Colors.black,
color: Colors.white,
size: 26,
),
label: Text(
fulldata ? t("Save") : t("Finish"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),
),
),
);
+112
View File
@@ -3,7 +3,10 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/library/dropdown_search/dropdown_search.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/sport.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/enums.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
@@ -385,10 +388,119 @@ class CustomerModifyPage extends StatelessWidget with Trans {
},
),
Divider(),
Divider(),
Text(
t("Your Primary Sport") + ":",
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(
color: Colors.orange,
fontSize: 20,
),
),
getSport(customerBloc),
Divider(),
],
),
),
),
);
}
Widget getSport(CustomerChangeBloc bloc) {
Sport? selected = bloc.selectedSport;
return Container(
padding: EdgeInsets.only(left: 65, right: 65),
child: DropdownSearch<Sport>(
dropdownSearchDecoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
labelText: t("Sport"),
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.indigo),
//fillColor: Colors.black38,
filled: false,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.blue, width: 0.4),
),
),
mode: Mode.MENU,
compareFn: (Sport? i, Sport? s) {
if (i == null || s == null) {
return false;
} else {
return i.sportId == s.sportId;
}
},
showSelectedItem: true,
selectedItem: selected,
itemAsString: (data) => data!.nameTranslations[AppLanguage().appLocal.toString()] != null
? data.nameTranslations[AppLanguage().appLocal.toString()]!
: data.name,
onChanged: (data) {
bloc.add(CustomerSportChange(sport: data!));
},
dropdownBuilder: _customDropDownItem,
popupItemBuilder: _customMenuBuilder,
popupBarrierColor: Colors.white10,
//popupBackgroundColor: Colors.yellow,
items: Cache().getSports(),
dropDownButton: Icon(
Icons.arrow_drop_down,
color: Colors.indigo,
),
));
//items: FitnessItem().toList()));
}
Widget _customMenuBuilder(BuildContext context, Sport? sport, bool isSelected) {
return Container(
decoration: !isSelected
? BoxDecoration(color: Colors.grey[300])
: BoxDecoration(
border: Border.all(color: Colors.blue),
borderRadius: BorderRadius.circular(12),
color: Colors.grey[100],
),
child: ListTile(
selected: isSelected,
title: Text(
sport!.nameTranslations[AppLanguage().appLocal.toString()] != null
? sport.nameTranslations[AppLanguage().appLocal.toString()]!
: sport.name,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.blue[600]),
),
subtitle: Text(
sport.name,
style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[600]),
),
),
);
}
Widget _customDropDownItem(BuildContext context, Sport? item, String itemDesignation) {
return Container(
child: (item == null)
? ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
t("No item selected"),
style: GoogleFonts.inter(fontSize: 14, color: Colors.blue[600]),
),
)
: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(
item.nameTranslations[AppLanguage().appLocal.toString()] != null
? item.nameTranslations[AppLanguage().appLocal.toString()]!
: item.name,
style: GoogleFonts.archivoBlack(fontSize: 20, color: Colors.blue[600]),
),
subtitle: Text(
item.name,
style: GoogleFonts.inter(fontSize: 12, color: Colors.blue[600]),
),
),
);
}
}
+8 -5
View File
@@ -64,8 +64,11 @@ class _CustomerSexPageState extends State<CustomerSexPage> with Trans {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pop();
Navigator.of(context).pushNamed("customerWeightPage", arguments: changeBloc.customerRepository);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).popAndPushNamed("customerWeightPage", arguments: changeBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -84,15 +87,15 @@ class _CustomerSexPageState extends State<CustomerSexPage> with Trans {
onPressed: () => {
changeBloc.add(CustomerSaveSex()),
},
backgroundColor: Color(0xffb4f500),
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
color: Colors.black,
color: Colors.white,
size: 26,
),
label: Text(
fulldata ? t("Save") : t("Next"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),
),
),
);
+8 -6
View File
@@ -1,7 +1,6 @@
import 'package:aitrainer_app/bloc/customer_change/customer_change_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/util/app_localization.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
@@ -65,8 +64,11 @@ class _CustomerWeightPageState extends State<CustomerWeightPage> with Trans {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is CustomerSaveSuccess) {
Navigator.of(context).pop();
Navigator.of(context).pushNamed("customerHeightPage", arguments: changeBloc.customerRepository);
if (fulldata) {
Navigator.of(context).pop();
} else {
Navigator.of(context).popAndPushNamed("customerHeightPage", arguments: changeBloc.customerRepository);
}
}
},
builder: (context, state) {
@@ -85,15 +87,15 @@ class _CustomerWeightPageState extends State<CustomerWeightPage> with Trans {
onPressed: () => {
changeBloc.add(CustomerSaveWeight()),
},
backgroundColor: Color(0xffb4f500),
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
color: Colors.black,
color: Colors.white,
size: 26,
),
label: Text(
fulldata ? t("Save") : t("Next"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.black),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white),
),
),
);
-1
View File
@@ -1,4 +1,3 @@
import 'package:aitrainer_app/library/button_animations.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar_min.dart';
import 'package:flutter/material.dart';
+10 -18
View File
@@ -231,7 +231,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
Divider(),
numberPickForm(exerciseBloc, 3),
SizedBox(
height: 80,
height: 120,
)
]),
)),
@@ -263,12 +263,10 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
}
Widget numberPickForm(ExerciseControlBloc exerciseBloc, int step) {
final String strTimes = step == 2 ? exerciseBloc.origQuantity.toStringAsFixed(0) : "max.";
//print("step $step, quantity ${exerciseBloc.origQuantity}");
final String strTimes = step == 2 ? exerciseBloc.controlList[step - 1].quantity!.toStringAsFixed(0) : "max.";
String title = (step + 1).toString() + "/4 " + t("Control Exercise:");
LinkedHashMap args = LinkedHashMap();
final TutorialBloc tutorialBloc = BlocProvider.of<TutorialBloc>(context);
List<Widget> listWidgets = [
Text(
@@ -294,7 +292,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
children: [
TextSpan(text: t("Please repeat with ")),
TextSpan(
text: exerciseBloc.unitQuantity.toStringAsFixed(0) +
text: exerciseBloc.controlList[step - 1].unitQuantity!.toStringAsFixed(0) +
" " +
exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit!,
style: GoogleFonts.inter(
@@ -324,7 +322,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
NumberPickerWidget(
minValue: 0,
maxValue: 200,
initalValue: exerciseBloc.origQuantity.round(),
initalValue: exerciseBloc.controlList[step - 1].quantity!.round(),
unit: t("reps"),
color: Colors.yellow[50]!,
onChange: (value) => {exerciseBloc.add(ExerciseControlQuantityChange(quantity: value.toDouble(), step: step))}),
@@ -335,12 +333,6 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
onSurface: Colors.blueAccent,
),
onPressed: () {
if (tutorialBloc.isActive) {
if (!tutorialBloc.checkAction("Save")) {
return;
}
}
exerciseBloc.add(ExerciseControlSubmit(step: step));
if (step == 3) {
Navigator.of(context).pop();
@@ -354,7 +346,7 @@ class _ExerciseControlPage extends State<ExerciseControlPage> with Trans {
children: [
Image.asset('asset/icon/gomb_orange_c.png', width: 140, height: 60),
Text(
t("Save"),
t("Done!"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
@@ -436,9 +428,9 @@ class _UnitQuantityControlState extends State<UnitQuantityControl> with Trans {
height: 20,
),
NumberPickerWidget(
minValue: (widget.exerciseBloc.unitQuantity - 30).round(),
maxValue: (widget.exerciseBloc.unitQuantity + 30).round(),
initalValue: widget.exerciseBloc.unitQuantity.round(),
minValue: (widget.exerciseBloc.controlList[widget.step - 1].unitQuantity! - 30).round(),
maxValue: (widget.exerciseBloc.controlList[widget.step - 1].unitQuantity! + 30).round(),
initalValue: widget.exerciseBloc.controlList[widget.step - 1].unitQuantity!.round(),
unit: t("kg"),
color: Colors.yellow[50]!,
onChange: (value) => {
@@ -452,9 +444,9 @@ class _UnitQuantityControlState extends State<UnitQuantityControl> with Trans {
onTap: () => {
if (changedValue == null)
{
changedValue = widget.exerciseBloc.unitQuantity,
changedValue = widget.exerciseBloc.controlList[widget.step - 1].unitQuantity,
},
//print("Changed new value $changedValue"),
print("Changed new value $changedValue, step ${widget.step}"),
widget.exerciseBloc.add(ExerciseControlUnitQuantityChange(quantity: changedValue!.toDouble(), step: widget.step)),
Navigator.of(context).pop(),
},
+40 -28
View File
@@ -8,6 +8,7 @@ import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_ability.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/service/logging.dart';
@@ -17,6 +18,7 @@ import 'package:aitrainer_app/widgets/bmi_widget.dart';
import 'package:aitrainer_app/widgets/bmr_widget.dart';
import 'package:aitrainer_app/widgets/dialog_common.dart';
import 'package:aitrainer_app/widgets/exercise_save.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/size_widget.dart';
import 'package:aitrainer_app/widgets/tutorial_widget.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -55,7 +57,9 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
title: t("Warning"),
descriptions: t(state.message),
text: "OK",
onTap: () => Navigator.of(context).pushNamed("login"),
onTap: () => {
Navigator.of(context).pop(),
},
onCancel: () => {
Navigator.of(context).pop(),
},
@@ -114,10 +118,12 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
return SizeWidget(exerciseBloc: exerciseBloc);
}
WorkoutMenuTree? workoutTree = menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(exerciseType.exerciseTypeId);
return Scaffold(
appBar: AppBarNav(depth: 1),
body: Container(
padding: EdgeInsets.only(top: 10, left: 20, right: 20),
padding: EdgeInsets.only(),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.jpg'),
@@ -126,37 +132,38 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
),
),
child: ExerciseSave(
exerciseName: exerciseBloc.exerciseRepository.exerciseType!.nameTranslation,
exerciseDescription: exerciseBloc.exerciseRepository.exerciseType!.descriptionTranslation,
exerciseTask: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null
? t("Please take a relative bigger weight and repeat 12-20 times and do your best! MAXIMIZE it!")
: t("Please repeat as much times as you can! MAXIMIZE it!"),
unit: exerciseBloc.exerciseRepository.exerciseType!.unit,
unitQuantityUnit: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit,
hasUnitQuantity: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null,
onQuantityChanged: (value) {
exerciseBloc.add(ExerciseNewQuantityChange(quantity: value));
},
onUnitQuantityChanged: (value) => exerciseBloc.add(ExerciseNewQuantityUnitChange(quantity: value)),
//onSubmit: () => confirmationDialog(exerciseBloc, menuBloc),
exerciseTypeId: exerciseType.exerciseTypeId,
)),
exerciseName: exerciseBloc.exerciseRepository.exerciseType!.nameTranslation,
exerciseDescription: exerciseBloc.exerciseRepository.exerciseType!.descriptionTranslation,
exerciseTask: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null
? t("Please take a relative bigger weight and repeat 12-20 times and do your best! MAXIMIZE it!")
: t("Please repeat as much times as you can! MAXIMIZE it!"),
unit: exerciseBloc.exerciseRepository.exerciseType!.unit,
unitQuantityUnit: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit,
hasUnitQuantity: exerciseBloc.exerciseRepository.exerciseType!.unitQuantityUnit != null,
onQuantityChanged: (value) {
exerciseBloc.add(ExerciseNewQuantityChange(quantity: value));
},
onUnitQuantityChanged: (value) => exerciseBloc.add(ExerciseNewQuantityUnitChange(quantity: value)),
//onSubmit: () => confirmationDialog(exerciseBloc, menuBloc),
exerciseTypeId: exerciseType.exerciseTypeId,
tip: ActivityDone.exerciseSaveTestTip,
menuImage: MenuImage(
imageName: workoutTree!.imageName,
workoutTreeId: workoutTree.id,
radius: 0,
))),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => save(exerciseBloc, menuBloc),
backgroundColor: Colors.orange[800],
backgroundColor: Colors.orange[600],
icon: Icon(
CustomIcon.save,
CustomIcon.ok_circled,
size: 20,
),
label: Text(
t("Save"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 12),
t("Done!"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
/* bottomNavigationBar: BottomBarMultipleExercises(
isSet: false,
exerciseTypeId: exerciseType.exerciseTypeId,
), */
);
}
@@ -195,6 +202,11 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
return;
}
if (bloc.quantity == -1 || bloc.unitQuantity == -1) {
bloc.add(ExerciseNewAddError(message: "Please type in a real number!"));
return;
}
String quantity = bloc.exerciseRepository.exercise!.quantity! % 1 == 0
? bloc.exerciseRepository.exercise!.quantity!.round().toString()
: bloc.exerciseRepository.exercise!.quantity!.toString();
@@ -209,9 +221,9 @@ class _ExerciseNewPageState extends State<ExerciseNewPage> with Trans, Logging {
// ignore: close_sinks
final TestSetExecuteBloc executeBloc = BlocProvider.of<TestSetExecuteBloc>(context);
final question = bloc.exerciseRepository.exercise!.quantity! == 12.0
? "Did you try the MAXIMUM what you can do? Are you sure we save the exercise with ONLY 12 repeats?"
: "Do you save this exercise with these parameters?";
/* final question = bloc.exerciseRepository.exercise!.quantity! == 12.0
? "Did you try the MAXIMUM what you can do? Are you sure we save the exercise with ONLY 12 repeats?" */
final question = "Do you save this exercise with these parameters?";
showCupertinoDialog(
useRootNavigator: true,
+1 -1
View File
@@ -37,7 +37,7 @@ class _MyDevelopmentBodyPage extends State<MyDevelopmentBodyPage> with Trans, Co
setContext(context);
return DialogPremium(
unlocked: Cache().hasPurchased,
unlockRound: 2,
unlockRound: 4,
function: "My Whole Body Development",
unlockedText: null,
onTap: () => {Navigator.of(context).pop(), Navigator.of(context).pop()},
+1 -1
View File
@@ -163,7 +163,7 @@ class _MyDevelopmentPage extends State<MyDevelopmentPage> with Trans {
builder: (BuildContext context) {
return DialogPremium(
unlocked: Cache().hasPurchased,
unlockRound: 3,
unlockRound: 12,
function: "Predictions",
unlockedText: null,
onTap: () => {Navigator.of(context).pop()},
+17 -3
View File
@@ -2,6 +2,7 @@ import 'dart:io';
import 'package:aitrainer_app/bloc/account/account_bloc.dart';
import 'package:aitrainer_app/bloc/login/login_bloc.dart';
import 'package:aitrainer_app/repository/customer_repository.dart';
import 'package:aitrainer_app/repository/training_plan_repository.dart';
import 'package:aitrainer_app/repository/user_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
@@ -23,12 +24,23 @@ class RegistrationPage extends StatelessWidget with Trans {
@override
Widget build(BuildContext context) {
final accountBloc = BlocProvider.of<AccountBloc>(context);
CustomerRepository? customerRepository;
if (ModalRoute.of(context) != null && ModalRoute.of(context)!.settings.arguments != null) {
customerRepository = ModalRoute.of(context)!.settings.arguments as CustomerRepository;
print("CustomerFitness reg ${customerRepository.customer!.toJson()}");
}
setContext(context);
return Scaffold(
appBar: AppBarMin(),
body: BlocProvider(
create: (context) =>
LoginBloc(userRepository: UserRepository(), accountBloc: accountBloc, context: context, isRegistration: true),
create: (context) => LoginBloc(
userRepository: UserRepository(),
accountBloc: accountBloc,
context: context,
isRegistration: true,
customerRepository: customerRepository),
child: BlocConsumer<LoginBloc, LoginState>(listener: (context, state) {
if (state is LoginError) {
ScaffoldMessenger.of(context).showSnackBar(
@@ -67,7 +79,9 @@ class RegistrationPage extends StatelessWidget with Trans {
}
}, builder: (context, state) {
final loginBloc = BlocProvider.of<LoginBloc>(context);
if (customerRepository != null) {
print("Customer data ${customerRepository.customer!.toJson()}");
}
return ModalProgressHUD(
child: loadForm(loginBloc, accountBloc),
inAsyncCall: state is LoginLoading,
+35 -22
View File
@@ -1,5 +1,3 @@
import 'dart:io';
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
import 'package:aitrainer_app/bloc/tutorial/tutorial_bloc.dart';
@@ -19,8 +17,8 @@ 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:toggle_switch/toggle_switch.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:mailto/mailto.dart';
import 'package:url_launcher/url_launcher.dart';
// ignore: must_be_immutable
class SettingsPage extends StatelessWidget with Trans {
@@ -87,7 +85,7 @@ class SettingsPage extends StatelessWidget with Trans {
//getTuturialBasic(settingsBloc),
getTermsOfUse(),
getPrivacy(),
getFaq(),
mailTo(),
getVersion(),
//getDevice(settingsBloc),
]);
@@ -264,25 +262,40 @@ class SettingsPage extends StatelessWidget with Trans {
);
}
Future<void> _printAndCopy(String cmd) async {
print(cmd);
await Clipboard.setData(ClipboardData(text: cmd));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Copied to Clipboard')),
ListTile mailTo() {
return ListTile(
leading: Icon(CustomIcon.mail_1),
title: TextButton(
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text("Feedback email", style: TextStyle(color: Colors.indigo)),
Icon(
Icons.arrow_forward_ios,
color: Colors.indigo,
),
]),
style: TextButton.styleFrom(
backgroundColor: Colors.white70,
onSurface: Colors.grey,
),
onPressed: () => {
launchMailto(),
Track().track(TrackingEvent.feedback_email),
},
),
);
}
void link1() {
String? cmd;
String cmdSuffix;
if (Platform.isIOS) {
cmd = '/usr/bin/xcrun simctl openurl booted';
} else if (Platform.isAndroid) {
cmd = '\$ANDROID_HOME/platform-tools/adb shell \'am start'
' -a android.intent.action.VIEW'
' -c android.intent.category.BROWSABLE -d';
cmdSuffix = "'";
}
launchMailto() async {
String from = Cache().userLoggedIn == null ? "" : Cache().userLoggedIn!.customerId!.toStringAsFixed(0);
final mailtoLink = Mailto(
to: ['service@workouttest.com'],
subject: 'Feedback from app: $from',
body: '',
);
// Convert the Mailto instance into a string.
// Use either Dart's string interpolation
// or the toString() method.
print("Mailto: $mailtoLink");
await launch('$mailtoLink');
}
}
+12 -2
View File
@@ -3,13 +3,16 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/test_set_execute/test_set_execute_bloc.dart';
import 'package:aitrainer_app/bloc/test_set_new/test_set_new_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/repository/exercise_repository.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/bottom_bar_multiple_exercises.dart';
import 'package:aitrainer_app/widgets/exercise_save.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
@@ -29,7 +32,6 @@ class TestSetNew extends StatelessWidget with Trans {
return Scaffold(
appBar: AppBarNav(depth: 1),
body: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.jpg'),
@@ -77,7 +79,7 @@ class TestSetNew extends StatelessWidget with Trans {
backgroundColor: Colors.orange[800],
icon: Icon(CustomIcon.save),
label: Text(
t("Save"),
t("Done"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
@@ -89,6 +91,8 @@ class TestSetNew extends StatelessWidget with Trans {
}
Widget getExercises(TestSetNewBloc bloc) {
WorkoutMenuTree? workoutTree =
bloc.executeBloc.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(bloc.exerciseType.exerciseTypeId);
return ExerciseSave(
exerciseName: bloc.exerciseType.nameTranslation,
exerciseDescription: bloc.exerciseType.descriptionTranslation,
@@ -103,6 +107,12 @@ class TestSetNew extends StatelessWidget with Trans {
},
onUnitQuantityChanged: (value) => bloc.add(TestSetNewChangeQuantityUnit(quantity: value)),
exerciseTypeId: bloc.exerciseType.exerciseTypeId,
tip: ActivityDone.exerciseSaveTestsetTip,
menuImage: MenuImage(
imageName: workoutTree!.imageName,
workoutTreeId: workoutTree.id,
radius: 0,
),
/* onSubmit: () {
Navigator.of(context).pop();
bloc.add(TestSetNewSubmit());
+71 -40
View File
@@ -6,6 +6,7 @@ import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/library/tree_view.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/training_plan.dart';
import 'package:aitrainer_app/model/training_plan_detail.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/util/app_language.dart';
import 'package:aitrainer_app/util/trans.dart';
@@ -58,7 +59,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
title: t("Warning"),
descriptions: t(state.message),
text: "OK",
onTap: () => Navigator.of(context).pushNamed("login"),
onTap: () => Navigator.of(context).pop(),
onCancel: () => {
Navigator.of(context).pop(),
},
@@ -197,21 +198,45 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
icon: Icon(Icons.list_sharp),
color: Colors.blue[800],
),
children: _getChildList(element, bloc),
children: _getDays(element, bloc),
)));
});
return listWidget;
}
List<Widget> _getChildList(TrainingPlan plan, TrainingPlanBloc bloc) {
List<Widget> _getDays(TrainingPlan plan, TrainingPlanBloc bloc) {
List<Widget> listWidget = [];
bloc.setMyTrainingPlan(plan);
bloc.activateTrainingPlanDays();
bloc.trainingPlanDayNames.forEach((value) {
listWidget.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: true,
parent: TreeviewParentWidget(
text: " * " + t("Training Day") + ": " + value,
fontSize: 16,
color: Colors.white,
icon: Icon(Icons.view_day),
backgroundColor: Colors.white24,
),
children: _getChildList(plan, bloc, value),
)));
});
return listWidget;
}
List<Widget> _getChildList(TrainingPlan plan, TrainingPlanBloc bloc, String dayName) {
List<Widget> list = [];
bool restricted = (!plan.free && !Cache().hasPurchased);
list.add(Card(
margin: EdgeInsets.only(left: 10, top: 5),
color: Colors.white60,
color: Colors.white24,
child: Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: Column(children: [
@@ -262,7 +287,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
),
))
: Offstage(),
getPlanDetails(plan, bloc),
getPlanDetails(plan, bloc, dayName),
ElevatedButton(
style: ElevatedButton.styleFrom(
onPrimary: Colors.white,
@@ -371,13 +396,17 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
}
}
Widget getPlanDetails(TrainingPlan plan, TrainingPlanBloc bloc) {
Widget getPlanDetails(TrainingPlan plan, TrainingPlanBloc bloc, String dayName) {
return SfDataGrid(
headerRowHeight: 30,
rowHeight: 60,
rowHeight: 70,
columnWidthMode: ColumnWidthMode.lastColumnFill,
defaultColumnWidth: 50,
source: TrainingPlanDetailSource(
plan: plan,
menuBloc: bloc.menuBloc,
bloc: bloc,
dayName: dayName,
onWeightTap: () => {
showDialog(
context: context,
@@ -438,18 +467,23 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
columns: [
GridTextColumn(
columnWidthMode: ColumnWidthMode.lastColumnFill,
maximumWidth: 160,
maximumWidth: 130,
columnName: 'exerciseImage',
label: Container(
color: Colors.green[50],
color: Colors.black38,
padding: EdgeInsets.only(left: 8.0),
alignment: Alignment.centerLeft,
child: Text(
t('Exercise'),
style: GoogleFonts.inter(
color: Colors.white,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
maximumWidth: 0,
visible: false,
columnName: 'exerciseName',
label: Container(
@@ -462,47 +496,40 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
maximumWidth: 40,
columnName: 'set',
maximumWidth: 60,
columnName: 'Set',
label: Container(
color: Colors.green[50],
color: Colors.black38,
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
t('Set'),
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
maximumWidth: 50,
columnName: 'repeats',
maximumWidth: 100,
columnWidthMode: ColumnWidthMode.fill,
columnName: 'Repeats',
label: Container(
color: Colors.green[50],
color: Colors.black38,
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
t('Reps'),
t('Repeats'),
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
maximumWidth: 60,
columnName: 'weight',
columnName: 'Weight',
label: Container(
color: Colors.green[50],
color: Colors.black38,
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
t('Weight'),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
maximumWidth: 50,
columnName: 'day',
label: Container(
color: Colors.green[50],
padding: EdgeInsets.symmetric(horizontal: 8.0),
alignment: Alignment.centerLeft,
child: Text(
t('Day'),
t('Weight_'),
style: GoogleFonts.inter(color: Colors.white, fontWeight: FontWeight.bold),
overflow: TextOverflow.ellipsis,
))),
],
@@ -512,19 +539,25 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
class TrainingPlanDetailSource extends DataGridSource {
final TrainingPlan plan;
final TrainingPlanBloc bloc;
final MenuBloc menuBloc;
final dayName;
final VoidCallback onDropsetTap;
final VoidCallback onWeightTap;
final VoidCallback onRepeatTap;
TrainingPlanDetailSource({
required this.plan,
required this.menuBloc,
required this.bloc,
required this.dayName,
required this.onDropsetTap,
required this.onWeightTap,
required this.onRepeatTap,
}) {
if (plan.details != null) {
dataGridRows = plan.details!.map((dataGridRow) {
List<TrainingPlanDetail> details = bloc.trainingPlanDetailSummary(plan, dayName);
dataGridRows = details.map((dataGridRow) {
WorkoutMenuTree? menuTree = menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(dataGridRow.exerciseTypeId);
if (menuTree == null) {
return DataGridRow(cells: []);
@@ -539,9 +572,8 @@ class TrainingPlanDetailSource extends DataGridSource {
)),
DataGridCell<String>(columnName: 'exerciseName', value: menuTree.name),
DataGridCell<int>(columnName: 'set', value: dataGridRow.set),
DataGridCell<int>(columnName: 'reps', value: dataGridRow.repeats),
DataGridCell<String>(columnName: 'reps', value: dataGridRow.summary!),
DataGridCell<double>(columnName: 'weight', value: dataGridRow.weight),
DataGridCell<String>(columnName: 'day', value: dataGridRow.day),
]);
}).toList();
}
@@ -557,9 +589,9 @@ class TrainingPlanDetailSource extends DataGridSource {
if (row.getCells().isEmpty) {
return null;
}
String name = row.getCells()[1].value;
String name = row.getCells()[1].value.toString();
return DataGridRowAdapter(
color: Colors.white60,
color: Colors.white12,
cells: row.getCells().map<Widget>((dataGridCell) {
return Container(
alignment: dataGridCell.columnName == "exerciseImage" ? Alignment.centerLeft : Alignment.centerLeft,
@@ -573,8 +605,7 @@ class TrainingPlanDetailSource extends DataGridSource {
name,
maxLines: 3,
overflow: TextOverflow.ellipsis,
style:
GoogleFonts.inter(fontSize: 10, color: Colors.yellow[600], fontWeight: FontWeight.bold, shadows: <Shadow>[
style: GoogleFonts.inter(fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold, shadows: <Shadow>[
Shadow(
offset: Offset(2.0, 2.0),
blurRadius: 6.0,
@@ -590,7 +621,7 @@ class TrainingPlanDetailSource extends DataGridSource {
},
child: Icon(
CustomIcon.question_circle,
color: Colors.indigo[300],
color: Colors.white,
))
: dataGridCell.columnName == "weight" && dataGridCell.value == -3
? GestureDetector(
@@ -608,12 +639,12 @@ class TrainingPlanDetailSource extends DataGridSource {
},
child: Icon(
CustomIcon.question_circle,
color: Colors.indigo[600],
color: Colors.white,
))
: Text(dataGridCell.value.toString(),
style: GoogleFonts.inter(
fontSize: 14,
color: Colors.indigo,
color: Colors.white,
fontWeight: FontWeight.bold,
)));
}).toList());
+15 -3
View File
@@ -45,8 +45,20 @@ class _TrainingPlanExecuteState extends State<TrainingPlanExecute> with Trans {
),
child: BlocConsumer<TrainingPlanBloc, TrainingPlanState>(listener: (context, state) {
if (state is TrainingPlanError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
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(),
},
);
});
} else if (state is TrainingPlanDayFinished) {
bloc.celebrating = false;
final HashMap args = HashMap();
@@ -368,7 +380,7 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
bloc.getMyPlan()!.days[widget.dayName] != null &&
bloc.getMyPlan()!.days[widget.dayName]!.isNotEmpty) {
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
if (prev != null && prev!.exerciseTypeId != element.exerciseTypeId) {
if (prev == null || (prev != null && prev!.exerciseTypeId != element.exerciseTypeId)) {
tiles.add(GestureDetector(
onTap: () =>
bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
-914
View File
@@ -1,914 +0,0 @@
import 'dart:collection';
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
import 'package:aitrainer_app/model/exercise_plan_detail.dart';
import 'package:aitrainer_app/util/app_localization.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:aitrainer_app/widgets/dialog_html.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/weight_control.dart';
import 'package:badges/badges.dart';
import 'package:extended_tabs/extended_tabs.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.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:timeline_tile/timeline_tile.dart';
// ignore: must_be_immutable
class TrainingPlanExecutePage extends StatefulWidget {
@override
_TrainingPlanExecutePageState createState() => _TrainingPlanExecutePageState();
}
class _TrainingPlanExecutePageState extends State<TrainingPlanExecutePage> with Trans {
final scrollController = ScrollController();
TrainingPlanBloc? bloc;
@override
Widget build(BuildContext context) {
final HashMap args = HashMap();
bloc = BlocProvider.of<TrainingPlanBloc>(context);
bloc!.activateDays();
setContext(context);
return Scaffold(
appBar: AppBarNav(depth: 0),
body: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('asset/image/WT_black_background.jpg'),
fit: BoxFit.cover,
alignment: Alignment.center,
),
),
child: BlocConsumer<TrainingPlanBloc, TrainingPlanState>(listener: (context, state) {
if (state is TrainingPlanError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
} else if (state is TrainingPlanDayFinished) {
bloc!.celebrating = false;
args["bloc"] = bloc;
args["day"] = bloc!.dayNames[bloc!.activeDayIndex];
Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args);
} else if (state is TrainingPlanDayReadyToRestart) {
if (!bloc!.celebrating) {
showCupertinoDialog(
useRootNavigator: true,
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text(t("The training is finished")),
content: Column(children: [Divider(), Text(t("Do you want to restart, or select a new Training Plan?"))]),
actions: [
TextButton(
child: Text(t("New Training Plan"), textAlign: TextAlign.center),
onPressed: () => {
Navigator.pop(context),
Navigator.of(context).popAndPushNamed('myTrainingPlans'),
bloc!.restarting = false,
}),
TextButton(
child: Text(t("Restart")),
onPressed: () {
bloc!.restart();
Navigator.pop(context);
Navigator.of(context).popAndPushNamed('home');
},
)
],
));
}
}
}, builder: (context, state) {
return ModalProgressHUD(
child: ExerciseTabs(bloc: bloc!),
inAsyncCall: state is TrainingPlanLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
}),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => {
args["bloc"] = bloc,
args["day"] = bloc!.dayNames[bloc!.activeDayIndex],
bloc!.getNext() != null
? _ExerciseListState.executeExercise(bloc!, bloc!.getNext()!, context)
: Navigator.of(context).pushNamed('myTrainingEvaluation', arguments: args),
},
backgroundColor: Colors.orange[800],
icon: Icon(CustomIcon.weight_hanging),
label: Text(
t("Training") + "!",
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
);
}
}
class ExerciseTabs extends StatefulWidget {
final TrainingPlanBloc bloc;
ExerciseTabs({required this.bloc});
@override
_ExerciseTabs createState() => _ExerciseTabs();
}
class _ExerciseTabs extends State<ExerciseTabs> with TickerProviderStateMixin {
late TabController tabController;
@override
void initState() {
super.initState();
print("init TAB ${widget.bloc.dayNames.length} index ${widget.bloc.activeDayIndex}");
tabController = TabController(length: widget.bloc.dayNames.length, vsync: this);
tabController.animateTo(widget.bloc.activeDayIndex, duration: Duration(milliseconds: 300));
}
@override
void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return getTabs(widget.bloc);
}
Widget getTabs(TrainingPlanBloc bloc) {
return Column(children: [
ExtendedTabBar(
indicator: BoxDecoration(
color: Colors.black87,
border: Border(
bottom: BorderSide(width: 4.0, color: Colors.blue),
top: BorderSide(width: 4.0, color: Colors.blue),
)),
labelPadding: EdgeInsets.only(left: 5, right: 5),
tabs: getTabNames(),
controller: tabController,
onTap: (index) => bloc.activeDayIndex = index,
),
Expanded(
child: ExtendedTabBarView(
children: getExerciseLists(),
controller: tabController,
/// if link is true and current tabbarview over scroll,
/// it will check and scroll ancestor or child tabbarView.
link: true,
/// cache page count
/// default is 0.
/// if cacheExtent is 1, it has two pages in cache
/// null is infinity, it will cache all pages
cacheExtent: 0,
)),
]);
}
List<Tab> getTabNames() {
List<Tab> tabs = [];
widget.bloc.dayNames.forEach((element) {
final Widget widget = Container(
//height: 50,
padding: EdgeInsets.only(top: 2, left: 5, right: 5, bottom: 2),
color: Colors.white24,
child: RichText(
textScaleFactor: 0.8,
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white,
),
children: [
TextSpan(
text: AppLocalizations.of(context)!.translate("Training Day") + ": \n",
style: GoogleFonts.inter(
fontSize: 14,
color: Colors.white,
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
TextSpan(
text: element,
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.yellow[400],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
])));
tabs.add(Tab(child: widget));
});
return tabs;
}
List<Widget> getExerciseLists() {
List<Widget> list = [];
widget.bloc.dayNames.forEach((element) {
list.add(ExerciseList(bloc: widget.bloc, dayName: element));
});
return list;
}
}
class ExerciseList extends StatefulWidget {
final TrainingPlanBloc bloc;
final String dayName;
ExerciseList({required this.bloc, required this.dayName});
@override
_ExerciseListState createState() => _ExerciseListState();
}
class _ExerciseListState extends State<ExerciseList> with Trans {
final scrollController = ScrollController();
double offset = 5;
@override
void initState() {
WidgetsBinding.instance!.addPostFrameCallback((_) {
animate();
});
super.initState();
}
@override
void didUpdateWidget(ExerciseList page) {
super.didUpdateWidget(page);
WidgetsBinding.instance!.addPostFrameCallback((_) {
animate();
});
}
void animate() {
offset = widget.bloc.getOffset();
if (scrollController.hasClients) {
scrollController.animateTo(offset, duration: Duration(milliseconds: 300), curve: Curves.easeIn);
}
}
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
setContext(context);
return CustomScrollView(controller: scrollController, slivers: [
SliverList(delegate: SliverChildListDelegate(getTiles(widget.bloc))),
]);
}
List<Widget> getTiles(TrainingPlanBloc bloc) {
List<Widget> tiles = [];
tiles.add(getStartTile(bloc));
tiles.addAll(getExerciseTiles(bloc, context));
if (bloc.getMyPlan() != null) tiles.add(getEndTile());
return tiles;
}
Widget getStartTile(TrainingPlanBloc bloc) {
String startText = "";
String explainingText = "";
if (null == bloc.getMyPlan()) {
startText = t("No Active Training Plan");
explainingText = t("Please select one in the Training menu, or create your custom plan");
} else {
startText = bloc.isStarted() ? t("Continue your training") : t("Start your training");
explainingText = bloc.getMyPlan()!.name != null ? bloc.getMyPlan()!.name! : "";
}
return TimelineTile(
alignment: TimelineAlign.manual,
lineXY: 0.1,
isFirst: true,
afterLineStyle: const LineStyle(
color: Colors.orange,
thickness: 6,
),
indicatorStyle: IndicatorStyle(
width: 40,
color: Colors.orange,
padding: const EdgeInsets.all(8),
iconStyle: IconStyle(
color: Colors.white,
iconData: Icons.emoji_flags_rounded,
),
),
endChild: Container(
padding: EdgeInsets.only(top: 30),
constraints: const BoxConstraints(
minHeight: 120,
),
color: Colors.transparent,
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white,
),
children: [
TextSpan(
text: startText,
style: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.yellow[400],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
TextSpan(
text: "\n",
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.white,
)),
TextSpan(
text: explainingText,
style: GoogleFonts.inter(
fontSize: 16,
color: Colors.white,
)),
])),
),
);
}
Widget getEndTile() {
return Container(
color: Colors.transparent,
child: TimelineTile(
alignment: TimelineAlign.manual,
lineXY: 0.1,
isLast: true,
beforeLineStyle: const LineStyle(
color: Colors.orange,
thickness: 6,
),
indicatorStyle: IndicatorStyle(
width: 40,
color: Colors.orange,
padding: const EdgeInsets.all(8),
iconStyle: IconStyle(
color: Colors.white,
iconData: Icons.thumb_up,
),
),
endChild: Container(
padding: EdgeInsets.only(top: 50),
constraints: const BoxConstraints(
minHeight: 120,
),
color: Colors.transparent,
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.white,
),
children: [
TextSpan(
text: "Finish!",
style: GoogleFonts.inter(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.yellow[400],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
])),
),
),
);
}
List<Widget> getExerciseTiles(TrainingPlanBloc bloc, BuildContext context) {
List<Widget> tiles = [];
if (bloc.getMyPlan() != null &&
bloc.getMyPlan()!.details.isNotEmpty &&
bloc.getMyPlan()!.days[widget.dayName] != null &&
bloc.getMyPlan()!.days[widget.dayName]!.isNotEmpty) {
bloc.getMyPlan()!.days[widget.dayName]!.forEach((element) {
tiles.add(
/* GestureDetector(
onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
child: */
ExerciseTile(
bloc: bloc,
detail: element,
));
});
}
return tiles;
}
static void executeExercise(TrainingPlanBloc bloc, CustomerTrainingPlanDetails detail, BuildContext context) {
CustomerTrainingPlanDetails? next = bloc.getNext();
if (next != null) {
String title = "";
String description = "";
String description2 = "";
if (next.exerciseTypeId != detail.exerciseTypeId) {
title = AppLocalizations.of(context)!.translate("Stop!");
description = AppLocalizations.of(context)!.translate("Please continue with the next exercise in the queue:") +
next.exerciseType!.nameTranslation;
} else {
final HashMap args = HashMap();
args['exerciseType'] = next.exerciseType;
args['customerTrainingPlanDetails'] = detail;
Navigator.of(context).pushNamed('myTrainingPlanExercise', arguments: args);
return;
}
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return DialogCommon(
title: title,
descriptions: description,
description2: description2,
text: "OK",
onTap: () => {Navigator.of(context).pop()},
onCancel: () => {Navigator.of(context).pop()},
);
});
} else {
Navigator.of(context).pushNamed('home');
}
}
}
class ExerciseTile extends StatefulWidget {
final TrainingPlanBloc bloc;
final CustomerTrainingPlanDetails detail;
ExerciseTile({required this.bloc, required this.detail});
@override
_ExerciseTileState createState() => _ExerciseTileState();
}
class _ExerciseTileState extends State<ExerciseTile> with Trans {
GestureRecognizer? _tapRecognizer;
@override
void initState() {
_tapRecognizer = TapGestureRecognizer()..onTap = _onPlusMinusWeight;
super.initState();
}
@override
void dispose() {
if (_tapRecognizer != null) {
_tapRecognizer!.dispose();
}
super.dispose();
}
void _onPlusMinusWeight() {
showDialog(
context: context,
builder: (BuildContext context) {
return WeightControl(
initialValue: widget.detail.weight != null ? widget.detail.weight! : 30,
onTap: (value) => widget.bloc.add(TrainingPlanWeightChangeRecalculate(detail: widget.detail, weight: value)),
);
});
}
Widget getIndicator(ExercisePlanDetailState state) {
CustomerTrainingPlanDetails? next = widget.bloc.getNext();
bool actual = false;
if (next != null) {
if (next.exerciseTypeId == widget.detail.exerciseTypeId) {
actual = true;
}
}
if (state.equalsTo(ExercisePlanDetailState.inProgress)) {
return ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: actual ? Colors.green : Colors.orange,
child: Icon(
CustomIcon.calendar_2,
size: 28,
color: Colors.white,
)));
} else if (state.equalsTo(ExercisePlanDetailState.finished)) {
return ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.white,
child: Icon(
CustomIcon.ok_circled,
size: 40,
color: Colors.green,
)));
} else if (state.equalsTo(ExercisePlanDetailState.skipped)) {
return ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.white,
child: Icon(
CustomIcon.stop_1,
size: 40,
color: Colors.grey,
)));
} else if (state.equalsTo(ExercisePlanDetailState.extra)) {
return ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.white,
child: Icon(
CustomIcon.stopwatch_20,
size: 40,
color: Colors.blue[800],
)));
} else {
return Image.asset(
"asset/image/pict_reps_volumen_db.png",
);
}
}
@override
Widget build(BuildContext context) {
setContext(context);
final ExercisePlanDetailState state = widget.detail.state;
final bool done = state.equalsTo(ExercisePlanDetailState.finished) || state.equalsTo(ExercisePlanDetailState.skipped);
final String countSerie = widget.detail.set.toString();
final String step = (widget.detail.exercises.length).toString();
String weight = widget.detail.weight != null ? widget.detail.weight!.toStringAsFixed(1) : "-";
bool isDrop = false;
if (widget.detail.weight == -3) {
weight = "DROP";
isDrop = true;
}
String restingTime = widget.detail.restingTime == null ? "" : widget.detail.restingTime!.toStringAsFixed(0);
bool isTest = false;
if (widget.detail.weight != null && widget.detail.weight! == -1) {
weight = "TEST";
isTest = true;
}
String repeats = widget.detail.repeats!.toString();
if (widget.detail.repeats! == -1) {
repeats = t("MAX");
}
final bool extraExercise = widget.detail.exerciseType!.name == "Warming Up" || widget.detail.exerciseType!.name == "Stretching";
bool buddyWarning = widget.detail.exerciseType == null ? false : widget.detail.exerciseType!.buddyWarning;
setContext(context);
return Container(
color: Colors.transparent,
child: TimelineTile(
alignment: TimelineAlign.manual,
lineXY: 0.1,
beforeLineStyle: const LineStyle(
color: Color(0xffb4f500),
thickness: 6,
),
afterLineStyle: const LineStyle(
color: Color(0xffb4f500),
thickness: 6,
),
indicatorStyle: IndicatorStyle(
width: 40,
height: 40,
indicator: getIndicator(state),
),
startChild: Container(
child: Column(children: [
SizedBox(
height: 1,
),
SizedBox(
height: 55,
),
done
? Offstage()
: IconButton(
padding: EdgeInsets.zero,
alignment: Alignment.centerLeft,
icon: Icon(
Icons.skip_next_sharp,
size: 30,
color: Colors.orange[300],
),
onPressed: () => skip()),
]),
),
endChild: Container(
padding: EdgeInsets.only(left: 10),
child: Row(children: [
Container(
width: 120,
height: 80,
child: Badge(
elevation: 0,
padding: EdgeInsets.all(0),
position: BadgePosition.bottomStart(start: -5),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.transparent,
showBadge: true,
badgeContent: IconButton(
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogHTML(
title: widget.detail.exerciseType!.nameTranslation,
htmlData: '<p>' + widget.detail.exerciseType!.descriptionTranslation + '</p>');
}),
icon: Icon(
Icons.info_outline,
color: Colors.yellow[200],
)),
child: Badge(
elevation: 0,
padding: EdgeInsets.all(0),
position: BadgePosition.topEnd(end: -8),
animationDuration: Duration(milliseconds: 500),
animationType: BadgeAnimationType.slide,
badgeColor: Colors.transparent,
showBadge: buddyWarning,
badgeContent: IconButton(
onPressed: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
warning: true,
text: "Warning",
descriptions: t("Attention!"),
description2: t("The safe and exact execution of this exercise you need a training buddy or a trainer"),
description3: t("Execution at your own risk!"),
onTap: () => Navigator.of(context).pop(),
onCancel: () => Navigator.of(context).pop(),
title: t('Training Buddy'),
);
}),
icon: Icon(
CustomIcon.exclamation_circle,
color: Colors.red[800],
)),
child: MenuImage(
imageName: widget.bloc.getActualImageName(widget.detail.exerciseType!.exerciseTypeId),
workoutTreeId: widget.bloc.getActualWorkoutTreeId(widget.detail.exerciseType!.exerciseTypeId)!,
radius: 12,
))),
),
SizedBox(
width: 10,
),
Expanded(
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: done ? Colors.grey[400] : Colors.white,
),
children: [
TextSpan(
text: widget.detail.exerciseType!.nameTranslation,
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: done ? Colors.grey[400] : Colors.orange[500],
shadows: <Shadow>[
Shadow(
offset: Offset(5.0, 5.0),
blurRadius: 12.0,
color: Colors.black54,
),
Shadow(
offset: Offset(-3.0, 3.0),
blurRadius: 12.0,
color: Colors.black54,
),
],
)),
widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise
? TextSpan(
text: "\n",
)
: TextSpan(),
widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise
? TextSpan(
text: t(widget.detail.exerciseType!.unitQuantityUnit!) + ": ",
style: GoogleFonts.inter(
fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold))
: TextSpan(),
widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise
? TextSpan(
text: t(weight),
style: GoogleFonts.inter(
fontSize: 12,
))
: TextSpan(),
widget.detail.exerciseType!.unitQuantityUnit != null && !extraExercise && weight != "TEST" && weight != "DROP"
? TextSpan(
text: " - +",
style: GoogleFonts.archivoBlack(
color: Colors.blue,
fontSize: 16,
),
recognizer: _tapRecognizer,
mouseCursor: SystemMouseCursors.precise,
)
: TextSpan(),
TextSpan(
text: "\n",
),
!extraExercise
? TextSpan(
text: t(widget.detail.exerciseType!.unit) + ": ",
style: GoogleFonts.inter(
fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold))
: TextSpan(),
!extraExercise
? TextSpan(
text: repeats,
style: GoogleFonts.inter(
fontSize: 12,
))
: TextSpan(),
TextSpan(
text: "\n",
),
!extraExercise
? TextSpan(
text: t("Set") + ": ",
style: GoogleFonts.inter(
fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold))
: TextSpan(),
!extraExercise
? TextSpan(
text: step + "/" + countSerie,
style: GoogleFonts.inter(
fontSize: 12,
))
: TextSpan(),
TextSpan(
text: "\n",
),
!extraExercise
? TextSpan(
text: t("Resting time") + ": ",
style: GoogleFonts.inter(
fontSize: 12, color: done ? Colors.grey[100] : Colors.yellow[400], fontWeight: FontWeight.bold))
: TextSpan(),
!extraExercise
? TextSpan(
text: restingTime + " " + t("min(s)"),
style:
GoogleFonts.inter(fontSize: 12, color: done ? Colors.grey[100] : Colors.white, fontWeight: FontWeight.bold))
: TextSpan(),
]),
)),
isTest
? Container(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
warning: false,
title: t("Why Test?"),
descriptions: t("This is your first exercise after at least 3 weeks."),
description2:
t("The first exercise will be a test. The following sets will be recalculated base on your test."),
description3: t("This is the most optimal way for your development"),
text: "OK",
onTap: () => Navigator.of(context).pop(),
onCancel: () => {
Navigator.of(context).pop(),
},
);
}),
child: Icon(
CustomIcon.question_circle,
color: Colors.yellowAccent[700],
size: 16,
)),
]))
: isDrop
? Container(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
GestureDetector(
onTap: () => showDialog(
context: context,
builder: (BuildContext context) {
return DialogCommon(
warning: false,
title: t("Drop Set"),
descriptions: t(
"Execute at least 3 sets with maximum repeats, without resting time, with decreasing the weight."),
description2:
t("The goal is to completly exhaust your muscle without lifting a ridiculous weight end the end."),
text: "OK",
onTap: () => Navigator.of(context).pop(),
onCancel: () => {
Navigator.of(context).pop(),
},
);
}),
child: Icon(
CustomIcon.question_circle,
color: Colors.orange[200],
size: 16,
)),
]))
: Offstage()
]),
),
),
);
}
void skip() {
showCupertinoDialog(
useRootNavigator: true,
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text(t("You want to skip really this exercise?")),
content: Column(children: [
Divider(),
]),
actions: [
TextButton(
child: Text(t("No")),
onPressed: () => {
Navigator.pop(context),
}),
TextButton(
child: Text(t("Yes")),
onPressed: () {
Navigator.pop(context);
widget.bloc.add(TrainingPlanSkipExercise(detail: widget.detail));
},
)
],
));
}
}
+12 -3
View File
@@ -2,10 +2,12 @@ import 'dart:collection';
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
import 'package:aitrainer_app/library/custom_icon_icons.dart';
import 'package:aitrainer_app/model/cache.dart';
import 'package:aitrainer_app/model/customer_training_plan_details.dart';
import 'package:aitrainer_app/util/trans.dart';
import 'package:aitrainer_app/widgets/app_bar.dart';
import 'package:aitrainer_app/widgets/exercise_save.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';
@@ -26,7 +28,7 @@ class TrainingPlanExercise extends StatelessWidget with Trans {
body: Container(
height: double.infinity,
width: double.infinity,
padding: EdgeInsets.all(20),
//padding: EdgeInsets.all(20),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("asset/image/WT_black_background.jpg"),
@@ -75,7 +77,7 @@ class TrainingPlanExercise extends StatelessWidget with Trans {
backgroundColor: Colors.orange[800],
icon: Icon(CustomIcon.save),
label: Text(
isDropSet ? t("Done") : t("Save"),
t("Done"),
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
@@ -92,7 +94,7 @@ class TrainingPlanExercise extends StatelessWidget with Trans {
unit: detail.exerciseType!.unit,
unitQuantityUnit: detail.exerciseType!.unitQuantityUnit,
hasUnitQuantity: detail.exerciseType!.unitQuantityUnit != null,
weight: detail.weight == -1 ? 0 : detail.weight,
weight: detail.weight,
repeats: detail.repeats == -1 ? 99 : detail.repeats,
set: detail.set,
exerciseNr: detail.exercises.length + 1,
@@ -100,6 +102,13 @@ class TrainingPlanExercise extends StatelessWidget with Trans {
onQuantityChanged: (value) => bloc.add(TrainingPlanRepeatsChange(repeats: value.toInt(), detail: detail)),
exerciseTypeId: detail.exerciseType!.exerciseTypeId,
originalQuantity: originalQuantity,
tip: ActivityDone.exerciseSaveTrainingTip,
menuImage: MenuImage(
imageName: bloc.getActualImageName(detail.exerciseType!.exerciseTypeId),
workoutTreeId: bloc.getActualWorkoutTreeId(detail.exerciseType!.exerciseTypeId)!,
radius: 0,
filter: false,
),
);
} else {
return getDropSet(bloc, detail);
+1 -1
View File
@@ -44,7 +44,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
title: t("Warning"),
descriptions: t(state.message),
text: "OK",
onTap: () => Navigator.of(context).pushNamed("login"),
onTap: () => Navigator.of(context).pop(),
onCancel: () => {
Navigator.of(context).pop(),
},