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
package/dist/components/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Flex, Text, Image, TextInput, Select, Box, useMantineTheme, Tooltip, alpha, Progress, RingProgress, Portal, Button, NumberInput, MultiSelect, Loader, ActionIcon, Stack, Group, JsonInput } from '@mantine/core';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
-
import { createContext, useContext, useRef, useState, useEffect, useMemo } from 'react';
|
|
3
|
+
import { createContext, useContext, useRef, useState, useEffect, useCallback, useMemo } from 'react';
|
|
4
4
|
import { create, useStore, createStore } from 'zustand';
|
|
5
5
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
6
6
|
import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
|
|
7
|
-
import { Info, X, AlertTriangle, Trash2, MapPin, Crosshair, EyeOff, Eye, RotateCcw,
|
|
7
|
+
import { Info, X, AlertTriangle, Trash2, RefreshCw, ChevronDown, Check, Copy, MapPin, Crosshair, EyeOff, Eye, RotateCcw, FlaskConical, ChevronUp, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
|
|
8
8
|
import clickSoundUrl from '../click_sound-PNCRRTM4.mp3';
|
|
9
9
|
import hoverSoundUrl from '../hover_sound-NBUA222C.mp3';
|
|
10
10
|
import { notifications } from '@mantine/notifications';
|
|
@@ -1229,11 +1229,11 @@ var colorNames = {
|
|
|
1229
1229
|
Yellow: { r: 255, g: 255, b: 0 },
|
|
1230
1230
|
YellowGreen: { r: 154, g: 205, b: 50 }
|
|
1231
1231
|
};
|
|
1232
|
-
function colorWithAlpha(color,
|
|
1232
|
+
function colorWithAlpha(color, alpha10) {
|
|
1233
1233
|
const lowerCasedColor = color.toLowerCase();
|
|
1234
1234
|
if (colorNames[lowerCasedColor]) {
|
|
1235
1235
|
const rgb = colorNames[lowerCasedColor];
|
|
1236
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${
|
|
1236
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha10})`;
|
|
1237
1237
|
}
|
|
1238
1238
|
if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
|
|
1239
1239
|
const hex = color.slice(1);
|
|
@@ -1241,12 +1241,12 @@ function colorWithAlpha(color, alpha9) {
|
|
|
1241
1241
|
const r = bigint >> 16 & 255;
|
|
1242
1242
|
const g = bigint >> 8 & 255;
|
|
1243
1243
|
const b = bigint & 255;
|
|
1244
|
-
return `rgba(${r}, ${g}, ${b}, ${
|
|
1244
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha10})`;
|
|
1245
1245
|
}
|
|
1246
1246
|
if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
|
|
1247
1247
|
const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
|
|
1248
1248
|
if (result) {
|
|
1249
|
-
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${
|
|
1249
|
+
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha10})`;
|
|
1250
1250
|
}
|
|
1251
1251
|
}
|
|
1252
1252
|
return color;
|
|
@@ -1292,7 +1292,11 @@ async function fetchNui(eventName, data, mockData) {
|
|
|
1292
1292
|
return {};
|
|
1293
1293
|
}
|
|
1294
1294
|
const overrideResourceName = useSettings.getState().overideResourceName;
|
|
1295
|
-
const
|
|
1295
|
+
const hasResourceContext = typeof window.GetParentResourceName === "function" || !!overrideResourceName;
|
|
1296
|
+
if (!hasResourceContext) {
|
|
1297
|
+
return mockData ?? {};
|
|
1298
|
+
}
|
|
1299
|
+
const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : overrideResourceName;
|
|
1296
1300
|
try {
|
|
1297
1301
|
const resp = await fetch(`https://${resourceName}/${eventName}`, options);
|
|
1298
1302
|
return await resp.json();
|
|
@@ -2465,9 +2469,25 @@ function SegmentedProgress(props) {
|
|
|
2465
2469
|
}
|
|
2466
2470
|
);
|
|
2467
2471
|
}
|
|
2472
|
+
function getSizePreset(size, themeMdFontSize) {
|
|
2473
|
+
switch (size) {
|
|
2474
|
+
case "xs":
|
|
2475
|
+
return { iconFontSize: "1.2vh", iconPadding: "xxs", titleSize: "xxs", titleLineHeight: "1.2vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
|
|
2476
|
+
case "sm":
|
|
2477
|
+
return { iconFontSize: "1.6vh", iconPadding: "xxs", titleSize: "xs", titleLineHeight: "1.6vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
|
|
2478
|
+
case "lg":
|
|
2479
|
+
return { iconFontSize: "2.6vh", iconPadding: "sm", titleSize: "md", titleLineHeight: "2.6vh", descriptionSize: "sm", innerGap: "sm", bottomPad: "sm" };
|
|
2480
|
+
case "xl":
|
|
2481
|
+
return { iconFontSize: "3.2vh", iconPadding: "sm", titleSize: "lg", titleLineHeight: "3.2vh", descriptionSize: "md", innerGap: "md", bottomPad: "md" };
|
|
2482
|
+
case "md":
|
|
2483
|
+
default:
|
|
2484
|
+
return { iconFontSize: themeMdFontSize, iconPadding: "xs", titleSize: "sm", titleLineHeight: themeMdFontSize, descriptionSize: "xs", innerGap: "sm", bottomPad: "sm" };
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2468
2487
|
function Title(props) {
|
|
2469
2488
|
const game = useSettings((state) => state.game);
|
|
2470
2489
|
const theme = useMantineTheme();
|
|
2490
|
+
const preset = getSizePreset(props.size ?? "md", theme.fontSizes.md);
|
|
2471
2491
|
return /* @__PURE__ */ jsx(
|
|
2472
2492
|
Flex,
|
|
2473
2493
|
{
|
|
@@ -2476,71 +2496,50 @@ function Title(props) {
|
|
|
2476
2496
|
gap: "xs",
|
|
2477
2497
|
w: props.w || "100%",
|
|
2478
2498
|
p: props.p || "unset",
|
|
2479
|
-
pb: !props.p ?
|
|
2499
|
+
pb: !props.p ? preset.bottomPad : props.p,
|
|
2480
2500
|
style: {
|
|
2481
2501
|
userSelect: "none",
|
|
2482
2502
|
borderBottom: props.removeBorder ? "none" : `0.3vh solid ${props.borderColor || colorWithAlpha(theme.colors[theme.primaryColor][9], 0.5)}`
|
|
2483
2503
|
},
|
|
2484
|
-
children: /* @__PURE__ */ jsxs(
|
|
2485
|
-
Flex,
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2504
|
+
children: /* @__PURE__ */ jsxs(Flex, { align: "center", justify: "center", children: [
|
|
2505
|
+
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: preset.innerGap, pr: "xs", children: [
|
|
2506
|
+
/* @__PURE__ */ jsx(
|
|
2507
|
+
BorderedIcon,
|
|
2508
|
+
{
|
|
2509
|
+
icon: props.icon,
|
|
2510
|
+
fontSize: preset.iconFontSize,
|
|
2511
|
+
color: props.iconColor,
|
|
2512
|
+
p: preset.iconPadding
|
|
2513
|
+
}
|
|
2514
|
+
),
|
|
2515
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: "0.25vh", children: [
|
|
2516
|
+
/* @__PURE__ */ jsx(
|
|
2517
|
+
Text,
|
|
2492
2518
|
{
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
color: props.iconColor
|
|
2503
|
-
}
|
|
2504
|
-
),
|
|
2505
|
-
/* @__PURE__ */ jsxs(
|
|
2506
|
-
Flex,
|
|
2507
|
-
{
|
|
2508
|
-
direction: "column",
|
|
2509
|
-
gap: "0.25vh",
|
|
2510
|
-
children: [
|
|
2511
|
-
/* @__PURE__ */ jsx(Text, { p: "0", size: "sm", style: {
|
|
2512
|
-
lineHeight: theme.fontSizes.md,
|
|
2513
|
-
fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
|
|
2514
|
-
letterSpacing: "0.05em",
|
|
2515
|
-
textTransform: "uppercase"
|
|
2516
|
-
}, children: props.title }),
|
|
2517
|
-
/* @__PURE__ */ jsx(
|
|
2518
|
-
Text,
|
|
2519
|
-
{
|
|
2520
|
-
size: "xs",
|
|
2521
|
-
c: "grey",
|
|
2522
|
-
style: { whiteSpace: "normal", wordWrap: "break-word" },
|
|
2523
|
-
children: props.description
|
|
2524
|
-
}
|
|
2525
|
-
)
|
|
2526
|
-
]
|
|
2527
|
-
}
|
|
2528
|
-
)
|
|
2529
|
-
]
|
|
2519
|
+
p: "0",
|
|
2520
|
+
size: preset.titleSize,
|
|
2521
|
+
style: {
|
|
2522
|
+
lineHeight: preset.titleLineHeight,
|
|
2523
|
+
fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
|
|
2524
|
+
letterSpacing: "0.05em",
|
|
2525
|
+
textTransform: "uppercase"
|
|
2526
|
+
},
|
|
2527
|
+
children: props.title
|
|
2530
2528
|
}
|
|
2531
2529
|
),
|
|
2532
2530
|
/* @__PURE__ */ jsx(
|
|
2533
|
-
|
|
2531
|
+
Text,
|
|
2534
2532
|
{
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
children: props.
|
|
2533
|
+
size: preset.descriptionSize,
|
|
2534
|
+
c: "grey",
|
|
2535
|
+
style: { whiteSpace: "normal", wordWrap: "break-word" },
|
|
2536
|
+
children: props.description
|
|
2539
2537
|
}
|
|
2540
2538
|
)
|
|
2541
|
-
]
|
|
2542
|
-
}
|
|
2543
|
-
|
|
2539
|
+
] })
|
|
2540
|
+
] }),
|
|
2541
|
+
/* @__PURE__ */ jsx(Flex, { ml: "auto", align: "center", gap: "xs", children: props.rightSection })
|
|
2542
|
+
] })
|
|
2544
2543
|
}
|
|
2545
2544
|
);
|
|
2546
2545
|
}
|
|
@@ -3198,6 +3197,246 @@ function ConfirmModal({
|
|
|
3198
3197
|
}
|
|
3199
3198
|
) });
|
|
3200
3199
|
}
|
|
3200
|
+
var TABS = [
|
|
3201
|
+
{ id: "ox", label: "ox_inventory" },
|
|
3202
|
+
{ id: "qb", label: "qb-inventory" },
|
|
3203
|
+
{ id: "esx", label: "ESX legacy SQL" }
|
|
3204
|
+
];
|
|
3205
|
+
var useMissingItemsAudit = create((set, get) => ({
|
|
3206
|
+
data: null,
|
|
3207
|
+
loaded: false,
|
|
3208
|
+
inFlight: false,
|
|
3209
|
+
refresh: async () => {
|
|
3210
|
+
if (get().inFlight) return;
|
|
3211
|
+
set({ inFlight: true });
|
|
3212
|
+
try {
|
|
3213
|
+
const res = await fetchNui("GET_MISSING_ITEMS", void 0, {
|
|
3214
|
+
success: true,
|
|
3215
|
+
data: { missing: [], snippets: { ox: "", qb: "", esx: "" } }
|
|
3216
|
+
});
|
|
3217
|
+
if (res?.success && res.data) {
|
|
3218
|
+
set({ data: res.data, loaded: true });
|
|
3219
|
+
} else {
|
|
3220
|
+
set({ loaded: true });
|
|
3221
|
+
}
|
|
3222
|
+
} catch {
|
|
3223
|
+
set({ loaded: true });
|
|
3224
|
+
} finally {
|
|
3225
|
+
set({ inFlight: false });
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
}));
|
|
3229
|
+
function MissingItemsBanner() {
|
|
3230
|
+
const theme = useMantineTheme();
|
|
3231
|
+
const audit = useMissingItemsAudit((s) => s.data);
|
|
3232
|
+
const loaded = useMissingItemsAudit((s) => s.loaded);
|
|
3233
|
+
const inFlight = useMissingItemsAudit((s) => s.inFlight);
|
|
3234
|
+
const refresh = useMissingItemsAudit((s) => s.refresh);
|
|
3235
|
+
const [expanded, setExpanded] = useState(false);
|
|
3236
|
+
const [activeTab, setActiveTab] = useState("ox");
|
|
3237
|
+
const [hoveredTab, setHoveredTab] = useState(null);
|
|
3238
|
+
const [copied, setCopied] = useState(null);
|
|
3239
|
+
useEffect(() => {
|
|
3240
|
+
if (!loaded) refresh();
|
|
3241
|
+
}, [loaded, refresh]);
|
|
3242
|
+
const handleCopy = useCallback((tab) => {
|
|
3243
|
+
if (!audit) return;
|
|
3244
|
+
const text = audit.snippets[tab] ?? "";
|
|
3245
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
3246
|
+
setCopied(tab);
|
|
3247
|
+
setTimeout(() => setCopied((c) => c === tab ? null : c), 1500);
|
|
3248
|
+
}).catch(() => {
|
|
3249
|
+
});
|
|
3250
|
+
}, [audit]);
|
|
3251
|
+
const handleRefresh = useCallback((e) => {
|
|
3252
|
+
e.stopPropagation();
|
|
3253
|
+
refresh();
|
|
3254
|
+
}, [refresh]);
|
|
3255
|
+
if (!audit || audit.missing.length === 0) return null;
|
|
3256
|
+
const warnColor = "#f59e0b";
|
|
3257
|
+
const names = audit.missing.map((m) => m.name);
|
|
3258
|
+
return /* @__PURE__ */ jsxs(
|
|
3259
|
+
"div",
|
|
3260
|
+
{
|
|
3261
|
+
style: {
|
|
3262
|
+
background: alpha(warnColor, 0.06),
|
|
3263
|
+
border: `0.1vh solid ${alpha(warnColor, 0.35)}`,
|
|
3264
|
+
borderLeft: `0.3vh solid ${warnColor}`,
|
|
3265
|
+
borderRadius: theme.radius.xs,
|
|
3266
|
+
margin: "0.6vh 1vh",
|
|
3267
|
+
overflow: "hidden"
|
|
3268
|
+
},
|
|
3269
|
+
children: [
|
|
3270
|
+
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: "0.8vh", p: "0.8vh 1vh", style: { cursor: "pointer" }, onClick: () => setExpanded((e) => !e), children: [
|
|
3271
|
+
/* @__PURE__ */ jsx(AlertTriangle, { size: "1.8vh", color: warnColor, strokeWidth: 2.5 }),
|
|
3272
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
3273
|
+
/* @__PURE__ */ jsx(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` }),
|
|
3274
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.5)", lineClamp: 1, style: { fontFamily: "monospace" }, children: names.join(", ") })
|
|
3275
|
+
] }),
|
|
3276
|
+
/* @__PURE__ */ jsx(
|
|
3277
|
+
"button",
|
|
3278
|
+
{
|
|
3279
|
+
onClick: handleRefresh,
|
|
3280
|
+
disabled: inFlight,
|
|
3281
|
+
style: {
|
|
3282
|
+
background: "transparent",
|
|
3283
|
+
border: "none",
|
|
3284
|
+
padding: "0.3vh",
|
|
3285
|
+
cursor: inFlight ? "wait" : "pointer",
|
|
3286
|
+
display: "flex",
|
|
3287
|
+
alignItems: "center",
|
|
3288
|
+
justifyContent: "center",
|
|
3289
|
+
opacity: inFlight ? 0.4 : 0.7
|
|
3290
|
+
},
|
|
3291
|
+
title: "Re-check",
|
|
3292
|
+
children: /* @__PURE__ */ jsx(
|
|
3293
|
+
motion.span,
|
|
3294
|
+
{
|
|
3295
|
+
animate: { rotate: inFlight ? 360 : 0 },
|
|
3296
|
+
transition: inFlight ? { duration: 1, repeat: Infinity, ease: "linear" } : { duration: 0 },
|
|
3297
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3298
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { size: "1.5vh", color: alpha(warnColor, 0.7) })
|
|
3299
|
+
}
|
|
3300
|
+
)
|
|
3301
|
+
}
|
|
3302
|
+
),
|
|
3303
|
+
/* @__PURE__ */ jsx(
|
|
3304
|
+
motion.div,
|
|
3305
|
+
{
|
|
3306
|
+
animate: { rotate: expanded ? 180 : 0 },
|
|
3307
|
+
transition: { duration: 0.18 },
|
|
3308
|
+
style: { display: "flex", alignItems: "center", justifyContent: "center" },
|
|
3309
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { size: "1.8vh", color: alpha(warnColor, 0.7) })
|
|
3310
|
+
}
|
|
3311
|
+
)
|
|
3312
|
+
] }),
|
|
3313
|
+
/* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: expanded && /* @__PURE__ */ jsxs(
|
|
3314
|
+
motion.div,
|
|
3315
|
+
{
|
|
3316
|
+
initial: { height: 0, opacity: 0 },
|
|
3317
|
+
animate: { height: "auto", opacity: 1 },
|
|
3318
|
+
exit: { height: 0, opacity: 0 },
|
|
3319
|
+
transition: { duration: 0.18, ease: "easeOut" },
|
|
3320
|
+
style: { overflow: "hidden", borderTop: `0.1vh solid ${alpha(warnColor, 0.18)}` },
|
|
3321
|
+
children: [
|
|
3322
|
+
/* @__PURE__ */ jsx(Flex, { gap: "0", style: { borderBottom: `0.1vh solid ${alpha(warnColor, 0.18)}` }, children: TABS.map((tab) => {
|
|
3323
|
+
const active = tab.id === activeTab;
|
|
3324
|
+
const hovered = hoveredTab === tab.id;
|
|
3325
|
+
let bg = "transparent";
|
|
3326
|
+
if (active) bg = alpha(warnColor, 0.12);
|
|
3327
|
+
else if (hovered) bg = alpha(warnColor, 0.08);
|
|
3328
|
+
return /* @__PURE__ */ jsx(
|
|
3329
|
+
"button",
|
|
3330
|
+
{
|
|
3331
|
+
onClick: (e) => {
|
|
3332
|
+
e.stopPropagation();
|
|
3333
|
+
setActiveTab(tab.id);
|
|
3334
|
+
},
|
|
3335
|
+
onMouseEnter: () => setHoveredTab(tab.id),
|
|
3336
|
+
onMouseLeave: () => setHoveredTab((h) => h === tab.id ? null : h),
|
|
3337
|
+
style: {
|
|
3338
|
+
flex: 1,
|
|
3339
|
+
background: bg,
|
|
3340
|
+
border: "none",
|
|
3341
|
+
borderBottom: active ? `0.2vh solid ${warnColor}` : "0.2vh solid transparent",
|
|
3342
|
+
padding: "0.3vh 1vh",
|
|
3343
|
+
cursor: active ? "default" : "pointer",
|
|
3344
|
+
color: active ? warnColor : "rgba(255,255,255,0.5)",
|
|
3345
|
+
fontFamily: "Akrobat Bold",
|
|
3346
|
+
fontSize: "var(--mantine-font-size-xxs)",
|
|
3347
|
+
letterSpacing: "0.07em",
|
|
3348
|
+
textTransform: "uppercase",
|
|
3349
|
+
transition: "background 0.12s"
|
|
3350
|
+
},
|
|
3351
|
+
children: tab.label
|
|
3352
|
+
},
|
|
3353
|
+
tab.id
|
|
3354
|
+
);
|
|
3355
|
+
}) }),
|
|
3356
|
+
/* @__PURE__ */ jsx(
|
|
3357
|
+
CodeView,
|
|
3358
|
+
{
|
|
3359
|
+
code: audit.snippets[activeTab] ?? "",
|
|
3360
|
+
copied: copied === activeTab,
|
|
3361
|
+
onCopy: (e) => {
|
|
3362
|
+
e.stopPropagation();
|
|
3363
|
+
handleCopy(activeTab);
|
|
3364
|
+
},
|
|
3365
|
+
warnColor
|
|
3366
|
+
}
|
|
3367
|
+
)
|
|
3368
|
+
]
|
|
3369
|
+
},
|
|
3370
|
+
"expanded"
|
|
3371
|
+
) })
|
|
3372
|
+
]
|
|
3373
|
+
}
|
|
3374
|
+
);
|
|
3375
|
+
}
|
|
3376
|
+
function CodeView({
|
|
3377
|
+
code,
|
|
3378
|
+
copied,
|
|
3379
|
+
onCopy,
|
|
3380
|
+
warnColor
|
|
3381
|
+
}) {
|
|
3382
|
+
const theme = useMantineTheme();
|
|
3383
|
+
const [hovered, setHovered] = useState(false);
|
|
3384
|
+
const lines = code === "" ? [""] : code.split("\n");
|
|
3385
|
+
const lineNumWidth = String(lines.length).length;
|
|
3386
|
+
const copyBg = copied ? alpha("#22c55e", 0.15) : hovered ? alpha(warnColor, 0.18) : alpha(warnColor, 0.1);
|
|
3387
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
3388
|
+
/* @__PURE__ */ jsxs(
|
|
3389
|
+
"button",
|
|
3390
|
+
{
|
|
3391
|
+
onClick: onCopy,
|
|
3392
|
+
onMouseEnter: () => setHovered(true),
|
|
3393
|
+
onMouseLeave: () => setHovered(false),
|
|
3394
|
+
style: {
|
|
3395
|
+
position: "absolute",
|
|
3396
|
+
top: "0.6vh",
|
|
3397
|
+
right: "0.8vh",
|
|
3398
|
+
zIndex: 2,
|
|
3399
|
+
background: copyBg,
|
|
3400
|
+
border: `0.1vh solid ${alpha(copied ? "#22c55e" : warnColor, 0.35)}`,
|
|
3401
|
+
borderRadius: theme.radius.xs,
|
|
3402
|
+
padding: "0.4vh 0.7vh",
|
|
3403
|
+
cursor: "pointer",
|
|
3404
|
+
display: "flex",
|
|
3405
|
+
alignItems: "center",
|
|
3406
|
+
gap: "0.4vh",
|
|
3407
|
+
transition: "background 0.12s"
|
|
3408
|
+
},
|
|
3409
|
+
children: [
|
|
3410
|
+
copied ? /* @__PURE__ */ jsx(Check, { size: "1.4vh", color: "#22c55e" }) : /* @__PURE__ */ jsx(Copy, { size: "1.4vh", color: warnColor }),
|
|
3411
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: copied ? "#22c55e" : warnColor, children: copied ? "Copied" : "Copy" })
|
|
3412
|
+
]
|
|
3413
|
+
}
|
|
3414
|
+
),
|
|
3415
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
3416
|
+
background: alpha(theme.colors.dark[9], 0.6),
|
|
3417
|
+
maxHeight: "40vh",
|
|
3418
|
+
overflowY: "auto",
|
|
3419
|
+
overflowX: "auto",
|
|
3420
|
+
padding: "0.6vh 0"
|
|
3421
|
+
}, children: /* @__PURE__ */ jsx("table", { style: { borderCollapse: "collapse", width: "100%", fontFamily: "monospace", fontSize: "1.2vh", lineHeight: 1.5 }, children: /* @__PURE__ */ jsx("tbody", { children: lines.map((line, i) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
3422
|
+
/* @__PURE__ */ jsx("td", { style: {
|
|
3423
|
+
width: `${lineNumWidth + 2}ch`,
|
|
3424
|
+
textAlign: "right",
|
|
3425
|
+
padding: "0 0.8vh 0 1vh",
|
|
3426
|
+
color: "rgba(255,255,255,0.25)",
|
|
3427
|
+
userSelect: "none",
|
|
3428
|
+
whiteSpace: "nowrap",
|
|
3429
|
+
verticalAlign: "top"
|
|
3430
|
+
}, children: i + 1 }),
|
|
3431
|
+
/* @__PURE__ */ jsx("td", { style: {
|
|
3432
|
+
padding: "0 1vh",
|
|
3433
|
+
color: "rgba(255,255,255,0.85)",
|
|
3434
|
+
whiteSpace: "pre",
|
|
3435
|
+
verticalAlign: "top"
|
|
3436
|
+
}, children: line || "\u200B" })
|
|
3437
|
+
] }, i)) }) }) })
|
|
3438
|
+
] });
|
|
3439
|
+
}
|
|
3201
3440
|
function getNested(obj, path) {
|
|
3202
3441
|
return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
|
|
3203
3442
|
}
|
|
@@ -3800,7 +4039,8 @@ function ConfigPanelInner({
|
|
|
3800
4039
|
resetConfirmText,
|
|
3801
4040
|
defaultConfig,
|
|
3802
4041
|
width,
|
|
3803
|
-
height
|
|
4042
|
+
height,
|
|
4043
|
+
suppressMissingItemsBanner
|
|
3804
4044
|
}) {
|
|
3805
4045
|
const { updateConfig, resetConfig, getHistory } = getScriptConfigInstance();
|
|
3806
4046
|
const form = useForm();
|
|
@@ -3920,8 +4160,8 @@ function ConfigPanelInner({
|
|
|
3920
4160
|
children: /* @__PURE__ */ jsx(ArrowLeft, { size: "1.4vh", color })
|
|
3921
4161
|
}
|
|
3922
4162
|
),
|
|
3923
|
-
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { minWidth: 0, lineHeight: 1 }, children: [
|
|
3924
|
-
/* @__PURE__ */ jsx(Text, { size: "
|
|
4163
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { minWidth: 0, flex: 1, lineHeight: 1, overflow: "hidden" }, children: [
|
|
4164
|
+
/* @__PURE__ */ jsx(Text, { size: "md", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
|
|
3925
4165
|
subtitle && /* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.08em", c: color, truncate: true, children: subtitle })
|
|
3926
4166
|
] })
|
|
3927
4167
|
] }),
|
|
@@ -4023,18 +4263,21 @@ function ConfigPanelInner({
|
|
|
4023
4263
|
] })
|
|
4024
4264
|
] })
|
|
4025
4265
|
] }),
|
|
4026
|
-
/* @__PURE__ */
|
|
4027
|
-
|
|
4028
|
-
{
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4266
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: [
|
|
4267
|
+
!suppressMissingItemsBanner && /* @__PURE__ */ jsx(MissingItemsBanner, {}),
|
|
4268
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
|
|
4269
|
+
motion.div,
|
|
4270
|
+
{
|
|
4271
|
+
initial: firstMountRef.current ? (firstMountRef.current = false, false) : { opacity: 0, y: 4 },
|
|
4272
|
+
animate: { opacity: 1, y: 0 },
|
|
4273
|
+
exit: { opacity: 0, y: -4 },
|
|
4274
|
+
transition: { duration: 0.15 },
|
|
4275
|
+
style: { flex: 1, display: "flex", flexDirection: "column", overflowY: "auto" },
|
|
4276
|
+
children: children(activeTab)
|
|
4277
|
+
},
|
|
4278
|
+
activeTab
|
|
4279
|
+
) })
|
|
4280
|
+
] })
|
|
4038
4281
|
]
|
|
4039
4282
|
}
|
|
4040
4283
|
)
|
|
@@ -4076,6 +4319,7 @@ function ConfigPanel(props) {
|
|
|
4076
4319
|
if (result?.success) {
|
|
4077
4320
|
form.reinitialize(cloneConfig(form.values));
|
|
4078
4321
|
configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
4322
|
+
useMissingItemsAudit.getState().refresh();
|
|
4079
4323
|
notifications.show({
|
|
4080
4324
|
color: "green",
|
|
4081
4325
|
title: locale("ConfigSaveSuccessTitle"),
|
|
@@ -4113,6 +4357,7 @@ function ConfigPanel(props) {
|
|
|
4113
4357
|
}
|
|
4114
4358
|
) });
|
|
4115
4359
|
}
|
|
4360
|
+
var MISSING_COLOR = "#f59e0b";
|
|
4116
4361
|
function LazyImage({ src, style }) {
|
|
4117
4362
|
const [visible, setVisible] = useState(false);
|
|
4118
4363
|
const ref = useRef(null);
|
|
@@ -4130,14 +4375,19 @@ function LazyImage({ src, style }) {
|
|
|
4130
4375
|
}
|
|
4131
4376
|
function SelectItem(props) {
|
|
4132
4377
|
const invItems = useItems();
|
|
4378
|
+
const isMissing = !!props.value && !invItems[props.value];
|
|
4133
4379
|
const formattedItems = useMemo(() => {
|
|
4134
4380
|
const seen = /* @__PURE__ */ new Set();
|
|
4135
|
-
|
|
4381
|
+
const list = useItemsList(props.excludeItemNames ?? []).filter((item) => {
|
|
4136
4382
|
if (seen.has(item.name)) return false;
|
|
4137
4383
|
seen.add(item.name);
|
|
4138
4384
|
return true;
|
|
4139
4385
|
}).map((item) => ({ value: item.name, label: item.label, image: item.image }));
|
|
4140
|
-
|
|
4386
|
+
if (isMissing) {
|
|
4387
|
+
list.unshift({ value: props.value, label: props.value, image: "" });
|
|
4388
|
+
}
|
|
4389
|
+
return list;
|
|
4390
|
+
}, [invItems, props.excludeItemNames, props.value, isMissing]);
|
|
4141
4391
|
return /* @__PURE__ */ jsx(
|
|
4142
4392
|
Select,
|
|
4143
4393
|
{
|
|
@@ -4152,10 +4402,11 @@ function SelectItem(props) {
|
|
|
4152
4402
|
data: formattedItems,
|
|
4153
4403
|
allowDeselect: false,
|
|
4154
4404
|
searchable: true,
|
|
4405
|
+
styles: isMissing ? { input: { color: MISSING_COLOR } } : void 0,
|
|
4155
4406
|
comboboxProps: { withinPortal: true, zIndex: 2e3 },
|
|
4156
4407
|
leftSectionWidth: "4vh",
|
|
4157
4408
|
leftSectionPointerEvents: "none",
|
|
4158
|
-
leftSection: props.value ? /* @__PURE__ */ jsx(
|
|
4409
|
+
leftSection: isMissing ? /* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", children: /* @__PURE__ */ jsx(AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }) : props.value ? /* @__PURE__ */ jsx(
|
|
4159
4410
|
Image,
|
|
4160
4411
|
{
|
|
4161
4412
|
fallbackSrc: "/placeholder.png",
|
|
@@ -4166,19 +4417,37 @@ function SelectItem(props) {
|
|
|
4166
4417
|
}
|
|
4167
4418
|
) : null,
|
|
4168
4419
|
nothingFoundMessage: locale("NoItemsFound"),
|
|
4169
|
-
renderOption: (item) =>
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
{
|
|
4173
|
-
|
|
4174
|
-
style: {
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4420
|
+
renderOption: (item) => {
|
|
4421
|
+
const optionMissing = !invItems[item.option.value] && item.option.value === props.value;
|
|
4422
|
+
if (optionMissing) {
|
|
4423
|
+
return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
4424
|
+
/* @__PURE__ */ jsx(Flex, { align: "center", justify: "center", w: "4vh", h: "4vh", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx(AlertTriangle, { size: "2vh", color: MISSING_COLOR, strokeWidth: 2.5 }) }),
|
|
4425
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", style: { flex: 1, minWidth: 0 }, children: [
|
|
4426
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", c: MISSING_COLOR, style: { fontFamily: "monospace" }, children: item.option.value }),
|
|
4427
|
+
/* @__PURE__ */ jsx(Text, { size: "xxs", c: "dimmed", children: locale("ItemNotInInventory") })
|
|
4428
|
+
] }),
|
|
4429
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
4430
|
+
background: "rgba(245,158,11,0.12)",
|
|
4431
|
+
border: `0.1vh solid ${MISSING_COLOR}59`,
|
|
4432
|
+
borderRadius: "0.3vh",
|
|
4433
|
+
padding: "0.1vh 0.6vh"
|
|
4434
|
+
}, children: /* @__PURE__ */ jsx(Text, { size: "xxs", c: MISSING_COLOR, ff: "Akrobat Bold", tt: "uppercase", lts: "0.06em", children: locale("Missing") }) })
|
|
4435
|
+
] });
|
|
4436
|
+
}
|
|
4437
|
+
return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xs", w: "100%", children: [
|
|
4438
|
+
/* @__PURE__ */ jsx(
|
|
4439
|
+
LazyImage,
|
|
4440
|
+
{
|
|
4441
|
+
src: invItems[item.option.value]?.image || "",
|
|
4442
|
+
style: { aspectRatio: "1 / 1" }
|
|
4443
|
+
}
|
|
4444
|
+
),
|
|
4445
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
|
|
4446
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", children: item.option.label }),
|
|
4447
|
+
/* @__PURE__ */ jsx(Text, { size: "xxs", c: "dimmed", children: item.option.value })
|
|
4448
|
+
] })
|
|
4449
|
+
] });
|
|
4450
|
+
}
|
|
4182
4451
|
}
|
|
4183
4452
|
);
|
|
4184
4453
|
}
|
|
@@ -4833,6 +5102,17 @@ function AdminPageTitle(props) {
|
|
|
4833
5102
|
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
|
|
4834
5103
|
] });
|
|
4835
5104
|
}
|
|
5105
|
+
var placementStyle = (placement) => {
|
|
5106
|
+
switch (placement) {
|
|
5107
|
+
case "top-center":
|
|
5108
|
+
return { top: "1vh", left: "50%", transform: "translateX(-50%)" };
|
|
5109
|
+
case "top-right":
|
|
5110
|
+
return { top: "1vh", right: "1vh" };
|
|
5111
|
+
case "top-left":
|
|
5112
|
+
default:
|
|
5113
|
+
return { top: "1vh", left: "1vh" };
|
|
5114
|
+
}
|
|
5115
|
+
};
|
|
4836
5116
|
var loadPersistedState = (storageKey) => {
|
|
4837
5117
|
try {
|
|
4838
5118
|
const raw = localStorage.getItem(storageKey);
|
|
@@ -4851,7 +5131,8 @@ function TestBed({
|
|
|
4851
5131
|
items,
|
|
4852
5132
|
storageKey = "testbed:open-state",
|
|
4853
5133
|
disablePersistence = false,
|
|
4854
|
-
title = "TestBed"
|
|
5134
|
+
title = "TestBed",
|
|
5135
|
+
placement = "top-left"
|
|
4855
5136
|
}) {
|
|
4856
5137
|
const [open, setOpen] = useState(false);
|
|
4857
5138
|
const itemsRef = useRef(items);
|
|
@@ -4881,8 +5162,7 @@ function TestBed({
|
|
|
4881
5162
|
{
|
|
4882
5163
|
style: {
|
|
4883
5164
|
position: "fixed",
|
|
4884
|
-
|
|
4885
|
-
left: "1vh",
|
|
5165
|
+
...placementStyle(placement),
|
|
4886
5166
|
zIndex: 2147483647,
|
|
4887
5167
|
pointerEvents: "auto",
|
|
4888
5168
|
fontSize: "1.4vh"
|
|
@@ -4988,6 +5268,6 @@ function TestBed({
|
|
|
4988
5268
|
);
|
|
4989
5269
|
}
|
|
4990
5270
|
|
|
4991
|
-
export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
|
|
5271
|
+
export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, MissingItemsBanner, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionSetButton, useMissingItemsAudit, useModal, useModalActions, useNavigation, useNavigationStore };
|
|
4992
5272
|
//# sourceMappingURL=index.js.map
|
|
4993
5273
|
//# sourceMappingURL=index.js.map
|