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

106 lines
3.3 KiB
TypeScript
Raw Normal View History

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-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
};
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 = () => {
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-08-27 15:58:36 +02:00
<Flex position="absolute" w="75%" h="80%" justifyContent="flex-end" alignItems="center">
<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 && (
<Flex
2022-03-28 16:49:07 +02:00
borderRadius="md"
bg="gray.800"
flex="1 15%"
alignSelf="stretch"
2022-03-28 16:49:07 +02:00
textAlign="center"
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" />
</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>
<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' }}
transition="300ms"
onClick={() => closeContext()}
>
<FontAwesomeIcon icon="xmark" fontSize={20} />
</Flex>
2022-03-28 16:49:07 +02:00
</Flex>
<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;