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