action display, and full display, started action editor
This commit is contained in:
259
lib/models/action_model.dart
Normal file
259
lib/models/action_model.dart
Normal file
@ -0,0 +1,259 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:sendtrain/daos/actions_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/helpers/date_time_helpers.dart';
|
||||
|
||||
class ActionModel {
|
||||
final ActionsDao dao;
|
||||
List<Item> items;
|
||||
Action action;
|
||||
|
||||
ActionModel({required this.action, required AppDatabase db})
|
||||
: dao = ActionsDao(db),
|
||||
items = _generateItems(action);
|
||||
|
||||
int get id => action.id;
|
||||
ActionStatus get status => action.status;
|
||||
Map get state => json.decode(action.state);
|
||||
List<Set> get sets => items.whereType<Set>().toList();
|
||||
List<Item> get allItems => _flattenedItems();
|
||||
int get totalTime {
|
||||
int time = 0;
|
||||
for (int i = 0; i < allItems.length; i++) {
|
||||
Item item = allItems[i];
|
||||
time += item.time ?? 0;
|
||||
}
|
||||
|
||||
return toSeconds(time);
|
||||
}
|
||||
|
||||
List<Item> _flattenedItems() {
|
||||
List<Item> items = [];
|
||||
|
||||
for (int i = 0; i < this.items.length; i++) {
|
||||
Item item = this.items[i];
|
||||
if (item.runtimeType == Set) {
|
||||
Set setItem = item as Set;
|
||||
for (int j = 0; j < setItem.items.length; j++) {
|
||||
items.add(setItem.items[j]);
|
||||
}
|
||||
} else {
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
static List<Item> _generateItems(Action action) {
|
||||
int totalItems = 0;
|
||||
int setItems = 0;
|
||||
List<Item> items = [];
|
||||
final List setReps = json.decode(action.totalReps);
|
||||
|
||||
if (action.restBeforeSets != null) {
|
||||
items.add(Rest(
|
||||
id: totalItems,
|
||||
position: totalItems,
|
||||
action: action,
|
||||
time: action.restBeforeSets!,
|
||||
name: 'prepare'));
|
||||
}
|
||||
|
||||
for (int i = 0; i < action.totalSets; i++) {
|
||||
final int totalReps;
|
||||
|
||||
if (setReps.length == 1) {
|
||||
totalReps = setReps.first;
|
||||
} else {
|
||||
totalReps = setReps[i];
|
||||
}
|
||||
|
||||
totalItems += 1;
|
||||
items.add(Set(
|
||||
id: totalItems,
|
||||
setOrder: setItems++,
|
||||
position: totalItems,
|
||||
action: action,
|
||||
totalReps: totalReps));
|
||||
|
||||
if (action.restBetweenSets != null && i < action.totalSets - 1) {
|
||||
totalItems += 1;
|
||||
items.add(Rest(
|
||||
id: totalItems,
|
||||
position: totalItems,
|
||||
action: action,
|
||||
time: action.restBetweenSets!,
|
||||
name: 'rest'));
|
||||
}
|
||||
}
|
||||
|
||||
if (action.restAfterSets != null && totalItems != items.length) {
|
||||
totalItems += 1;
|
||||
items.add(Rest(
|
||||
id: totalItems,
|
||||
position: totalItems,
|
||||
action: action,
|
||||
time: action.restAfterSets!,
|
||||
name: 'rest'));
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
Future<Action> updateStatus(ActionStatus status) async {
|
||||
Action newAction = action.copyWith(id: action.id, status: status);
|
||||
await dao.createOrUpdate(newAction.toCompanion(true));
|
||||
action = newAction;
|
||||
return newAction;
|
||||
}
|
||||
|
||||
Future<Action> updateState(String state) async {
|
||||
Action newAction = action.copyWith(id: action.id, state: state);
|
||||
await dao.createOrUpdate(newAction.toCompanion(true));
|
||||
action = newAction;
|
||||
return newAction;
|
||||
}
|
||||
}
|
||||
|
||||
class Item {
|
||||
final int id;
|
||||
final Action action;
|
||||
int position;
|
||||
List<Item> items = [];
|
||||
dynamic value;
|
||||
final String name;
|
||||
int? parentId;
|
||||
int? time;
|
||||
|
||||
Item(
|
||||
{required this.id,
|
||||
required this.position,
|
||||
required this.action,
|
||||
this.parentId,
|
||||
this.time})
|
||||
: name = action.title;
|
||||
|
||||
RepType get valueType => action.repType;
|
||||
String get humanValueType => valueType == RepType.time ? 'seconds' : 'reps';
|
||||
}
|
||||
|
||||
class Set extends Item {
|
||||
final int totalReps;
|
||||
int? setOrder;
|
||||
|
||||
Set(
|
||||
{required super.id,
|
||||
required super.action,
|
||||
required super.position,
|
||||
required this.totalReps,
|
||||
this.setOrder}) {
|
||||
items = _generateItems(action, id, totalReps);
|
||||
}
|
||||
|
||||
int? get weightMultiplyer =>
|
||||
action.setWeights != null ? json.decode(action.setWeights!)[id] : null;
|
||||
List<Reps> get reps => items.whereType<Reps>().toList();
|
||||
|
||||
static List<Item> _generateItems(action, id, totalReps) {
|
||||
List<Item> items = [];
|
||||
// add item for exercise
|
||||
int position = 0;
|
||||
|
||||
if (action.repType == RepType.time) {
|
||||
for (int i = 0; i < totalReps; i++) {
|
||||
position = position > 0 ? position + 1 : position;
|
||||
items.add(Reps(
|
||||
id: position, position: position, parentId: id, action: action));
|
||||
|
||||
if (action.isAlternating) {
|
||||
items.add(Rest(
|
||||
id: ++position,
|
||||
position: position,
|
||||
parentId: id,
|
||||
action: action,
|
||||
time: action.restBetweenReps,
|
||||
name: 'alternate'));
|
||||
items.add(Reps(
|
||||
id: ++position,
|
||||
position: position,
|
||||
parentId: id,
|
||||
action: action));
|
||||
|
||||
// don't show a rest after the last rep
|
||||
if (i < totalReps - 1) {
|
||||
items.add(Rest(
|
||||
id: ++position,
|
||||
position: position,
|
||||
parentId: id,
|
||||
action: action,
|
||||
time: action.restBetweenReps,
|
||||
name: 'prepare'));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
items.add(Reps(id: id, position: position, action: action));
|
||||
|
||||
if (action.isAlternating) {
|
||||
items.add(Rest(
|
||||
id: ++position,
|
||||
position: position,
|
||||
parentId: id,
|
||||
action: action,
|
||||
time: action.restBetweenReps,
|
||||
name: 'alternate'));
|
||||
items.add(Reps(id: id, position: ++position, action: action));
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
class Reps extends Item {
|
||||
Reps(
|
||||
{required super.id,
|
||||
required super.position,
|
||||
required super.action,
|
||||
super.parentId});
|
||||
|
||||
@override
|
||||
dynamic get value => type == RepType.time ? time : count;
|
||||
|
||||
RepType get type => action.repType;
|
||||
@override
|
||||
int? get time => toSeconds(action.repLength!);
|
||||
int? get count => getReps(id, json.decode(action.totalReps));
|
||||
int? get weight =>
|
||||
action.repWeights != null ? json.decode(action.repWeights!)[id] : null;
|
||||
|
||||
static int getReps(setId, reps) {
|
||||
if (reps.length > 1) {
|
||||
return reps[setId];
|
||||
} else {
|
||||
return reps.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Rest extends Item {
|
||||
@override
|
||||
String name;
|
||||
|
||||
Rest(
|
||||
{required super.id,
|
||||
required super.position,
|
||||
required super.action,
|
||||
super.parentId,
|
||||
required super.time,
|
||||
required this.name});
|
||||
|
||||
// @override
|
||||
// String get name => 'Rest';
|
||||
@override
|
||||
int get value => toSeconds(time ?? 0);
|
||||
@override
|
||||
RepType get valueType => RepType.time;
|
||||
}
|
Reference in New Issue
Block a user