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,
  };
}