SendTrain/lib/widgets/activities/activity_action_view.dart

228 lines
9.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/models/action_model.dart';
import 'package:sendtrain/providers/action_timer.dart';
import 'package:sendtrain/widgets/generic/elements/add_card_generic.dart';
class ActivityActionView extends StatefulWidget {
const ActivityActionView({super.key, required this.actions, this.resetOnLoad = true});
final List actions;
final bool resetOnLoad;
@override
State<ActivityActionView> createState() => ActivityActionViewState();
}
class ActivityActionViewState extends State<ActivityActionView> {
// class ActivityActionView extends StatelessWidget {
// ActivityActionView({super.key, required this.actions});
// final List actions;
final ItemScrollController itemScrollController = ItemScrollController();
final ScrollOffsetController scrollOffsetController =
ScrollOffsetController();
final ItemPositionsListener itemPositionsListener =
ItemPositionsListener.create();
final ScrollOffsetListener scrollOffsetListener =
ScrollOffsetListener.create();
late final ActionTimer at;
int actionCount = 0;
GestureDetector gtBuild(
ActionTimer at, Item item, int actionNum, int selectedIndex,
{int? order}) {
// default, for rests
String setItemRef = '-';
// non rests decimal reference to item
if (order != null) {
setItemRef = '${order + 1}.${item.position + 1}';
}
return GestureDetector(onTap: () {
at.setAction(actionNum, true);
}, child: Consumer<ActionTimer>(builder: (context, at, child) {
return Row(children: [
Ink(
width: 70,
padding: const EdgeInsets.all(15),
color: item == at.currentAction
? Theme.of(context).colorScheme.primaryContainer
: Theme.of(context).colorScheme.onPrimary,
child: Text(textAlign: TextAlign.center, setItemRef)),
Expanded(
child: Ink(
padding: const EdgeInsets.all(15),
color: item == at.currentAction
? Theme.of(context).colorScheme.surfaceBright
: Theme.of(context).colorScheme.surfaceContainerLow,
child: Text(
textAlign: TextAlign.center,
'${item.name}: ${item.value} ${item.humanValueType}'
.toTitleCase())))
]);
}));
}
@override
void initState() {
super.initState();
at = Provider.of<ActionTimer>(context, listen: false);
}
@override
Widget build(BuildContext context) {
if (widget.actions.isNotEmpty) {
at.setup(ActionModel(
action: widget.actions.first, db: Provider.of<AppDatabase>(context)), itemScrollController, widget.resetOnLoad);
// WidgetsBinding.instance.addPostFrameCallback((_) {
// if (itemScrollController.isAttached) {
// itemScrollController.scrollTo(
// index: at.currentAction.parentId != null
// ? at.currentAction.parentId!
// : at.currentAction.id,
// duration: Duration(milliseconds: 500),
// curve: Curves.easeInOutCubic);
// }
// });
return Expanded(
child: Column(children: [
Padding(
padding: const EdgeInsets.only(left: 10, right: 10),
child: Card(
clipBehavior: Clip.antiAlias,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
),
color: Theme.of(context).colorScheme.onPrimary,
child: Row(children: [
Ink(
width: 70,
color: Theme.of(context).colorScheme.primaryContainer,
child: Consumer<ActionTimer>(
builder: (context, at, child) {
return IconButton(
alignment: AlignmentDirectional.center,
icon: at.available
? const Icon(Icons.play_arrow_rounded)
: const Icon(Icons.pause_rounded),
onPressed: () => {
if (at.started)
{at.pause()}
else if (at.available)
{at.start()}
});
},
)),
Expanded(
flex: 1,
child: Stack(alignment: Alignment.center, children: [
Container(
alignment: Alignment.center,
child: Consumer<ActionTimer>(
builder: (context, at, child) {
return Text(
style: const TextStyle(fontSize: 20),
textAlign: TextAlign.center,
'${at.currentValue} ${at.currentAction.humanValueType}'
.toTitleCase());
},
),
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 15),
child: Consumer<ActionTimer>(
builder: (context, at, child) {
return Text(
style: const TextStyle(fontSize: 12),
textAlign: TextAlign.right,
'${at.state['currentAction'] + 1} of ${at.allActions.length}');
})),
])),
]))),
Padding(
padding: EdgeInsets.only(left: 14, right: 14),
child: Consumer<ActionTimer>(builder: (context, at, child) {
return LinearProgressIndicator(
value: at.progress,
semanticsLabel: 'Activity Progress',
);
})),
Expanded(
child: ScrollablePositionedList.builder(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 20),
itemCount: at.items.length,
// initialScrollIndex: at.currentAction.parentId != null
// ? at.currentAction.parentId!
// : at.currentAction.id,
itemScrollController: itemScrollController,
scrollOffsetController: scrollOffsetController,
itemPositionsListener: itemPositionsListener,
scrollOffsetListener: scrollOffsetListener,
itemBuilder: (BuildContext context, int itemNum) {
if (itemNum == 0) {
actionCount = 0;
}
List<GestureDetector> content = [];
Item item = at.items[itemNum];
if (item.runtimeType == Rest) {
content.add(gtBuild(at, item, actionCount++, itemNum));
} else if (item.runtimeType == Set) {
List<Item> setItems = item.items;
for (int setItemNum = 0;
setItemNum < setItems.length;
setItemNum++) {
Item setItem = setItems[setItemNum];
content.add(gtBuild(at, setItem, actionCount++, itemNum,
order: (item as Set).setOrder));
}
}
if (itemNum == 0) {
return Card(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(0),
topRight: Radius.circular(0),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
),
clipBehavior: Clip.antiAlias,
child: Column(children: content));
} else {
return Card(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
),
clipBehavior: Clip.antiAlias,
child: Column(children: content));
}
}))
]));
} else {
return AddCardGeneric(
title: 'Add an Action!',
description:
'Click here to create an exercise template (sets and reps, etc) for your activity!',
action: () {
print('teset');
});
}
}
}