refactor(web/menu)!: pass scrollIndex or checked in the same value

If the button is a scroll button then `isScroll` is passed into args, if a button is a checkbox then `isCheck` is passed into args.

Requires `args` to always be of type `table`
This commit is contained in:
Luke
2022-10-29 15:52:59 +02:00
parent c227282ce0
commit 9cc7b9270e
3 changed files with 45 additions and 38 deletions

View File

@@ -10,7 +10,7 @@ interface MenuOptions {
values?: Array<string | { label: string; description: string }>; values?: Array<string | { label: string; description: string }>;
description?: string; description?: string;
defaultIndex?: number; defaultIndex?: number;
args?: any; args?: Record<any, any>;
close?: boolean; close?: boolean;
} }

View File

@@ -14,7 +14,7 @@ local keepInput = IsNuiFocusKeepingInput()
---@field values? Array<string | { label: string, description: string }> ---@field values? Array<string | { label: string, description: string }>
---@field description? string ---@field description? string
---@field defaultIndex? number ---@field defaultIndex? number
---@field args? any ---@field args? {[any]: any}
---@field close? boolean ---@field close? boolean
---@class MenuProps ---@class MenuProps
@@ -148,7 +148,7 @@ RegisterNUICallback('changeIndex', function(data, cb)
data[2] += 1 -- scrollIndex data[2] += 1 -- scrollIndex
end end
openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args, data[3]) openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args)
end) end)
RegisterNUICallback('changeSelected', function(data, cb) RegisterNUICallback('changeSelected', function(data, cb)
@@ -157,11 +157,23 @@ RegisterNUICallback('changeSelected', function(data, cb)
data[1] += 1 -- selected data[1] += 1 -- selected
if data[2] then
local args = openMenu.options[data[1]].args
if args and type(args) ~= 'table' then
return error("Menu args must be passed as a table")
end
if not args then args = {} end
print(data[2], data[3])
if data[2] then args[data[3]] = true end
print(args.isScroll, args.isCheck)
if data[2] and not args.isCheck then
data[2] += 1 -- scrollIndex data[2] += 1 -- scrollIndex
end end
openMenu.onSelected(data[1], data[2], openMenu.options[data[1]].args, data[3]) openMenu.onSelected(data[1], data[2], args)
end) end)
RegisterNUICallback('changeChecked', function(data, cb) RegisterNUICallback('changeChecked', function(data, cb)
@@ -170,11 +182,7 @@ RegisterNUICallback('changeChecked', function(data, cb)
data[1] += 1 -- selected data[1] += 1 -- selected
if data[2] then openMenu.onCheck(data[1], data[2], openMenu.options[data[1]].args)
data[2] += 1 -- scrollIndex
end
openMenu.onCheck(data[1], data[2], openMenu.options[data[1]].args, data[3])
end) end)
RegisterNUICallback('closeMenu', function(data, cb) RegisterNUICallback('closeMenu', function(data, cb)

View File

@@ -61,43 +61,28 @@ const ListMenu: React.FC = () => {
}); });
break; break;
case 'ArrowRight': case 'ArrowRight':
if (Array.isArray(menu.items[selected].values)) { if (Array.isArray(menu.items[selected].values))
setIndexStates({ setIndexStates({
...indexStates, ...indexStates,
[selected]: [selected]:
indexStates[selected] + 1 <= menu.items[selected].values?.length! - 1 indexStates[selected] + 1 <= menu.items[selected].values?.length! - 1 ? indexStates[selected] + 1 : 0,
? indexStates[selected] + 1
: 0
}); });
} else if (menu.items[selected].checked !== undefined) {
setCheckedStates({
...checkedStates,
[selected]: !checkedStates[selected]
});
}
break; break;
case 'ArrowLeft': case 'ArrowLeft':
if (Array.isArray(menu.items[selected].values)) { if (Array.isArray(menu.items[selected].values))
setIndexStates({ setIndexStates({
...indexStates, ...indexStates,
[selected]: [selected]:
indexStates[selected] - 1 >= 0 indexStates[selected] - 1 >= 0 ? indexStates[selected] - 1 : menu.items[selected].values?.length! - 1,
? indexStates[selected] - 1
: menu.items[selected].values?.length! - 1
}); });
} else if (menu.items[selected].checked !== undefined) {
setCheckedStates({
...checkedStates,
[selected]: !checkedStates[selected]
});
}
break; break;
case 'Enter': case 'Enter':
if (!menu.items[selected]) return; if (!menu.items[selected]) return;
if (menu.items[selected].checked !== undefined) { if (menu.items[selected].checked !== undefined && !menu.items[selected].values) {
setCheckedStates({ return setCheckedStates({
...checkedStates, ...checkedStates,
[selected]: !checkedStates[selected] [selected]: !checkedStates[selected],
}); });
} }
fetchNui('confirmSelected', [selected, indexStates[selected]]).catch(); fetchNui('confirmSelected', [selected, indexStates[selected]]).catch();
@@ -113,10 +98,10 @@ const ListMenu: React.FC = () => {
} }
if (menu.items[selected]?.checked === undefined) return; if (menu.items[selected]?.checked === undefined) return;
const timer = setTimeout(() => { const timer = setTimeout(() => {
fetchNui('changeChecked', [selected, indexStates[selected], checkedStates[selected]]).catch(); fetchNui('changeChecked', [selected, checkedStates[selected]]).catch();
}, 100); }, 100);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [checkedStates]) }, [checkedStates]);
useEffect(() => { useEffect(() => {
if (firstRenderRef.current) { if (firstRenderRef.current) {
@@ -125,7 +110,7 @@ const ListMenu: React.FC = () => {
} }
if (!menu.items[selected]?.values) return; if (!menu.items[selected]?.values) return;
const timer = setTimeout(() => { const timer = setTimeout(() => {
fetchNui('changeIndex', [selected, indexStates[selected], checkedStates[selected]]).catch(); fetchNui('changeIndex', [selected, indexStates[selected]]).catch();
}, 100); }, 100);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [indexStates]); }, [indexStates]);
@@ -139,7 +124,15 @@ const ListMenu: React.FC = () => {
listRefs.current[selected]?.focus({ preventScroll: true }); listRefs.current[selected]?.focus({ preventScroll: true });
// debounces the callback to avoid spam // debounces the callback to avoid spam
const timer = setTimeout(() => { const timer = setTimeout(() => {
fetchNui('changeSelected', [selected, indexStates[selected], checkedStates[selected]]).catch(); fetchNui('changeSelected', [
selected,
menu.items[selected].values
? indexStates[selected]
: menu.items[selected].checked
? checkedStates[selected]
: null,
menu.items[selected].values ? 'isScroll' : menu.items[selected].checked ? 'isCheck' : null,
]).catch();
}, 100); }, 100);
return () => clearTimeout(timer); return () => clearTimeout(timer);
}, [selected, menu]); }, [selected, menu]);
@@ -224,7 +217,13 @@ const ListMenu: React.FC = () => {
{menu.items.map((item, index) => ( {menu.items.map((item, index) => (
<React.Fragment key={`menu-item-${index}`}> <React.Fragment key={`menu-item-${index}`}>
{item.label && ( {item.label && (
<ListItem index={index} item={item} scrollIndex={indexStates[index]} checked={checkedStates[index]} ref={listRefs} /> <ListItem
index={index}
item={item}
scrollIndex={indexStates[index]}
checked={checkedStates[index]}
ref={listRefs}
/>
)} )}
</React.Fragment> </React.Fragment>
))} ))}