Files
ox_lib/web/src/features/menu/context/ContextMenu.tsx

79 lines
2.6 KiB
TypeScript
Raw Normal View History

2022-08-27 15:58:36 +02:00
import { useNuiEvent } from '../../../hooks/useNuiEvent';
import { Box, Stack, Text, Flex, Transition } from '@mantine/core';
2022-08-27 15:58:36 +02:00
import { useEffect, useState } from 'react';
import { ContextMenuProps } from '../../../interfaces/context';
import ContextButton from './components/ContextButton';
2022-08-27 15:58:36 +02:00
import { fetchNui } from '../../../utils/fetchNui';
import ReactMarkdown from 'react-markdown';
import HeaderButton from './components/HeaderButton';
2022-12-31 15:03:16 +01:00
import ScaleFade from '../../../transitions/ScaleFade';
2022-03-28 16:49:07 +02:00
const openMenu = (id: string | undefined) => {
2022-11-06 11:01:39 +01:00
fetchNui<ContextMenuProps>('openContext', { id: id, back: true });
2022-03-28 16:49:07 +02:00
};
const ContextMenu: React.FC = () => {
const [visible, setVisible] = useState(false);
2022-03-28 16:49:07 +02:00
const [contextMenu, setContextMenu] = useState<ContextMenuProps>({
2022-08-27 15:58:36 +02:00
title: '',
options: { '': { description: '', metadata: [] } },
});
const closeContext = () => {
if (contextMenu.canClose === false) return;
setVisible(false);
2022-08-27 15:58:36 +02:00
fetchNui('closeContext');
};
2022-04-01 21:22:14 +02:00
// Hides the context menu on ESC
useEffect(() => {
if (!visible) return;
const keyHandler = (e: KeyboardEvent) => {
2022-08-27 15:58:36 +02:00
if (['Escape'].includes(e.code)) closeContext();
2022-04-01 21:22:14 +02:00
};
2022-08-27 15:58:36 +02:00
window.addEventListener('keydown', keyHandler);
2022-04-01 21:22:14 +02:00
2022-08-27 15:58:36 +02:00
return () => window.removeEventListener('keydown', keyHandler);
2022-04-01 21:22:14 +02:00
}, [visible]);
2022-08-27 15:58:36 +02:00
useNuiEvent('hideContext', () => setVisible(false));
2022-04-01 21:22:14 +02:00
2022-08-27 15:58:36 +02:00
useNuiEvent<ContextMenuProps>('showContext', async (data) => {
2022-03-28 16:49:07 +02:00
if (visible) {
setVisible(false);
await new Promise((resolve) => setTimeout(resolve, 100));
}
setContextMenu(data);
setVisible(true);
});
return (
2022-12-31 15:03:16 +01:00
<Box sx={{ position: 'absolute', top: '15%', right: '25%' }} w={320} h={580}>
<ScaleFade visible={visible}>
<Flex justify="center" align="center" mb={10} gap={6}>
{contextMenu.menu && (
<HeaderButton icon="chevron-left" iconSize={16} handleClick={() => openMenu(contextMenu.menu)} />
)}
<Box sx={{ borderRadius: 4, flex: '1 85%' }} bg="dark.6">
<Text color="dark.0" p={6} align="center">
<ReactMarkdown>{contextMenu.title}</ReactMarkdown>
</Text>
</Box>
2022-12-31 15:03:16 +01:00
<HeaderButton icon="xmark" canClose={contextMenu.canClose} iconSize={18} handleClick={closeContext} />
</Flex>
<Box sx={{ height: 560, overflowY: 'scroll' }}>
<Stack spacing={3}>
{Object.entries(contextMenu.options).map((option, index) => (
<ContextButton option={option} key={`context-item-${index}`} />
))}
</Stack>
</Box>
2022-12-31 15:03:16 +01:00
</ScaleFade>
</Box>
);
};
export default ContextMenu;