small refactor, better dao thigns

This commit is contained in:
Joshua Burman 2024-12-21 17:51:24 -05:00
parent 3153bf13f9
commit 1234a300e1
9 changed files with 152 additions and 182 deletions

View File

@ -11,8 +11,8 @@ class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMi
return await select(activities).get(); return await select(activities).get();
} }
Future<List<Activity>> find(int id) async { Future<Activity> find(int id) async {
return await (select(activities)..where((activity) => activity.id.equals(id) )).get(); return await (select(activities)..where((activity) => activity.id.equals(id) )).getSingle();
} }
Future<List<Activity>> sessionActivities(int id) async { Future<List<Activity>> sessionActivities(int id) async {

View File

@ -11,11 +11,31 @@ class MediaItemsDao extends DatabaseAccessor<AppDatabase> with _$MediaItemsDaoMi
return await select(mediaItems).get(); return await select(mediaItems).get();
} }
Future<List<MediaItem>> find(int id) async { Future<MediaItem> find(int id) async {
return await (select(mediaItems)..where((mediaItem) => mediaItem.id.equals(id) )).get(); return await (select(mediaItems)..where((mediaItem) => mediaItem.id.equals(id) )).getSingle();
} }
Future<List<MediaItem>> mediaItemsFromSession(Session session) async { Future<List<MediaItem>> fromActivity(Activity activity) async {
final result = select(db.objectMediaItems).join(
[
innerJoin(
db.mediaItems,
db.mediaItems.id.equalsExp(db.objectMediaItems.mediaId),
),
],
)
..where(
db.objectMediaItems.objectType.equals(ObjectType.activities.name))
..where(db.objectMediaItems.objectId.equals(activity.id));
final mediaItems = (await result.get())
.map((e) => e.readTable(db.mediaItems))
.toList();
return mediaItems;
}
Future<List<MediaItem>> fromSession(Session session) async {
final result = select(db.objectMediaItems).join( final result = select(db.objectMediaItems).join(
[ [
innerJoin( innerJoin(

View File

@ -11,11 +11,11 @@ class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionA
return await select(sessionActivities).get(); return await select(sessionActivities).get();
} }
Future<List<SessionActivity>> find(int id) async { Future<SessionActivity> find(int id) async {
return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).get(); return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).getSingle();
} }
Future<List<SessionActivity>> sessionActivitiesBySessionId(int id) async { Future<List<SessionActivity>> fromSessionId(int id) async {
final result = db.managers.sessionActivities final result = db.managers.sessionActivities
.filter((sessionActivity) => sessionActivity.sessionId.id(id)); .filter((sessionActivity) => sessionActivity.sessionId.id(id));

View File

@ -11,7 +11,7 @@ class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin
return await select(sessions).get(); return await select(sessions).get();
} }
Future<List<Session>> find(int id) async { Future<Session> find(int id) async {
return await (select(sessions)..where((session) => session.id.equals(id) )).get(); return await (select(sessions)..where((session) => session.id.equals(id) )).getSingle();
} }
} }

View File

@ -30,12 +30,13 @@ class ActivityTimerModel with ChangeNotifier {
double get progress => _progress; double get progress => _progress;
int get totalTime => _totalTime; int get totalTime => _totalTime;
void setup(ActivityModel activityModel) { void setup(ActivityModel activityModel, Activity activity) {
if (_activityModel == null || activityModel.id != _activityModel?.id) { if (_activityModel == null || activityModel.id != _activityModel?.id) {
_periodicTimer?.cancel(); _periodicTimer?.cancel();
_progress = 0; _progress = 0;
_isc = null; _isc = null;
_activityModel = activityModel; _activityModel = activityModel;
_activity = activity;
_sets = activityModel.actions[0].items(); _sets = activityModel.actions[0].items();
_currentActionNum = 0; _currentActionNum = 0;
_currentSetNum = 0; _currentSetNum = 0;

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/classes/media.dart'; import 'package:sendtrain/daos/media_items_dao.dart';
import 'package:sendtrain/database/database.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/models/activity_model.dart'; import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/models/activity_timer_model.dart';
@ -30,6 +30,13 @@ class ActivityCardState extends State<ActivityCard> {
final ActivityTimerModel atm = final ActivityTimerModel atm =
Provider.of<ActivityTimerModel>(context, listen: false); Provider.of<ActivityTimerModel>(context, listen: false);
return FutureBuilder<List<MediaItem>>(
future: MediaItemsDao(Provider.of<AppDatabase>(context))
.fromActivity(widget.data),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<MediaItem> mediaItems = snapshot.data!;
return Card( return Card(
color: atm.activity?.id == widget.activity.id color: atm.activity?.id == widget.activity.id
? Theme.of(context).colorScheme.primaryContainer ? Theme.of(context).colorScheme.primaryContainer
@ -50,7 +57,9 @@ class ActivityCardState extends State<ActivityCard> {
return SlideTransition( return SlideTransition(
position: custom, position: custom,
child: Dialog.fullscreen( child: Dialog.fullscreen(
child: ActivityView(activity: widget.activity))); child: ActivityView(
activityModel: widget.activity,
activity: widget.data)));
}, },
barrierDismissible: true, barrierDismissible: true,
barrierLabel: '', barrierLabel: '',
@ -70,11 +79,11 @@ class ActivityCardState extends State<ActivityCard> {
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
fit: BoxFit.cover, fit: BoxFit.cover,
image: findMediaByType( image:
widget.activity.actions[0].media, 'image')), findMediaByType(mediaItems, 'image')),
// color: Colors.blue, // color: Colors.blue,
borderRadius: borderRadius: const BorderRadius.all(
const BorderRadius.all(Radius.elliptical(10, 10)), Radius.elliptical(10, 10)),
), ),
)), )),
title: Consumer<ActivityTimerModel>( title: Consumer<ActivityTimerModel>(
@ -97,14 +106,17 @@ class ActivityCardState extends State<ActivityCard> {
context: context, context: context,
builder: (BuildContext context) => AlertDialog( builder: (BuildContext context) => AlertDialog(
title: const Text('Activity Removal'), title: const Text('Activity Removal'),
content: const Text('Would you like to permanently remove this activity from the current session?'), content: const Text(
'Would you like to permanently remove this activity from the current session?'),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
onPressed: () => Navigator.pop(context, 'Cancel'), onPressed: () =>
Navigator.pop(context, 'Cancel'),
child: const Text('Cancel'), child: const Text('Cancel'),
), ),
TextButton( TextButton(
onPressed: () => Navigator.pop(context, 'OK'), onPressed: () =>
Navigator.pop(context, 'OK'),
child: const Text('OK'), child: const Text('OK'),
), ),
], ],
@ -115,12 +127,16 @@ class ActivityCardState extends State<ActivityCard> {
], ],
)), )),
); );
} else {
return CircularProgressIndicator();
}
});
} }
ImageProvider findMediaByType(List<Media>? media, String type) { ImageProvider findMediaByType(List<MediaItem> media, String type) {
var found = media?.where((m) => m.type == 'image'); Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
if (found != null) { if (found.isNotEmpty) {
return NetworkImage(found.first.reference); return NetworkImage(found.first.reference);
} else { } else {
// Element is not found // Element is not found

View File

@ -1,16 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart'; import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:sendtrain/classes/activity_action.dart'; import 'package:sendtrain/database/database.dart';
import 'package:sendtrain/classes/media.dart';
import 'package:sendtrain/models/activity_model.dart'; import 'package:sendtrain/models/activity_model.dart';
import 'package:sendtrain/models/activity_timer_model.dart'; import 'package:sendtrain/models/activity_timer_model.dart';
import 'package:sendtrain/widgets/activity_action_view.dart'; import 'package:sendtrain/widgets/activity_action_view.dart';
import 'package:sendtrain/widgets/media_card.dart'; import 'package:sendtrain/widgets/activity_view_categories.dart';
import 'package:sendtrain/widgets/activity_view_media.dart';
class ActivityView extends StatefulWidget { class ActivityView extends StatefulWidget {
const ActivityView({super.key, required this.activity}); const ActivityView(
final ActivityModel activity; {super.key, required this.activityModel, required this.activity});
final ActivityModel activityModel;
final Activity activity;
@override @override
State<ActivityView> createState() => _ActivityViewState(); State<ActivityView> createState() => _ActivityViewState();
@ -19,11 +21,12 @@ class ActivityView extends StatefulWidget {
class _ActivityViewState extends State<ActivityView> { class _ActivityViewState extends State<ActivityView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ActivityModel activity = widget.activity; final ActivityModel activityModel = widget.activityModel;
final Activity activity = widget.activity;
ActivityTimerModel atm = ActivityTimerModel atm =
Provider.of<ActivityTimerModel>(context, listen: false); Provider.of<ActivityTimerModel>(context, listen: false);
atm.setup(activity); atm.setup(activityModel, activity);
return Scaffold( return Scaffold(
floatingActionButtonLocation: ExpandableFab.location, floatingActionButtonLocation: ExpandableFab.location,
@ -63,15 +66,15 @@ class _ActivityViewState extends State<ActivityView> {
maxLines: 1, maxLines: 1,
style: const TextStyle( style: const TextStyle(
fontSize: 25, fontWeight: FontWeight.bold), fontSize: 25, fontWeight: FontWeight.bold),
activity.title)), activityModel.title)),
ActivityViewCategories(categories: activity.categories), ActivityViewCategories(categories: activityModel.categories),
Padding( Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 0, bottom: 20, left: 15, right: 15), top: 0, bottom: 20, left: 15, right: 15),
child: Text( child: Text(
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: const TextStyle(fontSize: 15), style: const TextStyle(fontSize: 15),
activity.description)), activityModel.description)),
ActivityViewMedia(activity: activity), ActivityViewMedia(activity: activity),
const Padding( const Padding(
padding: EdgeInsets.fromLTRB(15, 30, 0, 10), padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
@ -139,77 +142,7 @@ class _ActivityViewState extends State<ActivityView> {
semanticsLabel: 'Activity Progress', semanticsLabel: 'Activity Progress',
); );
})), })),
ActivityActionView(action: activity.actions[0]), ActivityActionView(action: activityModel.actions[0]),
])); ]));
} }
} }
class ActivityViewCategories extends StatelessWidget {
const ActivityViewCategories({super.key, this.categories});
final List<String>? categories;
@override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 10),
child: SizedBox(
height: 40,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
itemCount: categories?.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.only(right: 5),
child: ActionChip(
visualDensity: VisualDensity.compact,
avatar: const Icon(Icons.check_circle_outline),
label: Text(maxLines: 1, '${categories?[index]}'),
onPressed: () {},
));
},
))),
],
);
}
}
class ActivityViewMedia extends StatelessWidget {
const ActivityViewMedia({super.key, this.activity});
final ActivityModel? activity;
@override
Widget build(BuildContext context) {
List<Media> media = [];
for (ActivityAction action in activity!.actions) {
if (action.media!.isNotEmpty) {
media.addAll(action.media as Iterable<Media>);
}
}
return Text("media!");
// List<Widget> mediaCards =
// List.generate(media.length, (i) => MediaCard(media: media[i]));
// return Column(
// children: [
// SizedBox(
// width: double.infinity,
// height: 100,
// child: GridView.count(
// padding: const EdgeInsets.fromLTRB(15, 0, 0, 0),
// scrollDirection: Axis.horizontal,
// crossAxisSpacing: 5,
// mainAxisSpacing: 5,
// crossAxisCount: 1,
// children: mediaCards))
// ],
// );
}
}

View File

@ -27,7 +27,7 @@ class SessionViewAchievements extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<List<SessionActivity>>( return FutureBuilder<List<SessionActivity>>(
future: SessionActivitiesDao(Provider.of<AppDatabase>(context)) future: SessionActivitiesDao(Provider.of<AppDatabase>(context))
.sessionActivitiesBySessionId(session.id), .fromSessionId(session.id),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final sessionActivities = snapshot.data!; final sessionActivities = snapshot.data!;

View File

@ -13,7 +13,7 @@ class SessionViewMedia extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<List<MediaItem>>( return FutureBuilder<List<MediaItem>>(
future: MediaItemsDao(Provider.of<AppDatabase>(context)) future: MediaItemsDao(Provider.of<AppDatabase>(context))
.mediaItemsFromSession(session), .fromSession(session),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
final mediaItems = snapshot.data!; final mediaItems = snapshot.data!;