From 3251eca91f8199058cf47cb8e6fe336a3015a48c Mon Sep 17 00:00:00 2001 From: Harvey Date: Sat, 28 Mar 2026 17:19:19 -0400 Subject: [PATCH] feat(notif): Swipe to delete notifs on map screen Add swipe to delete functionality to reminder cards displayed on the maps screen. Users can swipe left on any reminder to delete it. Still needs to be changed to round edges for the UI. Change was added as there was no easy way to delete reminders prior to this. --- lib/widgets/reminder_widgets.dart | 56 ++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/widgets/reminder_widgets.dart b/lib/widgets/reminder_widgets.dart index dcb1948..41d92c3 100644 --- a/lib/widgets/reminder_widgets.dart +++ b/lib/widgets/reminder_widgets.dart @@ -207,11 +207,55 @@ class _ReminderWidgetsState extends State { ), ); children.addAll( + // the dismissible widgets that show each reminder, swiping left deletes the reminder reminders.map( - (r) => ReminderWidget( - rtid: r.rtid, - stopName: getStopNameFromID(r.stpid), - eta: r.eta, + (r) => Dismissible( + key: Key('${r.stpid}|${r.rtid}'), + direction: DismissDirection.endToStart, + // the red background with the trash/delete icon that shows when swiping + background: Container( + color: Colors.red, // red background for delete action + alignment: Alignment.centerRight, + padding: EdgeInsets.only(right: 20.0), + child: Icon(Icons.delete, color: Colors.white), // white trash icon + ), + // when the user swipes enough to dismiss + // try to remove the reminder from the service + // if it fails put the widget back + confirmDismiss: (direction) async { + try { + await IncomingBusReminderService.removeReminder( + r.stpid, + r.rtid, + ); + return true; + } catch (e) { + if (kDebugMode) { + print('Failed to remove reminder: $e'); + } + return false; + } + }, + // if the reminder was successfully removed from the service + // also remove it from the local list so the widget disappears immediately + onDismissed: (_) { + // Remove from local list immediately so the dismissed + // widget leaves the tree before the async refresh. + setState(() { + reminders.removeWhere( + (x) => x.stpid == r.stpid && x.rtid == r.rtid, + ); + }); + _resetDataFuture(); + }, + // the actual reminder widget + child: ReminderWidget( + stpid: r.stpid, + rtid: r.rtid, + stopName: getStopNameFromID(r.stpid), + eta: r.eta, + onDismissed: _resetDataFuture, + ), ), ), ); @@ -231,14 +275,18 @@ class _ReminderWidgetsState extends State { class ReminderWidget extends StatelessWidget { const ReminderWidget({ super.key, + required this.stpid, required this.rtid, required this.stopName, required this.eta, + this.onDismissed, }); + final String stpid; final String rtid; final String stopName; final int? eta; + final VoidCallback? onDismissed; // called when the reminder is dismissed @override Widget build(BuildContext context) {