diff --git a/resource/interface/context/client.lua b/resource/interface/context/client.lua new file mode 100644 index 0000000..5bde37f --- /dev/null +++ b/resource/interface/context/client.lua @@ -0,0 +1,42 @@ +local contextMenus = {} + +local function showContext(id) + local data = contextMenus[id] + SetNuiFocus(true, true) + SendNUIMessage({ + action = 'showContext', + data = { + title = data.title, + menu = data.menu, + options = data.options + } + }) +end + +local function registerContext(context) + for k, v in pairs(context) do + if type(k) == 'number' then + contextMenus[v.id] = v + else + contextMenus[context.id] = context + break + end + end +end + +RegisterNUICallback('openContext', function(id) + showContext(id) +end) + +RegisterNUICallback('clickContext', function(data) + if data.event then TriggerEvent(data.event, data.args) end + if data.serverEvent then TriggerServerEvent(data.serverEvent, data.args) end + SetNuiFocus(false, false) + SendNUIMessage({ + action = 'hideContext' + }) +end) + +RegisterNUICallback('closeContext', function() + SetNuiFocus(false, false) +end) diff --git a/web/src/components/features/menu/ContextMenu.tsx b/web/src/components/features/menu/ContextMenu.tsx index 5e92600..0b75c23 100644 --- a/web/src/components/features/menu/ContextMenu.tsx +++ b/web/src/components/features/menu/ContextMenu.tsx @@ -1,7 +1,7 @@ import { useNuiEvent } from "../../../hooks/useNuiEvent"; import { Box, Text, Flex, ScaleFade } from "@chakra-ui/react"; import { debugData } from "../../../utils/debugData"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { ContextMenuProps } from "../../../interfaces"; import Item from "./Item"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -52,6 +52,24 @@ const ContextMenu: React.FC = () => { options: { "": { description: "", metadata: [] } }, }); + // Hides the context menu on ESC + useEffect(() => { + if (!visible) return; + + const keyHandler = (e: KeyboardEvent) => { + if (["Escape"].includes(e.code)) { + setVisible(false); + fetchNui("closeContext"); + } + }; + + window.addEventListener("keydown", keyHandler); + + return () => window.removeEventListener("keydown", keyHandler); + }, [visible]); + + useNuiEvent("hideContext", () => setVisible(false)); + useNuiEvent("showContext", async (data) => { if (visible) { setVisible(false); diff --git a/web/src/components/features/menu/Item.tsx b/web/src/components/features/menu/Item.tsx index f25d71d..8e52447 100644 --- a/web/src/components/features/menu/Item.tsx +++ b/web/src/components/features/menu/Item.tsx @@ -13,13 +13,18 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Option, ContextMenuProps } from "../../../interfaces"; import { fetchNui } from "../../../utils/fetchNui"; +interface DataProps { + event?: string; + serverEvent?: string; + args?: any; +} + const openMenu = (id: string | undefined) => { fetchNui("openContext", id); }; -const clickContext = () => { - // todo - fetchNui("clickContext"); +const clickContext = (data: DataProps) => { + fetchNui("clickContext", data); }; const Item: React.FC<{ @@ -49,7 +54,13 @@ const Item: React.FC<{ - option[1].menu ? openMenu(option[1].menu) : clickContext() + option[1].menu + ? openMenu(option[1].menu) + : clickContext({ + event: option[1].event, + serverEvent: option[1].serverEvent, + args: option[1].args, + }) } > diff --git a/web/src/interfaces/index.tsx b/web/src/interfaces/index.tsx index 8c46d9f..8e39429 100644 --- a/web/src/interfaces/index.tsx +++ b/web/src/interfaces/index.tsx @@ -2,6 +2,9 @@ export interface Option { menu?: string; description?: string; metadata?: string[] | { [key: string]: any }; + event?: string; + serverEvent?: string; + args?: any; } export interface Options {