fix: various improvements to events list

This commit is contained in:
Michael Thomas 2023-02-09 20:03:16 -05:00
parent d0d881fbbe
commit 2052e618ac
4 changed files with 111 additions and 164 deletions

View File

@ -19,10 +19,21 @@ class EventsService {
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
final eventsJson = jsonDecode(response.body);
return (eventsJson["results"] as List<dynamic>).map((event) =>
AthleticsEvent.fromJson(event)
);
try {
final eventsJson = jsonDecode(response.body);
if (eventsJson["results"] != null) {
return (eventsJson["results"] as List<dynamic>).map((event) =>
AthleticsEvent.fromJson(event)
);
} else {
return [];
}
} catch (e) {
throw
"Failed to parse athletics event data."
"\n"
"Exception: $e";
}
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
@ -37,14 +48,26 @@ class EventsService {
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
final eventsJson = jsonDecode(response.body);
return (eventsJson["results"] as List<dynamic>).map((event) =>
ClpEvent.fromJson(event)
);
try {
final eventsJson = jsonDecode(response.body);
if (eventsJson["results"] != null) {
return (eventsJson["results"] as List<dynamic>).map((event) =>
ClpEvent.fromJson(event)
);
} else {
return [];
}
} catch (e) {
throw
"Failed to parse CLP event data."
"\n"
"Exception: $e";
}
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load athletics events.');
throw Exception('Failed to load CLP events.');
}
}
}

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:furman_now/src/services/events/event.dart';
import 'package:furman_now/src/utils/theme.dart';
import 'package:furman_now/src/widgets/events/event_modal.dart';
import 'package:furman_now/src/widgets/text_with_icon.dart';
import 'package:intl/intl.dart';
class EventCard extends StatelessWidget {
@ -33,12 +34,6 @@ class EventCard extends StatelessWidget {
context,
event,
);
// showModalBottomSheet<void>(
// context: context,
// builder: (BuildContext context) {
// return EventModal(event: event);
// }
// );
},
child: Container(
decoration: const BoxDecoration(
@ -53,8 +48,11 @@ class EventCard extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(eventHour, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w700))),
Text(eventAmPm, style: Theme.of(context).textTheme.subtitle2),
Text(eventHour, style: furmanTextStyle(TextStyle(
color: Colors.grey[800],
fontWeight: FontWeight.w700
))),
Text(eventAmPm, style: Theme.of(context).textTheme.labelMedium),
],
),
),
@ -69,35 +67,19 @@ class EventCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(event.title, style: furmanTextStyle(const TextStyle(fontWeight: FontWeight.w600))),
Text(event.title, style: Theme.of(context).textTheme.titleSmall),
const SizedBox(height: 6),
RichText(text: TextSpan(
style: Theme.of(context).textTheme.subtitle2,
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(right: 5.0),
child: Icon(Icons.place_outlined, size: 20, color: Colors.grey[500])
),
),
TextSpan(text: event.location),
],
)),
TextWithIcon(
icon: Icons.place_outlined,
text: event.location,
size: TextWithIconSize.small,
),
const SizedBox(height: 2),
RichText(text: TextSpan(
style: Theme.of(context).textTheme.subtitle2,
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(left: 1.0, right: 6.0),
child: Icon(Icons.sell_outlined, size: 18, color: Colors.grey[500])
),
),
TextSpan(text: event.category),
],
)),
TextWithIcon(
icon: Icons.sell_outlined,
text: event.category,
size: TextWithIconSize.small,
),
],
),
),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:furman_now/src/services/events/event.dart';
import 'package:furman_now/src/services/events/events_service.dart';
import 'package:furman_now/src/widgets/text_with_icon.dart';
import 'package:intl/intl.dart';
void showEventsModal(BuildContext context, Event event) {
@ -31,16 +32,19 @@ class _EventModalState extends State<_EventModal> {
BoxConstraints? _parentConstraints;
final _key = GlobalKey();
double _maxChildHeight = 0.75;
static const _maxDialogHeight = 0.8;
var _maxChildHeight = _maxDialogHeight;
void updateMaxHeight() {
if (_parentConstraints != null) {
var listHeight = _key.currentContext?.size?.height;
var parentHeight = _parentConstraints?.maxHeight;
if (listHeight != null && parentHeight != null) {
var maxHeight = (listHeight + 50) / parentHeight;
var maxHeight = (listHeight + 70) / parentHeight;
setState(() {
_maxChildHeight = (maxHeight < 0.75) ? maxHeight : 0.75;
_maxChildHeight = (maxHeight < _maxDialogHeight)
? maxHeight : _maxDialogHeight;
});
}
}
@ -78,11 +82,13 @@ class _EventModalState extends State<_EventModal> {
child: CloseButton(),
),
Flexible(
child: NotificationListener<OverscrollIndicatorNotification>(
onNotification: (OverscrollIndicatorNotification overscroll) {
overscroll.disallowIndicator();
return true;
},
child: NotificationListener
<OverscrollIndicatorNotification>(
onNotification:
(OverscrollIndicatorNotification overscroll) {
overscroll.disallowIndicator();
return true;
},
child: _EventModalContent(
key: _key,
controller: controller,
@ -123,120 +129,55 @@ class _EventModalContent extends StatelessWidget {
// Title
Text(
event.title,
style: Theme.of(context).textTheme.headline1,
style: Theme.of(context).textTheme.headlineLarge,
),
const SizedBox(height: 10),
// Location
RichText(text: TextSpan(
style: Theme.of(context).textTheme.subtitle1,
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(right: 5.0),
child: Icon(
Icons.place_outlined, size: 24,
color: Colors.grey[500])
),
),
TextSpan(text: event.location),
],
)),
TextWithIcon(
icon: Icons.place_outlined,
text: event.location,
),
const SizedBox(height: 5),
if (event is ClpEvent) ...[
// Organization
RichText(text: TextSpan(
style: Theme.of(context).textTheme.subtitle1,
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(right: 5.0),
child: Icon(
Icons.group_outlined,
size: 24,
color: Colors.grey[500]
),
),
),
TextSpan(text: (event as ClpEvent).organization),
],
)),
const SizedBox(height: 5),
// Time
RichText(text: TextSpan(
style: Theme.of(context).textTheme.subtitle1,
children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Padding(
padding: const EdgeInsets.only(
right: 5.0),
child: Icon(
Icons.access_time_outlined,
size: 24,
color: Colors.grey[500])
),
),
WidgetSpan(
alignment: PlaceholderAlignment.top,
child: Column(
crossAxisAlignment: CrossAxisAlignment
.start,
children: [
Text(
DateFormat("EEEE, MMMM d")
.format(
(event as ClpEvent)
.startTime),
style: Theme
.of(context)
.textTheme
.subtitle1,
),
Text(
"${DateFormat.jm().format(
(event as ClpEvent)
.startTime)} - ${DateFormat
.jm().format(
(event as ClpEvent)
.endTime)}",
style: Theme
.of(context)
.textTheme
.subtitle1,
),
],
)
),
],
)),
const SizedBox(height: 5),
// Description
Row(
crossAxisAlignment: CrossAxisAlignment
.start,
children: [
Padding(
padding: const EdgeInsets.only(
right: 5.0),
child: Icon(Icons.notes, size: 24,
color: Colors
.grey[500])
),
Flexible(
child: Text(
(event as ClpEvent)
.description,
style: Theme
.of(context)
.textTheme
.subtitle1,
),
),
],
),
]
// Additional info for CLP events
if (event is ClpEvent) ...(() {
final clpEvent = event as ClpEvent;
return [
// Organization
TextWithIcon(
icon: Icons.group_outlined,
text: clpEvent.organization
),
const SizedBox(height: 5),
// Time
TextWithIcon(
icon: Icons.access_time_outlined,
text:
"${DateFormat("EEEE, MMMM d").format(clpEvent.startTime)}"
"\n"
"${DateFormat.jm().format(clpEvent.startTime)} - ${DateFormat.jm().format(clpEvent.endTime)}",
),
const SizedBox(height: 5),
// Description
TextWithIcon(
icon: Icons.notes,
text: clpEvent.description
),
];
})(),
// Additional info for Athletics Events
if (event is AthleticsEvent) ...(() {
final athleticsEvent = event as AthleticsEvent;
return [
// Time
TextWithIcon(
icon: Icons.access_time_outlined,
text:
"${DateFormat("EEEE, MMMM d").format(athleticsEvent.time)}"
"\n"
"${DateFormat.jm().format(athleticsEvent.time)}",
),
];
})(),
],
);
}

View File

@ -20,9 +20,10 @@ class EventsList extends StatefulWidget {
}) {
if (dateRange == null) {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
// final today = DateTime(now.year, now.month, now.day);
final tonight = DateTime(now.year, now.month, now.day, 23, 59, 59);
dateRange = DateTimeRange(start: today, end: tonight);
// dateRange = DateTimeRange(start: today, end: tonight);
dateRange = DateTimeRange(start: now, end: tonight);
}
return EventsList._(
dateRange: dateRange,