import 'dart:collection'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:aitrainer_app/bloc/test_set_edit/test_set_edit_bloc.dart'; import 'package:aitrainer_app/library/custom_icon_icons.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/workout_menu_tree.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:carousel_slider/carousel_slider.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'; // ignore: must_be_immutable class TestSetEdit extends StatelessWidget with Trans { @override Widget build(BuildContext context) { HashMap args = ModalRoute.of(context)!.settings.arguments as HashMap; final String templateName = args['templateName']; final String templateNameTranslation = args['templateNameTranslation']; // ignore: close_sinks final MenuBloc menuBloc = BlocProvider.of(context); late TestSetEditBloc bloc; final bool activeExercisePlan = Cache().activeExercisePlan != null; 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: BlocProvider( create: (context) => TestSetEditBloc( templateName: templateName, templateNameTranslation: templateNameTranslation, workoutTreeRepository: menuBloc.menuTreeRepository, menuBloc: menuBloc), child: BlocConsumer(listener: (context, state) { if (state is TestSetEditError) { showDialog( context: context, builder: (BuildContext context) { return DialogCommon( warning: true, title: t("Warning"), descriptions: t(state.message), text: "OK", onTap: () => Navigator.of(context).pushNamed("login"), onCancel: () => { Navigator.of(context).pop(), }, ); }); } else if (state is TestSetEditSaved) { Navigator.of(context).pop(); Navigator.of(context).pushNamed("testSetExecute"); } }, builder: (context, state) { bloc = BlocProvider.of(context); return ModalProgressHUD( child: getTestSetWidget(bloc, templateNameTranslation), inAsyncCall: state is TestSetEditLoading, opacity: 0.5, color: Colors.black54, progressIndicator: CircularProgressIndicator(), ); }))), floatingActionButton: FloatingActionButton.extended( onPressed: () { if (Cache().userLoggedIn == null) { bloc.add(TestSetEditAddError(message: "Please log in")); } else { if (activeExercisePlan) { showCupertinoDialog( useRootNavigator: true, context: context, builder: (_) => CupertinoAlertDialog( title: Text(t("You have an active Test Set!") + "\n" + Cache().activeExercisePlan!.name), content: Column(children: [ Divider(), Text(t("Do you want to override it?"), style: GoogleFonts.inter(color: Colors.black, fontSize: 16)), ]), actions: [ TextButton( child: Text(t("No, bring me there"), textAlign: TextAlign.center), onPressed: () => { Navigator.pop(context), Navigator.pop(context), Navigator.of(context).pushNamed("testSetExecute"), }, ), TextButton( child: Text(t("Yes")), onPressed: () { Navigator.pop(context); startTrainingDialog(bloc); }, ) ], )); } else { startTrainingDialog(bloc); } } }, backgroundColor: Colors.orange[800], icon: Icon(CustomIcon.clock), label: Text( t("Start training"), style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16), ), ), ); } void startTrainingDialog(TestSetEditBloc? bloc) { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return DialogCommon( title: "Start!", descriptions: t("Enjoy the exercises, good luck with the testing!"), text: "OK", onTap: () => { Navigator.of(context).pop(), if (bloc != null) { bloc.add(TestSetEditSubmit()), } }, onCancel: () => {Navigator.of(context).pop()}, ); }); } Widget getTestSetWidget(TestSetEditBloc bloc, String templateName) { return Container( padding: EdgeInsets.only(left: 10, right: 10), child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [ SliverAppBar( toolbarHeight: 135, automaticallyImplyLeading: false, backgroundColor: Colors.transparent, title: Column(mainAxisAlignment: MainAxisAlignment.start, children: [ RichText( textAlign: TextAlign.center, text: TextSpan( style: GoogleFonts.archivoBlack( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, shadows: [ 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, ), ], ), children: [ TextSpan(text: t("Edit Your Training Test Set"), style: GoogleFonts.inter(color: Colors.white, fontSize: 18)), TextSpan(text: "\n", style: GoogleFonts.inter(color: Colors.white, fontSize: 18)), TextSpan(text: t(templateName), style: GoogleFonts.archivoBlack(color: Colors.yellow[300], fontSize: 18)), ])), Divider( color: Colors.transparent, ), GestureDetector( onTap: () => showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return DialogHTML( title: bloc.templateNameTranslation, htmlData: bloc.templateDescription, ); }), child: Icon( CustomIcon.question_circle, color: Colors.orange[400], size: 40, )), ]), centerTitle: true, ), SliverList(delegate: SliverChildListDelegate(getExerciseTypeWidgets(bloc))), ])); } List imageSliders(int index, WorkoutMenuTree? workoutTree, TestSetEditBloc bloc) { final List list = []; bool deleted = workoutTree == null; bloc.displayPlanDetails[index].forEach((value) { ExerciseType alternative = value; final WorkoutMenuTree? workoutTreeAlternative = bloc.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(alternative.exerciseTypeId); list.add(getImageStack(workoutTreeAlternative!, bloc, index, deleted)); }); return list; } Stack getImageStack(WorkoutMenuTree element, TestSetEditBloc bloc, int index, bool deleted) { return Stack(alignment: Alignment.topRight, children: [ Stack(alignment: Alignment.bottomLeft, children: [ deleted ? Opacity(opacity: 0.2, child: MenuImage(imageName: element.imageName, workoutTreeId: element.id)) : MenuImage(imageName: element.imageName, workoutTreeId: element.id), Container( padding: EdgeInsets.only(left: 15, bottom: 15, right: 15), child: Text( element.name, maxLines: 4, style: GoogleFonts.archivoBlack(color: deleted ? element.color.withOpacity(0.2) : element.color, fontSize: 16, height: 1.1), ), ), ]), deleted == false ? Container( width: 40, height: 40, child: ClipRRect( borderRadius: BorderRadius.circular(24.0), child: GestureDetector( onTap: () => bloc.add(TestSetEditDeleteExerciseType(indexKey: index)), child: Container( color: Colors.red[600], child: Center( child: Text( "X", style: GoogleFonts.archivoBlack( color: Colors.white, fontSize: 28, ), ), ))))) : Container( width: 40, height: 40, child: ClipRRect( borderRadius: BorderRadius.circular(24.0), child: GestureDetector( onTap: () { bloc.add(TestSetEditAddExerciseType(indexKey: index)); }, child: Container( color: Colors.yellow[700], child: Center( child: Icon( Icons.undo_sharp, size: 40, color: Colors.white, )), )))) ]); } List getExerciseTypeWidgets(TestSetEditBloc bloc) { final List widgets = []; bloc.exercisePlanDetails.forEach((key, element) { WorkoutMenuTree? workoutTree; if (element != null) { workoutTree = bloc.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(element.exerciseTypeId); } final Widget widget = CarouselSlider( options: CarouselOptions( viewportFraction: 0.80, reverse: false, enableInfiniteScroll: false, autoPlay: false, aspectRatio: 2, enlargeCenterPage: true, onPageChanged: (index, reason) => bloc.add(TestSetEditChangeExerciseType(index: index, indexKey: key)), enlargeStrategy: CenterPageEnlargeStrategy.scale), items: imageSliders(key, workoutTree, bloc), ); widgets.add(widget); }); return widgets; } }