import 'dart:convert'; 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/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:carousel_slider/carousel_slider.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/modal_progress_hud.dart'; import 'package:transparent_image/transparent_image.dart'; import 'package:aitrainer_app/library/image_cache.dart' as wt; // ignore: must_be_immutable class TestSetEdit extends StatelessWidget with Trans { @override Widget build(BuildContext context) { final String templateName = ModalRoute.of(context).settings.arguments; // ignore: close_sinks final MenuBloc menuBloc = BlocProvider.of(context); TestSetEditBloc bloc; setContext(context); return Scaffold( 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: BlocProvider( create: (context) => TestSetEditBloc(templateName: templateName, workoutTreeRepository: menuBloc.menuTreeRepository, menuBloc: menuBloc), child: BlocConsumer(listener: (context, state) { if (state is TestSetEditError) { Scaffold.of(context).showSnackBar( SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); } else if (state is TestSetEditSaved) { Navigator.of(context).pushNamed("home"); } }, builder: (context, state) { bloc = BlocProvider.of(context); return ModalProgressHUD( child: getTestSetWidget(bloc, templateName), inAsyncCall: state is TestSetEditLoading, opacity: 0.5, color: Colors.black54, progressIndicator: CircularProgressIndicator(), ); }))), floatingActionButton: FloatingActionButton.extended( onPressed: () => showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return DialogCommon( title: "Start!", descriptions: "GO", text: "OK", onTap: () => { Navigator.of(context).pop(), if (bloc != null) { bloc.add(TestSetEditSubmit()), } }, onCancel: () => {Navigator.of(context).pop()}, ); }), backgroundColor: Colors.orange[800], icon: Icon(CustomIcon.clock), label: Text( "Start training", style: GoogleFonts.inter(fontWeight: FontWeight.bold, fontSize: 16), ), ), ); } 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 DialogCommon( title: "Own Body", descriptions: t("execute these exercises with maximum repeats. Leave at least 3 min rest time between time"), text: "OK", onTap: () => {Navigator.of(context).pop()}, onCancel: () => {Navigator.of(context).pop()}, ); }), child: Icon( CustomIcon.question_circle, color: Colors.orange[400], size: 40, )), ]), centerTitle: true, ), SliverList(delegate: SliverChildListDelegate(getExerciseTypeWidgets(bloc))), ])); } List imageSliders(List alternatives, MenuBloc menuBloc) { final List list = List(); alternatives.forEach((element) { list.add(getImageStack(element, menuBloc)); }); list.add(Container( padding: EdgeInsets.only(top: 25, bottom: 25), child: ClipRRect( borderRadius: BorderRadius.circular(24.0), child: Container( color: Colors.red[600], child: Center( child: Text( "X", style: GoogleFonts.archivoBlack( color: Colors.white, fontSize: 80, ), ), ))))); return list; } Stack getImageStack(WorkoutMenuTree element, MenuBloc menuBloc) { print(element.toJson()); return Stack(alignment: Alignment.bottomLeft, children: [ _getButtonImage(element, menuBloc), Container( padding: EdgeInsets.only(left: 15, bottom: 15, right: 15), child: Text( element.name, maxLines: 4, style: GoogleFonts.archivoBlack(color: element.color, fontSize: 16, height: 1.1), ), ), ]); } List getExerciseTypeWidgets(TestSetEditBloc bloc) { final List widgets = List(); bloc.exerciseTypes.forEach((element) { final WorkoutMenuTree workoutTree = bloc.menuBloc.menuTreeRepository.getMenuItemByExerciseTypeId(element.exerciseTypeId); final List alternativeMenuItems = bloc.menuBloc.menuTreeRepository.getWorkoutTreeAlternatives(workoutTree); if (workoutTree != null && alternativeMenuItems != null) { 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, exerciseTypeId: element.exerciseTypeId)), enlargeStrategy: CenterPageEnlargeStrategy.scale), items: imageSliders(alternativeMenuItems, bloc.menuBloc), ); widgets.add(widget); } }); return widgets; } Widget _getButtonImage(WorkoutMenuTree workoutTree, MenuBloc menuBloc) { if (workoutTree == null) { return Offstage(); } String imageString = menuBloc.getImage(workoutTree.id, workoutTree.imageName); Widget widget; if (imageString != null) { widget = ClipRRect( borderRadius: BorderRadius.circular(24.0), child: Container( color: Colors.transparent, child: FadeInImage( fadeInDuration: Duration(milliseconds: 100), image: MemoryImage(base64Decode(imageString)), placeholder: MemoryImage(kTransparentImage), ), )); } else { if (workoutTree.imageName.contains("https")) { if (!wt.ImageCache().existsImageInMap(workoutTree.id, workoutTree.imageName)) { widget = ClipRRect( borderRadius: BorderRadius.circular(24.0), child: Container( color: Colors.transparent, child: FadeInImage( fadeInDuration: Duration(milliseconds: 500), image: NetworkImage(workoutTree.imageName), placeholder: MemoryImage(kTransparentImage), ), )); } } else { widget = ClipRRect( borderRadius: BorderRadius.circular(24.0), child: Container( color: Colors.transparent, child: Image.asset(workoutTree.imageName), )); } } return widget; } }