summaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/modals/hooks.tsx
blob: 2b9b4c13692937da8f13a1e212275613f336e271 (plain)
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { useCallback, useContext, useMemo } from "react";
import { useDidUpdate } from "rooks";
import { log } from "utilities/logger";
import { ModalContext } from "./provider";

interface ModalInformation<T> {
  isShow: boolean;
  payload: T | null;
  closeModal: ReturnType<typeof useCloseModal>;
}

export function useModalInformation<T>(key: string): ModalInformation<T> {
  const isShow = useIsModalShow(key);
  const payload = useModalPayload<T>(key);
  const closeModal = useCloseModal();

  return useMemo(
    () => ({
      isShow,
      payload,
      closeModal,
    }),
    [isShow, payload, closeModal]
  );
}

export function useShowModal() {
  const {
    control: { push },
  } = useContext(ModalContext);

  return useCallback(
    <T,>(key: string, payload?: T) => {
      log("info", `modal ${key} sending payload`, payload);

      push({ key, payload });
    },
    [push]
  );
}

export function useCloseModal() {
  const {
    control: { pop },
  } = useContext(ModalContext);
  return useCallback(
    (key?: string) => {
      pop(key);
    },
    [pop]
  );
}

export function useIsModalShow(key: string) {
  const {
    control: { peek },
  } = useContext(ModalContext);
  const modal = peek();
  return key === modal?.key;
}

export function useOnModalShow<T>(
  callback: (payload: T | null) => void,
  key: string
) {
  const {
    modals,
    control: { peek },
  } = useContext(ModalContext);
  useDidUpdate(() => {
    const modal = peek();
    if (modal && modal.key === key) {
      callback(modal.payload ?? null);
    }
  }, [modals.length, key]);
}

export function useModalPayload<T>(key: string): T | null {
  const {
    control: { peek },
  } = useContext(ModalContext);
  return useMemo(() => {
    const modal = peek();
    if (modal && modal.key === key) {
      return (modal.payload as T) ?? null;
    } else {
      return null;
    }
  }, [key, peek]);
}