Files
ox_lib/resource/interface/client/context.lua
Linden fb2225e373 chore: add copyright notices to each file
Some people accidentally, mistakenly, and without any malicious intent forget to attribute code from this resource to its source. This change will hopefully assist people, so that they do not make that mistake again.
2025-03-18 18:46:09 +11:00

126 lines
3.2 KiB
Lua

--[[
https://github.com/overextended/ox_lib
This file is licensed under LGPL-3.0 or higher <https://www.gnu.org/licenses/lgpl-3.0.en.html>
Copyright (c) 2025 Linden <https://github.com/thelindat/fivem>
]]
local contextMenus = {}
local openContextMenu = nil
---@class ContextMenuItem
---@field title? string
---@field menu? string
---@field icon? string | {[1]: IconProp, [2]: string};
---@field iconColor? string
---@field image? string
---@field progress? number
---@field onSelect? fun(args: any)
---@field arrow? boolean
---@field description? string
---@field metadata? string | { [string]: any } | string[]
---@field disabled? boolean
---@field readOnly? boolean
---@field event? string
---@field serverEvent? string
---@field args? any
---@class ContextMenuArrayItem : ContextMenuItem
---@field title string
---@class ContextMenuProps
---@field id string
---@field title string
---@field menu? string
---@field onExit? fun()
---@field onBack? fun()
---@field canClose? boolean
---@field options { [string]: ContextMenuItem } | ContextMenuArrayItem[]
local function closeContext(_, cb, onExit)
if cb then cb(1) end
lib.resetNuiFocus()
if not openContextMenu then return end
if (cb or onExit) and contextMenus[openContextMenu].onExit then contextMenus[openContextMenu].onExit() end
if not cb then SendNUIMessage({ action = 'hideContext' }) end
openContextMenu = nil
end
---@param id string
function lib.showContext(id)
if not contextMenus[id] then error('No context menu of such id found.') end
local data = contextMenus[id]
openContextMenu = id
lib.setNuiFocus(false)
SendNuiMessage(json.encode({
action = 'showContext',
data = {
title = data.title,
canClose = data.canClose,
menu = data.menu,
options = data.options
}
}, { sort_keys = true }))
end
---@param context ContextMenuProps | ContextMenuProps[]
function lib.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
---@return string?
function lib.getOpenContextMenu() return openContextMenu end
---@param onExit boolean?
function lib.hideContext(onExit) closeContext(nil, nil, onExit) end
RegisterNUICallback('openContext', function(data, cb)
if data.back and contextMenus[openContextMenu].onBack then contextMenus[openContextMenu].onBack() end
cb(1)
lib.showContext(data.id)
end)
RegisterNUICallback('clickContext', function(id, cb)
cb(1)
if math.type(tonumber(id)) == 'float' then
id = math.tointeger(id)
elseif tonumber(id) then
id += 1
end
local data = contextMenus[openContextMenu].options[id]
if not data.event and not data.serverEvent and not data.onSelect then return end
openContextMenu = nil
SendNUIMessage({ action = 'hideContext' })
lib.resetNuiFocus()
if data.onSelect then data.onSelect(data.args) end
if data.event then TriggerEvent(data.event, data.args) end
if data.serverEvent then TriggerServerEvent(data.serverEvent, data.args) end
end)
RegisterNUICallback('closeContext', closeContext)