further refactoring, conversion to stream
This commit is contained in:
parent
fa374a5bc2
commit
8e0ec614a0
@ -4,7 +4,8 @@ import 'package:sendtrain/database/database.dart';
|
||||
part 'activities_dao.g.dart';
|
||||
|
||||
@DriftAccessor(tables: [Activities])
|
||||
class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMixin {
|
||||
class ActivitiesDao extends DatabaseAccessor<AppDatabase>
|
||||
with _$ActivitiesDaoMixin {
|
||||
ActivitiesDao(super.db);
|
||||
|
||||
Future<List<Activity>> all() async {
|
||||
@ -12,26 +13,71 @@ class ActivitiesDao extends DatabaseAccessor<AppDatabase> with _$ActivitiesDaoMi
|
||||
}
|
||||
|
||||
Future<Activity> find(int id) async {
|
||||
return await (select(activities)..where((activity) => activity.id.equals(id) )).getSingle();
|
||||
return await (select(activities)
|
||||
..where((activity) => activity.id.equals(id)))
|
||||
.getSingle();
|
||||
}
|
||||
|
||||
Future remove(Activity activity) => delete(activities).delete(activity);
|
||||
|
||||
Future<List<Activity>> sessionActivities(int id) async {
|
||||
final result = select(db.sessionActivities).join(
|
||||
Future<List<Activity>> activitiesFromSession(int id) async {
|
||||
final result = select(db.sessionActivities).join(
|
||||
[
|
||||
innerJoin(
|
||||
db.activities,
|
||||
db.activities.id
|
||||
.equalsExp(db.sessionActivities.activityId),
|
||||
db.activities.id.equalsExp(db.sessionActivities.activityId),
|
||||
),
|
||||
],
|
||||
)..where(db.sessionActivities.sessionId.equals(id));
|
||||
|
||||
final activities = (await result.get())
|
||||
.map((e) => e.readTable(db.activities))
|
||||
.toList();
|
||||
final activities =
|
||||
(await result.get()).map((e) => e.readTable(db.activities)).toList();
|
||||
|
||||
return activities;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<List<Activity>> watchSessionActivities(int id) {
|
||||
final query = select(db.sessionActivities).join(
|
||||
[
|
||||
innerJoin(
|
||||
db.activities,
|
||||
db.activities.id.equalsExp(db.sessionActivities.activityId),
|
||||
),
|
||||
],
|
||||
)..where(db.sessionActivities.sessionId.equals(id));
|
||||
|
||||
return query.watch().map((rows){
|
||||
final activities =
|
||||
(rows).map((e) => e.readTable(db.activities)).toList();
|
||||
|
||||
return activities;
|
||||
});
|
||||
}
|
||||
|
||||
// MultiSelectable<SessionActivity> _selectableSessionActivities(int id) {
|
||||
// // return select(db.sessionActivities)..limit(1, offset: 1);
|
||||
// // final query = select(db.sessionActivities).join(
|
||||
// // [
|
||||
// // innerJoin(
|
||||
// // db.activities,
|
||||
// // db.activities.id.equalsExp(db.sessionActivities.activityId),
|
||||
// // ),
|
||||
// // ],
|
||||
// // )..where(db.sessionActivities.sessionId.equals(id));
|
||||
|
||||
// // return query;
|
||||
|
||||
// final query = select(db.sessionActivities)..where((row) => row.sessionId.equals(id));
|
||||
|
||||
// query.join(
|
||||
// [
|
||||
// innerJoin(
|
||||
// db.activities,
|
||||
// db.activities.id.equalsExp(db.sessionActivities.activityId),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
|
||||
// return query;
|
||||
// }
|
||||
}
|
||||
|
3
lib/helpers/date_helpers.dart
Normal file
3
lib/helpers/date_helpers.dart
Normal file
@ -0,0 +1,3 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
13
lib/helpers/media_helpers.dart
Normal file
13
lib/helpers/media_helpers.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
|
||||
ImageProvider findMediaByType(List<MediaItem> media, String type) {
|
||||
Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
|
||||
|
||||
if (found.isNotEmpty) {
|
||||
return NetworkImage(found.first.reference);
|
||||
} else {
|
||||
// Element is not found
|
||||
return const AssetImage('assets/images/placeholder.jpg');
|
||||
}
|
||||
}
|
@ -4,8 +4,12 @@ import 'package:sendtrain/daos/activities_dao.dart';
|
||||
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||
import 'package:sendtrain/helpers/media_helpers.dart';
|
||||
import 'package:sendtrain/models/activity_timer_model.dart';
|
||||
import 'package:sendtrain/widgets/activities/activity_view.dart';
|
||||
import 'package:sendtrain/widgets/builders/dialogs.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/card_image.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
|
||||
|
||||
class ActivityCard extends StatefulWidget {
|
||||
final Activity activity;
|
||||
@ -43,49 +47,15 @@ class ActivityCardState extends State<ActivityCard> {
|
||||
: 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();
|
||||
}),
|
||||
onTap: () => showGenericDialog(
|
||||
ActivityView(activity: widget.activity), context),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
// visualDensity: VisualDensity(horizontal: VisualDensity.maximumDensity),
|
||||
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.fill,
|
||||
image:
|
||||
findMediaByType(mediaItems, 'image')),
|
||||
// color: Colors.blue,
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.elliptical(8, 8)),
|
||||
),
|
||||
)),
|
||||
leading: CardImage(
|
||||
image: findMediaByType(mediaItems, 'image')),
|
||||
title: Consumer<ActivityTimerModel>(
|
||||
builder: (context, atm, child) {
|
||||
if (atm.activity?.id == widget.activity.id) {
|
||||
@ -112,95 +82,27 @@ class ActivityCardState extends State<ActivityCard> {
|
||||
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: () => {
|
||||
ActivitiesDao(
|
||||
Provider.of<AppDatabase>(
|
||||
context,
|
||||
listen: false))
|
||||
.remove(widget.activity)
|
||||
.then((result) {
|
||||
setState(() {});
|
||||
}),
|
||||
Navigator.pop(context, 'OK')
|
||||
},
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
showRemovalDialog(
|
||||
'Activity Removal',
|
||||
'Would you like to permanently remove this activity from the current session?',
|
||||
context,
|
||||
ActivitiesDao(
|
||||
Provider.of<AppDatabase>(
|
||||
context,
|
||||
listen: false)),
|
||||
widget.activity)
|
||||
.then((result) {
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
)
|
||||
])
|
||||
// trailing: FittedBox(
|
||||
// alignment: Alignment.topCenter,
|
||||
// fit: BoxFit.fitHeight,
|
||||
// child: IconButton(
|
||||
// padding: EdgeInsets.all(0),
|
||||
// alignment: Alignment.topCenter,
|
||||
// // 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 Container(
|
||||
alignment: Alignment.center,
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
width: 50.0,
|
||||
child: CircularProgressIndicator(),
|
||||
));
|
||||
return GenericProgressIndicator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImageProvider findMediaByType(List<MediaItem> media, String type) {
|
||||
Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
|
||||
|
||||
if (found.isNotEmpty) {
|
||||
return NetworkImage(found.first.reference);
|
||||
} else {
|
||||
// Element is not found
|
||||
return const AssetImage('assets/images/placeholder.jpg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view.dart';
|
||||
|
||||
Future showSessionDialog(Session session, BuildContext parentContext) {
|
||||
Future showGenericDialog(dynamic object, BuildContext parentContext) {
|
||||
return showGeneralDialog(
|
||||
barrierColor: Colors.black.withOpacity(0.5),
|
||||
transitionDuration: const Duration(milliseconds: 220),
|
||||
@ -12,8 +10,7 @@ Future showSessionDialog(Session session, BuildContext parentContext) {
|
||||
begin: const Offset(0.0, 1.0), end: const Offset(0.0, 0.0))
|
||||
.animate(animation);
|
||||
return SlideTransition(
|
||||
position: custom,
|
||||
child: Dialog.fullscreen(child: SessionView(session: session)));
|
||||
position: custom, child: Dialog.fullscreen(child: object));
|
||||
},
|
||||
barrierDismissible: true,
|
||||
barrierLabel: '',
|
||||
|
19
lib/widgets/generic/elements/card_content.dart
Normal file
19
lib/widgets/generic/elements/card_content.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CardContent extends StatelessWidget {
|
||||
const CardContent({super.key, required this.content});
|
||||
|
||||
final String content;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListTile(
|
||||
contentPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
||||
title: Text(
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.w300),
|
||||
content),
|
||||
);
|
||||
}
|
||||
}
|
24
lib/widgets/generic/elements/card_image.dart
Normal file
24
lib/widgets/generic/elements/card_image.dart
Normal file
@ -0,0 +1,24 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CardImage extends StatelessWidget {
|
||||
const CardImage({super.key, required this.image});
|
||||
|
||||
final ImageProvider<Object> image;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
|
||||
child: Container(
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: image,
|
||||
// color: Colors.blue,
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.elliptical(8, 8)),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
16
lib/widgets/generic/elements/generic_progress_indicator.dart
Normal file
16
lib/widgets/generic/elements/generic_progress_indicator.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class GenericProgressIndicator extends StatelessWidget {
|
||||
const GenericProgressIndicator({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
width: 50.0,
|
||||
child: CircularProgressIndicator(),
|
||||
));
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/daos/sessions_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_card.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
@ -95,13 +96,7 @@ class _SessionsScreenState extends State<SessionsScreen> {
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
width: 50.0,
|
||||
child: CircularProgressIndicator(),
|
||||
));
|
||||
return GenericProgressIndicator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/daos/media_items_dao.dart';
|
||||
import 'package:sendtrain/daos/sessions_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart' hide ActivityAction;
|
||||
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||
import 'package:sendtrain/widgets/builders/dialogs.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_card_full.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_card_small.dart';
|
||||
|
||||
class SessionCard extends StatefulWidget {
|
||||
final int type;
|
||||
@ -24,11 +23,6 @@ class _SessionCardState extends State<SessionCard> {
|
||||
final Session session = widget.session;
|
||||
|
||||
initializeDateFormatting('en');
|
||||
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
||||
|
||||
Color color = (session.status == SessionStatus.started)
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: Theme.of(context).colorScheme.surfaceContainerLow;
|
||||
|
||||
return FutureBuilder<List<MediaItem>>(
|
||||
future: MediaItemsDao(Provider.of<AppDatabase>(context))
|
||||
@ -38,126 +32,13 @@ class _SessionCardState extends State<SessionCard> {
|
||||
List<MediaItem> mediaItems = snapshot.data!;
|
||||
|
||||
if (type == 0) {
|
||||
return Card(
|
||||
color: color,
|
||||
margin: const EdgeInsets.fromLTRB(15, 15, 15, 0),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
splashColor: Colors.deepPurple,
|
||||
onTap: () => showSessionDialog(session, context),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.only(left: 15),
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 8, 0, 0),
|
||||
child: Container(
|
||||
width: 60,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image:
|
||||
findMediaByType(mediaItems, 'image')),
|
||||
// color: Colors.blue,
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.elliptical(10, 10)),
|
||||
),
|
||||
)),
|
||||
title: Text(maxLines: 1, session.title.toTitleCase()),
|
||||
subtitle: Text(
|
||||
maxLines: 1,
|
||||
dateFormat.format(session.date as DateTime)),
|
||||
trailing: IconButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
alignment: Alignment.topCenter,
|
||||
icon: Icon(Icons.close_rounded),
|
||||
onPressed: () {
|
||||
showRemovalDialog(
|
||||
'Session Removal',
|
||||
'Would you like to permanently remove this session?',
|
||||
context,
|
||||
SessionsDao(Provider.of<AppDatabase>(
|
||||
context,
|
||||
listen: false)),
|
||||
session)
|
||||
.then((result) {
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
contentPadding:
|
||||
const EdgeInsets.fromLTRB(15, 0, 15, 15),
|
||||
title: Text(
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style:
|
||||
const TextStyle(fontWeight: FontWeight.w300),
|
||||
session.content),
|
||||
),
|
||||
],
|
||||
)),
|
||||
);
|
||||
return SessionCardFull(session: session, mediaItems: mediaItems);
|
||||
} else {
|
||||
return Card(
|
||||
color: color,
|
||||
child: InkWell(
|
||||
// overlayColor: MaterialStateColor(Colors.deepPurple as int),
|
||||
splashColor: Colors.deepPurple,
|
||||
borderRadius:
|
||||
const BorderRadius.all(Radius.elliptical(10, 10)),
|
||||
onTap: () => showSessionDialog(session, context),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: const Color.fromARGB(47, 0, 0, 0),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
image: DecorationImage(
|
||||
colorFilter: ColorFilter.mode(
|
||||
Color.fromARGB(220, 41, 39, 39),
|
||||
BlendMode.hardLight),
|
||||
image: findMediaByType(mediaItems, 'image'),
|
||||
fit: BoxFit.cover),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
maxLines: 3,
|
||||
session.title.toTitleCase(),
|
||||
textAlign: TextAlign.center),
|
||||
subtitle: Text(
|
||||
maxLines: 1,
|
||||
dateFormat
|
||||
.format(session.date as DateTime),
|
||||
textAlign: TextAlign.center),
|
||||
),
|
||||
])))));
|
||||
return SessionCardSmall(session: session, mediaItems: mediaItems);
|
||||
}
|
||||
} else {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
width: 50.0,
|
||||
child: CircularProgressIndicator(),
|
||||
));
|
||||
return GenericProgressIndicator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ImageProvider findMediaByType(List<MediaItem> media, String type) {
|
||||
Iterable<MediaItem>? found = media.where((m) => m.type == MediaType.image);
|
||||
|
||||
if (found.isNotEmpty) {
|
||||
return NetworkImage(found.first.reference);
|
||||
} else {
|
||||
// Element is not found
|
||||
return const AssetImage('assets/images/placeholder.jpg');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
72
lib/widgets/sessions/session_card_full.dart
Normal file
72
lib/widgets/sessions/session_card_full.dart
Normal file
@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/daos/sessions_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||
import 'package:sendtrain/helpers/date_helpers.dart';
|
||||
import 'package:sendtrain/helpers/media_helpers.dart';
|
||||
import 'package:sendtrain/widgets/builders/dialogs.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/card_content.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/card_image.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view.dart';
|
||||
|
||||
class SessionCardFull extends StatefulWidget {
|
||||
const SessionCardFull(
|
||||
{super.key, required this.session, required this.mediaItems});
|
||||
|
||||
final Session session;
|
||||
final List<MediaItem> mediaItems;
|
||||
|
||||
@override
|
||||
State<SessionCardFull> createState() => _SessionCardFullState();
|
||||
}
|
||||
|
||||
class _SessionCardFullState extends State<SessionCardFull> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Session session = widget.session;
|
||||
final List<MediaItem> mediaItems = widget.mediaItems;
|
||||
|
||||
return Card(
|
||||
color: (session.status == SessionStatus.started)
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
margin: const EdgeInsets.fromLTRB(15, 15, 15, 0),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
splashColor: Colors.deepPurple,
|
||||
onTap: () =>
|
||||
showGenericDialog(SessionView(session: session), context),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.only(left: 8),
|
||||
leading: CardImage(image: findMediaByType(mediaItems, 'image')),
|
||||
title: Text(maxLines: 1, session.title.toTitleCase()),
|
||||
subtitle: Text(
|
||||
maxLines: 1, dateFormat.format(session.date as DateTime)),
|
||||
trailing: IconButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
alignment: Alignment.topCenter,
|
||||
icon: Icon(Icons.close_rounded),
|
||||
onPressed: () {
|
||||
showRemovalDialog(
|
||||
'Session Removal',
|
||||
'Would you like to permanently remove this session?',
|
||||
context,
|
||||
SessionsDao(Provider.of<AppDatabase>(context,
|
||||
listen: false)),
|
||||
session)
|
||||
.then((result) {
|
||||
setState(() {});
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
CardContent(content: session.content)
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
62
lib/widgets/sessions/session_card_small.dart
Normal file
62
lib/widgets/sessions/session_card_small.dart
Normal file
@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||
import 'package:sendtrain/helpers/date_helpers.dart';
|
||||
import 'package:sendtrain/helpers/media_helpers.dart';
|
||||
import 'package:sendtrain/widgets/builders/dialogs.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view.dart';
|
||||
|
||||
class SessionCardSmall extends StatefulWidget {
|
||||
const SessionCardSmall(
|
||||
{super.key, required this.session, required this.mediaItems});
|
||||
|
||||
final Session session;
|
||||
final List<MediaItem> mediaItems;
|
||||
|
||||
@override
|
||||
State<SessionCardSmall> createState() => _SessionCardSmallState();
|
||||
}
|
||||
|
||||
class _SessionCardSmallState extends State<SessionCardSmall> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Session session = widget.session;
|
||||
final List<MediaItem> mediaItems = widget.mediaItems;
|
||||
|
||||
return Card(
|
||||
color: (session.status == SessionStatus.started)
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
child: InkWell(
|
||||
// overlayColor: MaterialStateColor(Colors.deepPurple as int),
|
||||
splashColor: Colors.deepPurple,
|
||||
borderRadius: const BorderRadius.all(Radius.elliptical(10, 10)),
|
||||
onTap: () => showGenericDialog(SessionView(session: session), context),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: const Color.fromARGB(47, 0, 0, 0),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
image: DecorationImage(
|
||||
colorFilter: ColorFilter.mode(
|
||||
Color.fromARGB(220, 41, 39, 39), BlendMode.hardLight),
|
||||
image: findMediaByType(mediaItems, 'image'),
|
||||
fit: BoxFit.cover),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
ListTile(
|
||||
title: Text(
|
||||
maxLines: 3,
|
||||
session.title.toTitleCase(),
|
||||
textAlign: TextAlign.center),
|
||||
subtitle: Text(
|
||||
maxLines: 1,
|
||||
dateFormat.format(session.date as DateTime),
|
||||
textAlign: TextAlign.center),
|
||||
),
|
||||
])))));
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/widgets/builders/dialogs.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/form_search_input.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/form_text_input.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view.dart';
|
||||
|
||||
class SessionCreator extends StatefulWidget {
|
||||
const SessionCreator({super.key, this.data, this.session});
|
||||
@ -123,8 +124,8 @@ class _SessionCreatorState extends State<SessionCreator> {
|
||||
createSession(_formKey.currentContext)
|
||||
.then((id) => {
|
||||
SessionsDao(db).find(id).then(
|
||||
(session) => showSessionDialog(
|
||||
session,
|
||||
(session) => showGenericDialog(
|
||||
SessionView(session: session),
|
||||
_formKey
|
||||
.currentContext!)),
|
||||
Navigator.pop(
|
||||
|
@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:sendtrain/daos/activities_dao.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/extensions/string_extensions.dart';
|
||||
import 'package:sendtrain/widgets/generic/elements/generic_progress_indicator.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view_achievements.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view_activities.dart';
|
||||
import 'package:sendtrain/widgets/sessions/session_view_media.dart';
|
||||
@ -28,12 +29,13 @@ class _SessionViewState extends State<SessionView> {
|
||||
initializeDateFormatting('en');
|
||||
final DateFormat dateFormat = DateFormat('yyyy-MM-dd');
|
||||
|
||||
return FutureBuilder<List<Activity>>(
|
||||
future: ActivitiesDao(Provider.of<AppDatabase>(context))
|
||||
.sessionActivities(session.id),
|
||||
return StreamBuilder<List<Activity>>(
|
||||
stream: ActivitiesDao(Provider.of<AppDatabase>(context))
|
||||
.watchSessionActivities(session.id),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
final activities = snapshot.data!;
|
||||
|
||||
return Scaffold(
|
||||
floatingActionButtonLocation: ExpandableFab.location,
|
||||
floatingActionButton: ExpandableFab(
|
||||
@ -100,13 +102,7 @@ class _SessionViewState extends State<SessionView> {
|
||||
],
|
||||
));
|
||||
} else {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: SizedBox(
|
||||
height: 50.0,
|
||||
width: 50.0,
|
||||
child: CircularProgressIndicator(),
|
||||
));
|
||||
return GenericProgressIndicator();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2,21 +2,27 @@ import 'package:flutter/material.dart';
|
||||
import 'package:sendtrain/database/database.dart';
|
||||
import 'package:sendtrain/widgets/activities/activity_card.dart';
|
||||
|
||||
class SessionViewActivities extends StatelessWidget {
|
||||
class SessionViewActivities extends StatefulWidget {
|
||||
const SessionViewActivities({super.key, required this.activities });
|
||||
|
||||
final List<Activity> activities;
|
||||
|
||||
@override
|
||||
State<SessionViewActivities> createState() => _SessionViewActivitiesState();
|
||||
}
|
||||
|
||||
class _SessionViewActivitiesState extends State<SessionViewActivities> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: ListView.builder(
|
||||
// shrinkWrap: true,
|
||||
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
||||
itemCount: activities.length,
|
||||
itemCount: widget.activities.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ActivityCard(
|
||||
activity: activities[index]);
|
||||
activity: widget.activities[index]);
|
||||
},
|
||||
));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user