306 lines
15 KiB
Dart
306 lines
15 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:drift/drift.dart' hide Column;
|
|
import 'package:flutter/material.dart' hide Action;
|
|
import 'package:provider/provider.dart';
|
|
import 'package:sendtrain/daos/actions_dao.dart';
|
|
import 'package:sendtrain/daos/activity_actions_dao.dart';
|
|
import 'package:sendtrain/database/database.dart';
|
|
import 'package:sendtrain/helpers/widget_helpers.dart';
|
|
import 'package:sendtrain/widgets/generic/elements/form_drop_down.dart';
|
|
import 'package:sendtrain/widgets/generic/elements/form_text_input.dart';
|
|
|
|
class ActivityActionEditor extends StatefulWidget {
|
|
const ActivityActionEditor(
|
|
{super.key,
|
|
required this.session,
|
|
required this.activity,
|
|
this.action,
|
|
this.callback});
|
|
|
|
final Session session;
|
|
final Activity activity;
|
|
final Action? action;
|
|
final Function? callback;
|
|
|
|
@override
|
|
State<ActivityActionEditor> createState() => _ActivityActionEditorState();
|
|
}
|
|
|
|
class _ActivityActionEditorState extends State<ActivityActionEditor> {
|
|
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
|
|
|
final Map<String, TextEditingController> actionEditController = {
|
|
'sets': TextEditingController(),
|
|
'reps': TextEditingController(),
|
|
'weight': TextEditingController(),
|
|
'repLength': TextEditingController(),
|
|
'preparation': TextEditingController(),
|
|
'setRest': TextEditingController(),
|
|
'repRest': TextEditingController(),
|
|
'cooldown': TextEditingController(),
|
|
'type': TextEditingController(),
|
|
'alternating': TextEditingController(),
|
|
};
|
|
|
|
late final AppDatabase db;
|
|
|
|
bool isAlternating = false;
|
|
bool isTimed = false;
|
|
String editorType = 'Create';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
db = Provider.of<AppDatabase>(context, listen: false);
|
|
|
|
// if we're editing a session, we'll want to populate it with the appropriate values
|
|
if (widget.action != null) {
|
|
final Action action = widget.action!;
|
|
editorType = 'Edit';
|
|
isAlternating = action.isAlternating;
|
|
isTimed = action.repType == RepType.time ? true : false;
|
|
|
|
actionEditController['sets']?.text = action.totalSets.toString();
|
|
actionEditController['reps']?.text =
|
|
json.decode(action.totalReps)[0].toString();
|
|
actionEditController['weight']?.text =
|
|
json.decode(action.repWeights ?? "")[0].toString();
|
|
actionEditController['repLength']?.text =
|
|
((action.repLength ?? 0) ~/ 1000).toString();
|
|
actionEditController['preparation']?.text =
|
|
((action.restBeforeSets ?? 0) ~/ 1000).toString();
|
|
actionEditController['setRest']?.text =
|
|
((action.restBetweenSets ?? 0) ~/ 1000).toString();
|
|
actionEditController['repRest']?.text =
|
|
((action.restBetweenReps ?? 0) ~/ 1000).toString();
|
|
actionEditController['cooldown']?.text =
|
|
((action.restAfterSets ?? 0) ~/ 1000).toString();
|
|
actionEditController['isTimed']?.text = isTimed.toString();
|
|
actionEditController['alternating']?.text = isAlternating.toString();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (widget.action != null) {
|
|
editorType = 'Edit';
|
|
}
|
|
|
|
return Padding(
|
|
padding: EdgeInsets.fromLTRB(15, 0, 15, 15),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 10, bottom: 10),
|
|
child: Text('$editorType Action',
|
|
textAlign: TextAlign.center,
|
|
style: Theme.of(context).textTheme.titleLarge)),
|
|
Row(children: [
|
|
formItemWrapper(
|
|
CheckboxListTile(
|
|
title: Text("Reps alternate? (eg. Left/Right Hand)"),
|
|
value: isAlternating,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius:
|
|
BorderRadius.all(Radius.circular(10.0)),
|
|
),
|
|
onChanged: (bool? value) {
|
|
setState(() {
|
|
isAlternating = value!;
|
|
});
|
|
},
|
|
),
|
|
EdgeInsets.fromLTRB(10, 10, 10, 10)),
|
|
]),
|
|
Row(children: [
|
|
formItemWrapper(
|
|
CheckboxListTile(
|
|
title: Text("Are reps timed?"),
|
|
value: isTimed,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius:
|
|
BorderRadius.all(Radius.circular(10.0)),
|
|
),
|
|
onChanged: (bool? value) {
|
|
setState(() {
|
|
isTimed = value!;
|
|
});
|
|
},
|
|
),
|
|
EdgeInsets.fromLTRB(10, 10, 10, 15))
|
|
]),
|
|
Row(children: [
|
|
FormDropDown(
|
|
title: 'Sets',
|
|
entries: numericDropDownItems('Set', 50),
|
|
controller: actionEditController['sets']!),
|
|
FormDropDown(
|
|
title: 'Reps',
|
|
entries: numericDropDownItems('Rep', 100),
|
|
controller: actionEditController['reps']!,
|
|
)
|
|
]),
|
|
Row(children: [
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['preparation']!,
|
|
title: 'Preparation (sec)',
|
|
hint: 'time before start',
|
|
requiresValidation: false),
|
|
EdgeInsets.fromLTRB(10, 5, 10, 0)),
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['cooldown']!,
|
|
title: 'Cooldown (sec)',
|
|
hint: 'rest after completion',
|
|
requiresValidation: false),
|
|
EdgeInsets.fromLTRB(10, 5, 10, 0)),
|
|
]),
|
|
Row(children: [
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['setRest']!,
|
|
title: 'Set Rest (sec)',
|
|
hint: 'Rest between sets',
|
|
requiresValidation: false),
|
|
EdgeInsets.only(left: 10, right: 10)),
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['repRest']!,
|
|
title: 'Rep Rest (sec)',
|
|
hint: 'Rest between reps',
|
|
requiresValidation: false),
|
|
EdgeInsets.only(left: 10, right: 10)),
|
|
]),
|
|
Row(children: [
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['repLength']!,
|
|
title: 'Rep Length (sec)',
|
|
hint: 'Total rep time (not required)',
|
|
requiresValidation: false),
|
|
EdgeInsets.only(left: 10, right: 10)),
|
|
formItemWrapper(
|
|
FormTextInput(
|
|
type: InputTypes.number,
|
|
controller: actionEditController['weight']!,
|
|
title: 'Weight',
|
|
hint: 'Weight for reps',
|
|
requiresValidation: false),
|
|
EdgeInsets.only(left: 10, right: 10)),
|
|
]),
|
|
Row(mainAxisAlignment: MainAxisAlignment.end, children: [
|
|
Padding(
|
|
padding: EdgeInsets.only(top: 10, right: 10),
|
|
child: FilledButton(
|
|
onPressed: () async {
|
|
if (_formKey.currentState!.validate()) {
|
|
if (widget.action != null) {
|
|
Action newAction = widget.action!.copyWith(
|
|
totalSets: int.parse(
|
|
actionEditController['sets']!.text),
|
|
totalReps: json.encode([
|
|
int.parse(
|
|
actionEditController['reps']!.text)
|
|
]),
|
|
repLength: Value<int>(int.parse(
|
|
actionEditController['repLength']!
|
|
.text) *
|
|
1000),
|
|
restBeforeSets: Value<int>(int.parse(
|
|
actionEditController['preparation']!
|
|
.text) *
|
|
1000),
|
|
restBetweenSets: Value<int>(int.parse(
|
|
actionEditController['setRest']!
|
|
.text) *
|
|
1000),
|
|
restBetweenReps: Value<int>(int.parse(
|
|
actionEditController['repRest']!
|
|
.text) *
|
|
1000),
|
|
restAfterSets: Value<int>(int.parse(
|
|
actionEditController['cooldown']!
|
|
.text) *
|
|
1000),
|
|
repType: int.parse(actionEditController[
|
|
'repLength']!
|
|
.text) >
|
|
0
|
|
? RepType.time
|
|
: RepType.count,
|
|
repWeights: Value<String>(json.encode([
|
|
int.parse(
|
|
actionEditController['weight']!.text)
|
|
])),
|
|
// setWeights: Value<String>(json.encode([actionEditController['setWeights']!.text])),
|
|
isAlternating: isAlternating,
|
|
);
|
|
|
|
// var result = await ActionsDao(db).createOrUpdate(
|
|
// newAction.toCompanion(true));
|
|
await ActionsDao(db).replace(newAction);
|
|
} else {
|
|
// create action
|
|
await ActionsDao(db)
|
|
.createOrUpdate(ActionsCompanion(
|
|
title: Value('rep'),
|
|
description: Value('exercise action'),
|
|
totalSets: Value(int.parse(
|
|
actionEditController['sets']!
|
|
.text)),
|
|
totalReps: Value(json.encode(
|
|
[int.parse(actionEditController['reps']!.text)])),
|
|
repLength: Value<int>(
|
|
int.parse(actionEditController['repLength']!.text) *
|
|
1000),
|
|
restBeforeSets: Value<int>(
|
|
int.parse(actionEditController['preparation']!.text) *
|
|
1000),
|
|
restBetweenSets: Value<int>(
|
|
int.parse(actionEditController['setRest']!.text) *
|
|
1000),
|
|
restBetweenReps:
|
|
Value<int>(int.parse(actionEditController['repRest']!.text) * 1000),
|
|
restAfterSets: Value<int>(int.parse(actionEditController['cooldown']!.text) * 1000),
|
|
repType: Value(int.parse(actionEditController['repLength']!.text) > 0 ? RepType.time : RepType.count),
|
|
repWeights: Value<String>(json.encode([int.parse(actionEditController['weight']!.text)])),
|
|
// setWeights: Value<String>(json.encode([actionEditController['setWeights']!.text])),
|
|
isAlternating: Value<bool>(isAlternating),
|
|
// repType: RepType.values.firstWhere((e) => e.toString() == "RepType.${actionEditController['repType']!.text}"),
|
|
set: Value("")))
|
|
.then((actionId) {
|
|
ActivityActionsDao(db).createOrUpdate(
|
|
ActivityActionsCompanion(
|
|
activityId:
|
|
Value(widget.activity.id),
|
|
sessionId: Value(widget.session.id),
|
|
actionId: Value(actionId),
|
|
position: Value(0)));
|
|
});
|
|
}
|
|
|
|
Navigator.pop(
|
|
_formKey.currentContext!, 'Submit');
|
|
|
|
if (widget.callback != null) {
|
|
await widget.callback!();
|
|
}
|
|
}
|
|
},
|
|
child: Text('Submit')))
|
|
])
|
|
])));
|
|
}
|
|
}
|