genericizing add card, activity ui tweaks

This commit is contained in:
Joshua Burman 2025-01-07 12:37:17 -05:00
parent 8ec531c0ea
commit 0b0ca884bc
7 changed files with 97 additions and 50 deletions

View File

@ -1,8 +1,10 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/daos/activities_dao.dart'; import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
// import 'package:sendtrain/widgets/activities/activity_card.dart'; import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/widgets/generic/elements/form_search_input.dart'; import 'package:sendtrain/widgets/generic/elements/form_search_input.dart';
class ActivityFinderService { class ActivityFinderService {
@ -27,10 +29,10 @@ class ActivityFinderService {
} }
Widget resultWidget(Activity activity, Function? callback) { Widget resultWidget(Activity activity, Function? callback) {
// return ActivityCard(activity: activity, callback: callback);
return ListTile( return ListTile(
title: Text(activity.title), title: Text(activity.title),
subtitle: Text(activity.description ?? ""), subtitle: Text(jsonToDescription(json.decode(activity.description ?? "")),
maxLines: 2, softWrap: true, overflow: TextOverflow.ellipsis),
onTap: () { onTap: () {
if (callback != null) { if (callback != null) {
callback(); callback();

View File

@ -11,6 +11,7 @@ import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activities/activity_action_view.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_categories.dart';
import 'package:sendtrain/widgets/activities/activity_view_media.dart'; import 'package:sendtrain/widgets/activities/activity_view_media.dart';
import 'package:sendtrain/widgets/generic/elements/add_card_generic.dart';
class ActivityView extends StatefulWidget { class ActivityView extends StatefulWidget {
const ActivityView({super.key, required this.activity}); const ActivityView({super.key, required this.activity});
@ -87,7 +88,15 @@ class _ActivityViewState extends State<ActivityView> {
ActivityActionView(actions: actions) ActivityActionView(actions: actions)
]; ];
} else { } else {
return [Text('add an action')]; return [
AddCardGeneric(
title: 'Add an Action!',
description:
'Click here to create an exercise template (sets and reps, etc) for your activity!',
action: () {
print('teset');
})
];
} }
} }
@ -178,8 +187,8 @@ class _ActivityViewState extends State<ActivityView> {
: []), : []),
ActivityViewCategories<List<ActivityType>>( ActivityViewCategories<List<ActivityType>>(
icon: Icon(Icons.type_specimen_rounded), icon: Icon(Icons.type_specimen_rounded),
text: 'Activity Equipments', text: 'Activity Type',
object: activity.equipment != null object: activity.type != null
? [activity.type!] ? [activity.type!]
: []), : []),
])), ])),
@ -189,10 +198,11 @@ class _ActivityViewState extends State<ActivityView> {
child: Text( child: Text(
maxLines: 4, maxLines: 4,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
softWrap: true, // softWrap: true,
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: const TextStyle(fontSize: 15), style: const TextStyle(fontSize: 15),
jsonToDescription(json.decode(activity.description ?? "")))), jsonToDescription([json
.decode(activity.description ?? "")[0]]))),
Padding( Padding(
padding: EdgeInsets.only(right: 15), padding: EdgeInsets.only(right: 15),
child: Align( child: Align(
@ -215,12 +225,18 @@ class _ActivityViewState extends State<ActivityView> {
context, context,
Padding( Padding(
padding: EdgeInsets.all(15), padding: EdgeInsets.all(15),
child: Text(jsonToDescription( child: Text(
json.decode(activity.description ?? style:
TextStyle(fontSize: 18),
jsonToDescription(json.decode(
activity.description ??
""))))); "")))));
}, },
child: Text("read more", child: Text(
textAlign: TextAlign.right, style: TextStyle(fontSize: 12),), "read more",
textAlign: TextAlign.right,
style: TextStyle(fontSize: 12),
),
))), ))),
const Padding( const Padding(
padding: EdgeInsets.fromLTRB(15, 10, 0, 10), padding: EdgeInsets.fromLTRB(15, 10, 0, 10),

View File

@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
class AddCardGeneric extends StatelessWidget {
const AddCardGeneric(
{super.key, required this.title, required this.description, this.action});
final String title;
final String description;
final Function? action;
@override
Widget build(BuildContext context) {
return Expanded(
child: ListView(
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
children: [
Card.outlined(
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onTap: () {
if (action != null) {
action!();
}
},
child: ListTile(
contentPadding:
EdgeInsets.only(top: 5, left: 15, right: 5, bottom: 5),
autofocus: true,
leading: Icon(Icons.add_box_rounded),
title: Text(title),
subtitle: Text(description),
)))
]));
}
}

View File

@ -11,9 +11,11 @@ import 'package:sendtrain/widgets/builders/dialogs.dart';
import 'package:video_player/video_player.dart'; import 'package:video_player/video_player.dart';
class MediaCard extends StatelessWidget { class MediaCard extends StatelessWidget {
const MediaCard({super.key, required this.media, this.callback}); const MediaCard(
{super.key, required this.media, this.callback, this.canDelete});
final MediaItem media; final MediaItem media;
final bool? canDelete;
final Function? callback; final Function? callback;
@override @override
@ -44,7 +46,9 @@ class MediaCard extends StatelessWidget {
RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
shadowColor: const Color.fromARGB(0, 255, 255, 255), shadowColor: const Color.fromARGB(0, 255, 255, 255),
child: TextButton( child: TextButton(
onLongPress: () => showRemovalDialog( onLongPress: () {
if (canDelete == true) {
showRemovalDialog(
'Media Removal', 'Media Removal',
'Would you like to permanently remove this media from the current session?', 'Would you like to permanently remove this media from the current session?',
context, () { context, () {
@ -55,7 +59,9 @@ class MediaCard extends StatelessWidget {
if (callback != null) { if (callback != null) {
callback!(); callback!();
} }
}), });
}
},
onPressed: () => showMediaDetailWidget(context, media), onPressed: () => showMediaDetailWidget(context, media),
child: const ListTile( child: const ListTile(
title: Text(''), title: Text(''),

View File

@ -83,7 +83,7 @@ class _SessionViewState extends State<SessionView> {
), ),
children: [ children: [
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.military_tech_rounded),
label: Text('Add Achievement'), label: Text('Add Achievement'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
@ -93,7 +93,7 @@ class _SessionViewState extends State<SessionView> {
}, },
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.sports_gymnastics_rounded),
label: Text('Add Activity'), label: Text('Add Activity'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
@ -104,7 +104,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.edit_outlined), icon: const Icon(Icons.edit_outlined),
label: Text('Edit'), label: Text('Edit Session'),
onPressed: () { onPressed: () {
showEditorSheet( showEditorSheet(
context, context,
@ -114,7 +114,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.history_outlined), icon: const Icon(Icons.history_outlined),
label: Text('Restart'), label: Text('Restart Session'),
onPressed: () { onPressed: () {
Session newSession = Session newSession =
session.copyWith(status: SessionStatus.pending); session.copyWith(status: SessionStatus.pending);
@ -131,7 +131,7 @@ class _SessionViewState extends State<SessionView> {
), ),
FloatingActionButton.extended( FloatingActionButton.extended(
icon: const Icon(Icons.done_all_outlined), icon: const Icon(Icons.done_all_outlined),
label: Text('Done'), label: Text('Finish Session'),
onPressed: () { onPressed: () {
Session newSession = Session newSession =
session.copyWith(status: SessionStatus.completed); session.copyWith(status: SessionStatus.completed);

View File

@ -4,6 +4,7 @@ import 'package:sendtrain/daos/activities_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/helpers/widget_helpers.dart'; import 'package:sendtrain/helpers/widget_helpers.dart';
import 'package:sendtrain/widgets/activities/activity_card.dart'; import 'package:sendtrain/widgets/activities/activity_card.dart';
import 'package:sendtrain/widgets/generic/elements/add_card_generic.dart';
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart'; import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
import 'package:sendtrain/widgets/sessions/session_activities_editor.dart'; import 'package:sendtrain/widgets/sessions/session_activities_editor.dart';
@ -32,36 +33,21 @@ class _SessionViewActivitiesState extends State<SessionViewActivities> {
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: activities.length, itemCount: activities.length,
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return ActivityCard(activity: activities[index], session: widget.session); return ActivityCard(
activity: activities[index], session: widget.session);
}, },
)); ));
} else { } else {
return Expanded( return AddCardGeneric(
child: ListView( title: 'Add an Activity!',
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), description:
children: [ 'Here you can associate one or more activities that you can follow along with during your session.',
Card.outlined( action: () {
child: InkWell(
customBorder: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onTap: () {
showEditorSheet( showEditorSheet(
context, context,
SessionActivitiesEditor( SessionActivitiesEditor(
session: widget.session, session: widget.session, callback: () {}));
callback: () {})); });
},
child: ListTile(
contentPadding: EdgeInsets.only(
top: 5, left: 15, right: 5, bottom: 5),
autofocus: true,
leading: Icon(Icons.add_box_rounded),
title: Text('Add an Activity!'),
subtitle: Text(
'Here you can associate one or more activities that you can follow along with during your session.'),
)))
]));
} }
} else { } else {
return GenericProgressIndicator(); return GenericProgressIndicator();

View File

@ -32,7 +32,7 @@ class _SessionViewMediaState extends State<SessionViewMedia> {
List<Widget> content; List<Widget> content;
if (mediaItems.isNotEmpty) { if (mediaItems.isNotEmpty) {
List<Widget> mediaCards = List.generate(mediaItems.length, List<Widget> mediaCards = List.generate(mediaItems.length,
(i) => MediaCard(media: mediaItems[i], callback: resetState)); (i) => MediaCard(media: mediaItems[i], callback: resetState, canDelete: true));
content = mediaCards; content = mediaCards;
} else { } else {
content = [ content = [