Untitled
unknown
plain_text
2 years ago
19 kB
4
Indexable
import 'package:client/enums.dart'; import 'package:client/services/training_services.dart'; import 'package:client/states/user_state.dart'; import 'package:client/utils/other_utils.dart'; import 'package:client/widgets/commons.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import '../../../../models/training_model.dart'; import '../../../../styles.dart'; class ExerciseSetTile extends StatefulWidget { final String number; final bool? withDivider; final BlockExerciseSetsModel exerciseSetsModel; final BlockType? blocktype; const ExerciseSetTile({ required this.number, this.withDivider, this.blocktype = BlockType.strenght, required this.exerciseSetsModel, Key? key, }) : super(key: key); @override State<ExerciseSetTile> createState() => _ExerciseSetTileState(); } //TODO re order by set //finds next editable text focus to focus on it extension Utility on BuildContext { void nextEditableTextFocus() { do { FocusScope.of(this).nextFocus(); } while (FocusScope.of(this).focusedChild!.context == null); } } class _ExerciseSetTileState extends State<ExerciseSetTile> { @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Column( children: [ Row( children: [ RowSpace(), //**numbering Container( height: 30, width: 30, decoration: BoxDecoration( color: mainColor, borderRadius: const BorderRadius.all(Radius.circular(5)), ), child: Center( child: Text( widget.number, style: textStyleCustom( color: Colors.white, fontSize: defaultFontSizeMinus), ), ), ), RowSpace( width: 10, ), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ //weight / sec /mins / meters / cals */ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExerciseEditableField( set: widget.exerciseSetsModel.repType == RepTypes.reps ? ExerciseSetFields.weight : widget.exerciseSetsModel.repType == RepTypes.secs ? ExerciseSetFields.time : widget.exerciseSetsModel.repType == RepTypes.mins ? ExerciseSetFields.time : widget.exerciseSetsModel.repType == RepTypes.meters ? ExerciseSetFields.distance : widget.exerciseSetsModel.repType == RepTypes.cals ? ExerciseSetFields.cals : ExerciseSetFields .weight, //todo here change on what field is it id: widget.exerciseSetsModel.id, val: widget.exerciseSetsModel.repType == RepTypes.reps ? widget.exerciseSetsModel.weight : widget.exerciseSetsModel.repType == RepTypes.secs ? widget.exerciseSetsModel.time : widget.exerciseSetsModel.repType == RepTypes.mins ? widget.exerciseSetsModel.time : widget.exerciseSetsModel.repType == RepTypes.meters ? widget.exerciseSetsModel.distance : widget.exerciseSetsModel.repType == RepTypes.cals ? widget.exerciseSetsModel.cals : widget .exerciseSetsModel.weight), RowSpace( width: 5, ), Text( widget.exerciseSetsModel.unit != "" ? widget.exerciseSetsModel.unit : widget.exerciseSetsModel.repType == RepTypes.cals ? "cals" : "", style: textStyleCustom( fontSize: defaultFontSizeMinus - 2, fontWeight: FontWeight.bold), ), ], ), //**Reps, Rounds, Total Reps, Total Cals */ // Strength & EMOM: repType==reps // AMRAP: make reps as Total Reps, Cals - Total Cals // RFT: Rounds if (((widget.blocktype == BlockType.strenght || widget.blocktype == BlockType.emom) && widget.exerciseSetsModel.repType == RepTypes.reps) || (widget.blocktype == BlockType.amrap || widget.blocktype == BlockType.rft) && (((widget.blocktype == BlockType.strenght || widget.blocktype == BlockType.emom) && widget.exerciseSetsModel.repType == RepTypes.meters) == false)) Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExerciseEditableField( set: widget.blocktype == BlockType.rft ? ExerciseSetFields.rounds : ExerciseSetFields.reps, id: widget.exerciseSetsModel.id, //for RFT get rounds for Streight get Reps val: widget.blocktype == BlockType.rft ? widget.exerciseSetsModel.rounds : widget.blocktype == BlockType.strenght ? widget.exerciseSetsModel.reps : widget.exerciseSetsModel.repType == RepTypes.reps ? widget.exerciseSetsModel.reps : widget.exerciseSetsModel.reps, ), RowSpace( width: 5, ), Text( widget.blocktype == BlockType.rft ? "rounds" : widget.blocktype == BlockType.amrap ? widget.exerciseSetsModel.repType == RepTypes.cals ? "Total Cals" : "Total Reps" : "reps", style: textStyleCustom( fontSize: defaultFontSizeMinus - 2, fontWeight: FontWeight.bold), ), ], ), //** TIME field */ // only for Strength and EMOM with repytpe of meters if ((widget.blocktype == BlockType.strenght || widget.blocktype == BlockType.emom) && widget.exerciseSetsModel.repType == RepTypes.meters) Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExerciseEditableField( set: ExerciseSetFields.time, id: widget.exerciseSetsModel.id, val: widget.exerciseSetsModel.time, ), RowSpace( width: 5, ), Text( "sec", style: textStyleCustom( fontSize: defaultFontSizeMinus - 2, fontWeight: FontWeight.bold), ), ], ), //**RPE/ //** all Strength and EMOM */ if (widget.blocktype == BlockType.strenght || widget.blocktype == BlockType.emom) Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ExerciseEditableField( set: ExerciseSetFields.rpe, id: widget.exerciseSetsModel.id, val: widget.exerciseSetsModel.rpe, ), RowSpace( width: 5, ), Text( "RPE", style: textStyleCustom( fontSize: defaultFontSizeMinus - 2, fontWeight: FontWeight.bold), ), ], ), //**Spacer if ((widget.blocktype == BlockType.rft || widget.blocktype == BlockType.amrap) || ((widget.blocktype == BlockType.strenght || widget.blocktype == BlockType.emom)) && (widget.exerciseSetsModel.repType == RepTypes.cals || widget.exerciseSetsModel.repType == RepTypes.mins || widget.exerciseSetsModel.repType == RepTypes.secs)) Row( children: [ Container( width: 40, ), RowSpace( width: 5, ), RowSpace( width: 20, ) ], ) ], ), ), ], ), widget.withDivider != null && widget.withDivider == true ? const Divider(thickness: 1) : Container() ], ); } } class ExerciseEditableField extends StatefulWidget { final String? val; final double? width; final int id; final ExerciseSetFields set; const ExerciseEditableField( {required this.set, required this.id, this.width, this.val, super.key}); @override State<ExerciseEditableField> createState() => _ExerciseEditableFieldState(); } class _ExerciseEditableFieldState extends State<ExerciseEditableField> { final FocusNode _focusNode = FocusNode(); TextEditingController controller = TextEditingController(); bool selected = false; @override void initState() { controller.text = widget.val ?? ""; controller.addListener(() { if (_focusNode.hasFocus && !selected) { final newText = controller.text; controller.value = controller.value.copyWith( text: newText, selection: TextSelection(baseOffset: 0, extentOffset: newText.length), ); } }); super.initState(); } @override Widget build(BuildContext context) { void save() { if (widget.set == ExerciseSetFields.weight) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: convert2Double(controller.text), reps: 0, rpe: 0, cals: 0, distance: 0, rounds: 0, time: 0); } if (widget.set == ExerciseSetFields.reps) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: convert2Int(controller.text), rpe: 0, cals: 0, distance: 0, rounds: 0, time: 0); } if (widget.set == ExerciseSetFields.rpe) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: 0, cals: 0, distance: 0, rounds: 0, time: 0, rpe: convert2Int(controller.text)); } if (widget.set == ExerciseSetFields.cals) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: 0, cals: convert2Double(controller.text), distance: 0, rounds: 0, time: 0, rpe: 0); } if (widget.set == ExerciseSetFields.distance) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: 0, cals: 0, distance: convert2Double(controller.text), rounds: 0, time: 0, rpe: 0); } if (widget.set == ExerciseSetFields.rounds) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: 0, cals: 0, distance: 0, rounds: convert2Int(controller.text), time: 0, rpe: 0); } if (widget.set == ExerciseSetFields.time) { TrainingServices().saveExerciseSet( accessToken: Provider.of<UserState>(context, listen: false).accessToken, setId: widget.id, set: widget.set, weight: 0, reps: 0, cals: 0, distance: 0, rounds: 0, time: convert2Int(controller.text), rpe: 0); } } return SizedBox( width: widget.width ?? 60, child: Center( child: Focus( focusNode: _focusNode, onKey: (node, event) { //trigger selected so it wont be selected again selected = true; return KeyEventResult.ignored; }, onFocusChange: (value) {}, child: CupertinoTextField( onChanged: (value) { selected = true; controller.selection = TextSelection( baseOffset: controller.text.length, extentOffset: controller.text.length); }, textInputAction: TextInputAction.done, controller: controller, onTap: () { controller.selection = TextSelection( baseOffset: 0, extentOffset: controller.text.length); }, onSubmitted: (value) { save(); context.nextEditableTextFocus(); }, onEditingComplete: () { save(); context.nextEditableTextFocus(); }, keyboardType: TextInputType.numberWithOptions(signed: true, decimal: false), textAlign: TextAlign.center, inputFormatters: [ RegExInputFormatter.withRegex( '^\$|^(0|([1-9][0-9]{0,}))(\\[0-9]{0,})?\$'), ], maxLines: 1, style: textStyleDefaultSmallerBold, // decoration: InputDecoration( // isCollapsed: true, // contentPadding: const EdgeInsets.all(8), // fillColor: trainingEditableFiledColor, // filled: true, // focusedBorder: const OutlineInputBorder( // borderSide: BorderSide(color: Colors.blueAccent, width: 1), // ), // border: OutlineInputBorder( // borderRadius: BorderRadius.circular(5), // borderSide: BorderSide.none, // ), // ), ), ), ), ); } } class RegExInputFormatter implements TextInputFormatter { final RegExp _regExp; RegExInputFormatter._(this._regExp); factory RegExInputFormatter.withRegex(String regexString) { try { final regex = RegExp(regexString); return RegExInputFormatter._(regex); } catch (e) { // Something not right with regex string. assert(false, e.toString()); final regex = RegExp(regexString); return RegExInputFormatter._(regex); } } @override TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue) { final oldValueValid = _isValid(oldValue.text); final newValueValid = _isValid(newValue.text); if (oldValueValid && !newValueValid) { return oldValue; } return newValue; } bool _isValid(String value) { try { final matches = _regExp.allMatches(value); for (Match match in matches) { if (match.start == 0 && match.end == value.length) { return true; } } return false; } catch (e) { // Invalid regex assert(false, e.toString()); return true; } } }
Editor is loading...