import 'dart:collection'; import 'package:aitrainer_app/bloc/exercise_add_by_plan_bloc.dart'; import 'package:aitrainer_app/bloc/exercise_by_plan/exercise_by_plan_bloc.dart'; import 'package:aitrainer_app/localization/app_language.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/splash.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_form_bloc/flutter_form_bloc.dart'; class ExerciseAddByPlanPage extends StatefulWidget{ _ExerciseAddByPlanPage createState() => _ExerciseAddByPlanPage(); } class _ExerciseAddByPlanPage extends State with Trans { @override Widget build(BuildContext context) { LinkedHashMap arguments = ModalRoute.of(context).settings.arguments; // ignore: close_sinks final ExerciseByPlanBloc bloc = arguments['blocExerciseByPlan']; final int customerId = arguments['customerId']; final WorkoutMenuTree workoutTree = arguments['workoutTree']; final ExerciseRepository exerciseRepository = ExerciseRepository(); setContext(context); return BlocProvider( create: (context) => ExerciseAddByPlanFormBloc( exerciseRepository: exerciseRepository, exercisePlanRepository: bloc.exercisePlanRepository, customerId: customerId, workoutTree: workoutTree), child: BlocBuilder( builder: (context, state) { // ignore: close_sinks final exerciseBloc = BlocProvider.of(context); if ( state is FormBlocLoading ) { return LoadingDialog(); } else if ( state is FormBlocSuccess) { return getControlForm(exerciseBloc); } else { return getControlForm(exerciseBloc); } } )); } Form getControlForm( ExerciseAddByPlanFormBloc exerciseBloc) { String exerciseName = AppLanguage().appLocal == Locale("en") ? exerciseBloc.exerciseRepository.exerciseType.name : exerciseBloc.exerciseRepository.exerciseType.nameTranslation; return Form( autovalidate: true, child: Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( backgroundColor: Colors.black, title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Add Exercise"), Image.asset( 'asset/image/WT_long_logo.png', fit: BoxFit.cover, height: 65.0, ), ], ), leading: IconButton( icon: Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.of(context).pop(), ), ), body: Container( width: MediaQuery .of(context) .size .width, height: MediaQuery .of(context) .size .height, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('asset/image/WT_light_background.png'), fit: BoxFit.fill, alignment: Alignment.center, ), ), child: Container( padding: const EdgeInsets.only (top: 25, left: 25, right: 25), child: SingleChildScrollView( scrollDirection: Axis.vertical, child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text(exerciseName, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.deepOrange), overflow: TextOverflow.fade, maxLines: 1, softWrap: true, ), Divider(color: Colors.transparent,), Divider(), Column( children: repeatExercises(exerciseBloc), ), Divider(), ]), ) ) ), ), ); } List repeatExercises(ExerciseAddByPlanFormBloc exerciseBloc) { List listColumns = List(); for ( int i = 0; i < exerciseBloc.countSteps; i++) { Column col = Column( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.start, children: [ Divider(color: Colors.transparent,), Text(t("Execute the") + " " + (i+1).toString() + t(". set!"), style: TextStyle(),), TextFieldBlocBuilder( readOnly: exerciseBloc.step != i+1, textFieldBloc: exerciseBloc.unitQuantity1Field, textAlign: TextAlign.center, style: TextStyle( fontSize: 18, color: Colors.black54, fontWeight: FontWeight.bold), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) ], decoration: InputDecoration( fillColor: Colors.white, filled: false, hintStyle: TextStyle( fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100), labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal), labelText: exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit, ), ), TextFieldBlocBuilder( readOnly: exerciseBloc.step != i+1, textFieldBloc: exerciseBloc.quantity1Field, textAlign: TextAlign.center, style: TextStyle( fontSize: 18, color: Colors.deepOrange, fontWeight: FontWeight.bold), inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r"[\d.]")) ], decoration: InputDecoration( fillColor: Colors.white, filled: false, hintStyle: TextStyle( fontSize: 14, color: Colors.black54, fontWeight: FontWeight.w100), hintText: t("The number of the exercise"), labelStyle: TextStyle(fontSize: 14, color: Colors.deepOrange, fontWeight: FontWeight.normal), labelText: t("Please repeat with") + " "+ exerciseBloc.unitQuantity1Field.value + " " + exerciseBloc.exerciseRepository.exerciseType.unitQuantityUnit + " " + exerciseBloc.exercisePlanRepository.getActualPlanDetail().repeats.toString() + " " + t("times!"), ), ), RaisedButton( padding: EdgeInsets.all(0), textColor: Colors.white, color: exerciseBloc.step == i+1 ? Colors.blue : Colors.black26, focusColor: Colors.blueAccent, onPressed: () => { print ("Submit step " + exerciseBloc.step.toString() + " (i) " + i.toString()), if ( exerciseBloc.step == i+1 ) { exerciseBloc.submit() }, if ( i+1 == exerciseBloc.countSteps) { Navigator.of(context).pop() } }, child: Text( t("Check"), style: TextStyle(fontSize: 12),) ), Divider(color: Colors.transparent,), ], ); listColumns.add(col); } return listColumns; } String validateNumberInput(input) { String error = t("Please type the right quantity 0-10000"); dynamic rc = (input != null && input.length > 0); if (!rc) { return null; } Pattern pattern = r'^\d+(?:\.\d+)?$'; RegExp regex = new RegExp(pattern); if (!regex.hasMatch(input)) { return error; } rc = double.tryParse(input); if (rc == null) { return error; } if (!(double.parse(input) < 10000 && double.parse(input) > 0)) { return error; } return null; } }