| | | 1 | | import { getSession, updateSession } from "~/lib/session.server"; |
| | | 2 | | import type { ToastInput } from "~/lib/toasts"; |
| | | 3 | | |
| | | 4 | | /** |
| | | 5 | | * Queue a toast on the user's session. Drained on the next loader run so the |
| | | 6 | | * message survives a redirect (where useActionData() does not). |
| | | 7 | | */ |
| | 0 | 8 | | export async function pushFlash(request: Request, flash: ToastInput): Promise<void> { |
| | 0 | 9 | | const session = await getSession(request); |
| | 0 | 10 | | if (!session) return; // unauthenticated requests can't carry flash messages |
| | 0 | 11 | | const next = [...(session.data.flashes ?? []), flash]; |
| | 0 | 12 | | await updateSession(session.sid, { ...session.data, flashes: next }); |
| | | 13 | | } |
| | | 14 | | |
| | | 15 | | /** |
| | | 16 | | * Read and clear pending flashes from the session. Call once per top-level |
| | | 17 | | * loader (root) so a single message is not delivered twice. |
| | | 18 | | */ |
| | 0 | 19 | | export async function drainFlashes(request: Request): Promise<readonly ToastInput[]> { |
| | 0 | 20 | | const session = await getSession(request); |
| | 0 | 21 | | if (!session) return []; |
| | 0 | 22 | | const flashes = session.data.flashes ?? []; |
| | 0 | 23 | | if (flashes.length === 0) return flashes; |
| | 0 | 24 | | await updateSession(session.sid, { ...session.data, flashes: [] }); |
| | 0 | 25 | | return flashes; |
| | | 26 | | } |