"use client" import { useEffect, useRef, useState } from "react" import { Ban, Loader2, Send } from "lucide-react" import { toast } from "sonner" const DEFAULT_DURATION_MS = 3000 type RefBox = { current: T } export function showPendingSendToast(options: { durationMs?: number onCommit: () => void | Promise onCancel: () => void }) { const durationMs = options.durationMs ?? DEFAULT_DURATION_MS const committedRef: RefBox = { current: false } const timerRef: RefBox = { current: null, } toast.custom( (toastId) => ( ), { duration: Infinity, onDismiss: () => { if (timerRef.current != null) { clearTimeout(timerRef.current) timerRef.current = null } if (!committedRef.current) { committedRef.current = true options.onCancel() } }, } ) } function PendingSendToastBody({ toastId, durationMs, committedRef, timerRef, onCommit, onCancel, }: { toastId: string | number durationMs: number committedRef: RefBox timerRef: RefBox onCommit: () => void | Promise onCancel: () => void }) { const onCommitRef = useRef(onCommit) const onCancelRef = useRef(onCancel) onCommitRef.current = onCommit onCancelRef.current = onCancel const [barImmediate, setBarImmediate] = useState(false) const commitNowRef = useRef<(opts?: { manual?: boolean }) => void>(() => {}) commitNowRef.current = (opts?: { manual?: boolean }) => { if (committedRef.current) return if (opts?.manual) setBarImmediate(true) committedRef.current = true if (timerRef.current != null) { clearTimeout(timerRef.current) timerRef.current = null } void (async () => { try { await onCommitRef.current() toast.success("Message envoyé") } catch { toast.error("L'envoi a échoué") onCancelRef.current() } finally { toast.dismiss(toastId) } })() } useEffect(() => { timerRef.current = window.setTimeout(() => { commitNowRef.current() }, durationMs) return () => { if (timerRef.current != null) { clearTimeout(timerRef.current) timerRef.current = null } } }, [durationMs, timerRef]) const handleSendNow = () => { commitNowRef.current({ manual: true }) } const handleCancel = () => { if (committedRef.current) return committedRef.current = true if (timerRef.current != null) { clearTimeout(timerRef.current) timerRef.current = null } onCancelRef.current() toast.dismiss(toastId) } return (

Envoi en cours…

) }