small refactor, better dao thigns
This commit is contained in:
parent
3153bf13f9
commit
1234a300e1
@ -11,8 +11,8 @@ class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMi
|
||||
return await select(activities).get();
|
||||
}
|
||||
|
||||
Future<List<Activity>> find(int id) async {
|
||||
return await (select(activities)..where((activity) => activity.id.equals(id) )).get();
|
||||
Future<Activity> find(int id) async {
|
||||
return await (select(activities)..where((activity) => activity.id.equals(id) )).getSingle();
|
||||
}
|
||||
|
||||
Future<List<Activity>> sessionActivities(int id) async {
|
||||
|
@ -11,11 +11,31 @@ class MediaItemsDao extends DatabaseAccessor<AppDatabase> with _$MediaItemsDaoMi
|
||||
return await select(mediaItems).get();
|
||||
}
|
||||
|
||||
Future<List<MediaItem>> find(int id) async {
|
||||
return await (select(mediaItems)..where((mediaItem) => mediaItem.id.equals(id) )).get();
|
||||
Future<MediaItem> find(int id) async {
|
||||
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(
|
||||
[
|
||||
innerJoin(
|
||||
|
@ -11,11 +11,11 @@ class SessionActivitiesDao extends DatabaseAccessor<AppDatabase> with _$SessionA
|
||||
return await select(sessionActivities).get();
|
||||
}
|
||||
|
||||
Future<List<SessionActivity>> find(int id) async {
|
||||
return await (select(sessionActivities)..where((sessionActivity) => sessionActivity.id.equals(id) )).get();
|
||||
Future<SessionActivity> find(int id) async {
|
||||
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
|
||||
.filter((sessionActivity) => sessionActivity.sessionId.id(id));
|
||||
|
||||
|
@ -11,7 +11,7 @@ class SessionsDao extends DatabaseAccessor<AppDatabase> with _$SessionsDaoMixin
|
||||
return await select(sessions).get();
|
||||
}
|
||||
|
||||
Future<List<Session>> find(int id) async {
|
||||
return await (select(sessions)..where((session) => session.id.equals(id) )).get();
|
||||
Future<Session> find(int id) async {
|
||||
return await (select(sessions)..where((session) => session.id.equals(id) )).getSingle();
|
||||
}
|
||||
}
|
@ -30,12 +30,13 @@ class ActivityTimerModel with ChangeNotifier {
|
||||
double get progress => _progress;
|
||||
int get totalTime => _totalTime;
|
||||
|
||||
void setup(ActivityModel activityModel) {
|
||||
void setup(ActivityModel activityModel, Activity activity) {
|
||||
if (_activityModel == null || activityModel.id != _activityModel?.id) {
|
||||
_periodicTimer?.cancel();
|
||||
_progress = 0;
|
||||
_isc = null;
|
||||
_activityModel = activityModel;
|
||||
_activity = activity;
|
||||
_sets = activityModel.actions[0].items();
|
||||
_currentActionNum = 0;
|
||||
_currentSetNum = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.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/models/activity_model.dart';
|
||||
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||
@ -30,97 +30,113 @@ class ActivityCardState extends State<ActivityCard> {
|
||||
final ActivityTimerModel atm =
|
||||
Provider.of<ActivityTimerModel>(context, listen: false);
|
||||
|
||||
return Card(
|
||||
color: atm.activity?.id == widget.activity.id
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
onTap: () => showGeneralDialog(
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: const Duration(milliseconds: 220),
|
||||
transitionBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
Animation<Offset> custom = Tween<Offset>(
|
||||
begin: const Offset(0.0, 1.0),
|
||||
end: const Offset(0.0, 0.0))
|
||||
.animate(animation);
|
||||
return SlideTransition(
|
||||
position: custom,
|
||||
child: Dialog.fullscreen(
|
||||
child: ActivityView(activity: widget.activity)));
|
||||
},
|
||||
barrierDismissible: true,
|
||||
barrierLabel: '',
|
||||
context: context,
|
||||
pageBuilder: (context, animation1, animation2) {
|
||||
return Container();
|
||||
}),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 5, bottom: 5),
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: findMediaByType(
|
||||
widget.activity.actions[0].media, 'image')),
|
||||
// color: Colors.blue,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.elliptical(10, 10)),
|
||||
),
|
||||
)),
|
||||
title: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
if (atm.activity?.id == widget.activity.id) {
|
||||
return Text(
|
||||
maxLines: 1,
|
||||
"${widget.data.title} (${formattedTime(atm.totalTime)})");
|
||||
} else {
|
||||
return Text(maxLines: 1, widget.data.title);
|
||||
}
|
||||
},
|
||||
),
|
||||
subtitle: Text(maxLines: 2, widget.data.description),
|
||||
trailing: IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(Icons.close_rounded),
|
||||
onPressed: () {
|
||||
showAdaptiveDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text('Activity Removal'),
|
||||
content: const Text('Would you like to permanently remove this activity from the current session?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
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(
|
||||
color: atm.activity?.id == widget.activity.id
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
onTap: () => showGeneralDialog(
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: const Duration(milliseconds: 220),
|
||||
transitionBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
Animation<Offset> custom = Tween<Offset>(
|
||||
begin: const Offset(0.0, 1.0),
|
||||
end: const Offset(0.0, 0.0))
|
||||
.animate(animation);
|
||||
return SlideTransition(
|
||||
position: custom,
|
||||
child: Dialog.fullscreen(
|
||||
child: ActivityView(
|
||||
activityModel: widget.activity,
|
||||
activity: widget.data)));
|
||||
},
|
||||
barrierDismissible: true,
|
||||
barrierLabel: '',
|
||||
context: context,
|
||||
pageBuilder: (context, animation1, animation2) {
|
||||
return Container();
|
||||
}),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 5, bottom: 5),
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image:
|
||||
findMediaByType(mediaItems, 'image')),
|
||||
// color: Colors.blue,
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.elliptical(10, 10)),
|
||||
),
|
||||
)),
|
||||
title: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
if (atm.activity?.id == widget.activity.id) {
|
||||
return Text(
|
||||
maxLines: 1,
|
||||
"${widget.data.title} (${formattedTime(atm.totalTime)})");
|
||||
} else {
|
||||
return Text(maxLines: 1, widget.data.title);
|
||||
}
|
||||
},
|
||||
),
|
||||
subtitle: Text(maxLines: 2, widget.data.description),
|
||||
trailing: IconButton(
|
||||
visualDensity: VisualDensity.compact,
|
||||
icon: Icon(Icons.close_rounded),
|
||||
onPressed: () {
|
||||
showAdaptiveDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) => AlertDialog(
|
||||
title: const Text('Activity Removal'),
|
||||
content: const Text(
|
||||
'Would you like to permanently remove this activity from the current session?'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
Navigator.pop(context, 'Cancel'),
|
||||
child: const Text('Cancel'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () =>
|
||||
Navigator.pop(context, 'OK'),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
)),
|
||||
],
|
||||
)),
|
||||
],
|
||||
)),
|
||||
);
|
||||
);
|
||||
} else {
|
||||
return CircularProgressIndicator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImageProvider findMediaByType(List<Media>? media, String type) {
|
||||
var found = media?.where((m) => m.type == 'image');
|
||||
ImageProvider findMediaByType(List<MediaItem> media, String type) {
|
||||
Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
|
||||
|
||||
if (found != null) {
|
||||
if (found.isNotEmpty) {
|
||||
return NetworkImage(found.first.reference);
|
||||
} else {
|
||||
// Element is not found
|
||||
|
@ -1,16 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/classes/activity_action.dart';
|
||||
import 'package:sendtrain/classes/media.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/models/activity_model.dart';
|
||||
import 'package:sendtrain/models/activity_timer_model.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 {
|
||||
const ActivityView({super.key, required this.activity});
|
||||
final ActivityModel activity;
|
||||
const ActivityView(
|
||||
{super.key, required this.activityModel, required this.activity});
|
||||
final ActivityModel activityModel;
|
||||
final Activity activity;
|
||||
|
||||
@override
|
||||
State<ActivityView> createState() => _ActivityViewState();
|
||||
@ -19,11 +21,12 @@ class ActivityView extends StatefulWidget {
|
||||
class _ActivityViewState extends State<ActivityView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
ActivityModel activity = widget.activity;
|
||||
final ActivityModel activityModel = widget.activityModel;
|
||||
final Activity activity = widget.activity;
|
||||
ActivityTimerModel atm =
|
||||
Provider.of<ActivityTimerModel>(context, listen: false);
|
||||
|
||||
atm.setup(activity);
|
||||
atm.setup(activityModel, activity);
|
||||
|
||||
return Scaffold(
|
||||
floatingActionButtonLocation: ExpandableFab.location,
|
||||
@ -63,15 +66,15 @@ class _ActivityViewState extends State<ActivityView> {
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 25, fontWeight: FontWeight.bold),
|
||||
activity.title)),
|
||||
ActivityViewCategories(categories: activity.categories),
|
||||
activityModel.title)),
|
||||
ActivityViewCategories(categories: activityModel.categories),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 0, bottom: 20, left: 15, right: 15),
|
||||
child: Text(
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(fontSize: 15),
|
||||
activity.description)),
|
||||
activityModel.description)),
|
||||
ActivityViewMedia(activity: activity),
|
||||
const Padding(
|
||||
padding: EdgeInsets.fromLTRB(15, 30, 0, 10),
|
||||
@ -139,77 +142,7 @@ class _ActivityViewState extends State<ActivityView> {
|
||||
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))
|
||||
// ],
|
||||
// );
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ class SessionViewAchievements extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<List<SessionActivity>>(
|
||||
future: SessionActivitiesDao(Provider.of<AppDatabase>(context))
|
||||
.sessionActivitiesBySessionId(session.id),
|
||||
.fromSessionId(session.id),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final sessionActivities = snapshot.data!;
|
||||
|
@ -13,7 +13,7 @@ class SessionViewMedia extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<List<MediaItem>>(
|
||||
future: MediaItemsDao(Provider.of<AppDatabase>(context))
|
||||
.mediaItemsFromSession(session),
|
||||
.fromSession(session),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final mediaItems = snapshot.data!;
|
||||
|
Loading…
x
Reference in New Issue
Block a user