mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-18 23:46:03 +01:00
refactor(web/menu): radial sub menu chaining
still some quirks to figure out but it's working well
This commit is contained in:
@@ -1,5 +1,25 @@
|
|||||||
local isOpen = false
|
local isOpen = false
|
||||||
|
local menus = {}
|
||||||
local menuItems = {}
|
local menuItems = {}
|
||||||
|
local currentRadial = nil
|
||||||
|
|
||||||
|
|
||||||
|
function lib.registerRadial(radial)
|
||||||
|
menus[radial.id] = radial
|
||||||
|
end
|
||||||
|
|
||||||
|
function lib.showRadial(id)
|
||||||
|
local radial = menus[id]
|
||||||
|
if not radial then return error('No radial menu with such id found.') end
|
||||||
|
currentRadial = radial
|
||||||
|
SendNUIMessage({
|
||||||
|
action = 'openRadialMenu',
|
||||||
|
data = {
|
||||||
|
items = radial.items,
|
||||||
|
sub = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
function lib.addRadialItem(items)
|
function lib.addRadialItem(items)
|
||||||
if table.type(items) == 'array' then
|
if table.type(items) == 'array' then
|
||||||
@@ -28,6 +48,29 @@ function lib.removeRadialItem(key)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RegisterNUICallback('radialClick', function(index, cb)
|
||||||
|
cb(1)
|
||||||
|
local item = not currentRadial and menuItems[index + 1] or currentRadial.items[index + 1]
|
||||||
|
if item.menu then lib.showRadial(item.menu) end
|
||||||
|
if item.onSelect then item.onSelect() end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- TODO: fix transition?
|
||||||
|
RegisterNUICallback('radialBack', function(_, cb)
|
||||||
|
cb(1)
|
||||||
|
if currentRadial.menu then
|
||||||
|
lib.showRadial(currentRadial.menu)
|
||||||
|
else
|
||||||
|
currentRadial = nil
|
||||||
|
SendNUIMessage({
|
||||||
|
action = 'openRadialMenu',
|
||||||
|
data = {
|
||||||
|
items = menuItems
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
local function openRadial()
|
local function openRadial()
|
||||||
isOpen = true
|
isOpen = true
|
||||||
SendNUIMessage({
|
SendNUIMessage({
|
||||||
@@ -38,6 +81,7 @@ local function openRadial()
|
|||||||
})
|
})
|
||||||
SetNuiFocus(true, true)
|
SetNuiFocus(true, true)
|
||||||
SetNuiFocusKeepInput(true)
|
SetNuiFocusKeepInput(true)
|
||||||
|
SetCursorLocation(0.5, 0.5)
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while isOpen do
|
while isOpen do
|
||||||
DisablePlayerFiring(cache.playerId, true)
|
DisablePlayerFiring(cache.playerId, true)
|
||||||
@@ -55,6 +99,7 @@ local function closeRadial()
|
|||||||
})
|
})
|
||||||
SetNuiFocus(false, false)
|
SetNuiFocus(false, false)
|
||||||
isOpen = false
|
isOpen = false
|
||||||
|
if currentRadial then currentRadial = nil end
|
||||||
end
|
end
|
||||||
|
|
||||||
RegisterCommand('+ox_lib-radial', openRadial)
|
RegisterCommand('+ox_lib-radial', openRadial)
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import { useNuiEvent } from '../../../hooks/useNuiEvent';
|
|||||||
import { fetchNui } from '../../../utils/fetchNui';
|
import { fetchNui } from '../../../utils/fetchNui';
|
||||||
import ScaleFade from '../../../transitions/ScaleFade';
|
import ScaleFade from '../../../transitions/ScaleFade';
|
||||||
|
|
||||||
const radius = 60;
|
|
||||||
|
|
||||||
export interface MenuItem {
|
export interface MenuItem {
|
||||||
icon: IconProp;
|
icon: IconProp;
|
||||||
label: string;
|
label: string;
|
||||||
@@ -62,8 +60,12 @@ const RadialMenu: React.FC = () => {
|
|||||||
sub: false,
|
sub: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
useNuiEvent('openRadialMenu', (data: { items: MenuItem[]; sub?: boolean } | false) => {
|
useNuiEvent('openRadialMenu', async (data: { items: MenuItem[]; sub?: boolean } | false) => {
|
||||||
if (!data) return setVisible(false);
|
if (!data) return setVisible(false);
|
||||||
|
if (visible) {
|
||||||
|
setVisible(false);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||||
|
}
|
||||||
setMenu(data);
|
setMenu(data);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
});
|
});
|
||||||
@@ -72,7 +74,7 @@ const RadialMenu: React.FC = () => {
|
|||||||
setMenu({ ...menu, items: data });
|
setMenu({ ...menu, items: data });
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = (index: number) => {
|
const handleClick = async (index: number) => {
|
||||||
fetchNui('radialClick', index);
|
fetchNui('radialClick', index);
|
||||||
// TODO: shouldClose
|
// TODO: shouldClose
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
@@ -124,11 +126,18 @@ const RadialMenu: React.FC = () => {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<g transform="translate(175, 175)" onClick={() => setVisible(false)}>
|
{/* TODO: rotate go back icon */}
|
||||||
|
<g
|
||||||
|
transform={`translate(175, 175)`}
|
||||||
|
onClick={() => {
|
||||||
|
setVisible(false);
|
||||||
|
menu.sub && fetchNui('radialBack');
|
||||||
|
}}
|
||||||
|
>
|
||||||
<circle r={30} className={classes.centerCircle} />
|
<circle r={30} className={classes.centerCircle} />
|
||||||
</g>
|
</g>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="xmark"
|
icon={!menu.sub ? 'xmark' : 'arrow-rotate-left'}
|
||||||
className={classes.centerIcon}
|
className={classes.centerIcon}
|
||||||
color="#fff"
|
color="#fff"
|
||||||
width={28}
|
width={28}
|
||||||
|
|||||||
Reference in New Issue
Block a user