2022-08-27 15:58:36 +02:00
|
|
|
import { useNuiEvent } from '../../../hooks/useNuiEvent';
|
|
|
|
|
import { Box, Text, Flex, ScaleFade } from '@chakra-ui/react';
|
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
|
import { ContextMenuProps } from '../../../interfaces/context';
|
|
|
|
|
import Item from './Item';
|
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
|
|
import { fetchNui } from '../../../utils/fetchNui';
|
2022-03-27 18:17:26 +02:00
|
|
|
|
2022-03-28 16:49:07 +02:00
|
|
|
const openMenu = (id: string | undefined) => {
|
2022-08-27 15:58:36 +02:00
|
|
|
fetchNui<ContextMenuProps>('openContext', id);
|
2022-03-28 16:49:07 +02:00
|
|
|
};
|
|
|
|
|
|
2022-03-27 18:17:26 +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: [] } },
|
2022-03-27 18:17:26 +02:00
|
|
|
});
|
|
|
|
|
|
2022-07-25 21:32:11 +02:00
|
|
|
const closeContext = () => {
|
|
|
|
|
setVisible(false);
|
2022-08-27 15:58:36 +02:00
|
|
|
fetchNui('closeContext');
|
2022-07-25 21:32:11 +02:00
|
|
|
};
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
2022-03-27 18:17:26 +02:00
|
|
|
setContextMenu(data);
|
|
|
|
|
setVisible(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
2022-08-27 15:58:36 +02:00
|
|
|
<Flex position="absolute" w="75%" h="80%" justifyContent="flex-end" alignItems="center">
|
2022-03-27 18:17:26 +02:00
|
|
|
<ScaleFade in={visible} unmountOnExit>
|
|
|
|
|
<Box w="xs" h={580}>
|
2022-03-28 16:49:07 +02:00
|
|
|
<Flex justifyContent="center" alignItems="center" mb={3}>
|
|
|
|
|
{contextMenu.menu && (
|
2022-07-07 14:33:53 +02:00
|
|
|
<Flex
|
2022-03-28 16:49:07 +02:00
|
|
|
borderRadius="md"
|
|
|
|
|
bg="gray.800"
|
|
|
|
|
flex="1 15%"
|
2022-07-07 14:33:53 +02:00
|
|
|
alignSelf="stretch"
|
2022-03-28 16:49:07 +02:00
|
|
|
textAlign="center"
|
2022-07-07 14:33:53 +02:00
|
|
|
justifyContent="center"
|
|
|
|
|
alignItems="center"
|
2022-03-28 16:49:07 +02:00
|
|
|
marginRight={2}
|
|
|
|
|
p={2}
|
2022-08-27 15:58:36 +02:00
|
|
|
_hover={{ bg: 'gray.700' }}
|
2022-03-28 16:49:07 +02:00
|
|
|
transition="300ms"
|
|
|
|
|
onClick={() => openMenu(contextMenu.menu)}
|
|
|
|
|
>
|
|
|
|
|
<FontAwesomeIcon icon="chevron-left" />
|
2022-07-07 14:33:53 +02:00
|
|
|
</Flex>
|
2022-03-28 16:49:07 +02:00
|
|
|
)}
|
|
|
|
|
<Box borderRadius="md" bg="gray.800" flex="1 85%">
|
2022-08-27 15:58:36 +02:00
|
|
|
<Text fontFamily="Poppins" fontSize="md" p={2} textAlign="center" fontWeight="light">
|
2022-03-28 16:49:07 +02:00
|
|
|
{contextMenu.title}
|
|
|
|
|
</Text>
|
|
|
|
|
</Box>
|
2022-07-25 21:32:11 +02:00
|
|
|
<Flex
|
|
|
|
|
borderRadius="md"
|
|
|
|
|
bg="gray.800"
|
|
|
|
|
flex="1 15%"
|
|
|
|
|
alignSelf="stretch"
|
|
|
|
|
textAlign="center"
|
|
|
|
|
justifyContent="center"
|
|
|
|
|
alignItems="center"
|
|
|
|
|
marginLeft={2}
|
|
|
|
|
p={2}
|
2022-08-27 15:58:36 +02:00
|
|
|
_hover={{ bg: 'gray.700' }}
|
2022-07-25 21:32:11 +02:00
|
|
|
transition="300ms"
|
|
|
|
|
onClick={() => closeContext()}
|
|
|
|
|
>
|
|
|
|
|
<FontAwesomeIcon icon="xmark" fontSize={20} />
|
|
|
|
|
</Flex>
|
2022-03-28 16:49:07 +02:00
|
|
|
</Flex>
|
2022-03-27 18:17:26 +02:00
|
|
|
<Box maxH={560} overflowY="scroll">
|
|
|
|
|
{Object.entries(contextMenu.options).map((option, index) => (
|
|
|
|
|
<Item option={option} key={`context-item-${index}`} />
|
|
|
|
|
))}
|
|
|
|
|
</Box>
|
|
|
|
|
</Box>
|
|
|
|
|
</ScaleFade>
|
|
|
|
|
</Flex>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default ContextMenu;
|