setting up timer and action management
This commit is contained in:
parent
9ffa0d178c
commit
29479e8aba
@ -1,7 +1,9 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sendtrain/models/activity_model.dart';
|
||||
import 'package:sendtrain/widgets/activity_action_view.dart';
|
||||
|
||||
class ActivityTimerModel with ChangeNotifier {
|
||||
late int _activityId;
|
||||
@ -12,49 +14,135 @@ class ActivityTimerModel with ChangeNotifier {
|
||||
late int _totalReps;
|
||||
late String _currentState;
|
||||
late Timer? _periodicTimer;
|
||||
late ActivityModel _activity;
|
||||
|
||||
// int _viewCount = 0;
|
||||
bool _active = false;
|
||||
int _currentAction = 0;
|
||||
|
||||
int get tickCount => _tickCount;
|
||||
int get currentSet => _currentSet;
|
||||
int get currentRep => _currentRep;
|
||||
int get currentAction => _currentAction;
|
||||
int get totalSets => _totalSets;
|
||||
int get totalReps => _totalReps;
|
||||
bool get active => _active;
|
||||
|
||||
void setAction(int actionNum, int setNum, String state) {
|
||||
_currentAction = actionNum;
|
||||
_currentSet = setNum;
|
||||
_currentState = state;
|
||||
stopTimer();
|
||||
|
||||
if (_currentState == "rest") {
|
||||
startTimer();
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void incrementAction() {
|
||||
_currentAction++;
|
||||
|
||||
if (_currentState == "rest") {
|
||||
_currentState = "rep";
|
||||
_currentSet++;
|
||||
stopTimer();
|
||||
} else {
|
||||
_currentState = "rest";
|
||||
startTimer();
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setupTimer(ActivityModel activity) {
|
||||
_activity = activity;
|
||||
_activityId = activity.id;
|
||||
_currentSet = 0;
|
||||
_currentRep = 0;
|
||||
_totalSets = activity.actions[0].activityActionSet.total;
|
||||
_totalReps = activity.actions[0].activityActionSet.reps.amounts[0];
|
||||
_tickCount = activity.actions[0].activityActionSet.rest ~/ 10000;
|
||||
_currentState = "rep";
|
||||
// ActivityActionView av = actionViews[_viewCount];
|
||||
// av.
|
||||
}
|
||||
|
||||
void startTimer(ActivityModel activity) {
|
||||
_active = true;
|
||||
_periodicTimer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
|
||||
if (_tickCount == 0) {
|
||||
if (_currentRep + 1 ==
|
||||
activity.actions[0].activityActionSet.reps.amounts[_currentSet]) {
|
||||
_currentSet++;
|
||||
if (_currentSet == activity.actions[0].activityActionSet.total) {
|
||||
timer.cancel();
|
||||
_active = false;
|
||||
setupTimer(activity);
|
||||
}
|
||||
_currentRep = 0;
|
||||
_totalReps =
|
||||
activity.actions[0].activityActionSet.reps.amounts[_currentSet];
|
||||
_tickCount = activity.actions[0].activityActionSet.rest ~/ 10000;
|
||||
void pauseTimer() {
|
||||
_active = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void stopTimer() {
|
||||
_active = false;
|
||||
_periodicTimer?.cancel();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void startTimer() {
|
||||
if (_currentState == 'rep') {
|
||||
// do nothing for now
|
||||
} else {
|
||||
|
||||
_active = true;
|
||||
_tickCount = _activity.actions[0].activityActionSet.rest ~/ 10000;
|
||||
|
||||
_periodicTimer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
|
||||
if (_tickCount == 0) {
|
||||
incrementAction();
|
||||
|
||||
|
||||
// if (_currentRep + 1 ==
|
||||
// _activity.actions[0].activityActionSet.reps.amounts[_currentSet]) {
|
||||
// _currentSet++;
|
||||
// if (_currentSet == _activity.actions[0].activityActionSet.total) {
|
||||
// timer.cancel();
|
||||
// _active = false;
|
||||
// setupTimer(_activity);
|
||||
// }
|
||||
// _currentRep = 0;
|
||||
// _totalReps =
|
||||
// _activity.actions[0].activityActionSet.reps.amounts[_currentSet];
|
||||
// _tickCount = _activity.actions[0].activityActionSet.rest ~/ 10000;
|
||||
// } else {
|
||||
// _currentRep++;
|
||||
// }
|
||||
} else {
|
||||
_currentRep++;
|
||||
if (_active) {
|
||||
_tickCount--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_tickCount--;
|
||||
}
|
||||
|
||||
notifyListeners();
|
||||
});
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// void startTimer(ActivityModel activity) {
|
||||
// _active = true;
|
||||
// _periodicTimer = Timer.periodic(const Duration(seconds: 1), (Timer timer) {
|
||||
// if (_tickCount == 0) {
|
||||
// if (_currentRep + 1 ==
|
||||
// activity.actions[0].activityActionSet.reps.amounts[_currentSet]) {
|
||||
// _currentSet++;
|
||||
// if (_currentSet == activity.actions[0].activityActionSet.total) {
|
||||
// timer.cancel();
|
||||
// _active = false;
|
||||
// setupTimer(activity);
|
||||
// }
|
||||
// _currentRep = 0;
|
||||
// _totalReps =
|
||||
// activity.actions[0].activityActionSet.reps.amounts[_currentSet];
|
||||
// _tickCount = activity.actions[0].activityActionSet.rest ~/ 10000;
|
||||
// } else {
|
||||
// _currentRep++;
|
||||
// }
|
||||
// } else {
|
||||
// _tickCount--;
|
||||
// }
|
||||
|
||||
// notifyListeners();
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
@ -1,21 +1,47 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/classes/activity_action.dart';
|
||||
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||
import 'package:sendtrain/widgets/action_card.dart';
|
||||
|
||||
class ActivityActionView extends StatefulWidget {
|
||||
ActivityActionView({super.key, required this.action});
|
||||
|
||||
ActivityAction action;
|
||||
// ActivityTimerModel activityTimerModel;
|
||||
// get incrementActivity => ActivityActionViewState().incrementActivity();
|
||||
|
||||
@override
|
||||
State<ActivityActionView> createState() => _ActivityActionViewState();
|
||||
State<ActivityActionView> createState() => ActivityActionViewState();
|
||||
// void incrementActivity() => _ActivityActionViewState().incrementActivity();
|
||||
}
|
||||
|
||||
class _ActivityActionViewState extends State<ActivityActionView> {
|
||||
class ActivityActionViewState extends State<ActivityActionView> {
|
||||
int _index = 0;
|
||||
int _currentAction = 0;
|
||||
// int _actionCount = 0;
|
||||
// int _currentState = "Active"
|
||||
|
||||
// void incrementActivity(int actionNum) {
|
||||
// setState(() {
|
||||
// atm.setAction(actionNum);
|
||||
// });
|
||||
// }
|
||||
|
||||
// void setActivity(int currentAction) {
|
||||
// setState(() {
|
||||
// widget.atm.setAction(currentAction);
|
||||
// });
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
int actionCount = 0;
|
||||
ActivityTimerModel atm = Provider.of<ActivityTimerModel>(context, listen: true);
|
||||
|
||||
return Expanded(
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||
@ -23,34 +49,61 @@ class _ActivityActionViewState extends State<ActivityActionView> {
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
String title = widget.action.title;
|
||||
Set actionSet = widget.action.activityActionSet;
|
||||
Reps setReps = widget.action.activityActionSet.reps;
|
||||
Reps setReps = actionSet.reps;
|
||||
int setRest = actionSet.rest ~/ 1000;
|
||||
List<Card> contents = [];
|
||||
int currentAction = actionCount;
|
||||
|
||||
// contents.add(Card(child: Text('Set ${index + 1}')));
|
||||
contents.add(Card(
|
||||
elevation: 0.5,
|
||||
// surfaceTintColor: actionCount == _index ? Colors.white : ,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
log('we tappn');
|
||||
setState(() {
|
||||
atm.setAction(currentAction, index, "rep");
|
||||
});
|
||||
},
|
||||
child: Row(children: [
|
||||
Consumer<ActivityTimerModel>(builder: (context, atm, child) {
|
||||
return Ink(
|
||||
padding: const EdgeInsets.all(15),
|
||||
color: currentAction == atm.currentAction
|
||||
? const Color.fromARGB(255, 49, 154, 52)
|
||||
: const Color(0xff3A5FB6),
|
||||
child: Text('Set: ${index + 1} '));
|
||||
}),
|
||||
Expanded(
|
||||
child: Text(
|
||||
textAlign: TextAlign.center,
|
||||
'$title: ${setReps.amounts[index]} reps'))
|
||||
]))));
|
||||
actionCount++;
|
||||
|
||||
for (int repCount = 0; repCount < setReps.amounts[index]; repCount++) {
|
||||
contents.add(Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(15, 15, 15, 15),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(children: [Text('Exercise: ${widget.action.title}')]),
|
||||
Row(children: [Text('Type: ${actionSet.type}')]),
|
||||
Row(children: [
|
||||
Text(
|
||||
'Set: ${index + 1} / ${widget.action.activityActionSet.total}')
|
||||
]),
|
||||
Row(children: [
|
||||
Text('Rep: ${repCount + 1} / ${setReps.amounts[index]}')
|
||||
]),
|
||||
Row(children: [Text('Tempo: ${setReps.tempo[index]}')]),
|
||||
Row(children: [
|
||||
Text('Weight: ${setReps.weights[index]}')
|
||||
]),
|
||||
Row(children: [Text('Rest: ${setReps.rest}')])
|
||||
],
|
||||
))));
|
||||
}
|
||||
contents.add(Card(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
atm.setAction(currentAction + 1, index, "rest");
|
||||
});
|
||||
},
|
||||
child: Row(children: [
|
||||
Consumer<ActivityTimerModel>(builder: (context, atm, child) {
|
||||
return Ink(
|
||||
padding: const EdgeInsets.all(15),
|
||||
color: currentAction + 1 == atm.currentAction
|
||||
? const Color.fromARGB(255, 49, 154, 52)
|
||||
: const Color(0xff3A5FB6),
|
||||
child: Text('Set: ${index + 1} '));
|
||||
}),
|
||||
Expanded(
|
||||
child: Text(
|
||||
textAlign: TextAlign.center,
|
||||
'Rest: $setRest seconds'))
|
||||
]))));
|
||||
actionCount++;
|
||||
|
||||
return Column(children: contents);
|
||||
},
|
||||
|
@ -9,7 +9,6 @@ import 'package:sendtrain/widgets/media_card.dart';
|
||||
|
||||
class ActivityView extends StatefulWidget {
|
||||
ActivityView({super.key, required this.activity});
|
||||
|
||||
ActivityModel activity;
|
||||
|
||||
@override
|
||||
@ -20,14 +19,16 @@ class _ActivityViewState extends State<ActivityView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ActivityModel activity = widget.activity;
|
||||
|
||||
ActivityTimerModel atm = Provider.of<ActivityTimerModel>(context, listen: false);
|
||||
ActivityTimerModel atm =
|
||||
Provider.of<ActivityTimerModel>(context, listen: false);
|
||||
// ActivityActionView activityActionView =
|
||||
// ActivityActionView(action: activity.actions[0]);
|
||||
|
||||
if (atm.active == false) {
|
||||
atm.setupTimer(activity);
|
||||
}
|
||||
|
||||
var content = [
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
AppBar(
|
||||
// surfaceTintColor: ThemeData.dark(useMaterial3: true).colorScheme.primary,
|
||||
// backgroundColor: ThemeData.dark(useMaterial3: true).colorScheme.primaryContainer,
|
||||
@ -55,55 +56,52 @@ class _ActivityViewState extends State<ActivityView> {
|
||||
child: Text(
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
'Actions:'))
|
||||
];
|
||||
|
||||
for (var action in activity.actions) {
|
||||
content.add(ActivityActionView(action: action));
|
||||
}
|
||||
|
||||
// add bottom bar to manage activity
|
||||
content.add(Container(
|
||||
height: MediaQuery.sizeOf(context).height * .07,
|
||||
color: ThemeData.dark(useMaterial3: true).colorScheme.primaryContainer,
|
||||
child: Row(children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Flex(direction: Axis.horizontal, children: [
|
||||
IconButton(
|
||||
iconSize: 30,
|
||||
icon: const Icon(Icons.play_arrow_rounded),
|
||||
onPressed: () =>
|
||||
atm.startTimer(activity)),
|
||||
IconButton(
|
||||
iconSize: 36,
|
||||
icon: const Icon(Icons.skip_next_rounded),
|
||||
onPressed: () {})
|
||||
])),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
return Text(
|
||||
style: const TextStyle(fontSize: 25),
|
||||
textAlign: TextAlign.center,
|
||||
'${atm.tickCount}');
|
||||
},
|
||||
)),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
'Actions:')),
|
||||
ActivityActionView(action: activity.actions[0]),
|
||||
Container(
|
||||
height: MediaQuery.sizeOf(context).height * .07,
|
||||
color:
|
||||
ThemeData.dark(useMaterial3: true).colorScheme.primaryContainer,
|
||||
child: Row(children: [
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Flex(direction: Axis.horizontal, children: [
|
||||
IconButton(
|
||||
iconSize: 30,
|
||||
icon: const Icon(Icons.play_arrow_rounded),
|
||||
onPressed: () => {
|
||||
atm.startTimer()
|
||||
}),
|
||||
IconButton(
|
||||
iconSize: 36,
|
||||
icon: const Icon(Icons.skip_next_rounded),
|
||||
onPressed: () {
|
||||
atm.incrementAction();
|
||||
})
|
||||
])),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
return Text(
|
||||
style: const TextStyle(fontSize: 15),
|
||||
textAlign: TextAlign.right,
|
||||
'Set: ${atm.currentSet + 1}/${atm.totalSets}\nRep: ${atm.currentRep + 1}/${atm.totalReps}');
|
||||
}))),
|
||||
])));
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start, children: content);
|
||||
style: const TextStyle(fontSize: 25),
|
||||
textAlign: TextAlign.center,
|
||||
'${atm.tickCount}');
|
||||
},
|
||||
)),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 10),
|
||||
child: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
return Text(
|
||||
style: const TextStyle(fontSize: 15),
|
||||
textAlign: TextAlign.right,
|
||||
'Set: ${atm.currentSet + 1}/${atm.totalSets}\nRep: ${atm.currentRep + 1}/${atm.totalReps}');
|
||||
}))),
|
||||
]))
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ class SessionCard extends StatelessWidget {
|
||||
actions: [
|
||||
ActivityAction(
|
||||
id: 1,
|
||||
title: 'test action',
|
||||
description: 'test description',
|
||||
title: '1, 3, 5',
|
||||
description: 'Move between the first, third, and fifth rungs, alternating hands. Rest and alternate sides, to start',
|
||||
media: [
|
||||
Media(
|
||||
id: 1,
|
||||
@ -76,8 +76,8 @@ class SessionCard extends StatelessWidget {
|
||||
actions: [
|
||||
ActivityAction(
|
||||
id: 1,
|
||||
title: 'test action',
|
||||
description: 'test description',
|
||||
title: 'Attempt Climb',
|
||||
description: 'Attempt your selected climb, if you fall off early in the climb, attempt again. 1 repitition equals roughly doing all the moves, not necessarily in 1 attempt.',
|
||||
media: [
|
||||
Media(
|
||||
id: 1,
|
||||
@ -92,15 +92,15 @@ class SessionCard extends StatelessWidget {
|
||||
description: 'How to project climbs')
|
||||
],
|
||||
activityActionSet: Set(
|
||||
type: 'drop_set',
|
||||
total: 3,
|
||||
type: 'standard',
|
||||
total: 10,
|
||||
rest: 300000,
|
||||
reps: Reps(
|
||||
type: 'count',
|
||||
tempo: [2, 3, 5],
|
||||
amounts: [5, 3, 2],
|
||||
weights: [50, 70, 80],
|
||||
rest: 20000))),
|
||||
tempo: [],
|
||||
amounts: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
weights: [],
|
||||
rest: 0))),
|
||||
],
|
||||
resources: ['https://www.youtube.com/watch?v=dyAvbUvY_PU']),
|
||||
ActivityModel(
|
||||
@ -113,8 +113,8 @@ class SessionCard extends StatelessWidget {
|
||||
actions: [
|
||||
ActivityAction(
|
||||
id: 1,
|
||||
title: 'test action',
|
||||
description: 'test description',
|
||||
title: 'Pull Ups',
|
||||
description: 'Select your desired weight to add, and pull up. Be sure to fully drop into extension at start, and make sure chin is above bar for a complete rep. Do not kip during the movement.',
|
||||
media: [
|
||||
Media(
|
||||
id: 1,
|
||||
@ -130,14 +130,14 @@ class SessionCard extends StatelessWidget {
|
||||
],
|
||||
activityActionSet: Set(
|
||||
type: 'drop_set',
|
||||
total: 3,
|
||||
total: 5,
|
||||
rest: 300000,
|
||||
reps: Reps(
|
||||
type: 'count',
|
||||
tempo: [2, 3, 5],
|
||||
amounts: [5, 3, 2],
|
||||
weights: [50, 70, 80],
|
||||
rest: 20000))),
|
||||
tempo: [],
|
||||
amounts: [3, 5, 5, 3, 6],
|
||||
weights: [80, 80, 80, 80, 80],
|
||||
rest: 0))),
|
||||
],
|
||||
resources: ['https://www.youtube.com/watch?v=dyAvbUvY_PU']),
|
||||
],
|
||||
|
Loading…
x
Reference in New Issue
Block a user