Deletion Toast
Toast notification for record deletion with undo support.
Appearance
- Position: Bottom of screen
- Contains: Trash icon, “Deleted” text, countdown timer
- “Undo” button to restore record
Behavior
- Appears when
softDeleteRecord()is called: the Delete button of the record editor, the cancel (x) button of a running timer, or the x button of a row in the mini timer window - The record is removed from storage right away; the toast is only the undo window, not a deferred delete
- The record’s image files stay on disk for the undo window (
TimeTrackingService.deleteRecord(_:keepingImages: true)) so that Undo restores them with the record - Shows a 60-second countdown and disappears when it reaches zero (a 1-second timer in
AppStatecallsexpirePendingDeletions) - Swiping the toast down more than 50 pt dismisses it early (
confirmDelete()) - The kept image files are purged (
purgeImages(of:)) when the deletion becomes final: on expiry, on swipe-dismiss, or when the storage folder is switched (reinitializeStorage()drops all toasts) - One pending entry per record: a second delete of the same record while the first is in flight or still pending is ignored
If the app quits inside the 60-second window, the record stays deleted and its image files remain as orphans. minuta doctor reports them in its image integrity check, see the CLI reference. The same happens to a file that cannot be removed during the purge.
Animation
- Animated entrance (slide up + fade)
- Animated exit (slide down + fade)
- Multiple deletions stack vertically
Implementation
Components:
DeletionToastView: Single toastDeletionToastContainer: Manages multiple toasts
Undo Flow
- User deletes a record (editor Delete button, running timer cancel, mini window x)
- Record is deleted from storage and removed from the lists; its image files are kept
- Toast appears with countdown
- User taps “Undo”
- The pending entry is taken out of the list and the record is saved again (
trackingService.restoreRecord, notupdateRecord: storage no longer holds the record, andupdateRecordrefuses a record it cannot find while a month file is unreadable), which puts it back in the month of its start time next to the kept image files - Record is put back into
todayRecordsonly if it starts today (the rule ofgetTodayRecords), and intorunningTimersif it was running; toast dismissed AppState.historyRevisionis bumped andContentViewreloads the History list, which dropped the record when it was deleted
Whoever removes the pending entry first decides the outcome: if expiry or a swipe already took it, Undo does nothing. If the save fails, the entry goes back into the list so Undo can be retried and the image files are still purged on expiry.
Related
- 403-app-state -
softDeleteRecord(),undoDelete(),confirmDelete() - 407-history-section - Triggers deletion
- 402-ios - Toast container
- 417-error-toast - A failed Undo is reported there