xref: /MusicFree/src/components/panels/usePanel.ts (revision b882a19d884fffa32f7c8cef31652b909dceaa0f)
1import {BottomSheetMethods} from '@gorhom/bottom-sheet/lib/typescript/types';
2import {atom, useAtom} from 'jotai';
3import {MutableRefObject, useEffect, useRef} from 'react';
4import {BackHandler, NativeEventSubscription} from 'react-native';
5import panels from './types';
6
7type IPanel = typeof panels;
8type IPanelkeys = keyof IPanel;
9
10const panelNameAtom = atom<IPanelkeys | null>(null);
11const payloadAtom = atom<any>(null);
12
13export function _usePanel(
14    ref?: MutableRefObject<BottomSheetMethods | undefined | null>,
15) {
16    const [panelName, setPanelName] = useAtom(panelNameAtom);
17    const [payload, setPayload] = useAtom(payloadAtom);
18    const backHandlerRef = useRef<NativeEventSubscription>();
19
20    function showPanel<T extends IPanelkeys>(
21        name: T,
22        payload?: Parameters<IPanel[T]>[0],
23    ) {
24        setPanelName(name);
25        setPayload(payload);
26    }
27
28    useEffect(() => {
29        if (backHandlerRef.current) {
30            backHandlerRef.current?.remove();
31            backHandlerRef.current = undefined;
32        }
33        if (ref) {
34            backHandlerRef.current = BackHandler.addEventListener(
35                'hardwareBackPress',
36                () => {
37                    ref.current?.close();
38                    return true;
39                },
40            );
41        }
42        return () => {
43            if (backHandlerRef.current) {
44                backHandlerRef.current?.remove();
45                backHandlerRef.current = undefined;
46            }
47        };
48    }, []);
49
50    function unmountPanel() {
51        setPanelName(null);
52        setPayload(null);
53    }
54
55    return {payload, panelName, showPanel, unmountPanel};
56}
57
58export default function usePanel() {
59    const {showPanel, unmountPanel} = _usePanel();
60    return {showPanel, unmountPanel};
61}
62