File size: 1,668 Bytes
f0743f4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import { useAtom } from 'jotai';
import { useRef, useEffect } from 'react';
import type { TShowToast } from '~/common';
import { NotificationSeverity } from '~/common';
import { toastState, type ToastState } from '~/store';
export default function useToast(showDelay = 100) {
const [toast, setToast] = useAtom(toastState);
const showTimerRef = useRef<number | null>(null);
const hideTimerRef = useRef<number | null>(null);
useEffect(() => {
return () => {
if (showTimerRef.current !== null) {
clearTimeout(showTimerRef.current);
}
if (hideTimerRef.current !== null) {
clearTimeout(hideTimerRef.current);
}
};
}, []);
const showToast = ({
message,
severity = NotificationSeverity.SUCCESS,
showIcon = true,
duration = 3000, // default duration for the toast to be visible
status,
}: TShowToast) => {
// Clear existing timeouts
if (showTimerRef.current !== null) {
clearTimeout(showTimerRef.current);
}
if (hideTimerRef.current !== null) {
clearTimeout(hideTimerRef.current);
}
// Timeout to show the toast
showTimerRef.current = window.setTimeout(() => {
setToast({
open: true,
message,
severity: (status as NotificationSeverity) ?? severity,
showIcon,
});
// Hides the toast after the specified duration
hideTimerRef.current = window.setTimeout(() => {
setToast((prevToast: ToastState) => ({ ...prevToast, open: false }));
}, duration);
}, showDelay);
};
return {
toast,
onOpenChange: (open: boolean) => setToast({ ...toast, open }),
showToast,
};
}
|