WT1.1.8+3 custom plan and training plan fixes

This commit is contained in:
bossanyit
2021-06-02 17:25:35 +02:00
parent 2b206fff49
commit d5deaf48a9
24 changed files with 1561 additions and 614 deletions
+8 -8
View File
@@ -241,11 +241,11 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
useRootNavigator: true,
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text(t("You have an active Training Plan!")),
title: Text(t("You have an active Training Plan")),
content: Column(children: [
Divider(),
Text(
t("Do you want to override it with "),
t("Do you want to override it with"),
style: (TextStyle(color: Colors.blue)),
),
Text(
@@ -318,7 +318,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.only(left: 8.0),
alignment: Alignment.centerLeft,
child: Text(
'Exercise',
t('Exercise'),
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
))),
@@ -330,7 +330,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.symmetric(horizontal: 8.0),
alignment: Alignment.centerLeft,
child: Text(
'Exercise',
t('Exercise'),
textAlign: TextAlign.start,
overflow: TextOverflow.ellipsis,
))),
@@ -342,7 +342,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
'Set',
t('Set'),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
@@ -353,7 +353,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
'Reps',
t('Reps'),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
@@ -364,7 +364,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.symmetric(horizontal: 2.0),
alignment: Alignment.centerLeft,
child: Text(
'Weight',
t('Weight'),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
@@ -375,7 +375,7 @@ class TrainingPlanActivatePage extends StatelessWidget with Trans {
padding: EdgeInsets.symmetric(horizontal: 8.0),
alignment: Alignment.centerLeft,
child: Text(
'Day',
t('Day'),
overflow: TextOverflow.ellipsis,
))),
],
+372
View File
@@ -0,0 +1,372 @@
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.dart';
import 'package:aitrainer_app/model/exercise_type.dart';
import 'package:aitrainer_app/model/workout_menu_tree.dart';
import 'package:aitrainer_app/library/tree_view.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/bottom_nav.dart';
import 'package:aitrainer_app/widgets/menu_image.dart';
import 'package:aitrainer_app/widgets/treeview_parent_widget.dart';
import 'package:ezanimation/ezanimation.dart';
import 'package:flutter/cupertino.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 TrainingPlanCustomPage extends StatefulWidget {
@override
_ExercisePlanCustomPage createState() => _ExercisePlanCustomPage();
}
class _ExercisePlanCustomPage extends State<TrainingPlanCustomPage> with Trans {
TrainingPlanBloc? bloc;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
setContext(context);
bloc = BlocProvider.of<TrainingPlanBloc>(context);
bloc!.menuBloc.menuTreeRepository.sortByMuscleType();
return Scaffold(
key: _scaffoldKey,
appBar: AppBarNav(depth: 1),
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(
content: Text(
state.message,
),
backgroundColor: Colors.orange,
));
}
}, builder: (context, state) {
return ModalProgressHUD(
child: exerciseWidget(bloc!),
inAsyncCall: state is TrainingPlanLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
})),
bottomNavigationBar: BottomNavigator(bottomNavIndex: 2),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => Navigator.of(context).popAndPushNamed('myTrainingPlanExecute'),
backgroundColor: Colors.orange[800],
icon: Icon(CustomIcon.weight_hanging),
label: Text(
t("Start") + "!",
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
);
}
Widget exerciseWidget(TrainingPlanBloc bloc) {
return TreeView(
startExpanded: false,
children: _getTreeChildren(bloc),
);
}
List<Widget> _getTreeChildren(TrainingPlanBloc bloc) {
List<Widget> exerciseTypes = [];
Card explanation = Card(
color: Colors.white60,
child: Container(
padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
children: [
Icon(
Icons.info,
color: Colors.orangeAccent,
),
Text(" "),
Text(
t("Custom Exercise Plan"),
style: GoogleFonts.archivoBlack(fontSize: 20),
),
],
),
Divider(
color: Colors.transparent,
),
Text(
t("Select manually the exercises what you would like to have in your plan. At the end don't forget to save."),
style: GoogleFonts.inter(fontSize: 12, fontWeight: FontWeight.normal),
),
],
)));
exerciseTypes.add(explanation);
bloc.menuBloc.menuTreeRepository.sortedTree.forEach((name, list) {
exerciseTypes.add(Container(
margin: const EdgeInsets.only(left: 4.0),
child: TreeViewChild(
startExpanded: false,
parent: TreeviewParentWidget(text: name),
children: getTiles(list, bloc),
)));
});
return exerciseTypes;
}
List<Widget> getTiles(List<WorkoutMenuTree> list, TrainingPlanBloc bloc) {
List<Widget> tiles = [];
tiles.addAll(getExerciseTiles(bloc, list));
return tiles;
}
List<Widget> getExerciseTiles(TrainingPlanBloc bloc, List<WorkoutMenuTree> listWorkoutTree) {
List<Widget> tiles = [];
listWorkoutTree.forEach((element) {
tiles.add(GestureDetector(
onTap: () => {},
child: ExerciseTile(
bloc: bloc,
exerciseType: element.exerciseType!,
)));
});
return tiles;
}
}
class ExerciseTile extends StatefulWidget {
final TrainingPlanBloc bloc;
final ExerciseType exerciseType;
ExerciseTile({required this.bloc, required this.exerciseType});
@override
_ExerciseTileState createState() => _ExerciseTileState();
}
class _ExerciseTileState extends State<ExerciseTile> with Trans {
final EzAnimation animation = EzAnimation(1.0, 30.0, Duration(seconds: 3), reverseCurve: Curves.easeIn);
@override
void initState() {
animation.start();
animation.addStatusListener((status) {
if (status == AnimationStatus.completed) {}
});
super.initState();
}
@override
bool didUpdateWidget(ExerciseTile oldWidget) {
super.didUpdateWidget(oldWidget);
Future.delayed(Duration(milliseconds: 400)).then((value) => animation.start());
return true;
}
void activateCustomPlan() {
widget.bloc.add(TrainingPlanCustomAddLoad(exerciseType: widget.exerciseType));
Navigator.of(context).popAndPushNamed("myTrainingPlanCustomAdd");
}
Widget getIndicator() {
if (widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.none)) {
return GestureDetector(
onTap: () {
if (widget.bloc.getMyPlan() != null && !widget.bloc.getMyPlan()!.type.equalsTo(CustomerTrainingPlanType.custom)) {
showCupertinoDialog(
useRootNavigator: true,
context: context,
builder: (_) => CupertinoAlertDialog(
title: Text(t("You have an active Training Plan")),
content: Column(children: [
Divider(),
Text(
t("Do you want to override it?"),
style: (TextStyle(color: Colors.blue)),
),
]),
actions: [
TextButton(
child: Text(t("No")),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(t("Yes")),
onPressed: () => activateCustomPlan(),
)
],
));
} else {
activateCustomPlan();
}
},
child: ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.blue,
child: Icon(
CustomIcon.plus_1,
size: 28,
color: Colors.white,
))));
} else if (widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.added)) {
return GestureDetector(
onTap: () => widget.bloc.add(TrainingPlanDeleteExerciseType(exerciseType: widget.exerciseType)),
child: ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
padding: EdgeInsets.only(left: 8, bottom: 3),
color: Colors.red[400],
child: Text("X",
style: GoogleFonts.archivoBlack(
fontSize: 30,
color: Colors.white,
)))));
} else {
return ClipRRect(
borderRadius: BorderRadius.circular(24.0),
child: Container(
color: Colors.blue,
child: Icon(
CustomIcon.down,
size: 28,
color: Colors.white,
)));
}
}
@override
Widget build(BuildContext context) {
bool added = widget.exerciseType.trainingPlanState.equalsTo(ExerciseTypeTrainingPlanState.added);
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(),
),
endChild: Container(
padding: EdgeInsets.only(left: 10),
child: Row(children: [
Container(
width: 120,
height: 80,
child: MenuImage(
imageName: widget.bloc.getActualImageName(widget.exerciseType.exerciseTypeId),
workoutTreeId: widget.bloc.getActualWorkoutTreeId(widget.exerciseType.exerciseTypeId)!,
),
),
SizedBox(
width: 10,
),
Expanded(
child: RichText(
text: TextSpan(
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: added ? Colors.white : Colors.grey,
),
children: [
TextSpan(
text: widget.exerciseType.nameTranslation,
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.bold,
color: added ? Colors.orange[500] : 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,
),
],
)),
widget.exerciseType.unitQuantityUnit != null
? TextSpan(
text: "\n",
)
: TextSpan(),
widget.exerciseType.unitQuantityUnit != null
? TextSpan(
text: t(widget.exerciseType.unitQuantityUnit!) + ": ",
style: GoogleFonts.inter(
fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold))
: TextSpan(),
widget.exerciseType.unitQuantityUnit != null
? TextSpan(
text: added ? widget.bloc.getWeightByExerciseType(widget.exerciseType) : "?",
style: GoogleFonts.inter(
fontSize: 12,
))
: TextSpan(),
TextSpan(
text: "\n",
),
TextSpan(
text: t(widget.exerciseType.unit) + ": ",
style:
GoogleFonts.inter(fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold)),
TextSpan(
text: added ? widget.bloc.getRepeatsByExerciseType(widget.exerciseType) : "?",
style: GoogleFonts.inter(
fontSize: 12,
)),
TextSpan(
text: "\n",
),
TextSpan(
text: t("Set") + ": ",
style:
GoogleFonts.inter(fontSize: 12, color: added ? Colors.yellow[400] : Colors.grey, fontWeight: FontWeight.bold)),
TextSpan(
text: added ? widget.bloc.getSetByExerciseType(widget.exerciseType) : "?",
style: GoogleFonts.inter(
fontSize: 12,
)),
]),
)),
]),
),
),
);
}
}
+259
View File
@@ -0,0 +1,259 @@
import 'package:aitrainer_app/bloc/training_plan/training_plan_bloc.dart';
import 'package:aitrainer_app/util/app_language.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:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:keyboard_actions/keyboard_actions_config.dart';
import 'package:keyboard_actions/keyboard_actions_item.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
class TrainingPlanCustomAddPage extends StatefulWidget {
@override
_ExercisePlanDetailAddPage createState() => _ExercisePlanDetailAddPage();
}
class _ExercisePlanDetailAddPage extends State<TrainingPlanCustomAddPage> with Trans {
final FocusNode _nodeText1 = FocusNode();
final FocusNode _nodeText2 = FocusNode();
final FocusNode _nodeText3 = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
keyboardBarColor: Colors.grey[200],
nextFocus: true,
actions: [
KeyboardActionsItem(focusNode: _nodeText2, toolbarButtons: [
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
padding: EdgeInsets.all(8.0),
color: Colors.orange[500],
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
]),
KeyboardActionsItem(
focusNode: _nodeText1,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
KeyboardActionsItem(
focusNode: _nodeText3,
toolbarButtons: [
//button 2
(node) {
return GestureDetector(
onTap: () => node.unfocus(),
child: Container(
color: Colors.orange,
padding: EdgeInsets.all(8.0),
child: Text(
t("Done"),
style: TextStyle(color: Colors.white),
),
),
);
}
],
),
],
);
}
@override
Widget build(BuildContext context) {
setContext(context);
return 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))));
}
},
builder: (context, state) {
// ignore: close_sinks
final bloc = BlocProvider.of<TrainingPlanBloc>(context);
return ModalProgressHUD(
child: getForm(bloc),
inAsyncCall: state is TrainingPlanLoading,
opacity: 0.5,
color: Colors.black54,
progressIndicator: CircularProgressIndicator(),
);
},
);
}
Widget getForm(TrainingPlanBloc bloc) {
String exerciseName = "";
exerciseName = bloc.getExerciseName(AppLanguage().appLocal);
final bool weightVisible = bloc.getMyDetail()!.exerciseType!.unitQuantityUnit != null;
String summary = bloc.getCustomAddSummary();
if (weightVisible && bloc.getMyDetail()!.weight != null && bloc.getMyDetail()!.weight! > 0) {
summary += " x " + bloc.getMyDetail()!.weight!.toStringAsFixed(1) + " kg";
}
final String unit = bloc.getMyDetail()!.exerciseType!.unit;
return Form(
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBarMin(back: true),
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: KeyboardActions(
config: _buildConfig(context),
child: Container(
child: SingleChildScrollView(
padding: const EdgeInsets.only(top: 25, left: 95, right: 95),
scrollDirection: Axis.vertical,
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
Text(t('Save The Exercise To The Training Plan'),
textAlign: TextAlign.center,
style: GoogleFonts.inter(
fontSize: 14,
color: Colors.white,
)),
Text(
exerciseName,
textAlign: TextAlign.center,
style: GoogleFonts.archivoBlack(fontSize: 18, color: Colors.yellow[200]),
overflow: TextOverflow.fade,
maxLines: 3,
softWrap: true,
),
Divider(
color: Colors.transparent,
height: 30,
),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Serie'),
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50], decorationColor: Colors.black12),
fillColor: Colors.white24,
filled: true,
border: OutlineInputBorder(
gapPadding: 8.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.black26, width: 0.4),
),
),
initialValue: bloc.getMyDetail()!.set!.toStringAsFixed(0),
focusNode: _nodeText1,
keyboardType: TextInputType.number,
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {bloc.add(TrainingPlanSetChange(detail: bloc.getMyDetail()!, set: int.parse(value)))}),
Divider(),
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t(unit),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 4.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50]!, width: 0.4),
),
),
focusNode: _nodeText2,
initialValue: bloc.getMyDetail()!.repeats!.toStringAsFixed(0),
keyboardType: TextInputType.number,
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => bloc.add(TrainingPlanRepeatsChange(detail: bloc.getMyDetail()!, repeats: int.parse(value))),
),
Divider(),
weightVisible
? TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
labelText: t('Weight'),
fillColor: Colors.white24,
labelStyle: GoogleFonts.inter(fontSize: 20, color: Colors.yellow[50]),
filled: true,
border: OutlineInputBorder(
gapPadding: 2.0,
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: Colors.green[50]!, width: 0.4),
),
),
focusNode: _nodeText3,
initialValue: bloc.getMyDetail()!.weight!.toStringAsFixed(1),
keyboardType: TextInputType.numberWithOptions(decimal: true),
style: GoogleFonts.archivoBlack(fontSize: 60, color: Colors.yellow[200]),
onChanged: (value) => {
if (value.isNotEmpty)
{
value = value.replaceFirst(",", "."),
value = value.replaceAll(RegExp(r'[^0-9.]'), ""),
bloc.add(TrainingPlanWeightChange(detail: bloc.getMyDetail()!, weight: double.parse(value))),
}
})
: Offstage(),
Divider(),
Text(
summary,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.normal, color: Colors.yellow[50]),
),
Divider(),
Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TextButton(
onPressed: () => {
bloc.add(TrainingPlanAddExerciseType()),
Navigator.of(context).popAndPushNamed("myTrainingPlanCustom"),
},
child: Stack(
alignment: Alignment.center,
children: [
Image.asset('asset/icon/gomb_zold_b-1.png', width: 140, height: 60),
Text(
t("Save"),
style: TextStyle(fontSize: 16, color: Colors.white),
),
],
)),
],
),
]),
)))),
));
}
}
+44 -7
View File
@@ -9,6 +9,7 @@ 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/menu_image.dart';
import 'package:aitrainer_app/widgets/victory_widget.dart';
import 'package:extended_tabs/extended_tabs.dart';
import 'package:ezanimation/ezanimation.dart';
import 'package:flutter/cupertino.dart';
@@ -48,7 +49,44 @@ class _TrainingPlanExecutePageState extends State<TrainingPlanExecutePage> with
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 TrainingPlanFinished) {}
} else if (state is TrainingPlanDayFinished) {
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Victory(
victory: true,
);
});
bloc!.celebrating = false;
} 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!),
@@ -66,7 +104,7 @@ class _TrainingPlanExecutePageState extends State<TrainingPlanExecutePage> with
backgroundColor: Colors.orange[800],
icon: Icon(CustomIcon.weight_hanging),
label: Text(
t("Training!"),
t("Training") + "!",
style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16),
),
),
@@ -88,7 +126,7 @@ class _ExerciseTabs extends State<ExerciseTabs> with TickerProviderStateMixin {
void initState() {
super.initState();
tabController = TabController(length: widget.bloc.dayNames.length, vsync: this);
tabController.animateTo(0, duration: Duration(milliseconds: 300));
tabController.animateTo(widget.bloc.activeDayIndex, duration: Duration(milliseconds: 300));
}
@override
@@ -107,6 +145,7 @@ class _ExerciseTabs extends State<ExerciseTabs> with TickerProviderStateMixin {
ExtendedTabBar(
tabs: getTabNames(),
controller: tabController,
onTap: (index) => bloc.activeDayIndex = index,
),
Expanded(
child: ExtendedTabBarView(
@@ -257,7 +296,6 @@ class _ExerciseListState extends State<ExerciseList> with Trans {
} else {
startText = bloc.isStarted() ? t("Continue your training") : t("Start your training");
explainingText = bloc.getMyPlan()!.name != null ? bloc.getMyPlan()!.name! : "";
print(" *** Plan NAME ${bloc.getMyPlan()!.name}");
}
return TimelineTile(
@@ -393,7 +431,6 @@ 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) {
//bloc.getMyPlan()!.details.forEach((element) {
tiles.add(GestureDetector(
onTap: () => bloc.getNext() != null ? executeExercise(bloc, bloc.getNext()!, context) : Navigator.of(context).pushNamed('home'),
child: ExerciseTile(
@@ -670,7 +707,7 @@ class _ExerciseTileState extends State<ExerciseTile> with Trans {
style: GoogleFonts.inter(fontSize: 12, color: done ? Colors.grey[100] : Colors.white, fontWeight: FontWeight.bold)),
]),
)),
done
/* done
? AnimatedBuilder(
animation: animation,
builder: (context, snapshot) {
@@ -682,7 +719,7 @@ class _ExerciseTileState extends State<ExerciseTile> with Trans {
Text("Result", style: GoogleFonts.inter(fontSize: 10, color: Colors.white)),
]);
})
: Offstage(),
: Offstage(), */
isTest
? AnimatedBuilder(
animation: animation,
@@ -52,6 +52,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
} else if (state is TrainingPlanFinished) {
Navigator.of(context).pop();
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
bloc.setMyPlan(Cache().myTrainingPlan);
Navigator.of(context).pushNamed("myTrainingPlanExecute", arguments: bloc);
}
},
@@ -76,7 +77,8 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
delegate: SliverChildListDelegate([
getTrainingPlan(t("My Active Training"), "asset/image/exercise_plan_execute.jpg", "",
color: Colors.yellow[400]!, route: "myTrainingPlanExecute"),
getTrainingPlan(t("My Custom Plan"), "asset/image/exercise_plan_custom.jpg", ""),
getTrainingPlan(t("My Custom Plan"), "asset/image/exercise_plan_custom.jpg", "",
color: Colors.green[100]!, route: "myTrainingPlanCustom"),
getTrainingPlan(t("Training Plans for Beginners"), "asset/menu/training_plans_q_beginner.jpg", "beginner"),
getTrainingPlan(t("Training Plans for Home"), "asset/menu/training_plans_q_home.jpg", "home"),
getTrainingPlan(t("Training Plans Advanced"), "asset/menu/training_plans_q_advanced.jpg", "advanced"),
@@ -104,7 +106,7 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
textAlignment: Alignment.topLeft,
text: name,
style: GoogleFonts.robotoMono(
textStyle: TextStyle(fontSize: 14, color: color, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
textStyle: TextStyle(fontSize: 12, color: color, fontWeight: FontWeight.bold, backgroundColor: Colors.black54.withOpacity(0.4))),
image: imageUrl,
left: 5,
textColor: color,
@@ -113,7 +115,11 @@ class MyTrainingPlans extends StatelessWidget with Trans, Logging {
if (route == "myTrainingPlanActivate") {
HashMap<String, dynamic> args = HashMap();
args['parentName'] = parentName;
Navigator.of(context).pushNamed("myTrainingPlanActivate", arguments: args);
Navigator.of(context).pushNamed(route, arguments: args);
} else if (route == "myTrainingPlanExecute") {
final TrainingPlanBloc bloc = BlocProvider.of<TrainingPlanBloc>(context);
bloc.setMyPlan(Cache().myTrainingPlan);
Navigator.of(context).pushNamed(route);
} else {
Navigator.of(context).pushNamed(route);
}