dirk-cfx-react 1.1.71 → 1.1.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.cjs +375 -93
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +40 -2
- package/dist/components/index.d.ts +40 -2
- package/dist/components/index.js +376 -96
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +5 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +5 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +394 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +392 -96
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +5 -1
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js +5 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/utils/index.cjs +5 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.js +5 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +115 -113
|
@@ -1236,11 +1236,11 @@ var colorNames = {
|
|
|
1236
1236
|
Yellow: { r: 255, g: 255, b: 0 },
|
|
1237
1237
|
YellowGreen: { r: 154, g: 205, b: 50 }
|
|
1238
1238
|
};
|
|
1239
|
-
function colorWithAlpha(color,
|
|
1239
|
+
function colorWithAlpha(color, alpha10) {
|
|
1240
1240
|
const lowerCasedColor = color.toLowerCase();
|
|
1241
1241
|
if (colorNames[lowerCasedColor]) {
|
|
1242
1242
|
const rgb = colorNames[lowerCasedColor];
|
|
1243
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${
|
|
1243
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha10})`;
|
|
1244
1244
|
}
|
|
1245
1245
|
if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
|
|
1246
1246
|
const hex = color.slice(1);
|
|
@@ -1248,12 +1248,12 @@ function colorWithAlpha(color, alpha9) {
|
|
|
1248
1248
|
const r = bigint >> 16 & 255;
|
|
1249
1249
|
const g = bigint >> 8 & 255;
|
|
1250
1250
|
const b = bigint & 255;
|
|
1251
|
-
return `rgba(${r}, ${g}, ${b}, ${
|
|
1251
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha10})`;
|
|
1252
1252
|
}
|
|
1253
1253
|
if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
|
|
1254
1254
|
const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
|
|
1255
1255
|
if (result) {
|
|
1256
|
-
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${
|
|
1256
|
+
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha10})`;
|
|
1257
1257
|
}
|
|
1258
1258
|
}
|
|
1259
1259
|
return color;
|
|
@@ -1299,7 +1299,11 @@ async function fetchNui(eventName, data, mockData) {
|
|
|
1299
1299
|
return {};
|
|
1300
1300
|
}
|
|
1301
1301
|
const overrideResourceName = useSettings.getState().overideResourceName;
|
|
1302
|
-
const
|
|
1302
|
+
const hasResourceContext = typeof window.GetParentResourceName === "function" || !!overrideResourceName;
|
|
1303
|
+
if (!hasResourceContext) {
|
|
1304
|
+
return mockData ?? {};
|
|
1305
|
+
}
|
|
1306
|
+
const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : overrideResourceName;
|
|
1303
1307
|
try {
|
|
1304
1308
|
const resp = await fetch(`https://${resourceName}/${eventName}`, options);
|
|
1305
1309
|
return await resp.json();
|
|
@@ -2472,9 +2476,25 @@ function SegmentedProgress(props) {
|
|
|
2472
2476
|
}
|
|
2473
2477
|
);
|
|
2474
2478
|
}
|
|
2479
|
+
function getSizePreset(size, themeMdFontSize) {
|
|
2480
|
+
switch (size) {
|
|
2481
|
+
case "xs":
|
|
2482
|
+
return { iconFontSize: "1.2vh", iconPadding: "xxs", titleSize: "xxs", titleLineHeight: "1.2vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
|
|
2483
|
+
case "sm":
|
|
2484
|
+
return { iconFontSize: "1.6vh", iconPadding: "xxs", titleSize: "xs", titleLineHeight: "1.6vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
|
|
2485
|
+
case "lg":
|
|
2486
|
+
return { iconFontSize: "2.6vh", iconPadding: "sm", titleSize: "md", titleLineHeight: "2.6vh", descriptionSize: "sm", innerGap: "sm", bottomPad: "sm" };
|
|
2487
|
+
case "xl":
|
|
2488
|
+
return { iconFontSize: "3.2vh", iconPadding: "sm", titleSize: "lg", titleLineHeight: "3.2vh", descriptionSize: "md", innerGap: "md", bottomPad: "md" };
|
|
2489
|
+
case "md":
|
|
2490
|
+
default:
|
|
2491
|
+
return { iconFontSize: themeMdFontSize, iconPadding: "xs", titleSize: "sm", titleLineHeight: themeMdFontSize, descriptionSize: "xs", innerGap: "sm", bottomPad: "sm" };
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2475
2494
|
function Title(props) {
|
|
2476
2495
|
const game = useSettings((state) => state.game);
|
|
2477
2496
|
const theme = core.useMantineTheme();
|
|
2497
|
+
const preset = getSizePreset(props.size ?? "md", theme.fontSizes.md);
|
|
2478
2498
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2479
2499
|
core.Flex,
|
|
2480
2500
|
{
|
|
@@ -2483,71 +2503,50 @@ function Title(props) {
|
|
|
2483
2503
|
gap: "xs",
|
|
2484
2504
|
w: props.w || "100%",
|
|
2485
2505
|
p: props.p || "unset",
|
|
2486
|
-
pb: !props.p ?
|
|
2506
|
+
pb: !props.p ? preset.bottomPad : props.p,
|
|
2487
2507
|
style: {
|
|
2488
2508
|
userSelect: "none",
|
|
2489
2509
|
borderBottom: props.removeBorder ? "none" : `0.3vh solid ${props.borderColor || colorWithAlpha(theme.colors[theme.primaryColor][9], 0.5)}`
|
|
2490
2510
|
},
|
|
2491
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2492
|
-
core.Flex,
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2511
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", justify: "center", children: [
|
|
2512
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: preset.innerGap, pr: "xs", children: [
|
|
2513
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2514
|
+
BorderedIcon,
|
|
2515
|
+
{
|
|
2516
|
+
icon: props.icon,
|
|
2517
|
+
fontSize: preset.iconFontSize,
|
|
2518
|
+
color: props.iconColor,
|
|
2519
|
+
p: preset.iconPadding
|
|
2520
|
+
}
|
|
2521
|
+
),
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "0.25vh", children: [
|
|
2523
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2524
|
+
core.Text,
|
|
2499
2525
|
{
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
color: props.iconColor
|
|
2510
|
-
}
|
|
2511
|
-
),
|
|
2512
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2513
|
-
core.Flex,
|
|
2514
|
-
{
|
|
2515
|
-
direction: "column",
|
|
2516
|
-
gap: "0.25vh",
|
|
2517
|
-
children: [
|
|
2518
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { p: "0", size: "sm", style: {
|
|
2519
|
-
lineHeight: theme.fontSizes.md,
|
|
2520
|
-
fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
|
|
2521
|
-
letterSpacing: "0.05em",
|
|
2522
|
-
textTransform: "uppercase"
|
|
2523
|
-
}, children: props.title }),
|
|
2524
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2525
|
-
core.Text,
|
|
2526
|
-
{
|
|
2527
|
-
size: "xs",
|
|
2528
|
-
c: "grey",
|
|
2529
|
-
style: { whiteSpace: "normal", wordWrap: "break-word" },
|
|
2530
|
-
children: props.description
|
|
2531
|
-
}
|
|
2532
|
-
)
|
|
2533
|
-
]
|
|
2534
|
-
}
|
|
2535
|
-
)
|
|
2536
|
-
]
|
|
2526
|
+
p: "0",
|
|
2527
|
+
size: preset.titleSize,
|
|
2528
|
+
style: {
|
|
2529
|
+
lineHeight: preset.titleLineHeight,
|
|
2530
|
+
fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
|
|
2531
|
+
letterSpacing: "0.05em",
|
|
2532
|
+
textTransform: "uppercase"
|
|
2533
|
+
},
|
|
2534
|
+
children: props.title
|
|
2537
2535
|
}
|
|
2538
2536
|
),
|
|
2539
2537
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2540
|
-
core.
|
|
2538
|
+
core.Text,
|
|
2541
2539
|
{
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
children: props.
|
|
2540
|
+
size: preset.descriptionSize,
|
|
2541
|
+
c: "grey",
|
|
2542
|
+
style: { whiteSpace: "normal", wordWrap: "break-word" },
|
|
2543
|
+
children: props.description
|
|
2546
2544
|
}
|
|
2547
2545
|
)
|
|
2548
|
-
]
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2546
|
+
] })
|
|
2547
|
+
] }),
|
|
2548
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { ml: "auto", align: "center", gap: "xs", children: props.rightSection })
|
|
2549
|
+
] })
|
|
2551
2550
|
}
|
|
2552
2551
|
);
|
|
2553
2552
|
}
|
|
@@ -3205,6 +3204,246 @@ function ConfirmModal({
|
|
|
3205
3204
|
}
|
|
3206
3205
|
) });
|
|
3207
3206
|
}
|
|
3207
|
+
var TABS = [
|
|
3208
|
+
{ id: "ox", label: "ox_inventory" },
|
|
3209
|
+
{ id: "qb", label: "qb-inventory" },
|
|
3210
|
+
{ id: "esx", label: "ESX legacy SQL" }
|
|
3211
|
+
];
|
|
3212
|
+
var useMissingItemsAudit = zustand.create((set, get) => ({
|
|
3213
|
+
data: null,
|
|
3214
|
+
loaded: false,
|
|
3215
|
+
inFlight: false,
|
|
3216
|
+
refresh: async () => {
|
|
3217
|
+
if (get().inFlight) return;
|
|
3218
|
+
set({ inFlight: true });
|
|
3219
|
+
try {
|
|
3220
|
+
const res = await fetchNui("GET_MISSING_ITEMS", void 0, {
|
|
3221
|
+
success: true,
|
|
3222
|
+
data: { missing: [], snippets: { ox: "", qb: "", esx: "" } }
|
|
3223
|
+
});
|
|
3224
|
+
if (res?.success && res.data) {
|
|
3225
|
+
set({ data: res.data, loaded: true });
|
|
3226
|
+
} else {
|
|
3227
|
+
set({ loaded: true });
|
|
3228
|
+
}
|
|
3229
|
+
} catch {
|
|
3230
|
+
set({ loaded: true });
|
|
3231
|
+
} finally {
|
|
3232
|
+
set({ inFlight: false });
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
}));
|
|
3236
|
+
function MissingItemsBanner() {
|
|
3237
|
+
const theme = core.useMantineTheme();
|
|
3238
|
+
const audit = useMissingItemsAudit((s) => s.data);
|
|
3239
|
+
const loaded = useMissingItemsAudit((s) => s.loaded);
|
|
3240
|
+
const inFlight = useMissingItemsAudit((s) => s.inFlight);
|
|
3241
|
+
const refresh = useMissingItemsAudit((s) => s.refresh);
|
|
3242
|
+
const [expanded, setExpanded] = react.useState(false);
|
|
3243
|
+
const [activeTab, setActiveTab] = react.useState("ox");
|
|
3244
|
+
const [hoveredTab, setHoveredTab] = react.useState(null);
|
|
3245
|
+
const [copied, setCopied] = react.useState(null);
|
|
3246
|
+
react.useEffect(() => {
|
|
3247
|
+
if (!loaded) refresh();
|
|
3248
|
+
}, [loaded, refresh]);
|
|
3249
|
+
const handleCopy = react.useCallback((tab) => {
|
|
3250
|
+
if (!audit) return;
|
|
3251
|
+
const text = audit.snippets[tab] ?? "";
|
|
3252
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
3253
|
+
setCopied(tab);
|
|
3254
|
+
setTimeout(() => setCopied((c) => c === tab ? null : c), 1500);
|
|
3255
|
+
}).catch(() => {
|
|
3256
|
+
});
|
|
3257
|
+
}, [audit]);
|
|
3258
|
+
const handleRefresh = react.useCallback((e) => {
|
|
3259
|
+
e.stopPropagation();
|
|
3260
|
+
refresh();
|
|
3261
|
+
}, [refresh]);
|
|
3262
|
+
if (!audit || audit.missing.length === 0) return null;
|
|
3263
|
+
const warnColor = "#f59e0b";
|
|
3264
|
+
const names = audit.missing.map((m) => m.name);
|
|
3265
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3266
|
+
"div",
|
|
3267
|
+
{
|
|
3268
|
+
style: {
|
|
3269
|
+
background: core.alpha(warnColor, 0.06),
|
|
3270
|
+
border: `0.1vh solid ${core.alpha(warnColor, 0.35)}`,
|
|
3271
|
+
borderLeft: `0.3vh solid ${warnColor}`,
|
|
3272
|
+
borderRadius: theme.radius.xs,
|
|
3273
|
+
margin: "0.6vh 1vh",
|
|
3274
|
+
overflow: "hidden"
|
|
3275
|
+
},
|
|
3276
|
+
children: [
|
|
3277
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.8vh", p: "0.8vh 1vh", style: { cursor: "pointer" }, onClick: () => setExpanded((e) => !e), children: [
|
|
3278
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "1.8vh", color: warnColor, strokeWidth: 2.5 }),
|
|
3279
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
3280
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", tt: "uppercase", lts: "0.07em", c: warnColor, children: audit.missing.length === 1 ? "1 item missing from your inventory" : `${audit.missing.length} items missing from your inventory` }),
|
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.5)", lineClamp: 1, style: { fontFamily: "monospace" }, children: names.join(", ") })
|
|
3282
|
+
] }),
|
|
3283
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3284
|
+
"button",
|
|
3285
|
+
{
|
|
3286
|
+
onClick: handleRefresh,
|
|
3287
|
+
disabled: inFlight,
|
|
3288
|
+
style: {
|
|
3289
|
+
background: "transparent",
|
|
3290
|
+
border: "none",
|
|
3291
|
+
padding: "0.3vh",
|
|
3292
|
+
cursor: inFlight ? "wait" : "pointer",
|
|
3293
|
+
display: "flex",
|
|
3294
|
+
alignItems: "center",
|
|
3295
|
+
justifyContent: "center",
|
|
3296
|
+
opacity: inFlight ? 0.4 : 0.7
|
|
3297
|
+
},
|
|
3298
|
+
title: "Re-check",
|
|
3299
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3300
|
+
framerMotion.motion.span,
|
|
3301
|
+
{
|
|
3302
|
+
animate: { rotate: inFlight ? 360 : 0 },
|
|
3303
|
+
transition: inFlight ? { duration: 1, repeat: Infinity, ease: "linear" } : { duration: 0 },
|
|
3304
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3305
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { size: "1.5vh", color: core.alpha(warnColor, 0.7) })
|
|
3306
|
+
}
|
|
3307
|
+
)
|
|
3308
|
+
}
|
|
3309
|
+
),
|
|
3310
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3311
|
+
framerMotion.motion.div,
|
|
3312
|
+
{
|
|
3313
|
+
animate: { rotate: expanded ? 180 : 0 },
|
|
3314
|
+
transition: { duration: 0.18 },
|
|
3315
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3316
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: "1.8vh", color: core.alpha(warnColor, 0.7) })
|
|
3317
|
+
}
|
|
3318
|
+
)
|
|
3319
|
+
] }),
|
|
3320
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, children: expanded && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3321
|
+
framerMotion.motion.div,
|
|
3322
|
+
{
|
|
3323
|
+
initial: { height: 0, opacity: 0 },
|
|
3324
|
+
animate: { height: "auto", opacity: 1 },
|
|
3325
|
+
exit: { height: 0, opacity: 0 },
|
|
3326
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
3327
|
+
style: { overflow: "hidden", borderTop: `0.1vh solid ${core.alpha(warnColor, 0.18)}` },
|
|
3328
|
+
children: [
|
|
3329
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { gap: "0", style: { borderBottom: `0.1vh solid ${core.alpha(warnColor, 0.18)}` }, children: TABS.map((tab) => {
|
|
3330
|
+
const active = tab.id === activeTab;
|
|
3331
|
+
const hovered = hoveredTab === tab.id;
|
|
3332
|
+
let bg = "transparent";
|
|
3333
|
+
if (active) bg = core.alpha(warnColor, 0.12);
|
|
3334
|
+
else if (hovered) bg = core.alpha(warnColor, 0.08);
|
|
3335
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3336
|
+
"button",
|
|
3337
|
+
{
|
|
3338
|
+
onClick: (e) => {
|
|
3339
|
+
e.stopPropagation();
|
|
3340
|
+
setActiveTab(tab.id);
|
|
3341
|
+
},
|
|
3342
|
+
onMouseEnter: () => setHoveredTab(tab.id),
|
|
3343
|
+
onMouseLeave: () => setHoveredTab((h) => h === tab.id ? null : h),
|
|
3344
|
+
style: {
|
|
3345
|
+
flex: 1,
|
|
3346
|
+
background: bg,
|
|
3347
|
+
border: "none",
|
|
3348
|
+
borderBottom: active ? `0.2vh solid ${warnColor}` : "0.2vh solid transparent",
|
|
3349
|
+
padding: "0.3vh 1vh",
|
|
3350
|
+
cursor: active ? "default" : "pointer",
|
|
3351
|
+
color: active ? warnColor : "rgba(255,255,255,0.5)",
|
|
3352
|
+
fontFamily: "Akrobat Bold",
|
|
3353
|
+
fontSize: "var(--mantine-font-size-xxs)",
|
|
3354
|
+
letterSpacing: "0.07em",
|
|
3355
|
+
textTransform: "uppercase",
|
|
3356
|
+
transition: "background 0.12s"
|
|
3357
|
+
},
|
|
3358
|
+
children: tab.label
|
|
3359
|
+
},
|
|
3360
|
+
tab.id
|
|
3361
|
+
);
|
|
3362
|
+
}) }),
|
|
3363
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3364
|
+
CodeView,
|
|
3365
|
+
{
|
|
3366
|
+
code: audit.snippets[activeTab] ?? "",
|
|
3367
|
+
copied: copied === activeTab,
|
|
3368
|
+
onCopy: (e) => {
|
|
3369
|
+
e.stopPropagation();
|
|
3370
|
+
handleCopy(activeTab);
|
|
3371
|
+
},
|
|
3372
|
+
warnColor
|
|
3373
|
+
}
|
|
3374
|
+
)
|
|
3375
|
+
]
|
|
3376
|
+
},
|
|
3377
|
+
"expanded"
|
|
3378
|
+
) })
|
|
3379
|
+
]
|
|
3380
|
+
}
|
|
3381
|
+
);
|
|
3382
|
+
}
|
|
3383
|
+
function CodeView({
|
|
3384
|
+
code,
|
|
3385
|
+
copied,
|
|
3386
|
+
onCopy,
|
|
3387
|
+
warnColor
|
|
3388
|
+
}) {
|
|
3389
|
+
const theme = core.useMantineTheme();
|
|
3390
|
+
const [hovered, setHovered] = react.useState(false);
|
|
3391
|
+
const lines = code === "" ? [""] : code.split("\n");
|
|
3392
|
+
const lineNumWidth = String(lines.length).length;
|
|
3393
|
+
const copyBg = copied ? core.alpha("#22c55e", 0.15) : hovered ? core.alpha(warnColor, 0.18) : core.alpha(warnColor, 0.1);
|
|
3394
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
|
|
3395
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
3396
|
+
"button",
|
|
3397
|
+
{
|
|
3398
|
+
onClick: onCopy,
|
|
3399
|
+
onMouseEnter: () => setHovered(true),
|
|
3400
|
+
onMouseLeave: () => setHovered(false),
|
|
3401
|
+
style: {
|
|
3402
|
+
position: "absolute",
|
|
3403
|
+
top: "0.6vh",
|
|
3404
|
+
right: "0.8vh",
|
|
3405
|
+
zIndex: 2,
|
|
3406
|
+
background: copyBg,
|
|
3407
|
+
border: `0.1vh solid ${core.alpha(copied ? "#22c55e" : warnColor, 0.35)}`,
|
|
3408
|
+
borderRadius: theme.radius.xs,
|
|
3409
|
+
padding: "0.4vh 0.7vh",
|
|
3410
|
+
cursor: "pointer",
|
|
3411
|
+
display: "flex",
|
|
3412
|
+
alignItems: "center",
|
|
3413
|
+
gap: "0.4vh",
|
|
3414
|
+
transition: "background 0.12s"
|
|
3415
|
+
},
|
|
3416
|
+
children: [
|
|
3417
|
+
copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: "1.4vh", color: "#22c55e" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: "1.4vh", color: warnColor }),
|
|
3418
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: copied ? "#22c55e" : warnColor, children: copied ? "Copied" : "Copy" })
|
|
3419
|
+
]
|
|
3420
|
+
}
|
|
3421
|
+
),
|
|
3422
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
3423
|
+
background: core.alpha(theme.colors.dark[9], 0.6),
|
|
3424
|
+
maxHeight: "40vh",
|
|
3425
|
+
overflowY: "auto",
|
|
3426
|
+
overflowX: "auto",
|
|
3427
|
+
padding: "0.6vh 0"
|
|
3428
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx("table", { style: { borderCollapse: "collapse", width: "100%", fontFamily: "monospace", fontSize: "1.2vh", lineHeight: 1.5 }, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
3429
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: {
|
|
3430
|
+
width: `${lineNumWidth + 2}ch`,
|
|
3431
|
+
textAlign: "right",
|
|
3432
|
+
padding: "0 0.8vh 0 1vh",
|
|
3433
|
+
color: "rgba(255,255,255,0.25)",
|
|
3434
|
+
userSelect: "none",
|
|
3435
|
+
whiteSpace: "nowrap",
|
|
3436
|
+
verticalAlign: "top"
|
|
3437
|
+
}, children: i + 1 }),
|
|
3438
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { style: {
|
|
3439
|
+
padding: "0 1vh",
|
|
3440
|
+
color: "rgba(255,255,255,0.85)",
|
|
3441
|
+
whiteSpace: "pre",
|
|
3442
|
+
verticalAlign: "top"
|
|
3443
|
+
}, children: line || "\u200B" })
|
|
3444
|
+
] }, i)) }) }) })
|
|
3445
|
+
] });
|
|
3446
|
+
}
|
|
3208
3447
|
function getNested(obj, path) {
|
|
3209
3448
|
return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
|
|
3210
3449
|
}
|
|
@@ -3807,7 +4046,8 @@ function ConfigPanelInner({
|
|
|
3807
4046
|
resetConfirmText,
|
|
3808
4047
|
defaultConfig,
|
|
3809
4048
|
width,
|
|
3810
|
-
height
|
|
4049
|
+
height,
|
|
4050
|
+
suppressMissingItemsBanner
|
|
3811
4051
|
}) {
|
|
3812
4052
|
const { updateConfig, resetConfig, getHistory } = getScriptConfigInstance();
|
|
3813
4053
|
const form = useForm();
|
|
@@ -3927,8 +4167,8 @@ function ConfigPanelInner({
|
|
|
3927
4167
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: "1.4vh", color })
|
|
3928
4168
|
}
|
|
3929
4169
|
),
|
|
3930
|
-
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, lineHeight: 1 }, children: [
|
|
3931
|
-
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "
|
|
4170
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, flex: 1, lineHeight: 1, overflow: "hidden" }, children: [
|
|
4171
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "md", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
|
|
3932
4172
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.08em", c: color, truncate: true, children: subtitle })
|
|
3933
4173
|
] })
|
|
3934
4174
|
] }),
|
|
@@ -4030,18 +4270,21 @@ function ConfigPanelInner({
|
|
|
4030
4270
|
] })
|
|
4031
4271
|
] })
|
|
4032
4272
|
] }),
|
|
4033
|
-
/* @__PURE__ */ jsxRuntime.
|
|
4034
|
-
|
|
4035
|
-
{
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4273
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: [
|
|
4274
|
+
!suppressMissingItemsBanner && /* @__PURE__ */ jsxRuntime.jsx(MissingItemsBanner, {}),
|
|
4275
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4276
|
+
framerMotion.motion.div,
|
|
4277
|
+
{
|
|
4278
|
+
initial: firstMountRef.current ? (firstMountRef.current = false, false) : { opacity: 0, y: 4 },
|
|
4279
|
+
animate: { opacity: 1, y: 0 },
|
|
4280
|
+
exit: { opacity: 0, y: -4 },
|
|
4281
|
+
transition: { duration: 0.15 },
|
|
4282
|
+
style: { flex: 1, display: "flex", flexDirection: "column", overflowY: "auto" },
|
|
4283
|
+
children: children(activeTab)
|
|
4284
|
+
},
|
|
4285
|
+
activeTab
|
|
4286
|
+
) })
|
|
4287
|
+
] })
|
|
4045
4288
|
]
|
|
4046
4289
|
}
|
|
4047
4290
|
)
|
|
@@ -4083,6 +4326,7 @@ function ConfigPanel(props) {
|
|
|
4083
4326
|
if (result?.success) {
|
|
4084
4327
|
form.reinitialize(cloneConfig(form.values));
|
|
4085
4328
|
configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
4329
|
+
useMissingItemsAudit.getState().refresh();
|
|
4086
4330
|
notifications.notifications.show({
|
|
4087
4331
|
color: "green",
|
|
4088
4332
|
title: locale("ConfigSaveSuccessTitle"),
|
|
@@ -4120,6 +4364,7 @@ function ConfigPanel(props) {
|
|
|
4120
4364
|
}
|
|
4121
4365
|
) });
|
|
4122
4366
|
}
|
|
4367
|
+
var MISSING_COLOR = "#f59e0b";
|
|
4123
4368
|
function LazyImage({ src, style }) {
|
|
4124
4369
|
const [visible, setVisible] = react.useState(false);
|
|
4125
4370
|
const ref = react.useRef(null);
|
|
@@ -4137,14 +4382,19 @@ function LazyImage({ src, style }) {
|
|
|
4137
4382
|
}
|
|
4138
4383
|
function SelectItem(props) {
|
|
4139
4384
|
const invItems = useItems();
|
|
4385
|
+
const isMissing = !!props.value && !invItems[props.value];
|
|
4140
4386
|
const formattedItems = react.useMemo(() => {
|
|
4141
4387
|
const seen = /* @__PURE__ */ new Set();
|
|
4142
|
-
|
|
4388
|
+
const list = useItemsList(props.excludeItemNames ?? []).filter((item) => {
|
|
4143
4389
|
if (seen.has(item.name)) return false;
|
|
4144
4390
|
seen.add(item.name);
|
|
4145
4391
|
return true;
|
|
4146
4392
|
}).map((item) => ({ value: item.name, label: item.label, image: item.image }));
|
|
4147
|
-
|
|
4393
|
+
if (isMissing) {
|
|
4394
|
+
list.unshift({ value: props.value, label: props.value, image: "" });
|
|
4395
|
+
}
|
|
4396
|
+
return list;
|
|
4397
|
+
}, [invItems, props.excludeItemNames, props.value, isMissing]);
|
|
4148
4398
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4149
4399
|
core.Select,
|
|
4150
4400
|
{
|
|
@@ -4159,10 +4409,11 @@ function SelectItem(props) {
|
|
|
4159
4409
|
data: formattedItems,
|
|
4160
4410
|
allowDeselect: false,
|
|
4161
4411
|
searchable: true,
|
|
4412
|
+
styles: isMissing ? { input: { color: MISSING_COLOR } } : void 0,
|
|
4162
4413
|
comboboxProps: { withinPortal: true, zIndex: 2e3 },
|
|
4163
4414
|
leftSectionWidth: "4vh",
|
|
4164
4415
|
leftSectionPointerEvents: "none",
|
|
4165
|
-
leftSection: props.value ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4416
|
+
leftSection: isMissing ? /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }) : props.value ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4166
4417
|
core.Image,
|
|
4167
4418
|
{
|
|
4168
4419
|
fallbackSrc: "/placeholder.png",
|
|
@@ -4173,19 +4424,37 @@ function SelectItem(props) {
|
|
|
4173
4424
|
}
|
|
4174
4425
|
) : null,
|
|
4175
4426
|
nothingFoundMessage: locale("NoItemsFound"),
|
|
4176
|
-
renderOption: (item) =>
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
{
|
|
4180
|
-
|
|
4181
|
-
style: {
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4427
|
+
renderOption: (item) => {
|
|
4428
|
+
const optionMissing = !invItems[item.option.value] && item.option.value === props.value;
|
|
4429
|
+
if (optionMissing) {
|
|
4430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
4431
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }),
|
|
4432
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
4433
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "sm", c: MISSING_COLOR, style: { fontFamily: "monospace" }, children: item.option.value }),
|
|
4434
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: "dimmed", children: locale("ItemNotInInventory") })
|
|
4435
|
+
] }),
|
|
4436
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
4437
|
+
background: "rgba(245,158,11,0.12)",
|
|
4438
|
+
border: `0.1vh solid ${MISSING_COLOR}59`,
|
|
4439
|
+
borderRadius: "0.3vh",
|
|
4440
|
+
padding: "0.1vh 0.6vh"
|
|
4441
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: MISSING_COLOR, ff: "Akrobat Bold", tt: "uppercase", lts: "0.06em", children: locale("Missing") }) })
|
|
4442
|
+
] });
|
|
4443
|
+
}
|
|
4444
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
4445
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4446
|
+
LazyImage,
|
|
4447
|
+
{
|
|
4448
|
+
src: invItems[item.option.value]?.image || "",
|
|
4449
|
+
style: { aspectRatio: "1 / 1" }
|
|
4450
|
+
}
|
|
4451
|
+
),
|
|
4452
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", children: [
|
|
4453
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "sm", children: item.option.label }),
|
|
4454
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "xxs", c: "dimmed", children: item.option.value })
|
|
4455
|
+
] })
|
|
4456
|
+
] });
|
|
4457
|
+
}
|
|
4189
4458
|
}
|
|
4190
4459
|
);
|
|
4191
4460
|
}
|
|
@@ -4840,6 +5109,17 @@ function AdminPageTitle(props) {
|
|
|
4840
5109
|
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
|
|
4841
5110
|
] });
|
|
4842
5111
|
}
|
|
5112
|
+
var placementStyle = (placement) => {
|
|
5113
|
+
switch (placement) {
|
|
5114
|
+
case "top-center":
|
|
5115
|
+
return { top: "1vh", left: "50%", transform: "translateX(-50%)" };
|
|
5116
|
+
case "top-right":
|
|
5117
|
+
return { top: "1vh", right: "1vh" };
|
|
5118
|
+
case "top-left":
|
|
5119
|
+
default:
|
|
5120
|
+
return { top: "1vh", left: "1vh" };
|
|
5121
|
+
}
|
|
5122
|
+
};
|
|
4843
5123
|
var loadPersistedState = (storageKey) => {
|
|
4844
5124
|
try {
|
|
4845
5125
|
const raw = localStorage.getItem(storageKey);
|
|
@@ -4858,7 +5138,8 @@ function TestBed({
|
|
|
4858
5138
|
items,
|
|
4859
5139
|
storageKey = "testbed:open-state",
|
|
4860
5140
|
disablePersistence = false,
|
|
4861
|
-
title = "TestBed"
|
|
5141
|
+
title = "TestBed",
|
|
5142
|
+
placement = "top-left"
|
|
4862
5143
|
}) {
|
|
4863
5144
|
const [open, setOpen] = react.useState(false);
|
|
4864
5145
|
const itemsRef = react.useRef(items);
|
|
@@ -4888,8 +5169,7 @@ function TestBed({
|
|
|
4888
5169
|
{
|
|
4889
5170
|
style: {
|
|
4890
5171
|
position: "fixed",
|
|
4891
|
-
|
|
4892
|
-
left: "1vh",
|
|
5172
|
+
...placementStyle(placement),
|
|
4893
5173
|
zIndex: 2147483647,
|
|
4894
5174
|
pointerEvents: "auto",
|
|
4895
5175
|
fontSize: "1.4vh"
|
|
@@ -5015,6 +5295,7 @@ exports.InfoBox = InfoBox;
|
|
|
5015
5295
|
exports.InputContainer = InputContainer;
|
|
5016
5296
|
exports.LevelBanner = LevelBanner;
|
|
5017
5297
|
exports.LevelPanel = LevelPanel;
|
|
5298
|
+
exports.MissingItemsBanner = MissingItemsBanner;
|
|
5018
5299
|
exports.Modal = Modal;
|
|
5019
5300
|
exports.ModalContext = ModalContext;
|
|
5020
5301
|
exports.ModalProvider = ModalProvider;
|
|
@@ -5036,6 +5317,7 @@ exports.Vector4DeleteButton = Vector4DeleteButton;
|
|
|
5036
5317
|
exports.Vector4Display = Vector4Display;
|
|
5037
5318
|
exports.WorldPositionGotoButton = WorldPositionGotoButton;
|
|
5038
5319
|
exports.WorldPositionSetButton = WorldPositionSetButton;
|
|
5320
|
+
exports.useMissingItemsAudit = useMissingItemsAudit;
|
|
5039
5321
|
exports.useModal = useModal;
|
|
5040
5322
|
exports.useModalActions = useModalActions;
|
|
5041
5323
|
exports.useNavigation = useNavigation;
|