SendTrain/lib/widgets/activities/activity_view.dart
2025-01-06 14:47:14 -05:00

333 lines
17 KiB
Dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:provider/provider.dart';
import 'package:sendtrain/daos/actions_dao.dart';
import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/extensions/string_extensions.dart';
import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activities/activity_action_view.dart';
import 'package:sendtrain/widgets/activities/activity_view_categories.dart';
import 'package:sendtrain/widgets/activities/activity_view_media.dart';
class ActivityView extends StatefulWidget {
const ActivityView({super.key, required this.activity});
final Activity activity;
@override
State<ActivityView> createState() => _ActivityViewState();
}
class _ActivityViewState extends State<ActivityView> {
List<Widget> action(actions) {
if (actions.isNotEmpty) {
return [
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<ActivityTimerModel>(
builder: (context, atm, child) {
return IconButton(
alignment: AlignmentDirectional.center,
icon: atm.isActive
? const Icon(Icons.pause_rounded)
: const Icon(Icons.play_arrow_rounded),
onPressed: () =>
{atm.isActive ? atm.pause() : atm.start()});
},
)),
Expanded(
flex: 1,
child: Stack(alignment: Alignment.center, children: [
Container(
alignment: Alignment.center,
child: Consumer<ActivityTimerModel>(
builder: (context, atm, child) {
return Text(
style: const TextStyle(fontSize: 20),
textAlign: TextAlign.center,
'${atm.actionCount} ${atm.currentAction['type']}'
.toTitleCase());
},
),
),
Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 15),
child: Consumer<ActivityTimerModel>(
builder: (context, atm, child) {
return Text(
style: const TextStyle(fontSize: 12),
textAlign: TextAlign.right,
'${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}');
})),
])),
]))),
Padding(
padding: EdgeInsets.only(left: 14, right: 14),
child: Consumer<ActivityTimerModel>(builder: (context, atm, child) {
return LinearProgressIndicator(
value: atm.progress,
semanticsLabel: 'Activity Progress',
);
})),
ActivityActionView(actions: actions)
];
} else {
return [Text('add an action')];
}
}
@override
Widget build(BuildContext context) {
final Activity activity = widget.activity;
ActivityTimerModel atm =
Provider.of<ActivityTimerModel>(context, listen: false);
return FutureBuilder<List>(
future: ActionsDao(Provider.of<AppDatabase>(context))
.fromActivity(activity),
builder: (context, snapshot) {
if (snapshot.hasData) {
List actions = snapshot.data!;
atm.setup(activity, actions);
return Scaffold(
floatingActionButtonLocation: ExpandableFab.location,
floatingActionButton: ExpandableFab(
distance: 70,
type: ExpandableFabType.up,
overlayStyle: ExpandableFabOverlayStyle(
color: Colors.black.withOpacity(0.5),
blur: 10,
),
children: [
// FloatingActionButton.extended(
// icon: const Icon(Icons.upload_outlined),
// label: Text('Upload Media'),
// onPressed: () {},
// ),
FloatingActionButton.extended(
icon: const Icon(Icons.note_add_outlined),
label: Text('Add Note'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.history_outlined),
label: Text('Restart'),
onPressed: () {},
),
FloatingActionButton.extended(
icon: const Icon(Icons.done_all_outlined),
label: Text('Done'),
onPressed: () {},
),
]),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppBar(
titleSpacing: 0,
centerTitle: true,
title: const Text('Activity',
style: TextStyle(fontSize: 15)),
),
Padding(
padding: const EdgeInsets.only(
left: 15, right: 20, top: 15, bottom: 10),
child: Text(
maxLines: 1,
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold),
activity.title.toTitleCase())),
Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 0, 10),
child:
Flex(direction: Axis.horizontal, children: [
ActivityViewCategories<List<ActivityLevel>>(
icon: Icon(Icons.stairs_rounded),
text: "Activity Level",
object: activity.level != null
? [activity.level!]
: []),
// ActivityViewCategories<List<ActivityMechanic>>(
// icon: Icon(Icons.),
// text: 'Activity Mechanic',
// object: activity.mechanic != null
// ? [activity.mechanic!]
// : []),
ActivityViewCategories<List<ActivityEquipment>>(
icon: Icon(Icons.fitness_center_rounded),
text: 'Activity Equipments',
object: activity.equipment != null
? [activity.equipment!]
: []),
ActivityViewCategories<List<ActivityType>>(
icon: Icon(Icons.type_specimen_rounded),
text: 'Activity Equipments',
object: activity.equipment != null
? [activity.type!]
: []),
])),
Padding(
padding: const EdgeInsets.only(
top: 0, bottom: 10, left: 15, right: 15),
child: Text(
maxLines: 4,
overflow: TextOverflow. ellipsis,
softWrap: true,
textAlign: TextAlign.left,
style: const TextStyle(fontSize: 15),
jsonToDescription(json.decode(activity.description ?? "")))),
Padding(
padding: EdgeInsets.only(right: 15),
child: Align(
alignment: Alignment.topRight,
child: TextButton(
style: ButtonStyle(
textStyle:
WidgetStateProperty.all<TextStyle>(
TextStyle(
fontWeight:
FontWeight.normal)),
shape: WidgetStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10.0),
))),
onPressed: () {
showGenericSheet(
context,
Padding(
padding: EdgeInsets.all(15),
child: Text(jsonToDescription(
json.decode(activity.description ??
"")))));
},
child: Text("Read More...",
textAlign: TextAlign.right),
))),
const Padding(
padding: EdgeInsets.fromLTRB(15, 10, 0, 10),
child: Text(
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
'Media:')),
ActivityViewMedia(activity: activity),
const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
child: Text(
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
'Actions')),
// 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<ActivityTimerModel>(
// builder: (context, atm, child) {
// return IconButton(
// alignment:
// AlignmentDirectional.center,
// icon: atm.isActive
// ? const Icon(
// Icons.pause_rounded)
// : const Icon(
// Icons.play_arrow_rounded),
// onPressed: () => {
// atm.isActive
// ? atm.pause()
// : atm.start()
// });
// },
// )),
// Expanded(
// flex: 1,
// child: Stack(
// alignment: Alignment.center,
// children: [
// Container(
// alignment: Alignment.center,
// child: Consumer<ActivityTimerModel>(
// builder: (context, atm, child) {
// return Text(
// style: const TextStyle(
// fontSize: 20),
// textAlign: TextAlign.center,
// '${atm.actionCount} ${atm.currentAction['type']}'
// .toTitleCase());
// },
// ),
// ),
// Container(
// alignment: Alignment.centerRight,
// padding:
// EdgeInsets.only(right: 15),
// child:
// Consumer<ActivityTimerModel>(
// builder: (context, atm,
// child) {
// return Text(
// style: const TextStyle(
// fontSize: 12),
// textAlign: TextAlign.right,
// '${atm.currentAction['actionID'] + 1} of ${atm.totalActions()}');
// })),
// ])),
// ]))),
// Padding(
// padding: EdgeInsets.only(left: 14, right: 14),
// child: Consumer<ActivityTimerModel>(
// builder: (context, atm, child) {
// return LinearProgressIndicator(
// value: atm.progress,
// semanticsLabel: 'Activity Progress',
// );
// })),
// ActivityActionView(actions: actions),
] +
action(actions)));
} else {
return Container(
alignment: Alignment.center,
child: SizedBox(
height: 50.0,
width: 50.0,
child: CircularProgressIndicator(),
));
}
});
}
}