dirk-cfx-react 1.1.87 → 1.1.89
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 +872 -32
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +192 -2
- package/dist/components/index.d.ts +192 -2
- package/dist/components/index.js +863 -37
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +159 -26
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +16 -1
- package/dist/hooks/index.d.ts +16 -1
- package/dist/hooks/index.js +157 -28
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +1439 -451
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1342 -374
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +133 -1
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.d.cts +3 -1
- package/dist/providers/index.d.ts +3 -1
- package/dist/providers/index.js +134 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/usePlayers-BlGBBevs.d.cts +37 -0
- package/dist/usePlayers-BlGBBevs.d.ts +37 -0
- package/dist/utils/index.cjs +16 -8
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +2 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +16 -9
- package/dist/utils/index.js.map +1 -1
- package/package.json +123 -117
package/dist/index.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { Flex, Text, Image as Image$1, createTheme, Box, Stack, Title as Title$1, Code, TextInput, Select, useMantineTheme, Tooltip,
|
|
1
|
+
import { Flex, Text, Image as Image$1, createTheme, alpha, Box, Stack, Title as Title$1, Code, TextInput, Select, useMantineTheme, Tooltip, Progress, RingProgress, Portal, Button, MantineProvider, NumberInput, MultiSelect, Loader, Switch, ActionIcon, ColorInput, Popover, BackgroundImage, Group, JsonInput } from '@mantine/core';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
-
import
|
|
3
|
+
import React4, { createContext, memo, useRef, useEffect, useContext, useState, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
4
4
|
import { create, useStore, createStore } from 'zustand';
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
7
7
|
import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
|
|
8
|
-
import { Info, X, AlertTriangle, Trash2, RefreshCw, ChevronDown, Check, Copy, MapPin, Crosshair, EyeOff, Eye, RotateCcw, FlaskConical, ChevronUp, Palette, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
|
|
8
|
+
import { Info, X, AlertTriangle, Trash2, RefreshCw, ChevronDown, Check, Copy, MapPin, Crosshair, EyeOff, Eye, RotateCcw, FlaskConical, ChevronUp, Palette, DoorOpen, Plus, Minus, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
|
|
9
9
|
import clickSoundUrl from './click_sound-PNCRRTM4.mp3';
|
|
10
10
|
import hoverSoundUrl from './hover_sound-NBUA222C.mp3';
|
|
11
11
|
import { notifications } from '@mantine/notifications';
|
|
12
|
-
import { QueryClient, QueryClientProvider, useInfiniteQuery } from '@tanstack/react-query';
|
|
13
|
-
import { generateColors } from '@mantine/colors-generator';
|
|
12
|
+
import { QueryClient, QueryClientProvider, useQuery, keepPreviousData, useInfiniteQuery } from '@tanstack/react-query';
|
|
14
13
|
import '@mantine/core/styles.css';
|
|
15
14
|
import '@mantine/notifications/styles.css';
|
|
16
15
|
import './styles/fonts.css';
|
|
@@ -21,6 +20,12 @@ import { library } from '@fortawesome/fontawesome-svg-core';
|
|
|
21
20
|
import { fab } from '@fortawesome/free-brands-svg-icons';
|
|
22
21
|
import { far } from '@fortawesome/free-regular-svg-icons';
|
|
23
22
|
import { fas } from '@fortawesome/free-solid-svg-icons';
|
|
23
|
+
import { generateColors } from '@mantine/colors-generator';
|
|
24
|
+
import { createPortal } from 'react-dom';
|
|
25
|
+
import { CRS, tileLayer, latLngBounds, latLng } from 'leaflet';
|
|
26
|
+
import 'leaflet/dist/leaflet.css';
|
|
27
|
+
import { MapContainer, useMap } from 'react-leaflet';
|
|
28
|
+
import { Marker } from '@adamscybot/react-leaflet-component-marker';
|
|
24
29
|
import { z } from 'zod';
|
|
25
30
|
|
|
26
31
|
var __defProp = Object.defineProperty;
|
|
@@ -967,6 +972,18 @@ var BLIP_COLOR_DATA = BLIP_COLORS.map(([id, label2]) => ({
|
|
|
967
972
|
}));
|
|
968
973
|
var blipEntryMap = new Map(BLIP_ENTRIES.map(([id, name, ext]) => [String(id), { id, name, ext }]));
|
|
969
974
|
var blipColorMap = new Map(BLIP_COLORS.map(([id, label2, hex]) => [String(id), { id, label: label2, hex }]));
|
|
975
|
+
function getBlipEntry(spriteId) {
|
|
976
|
+
if (spriteId == null) return void 0;
|
|
977
|
+
return blipEntryMap.get(String(spriteId));
|
|
978
|
+
}
|
|
979
|
+
function getBlipColor(colorId) {
|
|
980
|
+
if (colorId == null) return void 0;
|
|
981
|
+
return blipColorMap.get(String(colorId));
|
|
982
|
+
}
|
|
983
|
+
function blipUrlForSprite(spriteId) {
|
|
984
|
+
const entry = getBlipEntry(spriteId);
|
|
985
|
+
return entry ? blipUrl(entry.name, entry.ext) : null;
|
|
986
|
+
}
|
|
970
987
|
var renderBlipOption = ({ option }) => {
|
|
971
988
|
const entry = blipEntryMap.get(option.value);
|
|
972
989
|
if (!entry) return option.label;
|
|
@@ -1244,11 +1261,11 @@ var colorNames = {
|
|
|
1244
1261
|
Yellow: { r: 255, g: 255, b: 0 },
|
|
1245
1262
|
YellowGreen: { r: 154, g: 205, b: 50 }
|
|
1246
1263
|
};
|
|
1247
|
-
function colorWithAlpha(color,
|
|
1264
|
+
function colorWithAlpha(color, alpha18) {
|
|
1248
1265
|
const lowerCasedColor = color.toLowerCase();
|
|
1249
1266
|
if (colorNames[lowerCasedColor]) {
|
|
1250
1267
|
const rgb = colorNames[lowerCasedColor];
|
|
1251
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${
|
|
1268
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha18})`;
|
|
1252
1269
|
}
|
|
1253
1270
|
if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
|
|
1254
1271
|
const hex = color.slice(1);
|
|
@@ -1256,12 +1273,12 @@ function colorWithAlpha(color, alpha12) {
|
|
|
1256
1273
|
const r = bigint >> 16 & 255;
|
|
1257
1274
|
const g = bigint >> 8 & 255;
|
|
1258
1275
|
const b = bigint & 255;
|
|
1259
|
-
return `rgba(${r}, ${g}, ${b}, ${
|
|
1276
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha18})`;
|
|
1260
1277
|
}
|
|
1261
1278
|
if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
|
|
1262
1279
|
const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
|
|
1263
1280
|
if (result) {
|
|
1264
|
-
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${
|
|
1281
|
+
return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha18})`;
|
|
1265
1282
|
}
|
|
1266
1283
|
}
|
|
1267
1284
|
return color;
|
|
@@ -1423,6 +1440,7 @@ if (typeof window !== "undefined") {
|
|
|
1423
1440
|
const msg = event.data;
|
|
1424
1441
|
if (!msg || msg.action !== "UPDATE_DIRK_LIB_LOCALES") return;
|
|
1425
1442
|
if (!msg.data || typeof msg.data !== "object") return;
|
|
1443
|
+
if (Object.keys(msg.data).length === 0) return;
|
|
1426
1444
|
localeStore.setState({ locales: msg.data });
|
|
1427
1445
|
});
|
|
1428
1446
|
}
|
|
@@ -1949,15 +1967,21 @@ var useFrameworkGroups = create(() => ({
|
|
|
1949
1967
|
gangs: [],
|
|
1950
1968
|
loaded: false
|
|
1951
1969
|
}));
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1970
|
+
var frameworkGroupsRequested = false;
|
|
1971
|
+
function ensureFrameworkGroups() {
|
|
1972
|
+
if (frameworkGroupsRequested) return;
|
|
1973
|
+
frameworkGroupsRequested = true;
|
|
1974
|
+
fetchNui("GET_FRAMEWORK_GROUPS", void 0).then((data) => {
|
|
1975
|
+
useFrameworkGroups.setState({
|
|
1976
|
+
jobs: Array.isArray(data?.jobs) ? data.jobs : [],
|
|
1977
|
+
gangs: Array.isArray(data?.gangs) ? data.gangs : [],
|
|
1978
|
+
loaded: true
|
|
1979
|
+
});
|
|
1980
|
+
}).catch(() => {
|
|
1981
|
+
frameworkGroupsRequested = false;
|
|
1982
|
+
useFrameworkGroups.setState({ loaded: true });
|
|
1957
1983
|
});
|
|
1958
|
-
}
|
|
1959
|
-
useFrameworkGroups.setState({ loaded: true });
|
|
1960
|
-
});
|
|
1984
|
+
}
|
|
1961
1985
|
function selectAllGroups(state) {
|
|
1962
1986
|
return [...state.jobs, ...state.gangs];
|
|
1963
1987
|
}
|
|
@@ -2991,7 +3015,7 @@ function NavigationProvider({ children, defaultPage }) {
|
|
|
2991
3015
|
}
|
|
2992
3016
|
function NavBar(props) {
|
|
2993
3017
|
const pageId = useNavigation((state) => state.pageId);
|
|
2994
|
-
const
|
|
3018
|
+
const store2 = useNavigationStore();
|
|
2995
3019
|
return /* @__PURE__ */ jsx(
|
|
2996
3020
|
SegmentedControl,
|
|
2997
3021
|
{
|
|
@@ -3000,7 +3024,7 @@ function NavBar(props) {
|
|
|
3000
3024
|
value: pageId,
|
|
3001
3025
|
items: props.items,
|
|
3002
3026
|
onChange: (value) => {
|
|
3003
|
-
|
|
3027
|
+
store2.setState({ pageId: value });
|
|
3004
3028
|
}
|
|
3005
3029
|
}
|
|
3006
3030
|
);
|
|
@@ -4307,29 +4331,29 @@ function FormProvider({
|
|
|
4307
4331
|
return /* @__PURE__ */ jsx(FormContext.Provider, { value: storeRef.current, children });
|
|
4308
4332
|
}
|
|
4309
4333
|
function useForm() {
|
|
4310
|
-
const
|
|
4311
|
-
if (!
|
|
4334
|
+
const store2 = useContext(FormContext);
|
|
4335
|
+
if (!store2) {
|
|
4312
4336
|
throw new Error("useForm must be used inside <FormProvider>");
|
|
4313
4337
|
}
|
|
4314
|
-
const state = useStore(
|
|
4338
|
+
const state = useStore(store2);
|
|
4315
4339
|
const changedFields = useMemo(() => {
|
|
4316
4340
|
return collectChangedPaths(state.values, state.initialValues);
|
|
4317
4341
|
}, [state.values, state.initialValues]);
|
|
4318
4342
|
return { ...state, changedFields, changedCount: changedFields.length };
|
|
4319
4343
|
}
|
|
4320
4344
|
function useFormField(path) {
|
|
4321
|
-
const
|
|
4322
|
-
if (!
|
|
4345
|
+
const store2 = useContext(FormContext);
|
|
4346
|
+
if (!store2) {
|
|
4323
4347
|
throw new Error("useFormField must be used inside <FormProvider>");
|
|
4324
4348
|
}
|
|
4325
|
-
return useStore(
|
|
4349
|
+
return useStore(store2, (s) => getNested(s.values, path));
|
|
4326
4350
|
}
|
|
4327
4351
|
function useFormFields(...paths) {
|
|
4328
|
-
const
|
|
4329
|
-
if (!
|
|
4352
|
+
const store2 = useContext(FormContext);
|
|
4353
|
+
if (!store2) {
|
|
4330
4354
|
throw new Error("useFormFields must be used inside <FormProvider>");
|
|
4331
4355
|
}
|
|
4332
|
-
return useStore(
|
|
4356
|
+
return useStore(store2, (s) => {
|
|
4333
4357
|
const result = {};
|
|
4334
4358
|
for (const path of paths) {
|
|
4335
4359
|
result[path] = getNested(s.values, path);
|
|
@@ -4338,18 +4362,18 @@ function useFormFields(...paths) {
|
|
|
4338
4362
|
});
|
|
4339
4363
|
}
|
|
4340
4364
|
function useFormError(path) {
|
|
4341
|
-
const
|
|
4342
|
-
if (!
|
|
4365
|
+
const store2 = useContext(FormContext);
|
|
4366
|
+
if (!store2) {
|
|
4343
4367
|
throw new Error("useFormError must be used inside <FormProvider>");
|
|
4344
4368
|
}
|
|
4345
|
-
return useStore(
|
|
4369
|
+
return useStore(store2, (s) => s.errors[path]);
|
|
4346
4370
|
}
|
|
4347
4371
|
function useFormErrors(...paths) {
|
|
4348
|
-
const
|
|
4349
|
-
if (!
|
|
4372
|
+
const store2 = useContext(FormContext);
|
|
4373
|
+
if (!store2) {
|
|
4350
4374
|
throw new Error("useFormErrors must be used inside <FormProvider>");
|
|
4351
4375
|
}
|
|
4352
|
-
return useStore(
|
|
4376
|
+
return useStore(store2, (s) => {
|
|
4353
4377
|
const result = {};
|
|
4354
4378
|
for (const path of paths) {
|
|
4355
4379
|
result[path] = s.errors[path];
|
|
@@ -4358,12 +4382,223 @@ function useFormErrors(...paths) {
|
|
|
4358
4382
|
});
|
|
4359
4383
|
}
|
|
4360
4384
|
function useFormActions() {
|
|
4361
|
-
const
|
|
4362
|
-
if (!
|
|
4385
|
+
const store2 = useContext(FormContext);
|
|
4386
|
+
if (!store2) {
|
|
4363
4387
|
throw new Error("useFormActions must be used inside <FormProvider>");
|
|
4364
4388
|
}
|
|
4365
|
-
return
|
|
4389
|
+
return store2.getState();
|
|
4390
|
+
}
|
|
4391
|
+
var store = /* @__PURE__ */ new Map();
|
|
4392
|
+
var listeners = /* @__PURE__ */ new Map();
|
|
4393
|
+
function notify(key) {
|
|
4394
|
+
const ls = listeners.get(key);
|
|
4395
|
+
if (!ls) return;
|
|
4396
|
+
ls.forEach((fn) => fn());
|
|
4397
|
+
}
|
|
4398
|
+
function useAdminState(key, initial) {
|
|
4399
|
+
const [, setTick] = useState(0);
|
|
4400
|
+
useEffect(() => {
|
|
4401
|
+
const set = listeners.get(key) ?? /* @__PURE__ */ new Set();
|
|
4402
|
+
listeners.set(key, set);
|
|
4403
|
+
const handler = () => setTick((t3) => t3 + 1);
|
|
4404
|
+
set.add(handler);
|
|
4405
|
+
return () => {
|
|
4406
|
+
set.delete(handler);
|
|
4407
|
+
if (set.size === 0) listeners.delete(key);
|
|
4408
|
+
};
|
|
4409
|
+
}, [key]);
|
|
4410
|
+
const value = store.has(key) ? store.get(key) : initial;
|
|
4411
|
+
const setValue = (v) => {
|
|
4412
|
+
const next = typeof v === "function" ? v(value) : v;
|
|
4413
|
+
store.set(key, next);
|
|
4414
|
+
notify(key);
|
|
4415
|
+
};
|
|
4416
|
+
return [value, setValue];
|
|
4417
|
+
}
|
|
4418
|
+
function clearAdminState(key) {
|
|
4419
|
+
if (key) {
|
|
4420
|
+
store.delete(key);
|
|
4421
|
+
notify(key);
|
|
4422
|
+
} else {
|
|
4423
|
+
const keys = Array.from(store.keys());
|
|
4424
|
+
store.clear();
|
|
4425
|
+
keys.forEach(notify);
|
|
4426
|
+
}
|
|
4366
4427
|
}
|
|
4428
|
+
var label = {
|
|
4429
|
+
fontSize: "var(--mantine-font-size-xs)",
|
|
4430
|
+
fontFamily: "Akrobat Bold",
|
|
4431
|
+
letterSpacing: "0.05em",
|
|
4432
|
+
textTransform: "uppercase"
|
|
4433
|
+
};
|
|
4434
|
+
var error = {
|
|
4435
|
+
fontSize: "var(--mantine-font-size-xs)",
|
|
4436
|
+
fontFamily: "Akrobat Regular"
|
|
4437
|
+
};
|
|
4438
|
+
var description = {
|
|
4439
|
+
fontSize: "var(--mantine-font-size-xs)"
|
|
4440
|
+
};
|
|
4441
|
+
var genericInputStyles = {
|
|
4442
|
+
styles: {
|
|
4443
|
+
label,
|
|
4444
|
+
error,
|
|
4445
|
+
description,
|
|
4446
|
+
input: {
|
|
4447
|
+
background: "rgba(255,255,255,0.04)",
|
|
4448
|
+
border: "0.1vh solid rgba(255,255,255,0.08)",
|
|
4449
|
+
color: "rgba(255,255,255,0.85)",
|
|
4450
|
+
minHeight: "4vh"
|
|
4451
|
+
}
|
|
4452
|
+
}
|
|
4453
|
+
};
|
|
4454
|
+
var theme = createTheme({
|
|
4455
|
+
primaryColor: "dirk",
|
|
4456
|
+
primaryShade: 9,
|
|
4457
|
+
defaultRadius: "xs",
|
|
4458
|
+
fontFamily: "Akrobat Regular, sans-serif",
|
|
4459
|
+
radius: {
|
|
4460
|
+
xxs: "0.3vh",
|
|
4461
|
+
xs: "0.5vh",
|
|
4462
|
+
sm: "0.75vh",
|
|
4463
|
+
md: "1vh",
|
|
4464
|
+
lg: "1.5vh",
|
|
4465
|
+
xl: "2vh",
|
|
4466
|
+
xxl: "3vh"
|
|
4467
|
+
},
|
|
4468
|
+
fontSizes: {
|
|
4469
|
+
xxs: "1.2vh",
|
|
4470
|
+
xs: "1.5vh",
|
|
4471
|
+
sm: "1.8vh",
|
|
4472
|
+
md: "2.2vh",
|
|
4473
|
+
lg: "2.8vh",
|
|
4474
|
+
xl: "3.3vh",
|
|
4475
|
+
xxl: "3.8vh"
|
|
4476
|
+
},
|
|
4477
|
+
lineHeights: {
|
|
4478
|
+
xxs: "1.4vh",
|
|
4479
|
+
xs: "1.8vh",
|
|
4480
|
+
sm: "2.2vh",
|
|
4481
|
+
md: "2.8vh",
|
|
4482
|
+
lg: "3.3vh",
|
|
4483
|
+
xl: "3.8vh"
|
|
4484
|
+
},
|
|
4485
|
+
spacing: {
|
|
4486
|
+
xxs: "0.5vh",
|
|
4487
|
+
xs: "0.75vh",
|
|
4488
|
+
sm: "1.5vh",
|
|
4489
|
+
md: "2vh",
|
|
4490
|
+
lg: "3vh",
|
|
4491
|
+
xl: "4vh",
|
|
4492
|
+
xxl: "5vh"
|
|
4493
|
+
},
|
|
4494
|
+
components: {
|
|
4495
|
+
Progress: {
|
|
4496
|
+
styles: {
|
|
4497
|
+
label: {
|
|
4498
|
+
fontFamily: "Akrobat Bold",
|
|
4499
|
+
letterSpacing: "0.05em",
|
|
4500
|
+
textTransform: "uppercase"
|
|
4501
|
+
},
|
|
4502
|
+
root: {
|
|
4503
|
+
backgroundColor: "rgba(77, 77, 77, 0.4)"
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
},
|
|
4507
|
+
Input: genericInputStyles,
|
|
4508
|
+
TextInput: genericInputStyles,
|
|
4509
|
+
NumberInput: genericInputStyles,
|
|
4510
|
+
Select: genericInputStyles,
|
|
4511
|
+
MultiSelect: genericInputStyles,
|
|
4512
|
+
Textarea: genericInputStyles,
|
|
4513
|
+
ColorInput: genericInputStyles,
|
|
4514
|
+
DateInput: genericInputStyles,
|
|
4515
|
+
// Mantine's <Button> defaults to rem-based heights (xs ≈ 1.875rem)
|
|
4516
|
+
// which doesn't match this theme's vh-based input min-heights, so
|
|
4517
|
+
// `<Button size="xs">` rendered next to `<TextInput size="xs">` ends
|
|
4518
|
+
// up visibly shorter. Pin the button heights to the same vh values
|
|
4519
|
+
// the inputs use so xs-everything lines up out of the box.
|
|
4520
|
+
Button: {
|
|
4521
|
+
styles: {
|
|
4522
|
+
label: {
|
|
4523
|
+
fontFamily: "Akrobat Bold",
|
|
4524
|
+
letterSpacing: "0.05em",
|
|
4525
|
+
textTransform: "uppercase"
|
|
4526
|
+
},
|
|
4527
|
+
root: {
|
|
4528
|
+
// Mantine maps these to --button-height per size; setting them
|
|
4529
|
+
// directly here keeps native Button sizing logic intact.
|
|
4530
|
+
}
|
|
4531
|
+
},
|
|
4532
|
+
vars: (_theme, props) => {
|
|
4533
|
+
const heights = {
|
|
4534
|
+
xs: "4vh",
|
|
4535
|
+
sm: "4.5vh",
|
|
4536
|
+
md: "5vh",
|
|
4537
|
+
lg: "5.5vh",
|
|
4538
|
+
xl: "6vh"
|
|
4539
|
+
};
|
|
4540
|
+
const h = heights[props.size ?? "sm"] ?? "4.5vh";
|
|
4541
|
+
return {
|
|
4542
|
+
root: {
|
|
4543
|
+
"--button-height": h
|
|
4544
|
+
}
|
|
4545
|
+
};
|
|
4546
|
+
}
|
|
4547
|
+
},
|
|
4548
|
+
Pill: {
|
|
4549
|
+
styles: (theme2) => ({
|
|
4550
|
+
root: {
|
|
4551
|
+
display: "inline-flex",
|
|
4552
|
+
alignItems: "center",
|
|
4553
|
+
justifyContent: "space-between",
|
|
4554
|
+
backgroundColor: "rgba(76, 76, 76, 0.3)",
|
|
4555
|
+
height: "fit-content",
|
|
4556
|
+
textTransform: "uppercase",
|
|
4557
|
+
letterSpacing: "0.05em",
|
|
4558
|
+
fontFamily: "Akrobat Bold",
|
|
4559
|
+
fontSize: "1.25vh",
|
|
4560
|
+
borderRadius: theme2.defaultRadius,
|
|
4561
|
+
paddingBottom: "0.5vh",
|
|
4562
|
+
paddingTop: "0.5vh"
|
|
4563
|
+
}
|
|
4564
|
+
})
|
|
4565
|
+
},
|
|
4566
|
+
// Mantine's <Tooltip> defaults to a white card with black text — looks
|
|
4567
|
+
// jarring against every dirk consumer's dark configurator. Every script
|
|
4568
|
+
// used to hand-paste this dark style block per Tooltip; centralised here
|
|
4569
|
+
// so consumers get the right look automatically and never need to think
|
|
4570
|
+
// about it again.
|
|
4571
|
+
Tooltip: {
|
|
4572
|
+
styles: (theme2) => ({
|
|
4573
|
+
tooltip: {
|
|
4574
|
+
background: alpha(theme2.colors.dark[7], 0.95),
|
|
4575
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4576
|
+
color: "rgba(255,255,255,0.75)",
|
|
4577
|
+
fontFamily: "Akrobat Bold",
|
|
4578
|
+
fontSize: "1.3vh",
|
|
4579
|
+
lineHeight: 1.3,
|
|
4580
|
+
padding: "0.6vh 0.8vh",
|
|
4581
|
+
letterSpacing: "0.03em"
|
|
4582
|
+
}
|
|
4583
|
+
})
|
|
4584
|
+
}
|
|
4585
|
+
},
|
|
4586
|
+
colors: {
|
|
4587
|
+
dirk: [
|
|
4588
|
+
"#ffffff",
|
|
4589
|
+
"#f3fce9",
|
|
4590
|
+
"#dbf5bd",
|
|
4591
|
+
"#c3ee91",
|
|
4592
|
+
"#ace765",
|
|
4593
|
+
"#94e039",
|
|
4594
|
+
"#7ac61f",
|
|
4595
|
+
"#5f9a18",
|
|
4596
|
+
"#29420a",
|
|
4597
|
+
"#446e11"
|
|
4598
|
+
]
|
|
4599
|
+
}
|
|
4600
|
+
});
|
|
4601
|
+
var theme_default = theme;
|
|
4367
4602
|
var useNuiEvent = (action, handler) => {
|
|
4368
4603
|
const savedHandler = useRef(noop);
|
|
4369
4604
|
useEffect(() => {
|
|
@@ -4382,13 +4617,35 @@ var useNuiEvent = (action, handler) => {
|
|
|
4382
4617
|
return () => window.removeEventListener("message", eventListener);
|
|
4383
4618
|
}, [action]);
|
|
4384
4619
|
};
|
|
4620
|
+
|
|
4621
|
+
// src/utils/mergeMantineTheme.ts
|
|
4622
|
+
var isValidColorScale = (v) => Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === "string");
|
|
4623
|
+
function mergeMantineThemeSafe(base, custom, override) {
|
|
4624
|
+
const colors = { ...base.colors };
|
|
4625
|
+
if (custom && isValidColorScale(custom)) {
|
|
4626
|
+
colors["custom"] = custom;
|
|
4627
|
+
} else if (!colors["custom"]) {
|
|
4628
|
+
const fallback = base.colors && base.colors.dirk;
|
|
4629
|
+
if (fallback && isValidColorScale(fallback)) {
|
|
4630
|
+
colors["custom"] = fallback;
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
return {
|
|
4634
|
+
...base,
|
|
4635
|
+
...override,
|
|
4636
|
+
colors: {
|
|
4637
|
+
...colors,
|
|
4638
|
+
...override?.colors ?? {}
|
|
4639
|
+
}
|
|
4640
|
+
};
|
|
4641
|
+
}
|
|
4385
4642
|
var _instance = null;
|
|
4386
4643
|
function getScriptConfigInstance() {
|
|
4387
4644
|
if (!_instance) throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
4388
4645
|
return _instance;
|
|
4389
4646
|
}
|
|
4390
4647
|
function createScriptConfig(defaultValue) {
|
|
4391
|
-
const
|
|
4648
|
+
const store2 = create(() => defaultValue);
|
|
4392
4649
|
let clientVersion = 0;
|
|
4393
4650
|
const useScriptConfigHooks = () => {
|
|
4394
4651
|
useNuiEvent("UPDATE_SCRIPT_CONFIG", (data) => {
|
|
@@ -4397,7 +4654,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4397
4654
|
clientVersion = data.clientVersion;
|
|
4398
4655
|
}
|
|
4399
4656
|
if (data.config && typeof data.config === "object") {
|
|
4400
|
-
|
|
4657
|
+
store2.setState((prev) => ({ ...prev, ...data.config }));
|
|
4401
4658
|
}
|
|
4402
4659
|
});
|
|
4403
4660
|
};
|
|
@@ -4405,7 +4662,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4405
4662
|
try {
|
|
4406
4663
|
const response = await fetchNui("GET_FULL_SCRIPT_CONFIG");
|
|
4407
4664
|
if (response?.success && response.data?.config) {
|
|
4408
|
-
|
|
4665
|
+
store2.setState(() => response.data.config);
|
|
4409
4666
|
if (typeof response.data.clientVersion === "number") {
|
|
4410
4667
|
clientVersion = response.data.clientVersion;
|
|
4411
4668
|
}
|
|
@@ -4416,7 +4673,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4416
4673
|
return null;
|
|
4417
4674
|
};
|
|
4418
4675
|
const updateScriptConfig = async (newConfig) => {
|
|
4419
|
-
|
|
4676
|
+
store2.setState((prev) => ({ ...prev, ...newConfig }));
|
|
4420
4677
|
const response = await fetchNui("UPDATE_SCRIPT_CONFIG", {
|
|
4421
4678
|
data: newConfig,
|
|
4422
4679
|
expectedVersion: clientVersion
|
|
@@ -4425,7 +4682,7 @@ function createScriptConfig(defaultValue) {
|
|
|
4425
4682
|
clientVersion = response.meta.client_version;
|
|
4426
4683
|
}
|
|
4427
4684
|
if (response?.success === false && response?.meta?.latestData) {
|
|
4428
|
-
|
|
4685
|
+
store2.setState((prev) => ({ ...prev, ...response.meta.latestData }));
|
|
4429
4686
|
}
|
|
4430
4687
|
return response;
|
|
4431
4688
|
};
|
|
@@ -4437,27 +4694,250 @@ function createScriptConfig(defaultValue) {
|
|
|
4437
4694
|
if (response?.success) {
|
|
4438
4695
|
const fresh = await fetchScriptConfig();
|
|
4439
4696
|
if (fresh) {
|
|
4440
|
-
|
|
4697
|
+
store2.setState(() => fresh);
|
|
4441
4698
|
}
|
|
4442
4699
|
}
|
|
4443
4700
|
return response;
|
|
4444
4701
|
};
|
|
4445
4702
|
_instance = {
|
|
4446
|
-
store,
|
|
4703
|
+
store: store2,
|
|
4447
4704
|
updateConfig: updateScriptConfig,
|
|
4448
4705
|
resetConfig,
|
|
4449
4706
|
getHistory: getScriptConfigHistory,
|
|
4450
4707
|
fetchConfig: fetchScriptConfig
|
|
4451
4708
|
};
|
|
4452
|
-
return { store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
|
|
4709
|
+
return { store: store2, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
|
|
4710
|
+
}
|
|
4711
|
+
var DirkErrorBoundary = class extends React4.Component {
|
|
4712
|
+
constructor() {
|
|
4713
|
+
super(...arguments);
|
|
4714
|
+
__publicField(this, "state", { error: null, stack: void 0 });
|
|
4715
|
+
}
|
|
4716
|
+
static getDerivedStateFromError(error2) {
|
|
4717
|
+
return { error: error2 };
|
|
4718
|
+
}
|
|
4719
|
+
componentDidCatch(error2, info) {
|
|
4720
|
+
console.group("\u{1F525} Dirk UI Crash");
|
|
4721
|
+
console.error("Error:", error2);
|
|
4722
|
+
console.error("Component Stack:", info.componentStack);
|
|
4723
|
+
console.groupEnd();
|
|
4724
|
+
}
|
|
4725
|
+
render() {
|
|
4726
|
+
if (!this.state.error) return this.props.children;
|
|
4727
|
+
return /* @__PURE__ */ jsx(
|
|
4728
|
+
Box,
|
|
4729
|
+
{
|
|
4730
|
+
style: {
|
|
4731
|
+
position: "fixed",
|
|
4732
|
+
inset: 0,
|
|
4733
|
+
width: "100vw",
|
|
4734
|
+
height: "100vh",
|
|
4735
|
+
background: "rgba(10, 10, 12, 0.92)",
|
|
4736
|
+
display: "flex",
|
|
4737
|
+
alignItems: "center",
|
|
4738
|
+
justifyContent: "center",
|
|
4739
|
+
padding: "2rem",
|
|
4740
|
+
zIndex: 999999
|
|
4741
|
+
},
|
|
4742
|
+
children: /* @__PURE__ */ jsx(
|
|
4743
|
+
Box,
|
|
4744
|
+
{
|
|
4745
|
+
maw: 900,
|
|
4746
|
+
w: "100%",
|
|
4747
|
+
p: "lg",
|
|
4748
|
+
style: {
|
|
4749
|
+
background: "rgba(20,20,24,0.75)",
|
|
4750
|
+
border: "1px solid rgba(255,255,255,0.08)",
|
|
4751
|
+
borderRadius: "10px",
|
|
4752
|
+
boxShadow: "0 10px 40px rgba(0,0,0,0.6)"
|
|
4753
|
+
},
|
|
4754
|
+
children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
4755
|
+
/* @__PURE__ */ jsx(Title$1, { order: 2, c: "red.5", children: "Dirk UI Crash" }),
|
|
4756
|
+
/* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: "The interface encountered a fatal error and stopped rendering." }),
|
|
4757
|
+
/* @__PURE__ */ jsx(Code, { block: true, style: { maxHeight: 150, overflow: "auto" }, children: this.state.error?.message }),
|
|
4758
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Check console for full stack trace" })
|
|
4759
|
+
] })
|
|
4760
|
+
}
|
|
4761
|
+
)
|
|
4762
|
+
}
|
|
4763
|
+
);
|
|
4764
|
+
}
|
|
4765
|
+
};
|
|
4766
|
+
var useAdminToolStore = create((set, get) => ({
|
|
4767
|
+
active: null,
|
|
4768
|
+
begin: (spec) => new Promise((resolve) => {
|
|
4769
|
+
const prev = get().active;
|
|
4770
|
+
if (prev) prev.resolve(null);
|
|
4771
|
+
set({ active: { ...spec, resolve } });
|
|
4772
|
+
}),
|
|
4773
|
+
resolveActive: (value) => {
|
|
4774
|
+
const cur = get().active;
|
|
4775
|
+
if (!cur) return;
|
|
4776
|
+
cur.resolve(value);
|
|
4777
|
+
set({ active: null });
|
|
4778
|
+
},
|
|
4779
|
+
cancelActive: () => {
|
|
4780
|
+
const cur = get().active;
|
|
4781
|
+
if (!cur) return;
|
|
4782
|
+
cur.resolve(null);
|
|
4783
|
+
set({ active: null });
|
|
4784
|
+
}
|
|
4785
|
+
}));
|
|
4786
|
+
|
|
4787
|
+
// src/components/AdminTools/AdminOverlays.tsx
|
|
4788
|
+
var listenerInstalled = false;
|
|
4789
|
+
function installNuiListener() {
|
|
4790
|
+
if (listenerInstalled || typeof window === "undefined") return;
|
|
4791
|
+
listenerInstalled = true;
|
|
4792
|
+
window.addEventListener("message", (e) => {
|
|
4793
|
+
const msg = e?.data;
|
|
4794
|
+
if (!msg || typeof msg !== "object" || typeof msg.action !== "string") return;
|
|
4795
|
+
const action = msg.action;
|
|
4796
|
+
const cur = useAdminToolStore.getState().active;
|
|
4797
|
+
if (!cur) return;
|
|
4798
|
+
if (action === `${cur.id}_RESULT`) {
|
|
4799
|
+
useAdminToolStore.getState().resolveActive(msg.data ?? null);
|
|
4800
|
+
} else if (action === `${cur.id}_CANCELLED`) {
|
|
4801
|
+
useAdminToolStore.getState().cancelActive();
|
|
4802
|
+
}
|
|
4803
|
+
});
|
|
4804
|
+
}
|
|
4805
|
+
var BODY_HIDE_STYLE_ID = "dirk-instruction-panel-style";
|
|
4806
|
+
var BODY_HIDE_ATTR = "data-dirk-instruction-active";
|
|
4807
|
+
var OVERLAY_ATTR = "data-dirk-instruction-overlay";
|
|
4808
|
+
function ensureBodyHideStyle() {
|
|
4809
|
+
if (typeof document === "undefined") return;
|
|
4810
|
+
if (document.getElementById(BODY_HIDE_STYLE_ID)) return;
|
|
4811
|
+
const el = document.createElement("style");
|
|
4812
|
+
el.id = BODY_HIDE_STYLE_ID;
|
|
4813
|
+
el.textContent = `
|
|
4814
|
+
body[${BODY_HIDE_ATTR}] > *:not([${OVERLAY_ATTR}]) {
|
|
4815
|
+
visibility: hidden !important;
|
|
4816
|
+
opacity: 0 !important;
|
|
4817
|
+
pointer-events: none !important;
|
|
4818
|
+
}
|
|
4819
|
+
`;
|
|
4820
|
+
document.head.appendChild(el);
|
|
4821
|
+
}
|
|
4822
|
+
function AdminOverlays() {
|
|
4823
|
+
const active = useAdminToolStore((s) => s.active);
|
|
4824
|
+
useEffect(() => {
|
|
4825
|
+
installNuiListener();
|
|
4826
|
+
}, []);
|
|
4827
|
+
useEffect(() => {
|
|
4828
|
+
if (!active || typeof document === "undefined") return;
|
|
4829
|
+
ensureBodyHideStyle();
|
|
4830
|
+
document.body.setAttribute(BODY_HIDE_ATTR, "");
|
|
4831
|
+
return () => {
|
|
4832
|
+
document.body.removeAttribute(BODY_HIDE_ATTR);
|
|
4833
|
+
};
|
|
4834
|
+
}, [active]);
|
|
4835
|
+
return null;
|
|
4453
4836
|
}
|
|
4454
|
-
|
|
4837
|
+
library.add(fas, far, fab);
|
|
4838
|
+
var dirkQueryClient = new QueryClient({
|
|
4455
4839
|
defaultOptions: { queries: { staleTime: 3e4, gcTime: 5 * 6e4 } }
|
|
4456
4840
|
});
|
|
4457
|
-
function
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4841
|
+
function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
4842
|
+
const {
|
|
4843
|
+
primaryColor,
|
|
4844
|
+
primaryShade,
|
|
4845
|
+
customTheme,
|
|
4846
|
+
game
|
|
4847
|
+
} = useSettings();
|
|
4848
|
+
localeStore((s) => s.locales);
|
|
4849
|
+
const [scTheme, setScTheme] = useState(null);
|
|
4850
|
+
useLayoutEffect(() => {
|
|
4851
|
+
useSettings.setState({
|
|
4852
|
+
overideResourceName
|
|
4853
|
+
});
|
|
4854
|
+
}, [overideResourceName]);
|
|
4855
|
+
useEffect(() => {
|
|
4856
|
+
fetchNui("NUI_READY").catch(() => {
|
|
4857
|
+
});
|
|
4858
|
+
Promise.all([
|
|
4859
|
+
fetchNui("GET_SETTINGS"),
|
|
4860
|
+
fetchNui("GET_RESOURCE_VERSION", void 0, { version: "dev" })
|
|
4861
|
+
]).then(([data, resourceInfo]) => {
|
|
4862
|
+
useSettings.setState({
|
|
4863
|
+
...data,
|
|
4864
|
+
resourceVersion: resourceInfo?.version || "dev"
|
|
4865
|
+
});
|
|
4866
|
+
}).catch((err) => {
|
|
4867
|
+
console.error("Failed to fetch initial settings within dirk-cfx-react:", err);
|
|
4868
|
+
});
|
|
4869
|
+
}, []);
|
|
4870
|
+
useNuiEvent("UPDATE_DIRK_LIB_SETTINGS", (data) => {
|
|
4871
|
+
if (!data || typeof data !== "object") return;
|
|
4872
|
+
useSettings.setState(data);
|
|
4873
|
+
});
|
|
4874
|
+
useNuiEvent(
|
|
4875
|
+
"UPDATE_SCRIPT_CONFIG",
|
|
4876
|
+
(data) => {
|
|
4877
|
+
if (!data || !data.config || typeof data.config !== "object") return;
|
|
4878
|
+
try {
|
|
4879
|
+
const inst = getScriptConfigInstance();
|
|
4880
|
+
inst.store.setState((prev) => ({ ...prev, ...data.config }));
|
|
4881
|
+
} catch {
|
|
4882
|
+
}
|
|
4883
|
+
}
|
|
4884
|
+
);
|
|
4885
|
+
useEffect(() => {
|
|
4886
|
+
let unsubscribe;
|
|
4887
|
+
try {
|
|
4888
|
+
const inst = getScriptConfigInstance();
|
|
4889
|
+
setScTheme(inst.store.getState()?.theme ?? null);
|
|
4890
|
+
const subscribable = inst.store;
|
|
4891
|
+
if (typeof subscribable.subscribe === "function") {
|
|
4892
|
+
unsubscribe = subscribable.subscribe((s) => {
|
|
4893
|
+
setScTheme(s?.theme ?? null);
|
|
4894
|
+
});
|
|
4895
|
+
}
|
|
4896
|
+
inst.fetchConfig?.().then((full) => {
|
|
4897
|
+
if (full && typeof full === "object") {
|
|
4898
|
+
setScTheme(full.theme ?? null);
|
|
4899
|
+
}
|
|
4900
|
+
}).catch(() => {
|
|
4901
|
+
});
|
|
4902
|
+
} catch {
|
|
4903
|
+
}
|
|
4904
|
+
return () => {
|
|
4905
|
+
unsubscribe?.();
|
|
4906
|
+
};
|
|
4907
|
+
}, []);
|
|
4908
|
+
const overrideActive = scTheme?.useOverride === true;
|
|
4909
|
+
const effectivePrimaryColor = overrideActive ? scTheme.primaryColor ?? primaryColor : primaryColor;
|
|
4910
|
+
const effectivePrimaryShade = overrideActive ? scTheme.primaryShade ?? primaryShade : primaryShade;
|
|
4911
|
+
const effectiveCustomTheme = overrideActive ? scTheme.customTheme ?? customTheme : customTheme;
|
|
4912
|
+
const mergedTheme = useMemo(
|
|
4913
|
+
() => mergeMantineThemeSafe(
|
|
4914
|
+
{ ...theme_default, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade },
|
|
4915
|
+
effectiveCustomTheme,
|
|
4916
|
+
themeOverride
|
|
4917
|
+
),
|
|
4918
|
+
[effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]
|
|
4919
|
+
);
|
|
4920
|
+
useEffect(() => {
|
|
4921
|
+
document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
|
|
4922
|
+
}, [game]);
|
|
4923
|
+
const content = isEnvBrowser() ? /* @__PURE__ */ jsx(
|
|
4924
|
+
BackgroundImage,
|
|
4925
|
+
{
|
|
4926
|
+
w: "100vw",
|
|
4927
|
+
h: "100vh",
|
|
4928
|
+
src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
|
|
4929
|
+
children
|
|
4930
|
+
}
|
|
4931
|
+
) : children;
|
|
4932
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client: dirkQueryClient, children: /* @__PURE__ */ jsx(MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxs(DirkErrorBoundary, { children: [
|
|
4933
|
+
content,
|
|
4934
|
+
/* @__PURE__ */ jsx(AdminOverlays, {})
|
|
4935
|
+
] }) }) });
|
|
4936
|
+
}
|
|
4937
|
+
function NavItemButton({
|
|
4938
|
+
icon: Icon,
|
|
4939
|
+
label: label2,
|
|
4940
|
+
active,
|
|
4461
4941
|
onClick
|
|
4462
4942
|
}) {
|
|
4463
4943
|
const theme2 = useMantineTheme();
|
|
@@ -4782,7 +5262,7 @@ function ConfigPanelInner({
|
|
|
4782
5262
|
const theme2 = useMantineTheme();
|
|
4783
5263
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4784
5264
|
const version = useSettings((s) => s.resourceVersion);
|
|
4785
|
-
const [activeTab, setActiveTab] =
|
|
5265
|
+
const [activeTab, setActiveTab] = useAdminState("__dirkConfigPanel:activeTab", navItems[0]?.id ?? "");
|
|
4786
5266
|
const firstMountRef = useRef(true);
|
|
4787
5267
|
const [jsonOpen, setJsonOpen] = useState(false);
|
|
4788
5268
|
const [historyOpen, setHistoryOpen] = useState(false);
|
|
@@ -4825,8 +5305,8 @@ function ConfigPanelInner({
|
|
|
4825
5305
|
setResetOpen(false);
|
|
4826
5306
|
const result = await resetConfig();
|
|
4827
5307
|
if (result?.success) {
|
|
4828
|
-
const { store } = getScriptConfigInstance();
|
|
4829
|
-
form.reinitialize(cloneConfig(
|
|
5308
|
+
const { store: store2 } = getScriptConfigInstance();
|
|
5309
|
+
form.reinitialize(cloneConfig(store2.getState()));
|
|
4830
5310
|
notifications.show({
|
|
4831
5311
|
color: "green",
|
|
4832
5312
|
title: locale("ConfigResetSuccessTitle"),
|
|
@@ -5054,13 +5534,13 @@ function ServerOnlyFetcher() {
|
|
|
5054
5534
|
var defaultOnClose = () => fetchNui("CLOSE_ADMIN_SECTION");
|
|
5055
5535
|
function ConfigPanel(props) {
|
|
5056
5536
|
const { open, onClose = defaultOnClose } = props;
|
|
5057
|
-
const { store, updateConfig } = getScriptConfigInstance();
|
|
5537
|
+
const { store: store2, updateConfig } = getScriptConfigInstance();
|
|
5058
5538
|
const [isSaving, setIsSaving] = useState(false);
|
|
5059
5539
|
if (!open) return null;
|
|
5060
|
-
return /* @__PURE__ */ jsx(
|
|
5540
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
5061
5541
|
FormProvider,
|
|
5062
5542
|
{
|
|
5063
|
-
initialValues: cloneConfig(
|
|
5543
|
+
initialValues: cloneConfig(store2.getState()),
|
|
5064
5544
|
onSubmit: async (form) => {
|
|
5065
5545
|
if (isSaving) return;
|
|
5066
5546
|
setIsSaving(true);
|
|
@@ -5068,7 +5548,7 @@ function ConfigPanel(props) {
|
|
|
5068
5548
|
const result = await updateConfig(form.values);
|
|
5069
5549
|
if (result?.success) {
|
|
5070
5550
|
form.reinitialize(cloneConfig(form.values));
|
|
5071
|
-
|
|
5551
|
+
dirkQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
5072
5552
|
useMissingItemsAudit.getState().refresh();
|
|
5073
5553
|
notifications.show({
|
|
5074
5554
|
color: "green",
|
|
@@ -5078,7 +5558,7 @@ function ConfigPanel(props) {
|
|
|
5078
5558
|
});
|
|
5079
5559
|
return;
|
|
5080
5560
|
}
|
|
5081
|
-
form.reinitialize(cloneConfig(
|
|
5561
|
+
form.reinitialize(cloneConfig(store2.getState()));
|
|
5082
5562
|
const err = result?._error || "Unknown";
|
|
5083
5563
|
console.warn(`[ConfigPanel] config save failed: ${err}`);
|
|
5084
5564
|
const titleKey = err === "NoPermission" ? "ConfigSaveNoPermissionTitle" : err === "VersionConflict" ? "ConfigSaveVersionConflictTitle" : err === "NotReady" ? "ConfigSaveNotReadyTitle" : "ConfigSaveFailedTitle";
|
|
@@ -5575,6 +6055,9 @@ function GroupName(props) {
|
|
|
5575
6055
|
const ctx = useContext(GroupSelectContext);
|
|
5576
6056
|
const jobs = useFrameworkGroups((s) => s.jobs);
|
|
5577
6057
|
const gangs = useFrameworkGroups((s) => s.gangs);
|
|
6058
|
+
useEffect(() => {
|
|
6059
|
+
ensureFrameworkGroups();
|
|
6060
|
+
}, []);
|
|
5578
6061
|
const inCompound = ctx !== null;
|
|
5579
6062
|
const currentValue = inCompound ? ctx.value.name : props.value;
|
|
5580
6063
|
const filterType = inCompound ? ctx.type : props.type;
|
|
@@ -5614,6 +6097,9 @@ function GroupRank(props) {
|
|
|
5614
6097
|
}
|
|
5615
6098
|
const jobs = useFrameworkGroups((s) => s.jobs);
|
|
5616
6099
|
const gangs = useFrameworkGroups((s) => s.gangs);
|
|
6100
|
+
useEffect(() => {
|
|
6101
|
+
ensureFrameworkGroups();
|
|
6102
|
+
}, []);
|
|
5617
6103
|
const all = [...jobs, ...gangs];
|
|
5618
6104
|
const selectedGroup = all.find((g) => g.name === ctx.value.name) ?? null;
|
|
5619
6105
|
const grades = selectedGroup?.grades ?? [];
|
|
@@ -7259,349 +7745,831 @@ function AccountSelect(props) {
|
|
|
7259
7745
|
!hideFrameworkHint && /* @__PURE__ */ jsx(FrameworkHint, { framework })
|
|
7260
7746
|
] });
|
|
7261
7747
|
}
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7748
|
+
var BODY_HIDE_STYLE_ID2 = "dirk-instruction-panel-style";
|
|
7749
|
+
var BODY_HIDE_ATTR2 = "data-dirk-instruction-active";
|
|
7750
|
+
var OVERLAY_ATTR2 = "data-dirk-instruction-overlay";
|
|
7751
|
+
function ensureBodyHideStyle2() {
|
|
7752
|
+
if (document.getElementById(BODY_HIDE_STYLE_ID2)) return;
|
|
7753
|
+
const el = document.createElement("style");
|
|
7754
|
+
el.id = BODY_HIDE_STYLE_ID2;
|
|
7755
|
+
el.textContent = `
|
|
7756
|
+
body[${BODY_HIDE_ATTR2}] > *:not([${OVERLAY_ATTR2}]) {
|
|
7757
|
+
visibility: hidden !important;
|
|
7758
|
+
opacity: 0 !important;
|
|
7759
|
+
pointer-events: none !important;
|
|
7760
|
+
}
|
|
7761
|
+
`;
|
|
7762
|
+
document.head.appendChild(el);
|
|
7265
7763
|
}
|
|
7266
|
-
function
|
|
7764
|
+
function InstructionPanel({
|
|
7765
|
+
visible,
|
|
7766
|
+
title,
|
|
7767
|
+
hint,
|
|
7768
|
+
keys,
|
|
7769
|
+
icon: Icon = MapPin,
|
|
7770
|
+
hideRestOfAdmin = true
|
|
7771
|
+
}) {
|
|
7772
|
+
const theme2 = useMantineTheme();
|
|
7773
|
+
const pc = theme2.colors[theme2.primaryColor];
|
|
7774
|
+
useEffect(() => {
|
|
7775
|
+
if (!visible || !hideRestOfAdmin) return;
|
|
7776
|
+
ensureBodyHideStyle2();
|
|
7777
|
+
document.body.setAttribute(BODY_HIDE_ATTR2, "");
|
|
7778
|
+
return () => {
|
|
7779
|
+
document.body.removeAttribute(BODY_HIDE_ATTR2);
|
|
7780
|
+
};
|
|
7781
|
+
}, [visible, hideRestOfAdmin]);
|
|
7782
|
+
if (!visible) return null;
|
|
7783
|
+
return createPortal(
|
|
7784
|
+
/* @__PURE__ */ jsx(
|
|
7785
|
+
"div",
|
|
7786
|
+
{
|
|
7787
|
+
...{ [OVERLAY_ATTR2]: "" },
|
|
7788
|
+
style: { position: "fixed", inset: 0, pointerEvents: "none", zIndex: 1e4 },
|
|
7789
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
|
|
7790
|
+
motion.div,
|
|
7791
|
+
{
|
|
7792
|
+
initial: { opacity: 0, y: 12, scale: 0.92 },
|
|
7793
|
+
animate: { opacity: 1, y: 0, scale: 1 },
|
|
7794
|
+
exit: { opacity: 0, y: 12, scale: 0.92 },
|
|
7795
|
+
transition: { duration: 0.25, ease: "easeInOut" },
|
|
7796
|
+
style: { position: "absolute", bottom: "3vh", right: "3vh", userSelect: "none" },
|
|
7797
|
+
children: /* @__PURE__ */ jsxs(
|
|
7798
|
+
Flex,
|
|
7799
|
+
{
|
|
7800
|
+
direction: "column",
|
|
7801
|
+
gap: "0.8vh",
|
|
7802
|
+
style: {
|
|
7803
|
+
background: alpha(theme2.colors.dark[9], 0.55),
|
|
7804
|
+
border: "0.1vh solid rgba(255,255,255,0.07)",
|
|
7805
|
+
borderRadius: theme2.radius.sm,
|
|
7806
|
+
boxShadow: "0 0.74vh 2.96vh rgba(0,0,0,0.5)",
|
|
7807
|
+
padding: "1.4vh 1.6vh",
|
|
7808
|
+
minWidth: "22vh",
|
|
7809
|
+
maxWidth: "28vh"
|
|
7810
|
+
},
|
|
7811
|
+
children: [
|
|
7812
|
+
/* @__PURE__ */ jsxs(Flex, { align: "center", gap: "0.6vh", children: [
|
|
7813
|
+
/* @__PURE__ */ jsx(Icon, { size: "1.6vh", color: pc[6], strokeWidth: 2.5 }),
|
|
7814
|
+
/* @__PURE__ */ jsx(
|
|
7815
|
+
Text,
|
|
7816
|
+
{
|
|
7817
|
+
style: {
|
|
7818
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7819
|
+
fontSize: "1.7vh",
|
|
7820
|
+
fontWeight: 700,
|
|
7821
|
+
letterSpacing: "0.14em",
|
|
7822
|
+
textTransform: "uppercase",
|
|
7823
|
+
color: pc[6],
|
|
7824
|
+
textShadow: `0 0 0.8vh ${alpha(pc[7], 0.5)}, 0 0 1.6vh ${alpha(pc[9], 0.3)}`
|
|
7825
|
+
},
|
|
7826
|
+
children: title
|
|
7827
|
+
}
|
|
7828
|
+
)
|
|
7829
|
+
] }),
|
|
7830
|
+
(hint || keys && keys.length > 0) && /* @__PURE__ */ jsx("div", { style: { height: "0.1vh", background: "rgba(255,255,255,0.06)", margin: "0.1vh 0" } }),
|
|
7831
|
+
hint && /* @__PURE__ */ jsx(
|
|
7832
|
+
Text,
|
|
7833
|
+
{
|
|
7834
|
+
style: {
|
|
7835
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7836
|
+
fontSize: "1.05vh",
|
|
7837
|
+
color: "rgba(255,255,255,0.45)",
|
|
7838
|
+
letterSpacing: "0.06em",
|
|
7839
|
+
textTransform: "uppercase",
|
|
7840
|
+
lineHeight: 1.4
|
|
7841
|
+
},
|
|
7842
|
+
children: hint
|
|
7843
|
+
}
|
|
7844
|
+
),
|
|
7845
|
+
keys && keys.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7846
|
+
hint && /* @__PURE__ */ jsx("div", { style: { height: "0.1vh", background: "rgba(255,255,255,0.06)", margin: "0.1vh 0" } }),
|
|
7847
|
+
/* @__PURE__ */ jsx(Flex, { direction: "column", gap: "0.5vh", children: keys.map((k, i) => /* @__PURE__ */ jsx(InstructionKeyRow, { keyLabel: k.key, action: k.action }, i)) })
|
|
7848
|
+
] })
|
|
7849
|
+
]
|
|
7850
|
+
}
|
|
7851
|
+
)
|
|
7852
|
+
},
|
|
7853
|
+
"instruction-card"
|
|
7854
|
+
) })
|
|
7855
|
+
}
|
|
7856
|
+
),
|
|
7857
|
+
document.body
|
|
7858
|
+
);
|
|
7859
|
+
}
|
|
7860
|
+
function renderKeyContent(keyLabel) {
|
|
7861
|
+
const normalized = keyLabel.trim().toUpperCase();
|
|
7862
|
+
if (normalized === "LMB") return /* @__PURE__ */ jsx(MouseIcon, { side: "left" });
|
|
7863
|
+
if (normalized === "RMB") return /* @__PURE__ */ jsx(MouseIcon, { side: "right" });
|
|
7864
|
+
if (normalized === "BACKSPACE" || keyLabel === "\u232B") return /* @__PURE__ */ jsx(BackspaceIcon, {});
|
|
7267
7865
|
return /* @__PURE__ */ jsx(
|
|
7268
|
-
|
|
7866
|
+
Text,
|
|
7269
7867
|
{
|
|
7270
|
-
style: {
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7277
|
-
|
|
7278
|
-
numOctaves: "5",
|
|
7279
|
-
seed: "9",
|
|
7280
|
-
result: "noise1"
|
|
7281
|
-
}
|
|
7282
|
-
),
|
|
7283
|
-
/* @__PURE__ */ jsx(
|
|
7284
|
-
"feTurbulence",
|
|
7285
|
-
{
|
|
7286
|
-
type: "fractalNoise",
|
|
7287
|
-
baseFrequency: "0.08 0.12",
|
|
7288
|
-
numOctaves: "2",
|
|
7289
|
-
seed: "3",
|
|
7290
|
-
result: "noise2"
|
|
7291
|
-
}
|
|
7292
|
-
),
|
|
7293
|
-
/* @__PURE__ */ jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
|
|
7294
|
-
/* @__PURE__ */ jsx(
|
|
7295
|
-
"feDisplacementMap",
|
|
7296
|
-
{
|
|
7297
|
-
in: "SourceGraphic",
|
|
7298
|
-
in2: "combinedNoise",
|
|
7299
|
-
scale: "52",
|
|
7300
|
-
xChannelSelector: "R",
|
|
7301
|
-
yChannelSelector: "G",
|
|
7302
|
-
result: "displaced"
|
|
7303
|
-
}
|
|
7304
|
-
),
|
|
7305
|
-
/* @__PURE__ */ jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
|
|
7306
|
-
/* @__PURE__ */ jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
|
|
7307
|
-
/* @__PURE__ */ jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
|
|
7308
|
-
/* @__PURE__ */ jsx("feMerge", { children: /* @__PURE__ */ jsx("feMergeNode", { in: "eroded" }) })
|
|
7309
|
-
] }) })
|
|
7868
|
+
style: {
|
|
7869
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7870
|
+
fontSize: "1.2vh",
|
|
7871
|
+
color: "rgba(255,255,255,0.85)",
|
|
7872
|
+
lineHeight: 1,
|
|
7873
|
+
padding: "0 0.3vh"
|
|
7874
|
+
},
|
|
7875
|
+
children: keyLabel
|
|
7310
7876
|
}
|
|
7311
7877
|
);
|
|
7312
7878
|
}
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
sm: "0.75vh",
|
|
7348
|
-
md: "1vh",
|
|
7349
|
-
lg: "1.5vh",
|
|
7350
|
-
xl: "2vh",
|
|
7351
|
-
xxl: "3vh"
|
|
7352
|
-
},
|
|
7353
|
-
fontSizes: {
|
|
7354
|
-
xxs: "1.2vh",
|
|
7355
|
-
xs: "1.5vh",
|
|
7356
|
-
sm: "1.8vh",
|
|
7357
|
-
md: "2.2vh",
|
|
7358
|
-
lg: "2.8vh",
|
|
7359
|
-
xl: "3.3vh",
|
|
7360
|
-
xxl: "3.8vh"
|
|
7361
|
-
},
|
|
7362
|
-
lineHeights: {
|
|
7363
|
-
xxs: "1.4vh",
|
|
7364
|
-
xs: "1.8vh",
|
|
7365
|
-
sm: "2.2vh",
|
|
7366
|
-
md: "2.8vh",
|
|
7367
|
-
lg: "3.3vh",
|
|
7368
|
-
xl: "3.8vh"
|
|
7369
|
-
},
|
|
7370
|
-
spacing: {
|
|
7371
|
-
xxs: "0.5vh",
|
|
7372
|
-
xs: "0.75vh",
|
|
7373
|
-
sm: "1.5vh",
|
|
7374
|
-
md: "2vh",
|
|
7375
|
-
lg: "3vh",
|
|
7376
|
-
xl: "4vh",
|
|
7377
|
-
xxl: "5vh"
|
|
7378
|
-
},
|
|
7379
|
-
components: {
|
|
7380
|
-
Progress: {
|
|
7381
|
-
styles: {
|
|
7382
|
-
label: {
|
|
7383
|
-
fontFamily: "Akrobat Bold",
|
|
7384
|
-
letterSpacing: "0.05em",
|
|
7879
|
+
function InstructionKeyRow({ keyLabel, action }) {
|
|
7880
|
+
const normalized = keyLabel.trim().toUpperCase();
|
|
7881
|
+
const isIconKey = normalized === "LMB" || normalized === "RMB" || normalized === "BACKSPACE" || keyLabel === "\u232B";
|
|
7882
|
+
const minWidth = isIconKey ? "2.6vh" : "2.4vh";
|
|
7883
|
+
return /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "0.6vh", children: [
|
|
7884
|
+
/* @__PURE__ */ jsx(
|
|
7885
|
+
"div",
|
|
7886
|
+
{
|
|
7887
|
+
style: {
|
|
7888
|
+
minWidth,
|
|
7889
|
+
height: "2.4vh",
|
|
7890
|
+
padding: "0 0.4vh",
|
|
7891
|
+
borderRadius: "0.3vh",
|
|
7892
|
+
border: "0.15vh solid rgba(255,255,255,0.35)",
|
|
7893
|
+
background: "rgba(255,255,255,0.06)",
|
|
7894
|
+
display: "flex",
|
|
7895
|
+
alignItems: "center",
|
|
7896
|
+
justifyContent: "center",
|
|
7897
|
+
opacity: 0.85,
|
|
7898
|
+
filter: "drop-shadow(0 0 0.3vh rgba(0,0,0,0.5))",
|
|
7899
|
+
flexShrink: 0,
|
|
7900
|
+
boxSizing: "border-box"
|
|
7901
|
+
},
|
|
7902
|
+
children: renderKeyContent(keyLabel)
|
|
7903
|
+
}
|
|
7904
|
+
),
|
|
7905
|
+
/* @__PURE__ */ jsx(
|
|
7906
|
+
Text,
|
|
7907
|
+
{
|
|
7908
|
+
style: {
|
|
7909
|
+
fontFamily: "Akrobat Bold, sans-serif",
|
|
7910
|
+
fontSize: "1.05vh",
|
|
7911
|
+
color: "rgba(255,255,255,0.45)",
|
|
7912
|
+
letterSpacing: "0.06em",
|
|
7385
7913
|
textTransform: "uppercase"
|
|
7386
7914
|
},
|
|
7387
|
-
|
|
7388
|
-
backgroundColor: "rgba(77, 77, 77, 0.4)"
|
|
7389
|
-
}
|
|
7915
|
+
children: action
|
|
7390
7916
|
}
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7917
|
+
)
|
|
7918
|
+
] });
|
|
7919
|
+
}
|
|
7920
|
+
function MouseIcon({ side }) {
|
|
7921
|
+
const stroke = "rgba(255,255,255,0.85)";
|
|
7922
|
+
const fillActive = "rgba(255,255,255,0.85)";
|
|
7923
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 16 22", width: "1.4vh", height: "1.9vh", fill: "none", stroke, strokeWidth: "1.4", strokeLinejoin: "round", children: [
|
|
7924
|
+
/* @__PURE__ */ jsx("rect", { x: "1", y: "1", width: "14", height: "20", rx: "6" }),
|
|
7925
|
+
/* @__PURE__ */ jsx("line", { x1: "8", y1: "1", x2: "8", y2: "9" }),
|
|
7926
|
+
/* @__PURE__ */ jsx(
|
|
7927
|
+
"path",
|
|
7928
|
+
{
|
|
7929
|
+
d: side === "left" ? "M 7.4 1.6 L 2 1.6 A 5 5 0 0 0 1 6 L 1 9 L 7.4 9 Z" : "M 8.6 1.6 L 14 1.6 A 5 5 0 0 1 15 6 L 15 9 L 8.6 9 Z",
|
|
7930
|
+
fill: fillActive,
|
|
7931
|
+
stroke: "none"
|
|
7932
|
+
}
|
|
7933
|
+
)
|
|
7934
|
+
] });
|
|
7935
|
+
}
|
|
7936
|
+
function BackspaceIcon() {
|
|
7937
|
+
const stroke = "rgba(255,255,255,0.85)";
|
|
7938
|
+
return /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 22 16", width: "1.7vh", height: "1.3vh", fill: "none", stroke, strokeWidth: "1.4", strokeLinejoin: "round", strokeLinecap: "round", children: [
|
|
7939
|
+
/* @__PURE__ */ jsx("path", { d: "M 21 2 L 8 2 L 2 8 L 8 14 L 21 14 Z" }),
|
|
7940
|
+
/* @__PURE__ */ jsx("line", { x1: "11", y1: "6", x2: "16", y2: "11" }),
|
|
7941
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "6", x2: "11", y2: "11" })
|
|
7942
|
+
] });
|
|
7943
|
+
}
|
|
7944
|
+
function WorldPositionPicker({ value, onChange, compact, setOnly, gotoOnly }) {
|
|
7945
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7946
|
+
!gotoOnly && /* @__PURE__ */ jsx(WorldPositionSetButton2, { value, onChange, compact }),
|
|
7947
|
+
!setOnly && /* @__PURE__ */ jsx(WorldPositionGotoButton2, { value, compact })
|
|
7948
|
+
] });
|
|
7949
|
+
}
|
|
7950
|
+
function WorldPositionSetButton2({
|
|
7951
|
+
value,
|
|
7952
|
+
onChange,
|
|
7953
|
+
compact
|
|
7954
|
+
}) {
|
|
7955
|
+
const theme2 = useMantineTheme();
|
|
7956
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
7957
|
+
const begin = useAdminToolStore((s) => s.begin);
|
|
7958
|
+
const onClick = async () => {
|
|
7959
|
+
const instructions = {
|
|
7960
|
+
title: locale("PickPositionTitle") || "Pick Position",
|
|
7961
|
+
hint: locale("PickPositionHint") || "Walk to where you want this set",
|
|
7962
|
+
keys: [
|
|
7963
|
+
{ key: "E", action: locale("Set") || "Set" },
|
|
7964
|
+
{ key: "\u232B", action: locale("Cancel") || "Cancel" }
|
|
7965
|
+
]
|
|
7966
|
+
};
|
|
7967
|
+
const pendingResult = begin({ id: "capturePosition", ...instructions });
|
|
7968
|
+
fetchNui("ADMIN_TOOL_BEGIN", { id: "capturePosition", instructions }).catch(() => {
|
|
7969
|
+
useAdminToolStore.getState().cancelActive();
|
|
7970
|
+
});
|
|
7971
|
+
const result = await pendingResult;
|
|
7972
|
+
if (result) onChange(result);
|
|
7973
|
+
};
|
|
7974
|
+
return /* @__PURE__ */ jsx(Tooltip, { label: locale("SetWorldTooltip"), position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxs(
|
|
7975
|
+
motion.button,
|
|
7976
|
+
{
|
|
7977
|
+
onClick,
|
|
7978
|
+
whileHover: { background: alpha(color, 0.18) },
|
|
7979
|
+
whileTap: { scale: 0.95 },
|
|
7980
|
+
style: {
|
|
7981
|
+
background: alpha(color, 0.1),
|
|
7982
|
+
border: `0.1vh solid ${alpha(color, 0.35)}`,
|
|
7983
|
+
borderRadius: theme2.radius.xs,
|
|
7984
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
7985
|
+
cursor: "pointer",
|
|
7986
|
+
display: "flex",
|
|
7987
|
+
alignItems: "center",
|
|
7988
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
7989
|
+
},
|
|
7990
|
+
children: [
|
|
7991
|
+
/* @__PURE__ */ jsx(Crosshair, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
7992
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: locale("Set") })
|
|
7993
|
+
]
|
|
7417
7994
|
}
|
|
7418
|
-
}
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7995
|
+
) });
|
|
7996
|
+
}
|
|
7997
|
+
function WorldPositionGotoButton2({
|
|
7998
|
+
value,
|
|
7999
|
+
compact
|
|
8000
|
+
}) {
|
|
8001
|
+
const theme2 = useMantineTheme();
|
|
8002
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8003
|
+
const onClick = () => {
|
|
8004
|
+
fetchNui("ADMIN_TOOL_INVOKE", { id: "gotoCoord", value }).catch(() => {
|
|
8005
|
+
});
|
|
8006
|
+
};
|
|
8007
|
+
return /* @__PURE__ */ jsx(Tooltip, { label: locale("GotoWorldTooltip"), position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxs(
|
|
8008
|
+
motion.button,
|
|
8009
|
+
{
|
|
8010
|
+
onClick,
|
|
8011
|
+
whileHover: { background: alpha(color, 0.18) },
|
|
8012
|
+
whileTap: { scale: 0.95 },
|
|
8013
|
+
style: {
|
|
8014
|
+
background: alpha(color, 0.1),
|
|
8015
|
+
border: `0.1vh solid ${alpha(color, 0.35)}`,
|
|
8016
|
+
borderRadius: theme2.radius.xs,
|
|
8017
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
8018
|
+
cursor: "pointer",
|
|
8019
|
+
display: "flex",
|
|
8020
|
+
alignItems: "center",
|
|
8021
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
8022
|
+
},
|
|
8023
|
+
children: [
|
|
8024
|
+
/* @__PURE__ */ jsx(MapPin, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
8025
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: locale("Goto") })
|
|
8026
|
+
]
|
|
7446
8027
|
}
|
|
7447
|
-
}
|
|
8028
|
+
) });
|
|
8029
|
+
}
|
|
8030
|
+
function usePlayers(opts = {}) {
|
|
8031
|
+
const {
|
|
8032
|
+
includeOffline = false,
|
|
8033
|
+
search = "",
|
|
8034
|
+
limit = 50,
|
|
8035
|
+
staleTimeMs,
|
|
8036
|
+
refetchIntervalMs
|
|
8037
|
+
} = opts;
|
|
8038
|
+
const query = useQuery({
|
|
8039
|
+
queryKey: includeOffline ? ["dirk:players", "search", search.trim().toLowerCase(), limit] : ["dirk:players", "online"],
|
|
8040
|
+
queryFn: async () => {
|
|
8041
|
+
const toolId = includeOffline ? "searchPlayers" : "getOnlinePlayers";
|
|
8042
|
+
const payload = includeOffline ? { id: toolId, value: { search: search.trim(), limit } } : { id: toolId };
|
|
8043
|
+
const result = await fetchNui(
|
|
8044
|
+
"ADMIN_TOOL_QUERY",
|
|
8045
|
+
payload,
|
|
8046
|
+
// Browser-dev fallback. Returns a couple of mock players so the
|
|
8047
|
+
// dev shell isn't blank.
|
|
8048
|
+
includeOffline ? [
|
|
8049
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true },
|
|
8050
|
+
{ id: null, citizenId: "DEF67890", name: "", charName: "Jane Offline", online: false }
|
|
8051
|
+
] : [
|
|
8052
|
+
{ id: 1, citizenId: "ABC12345", name: "Dev User", charName: "John Doe", online: true }
|
|
8053
|
+
]
|
|
8054
|
+
);
|
|
8055
|
+
return Array.isArray(result) ? result : [];
|
|
8056
|
+
},
|
|
8057
|
+
staleTime: staleTimeMs ?? (includeOffline ? 3e4 : 5e3),
|
|
8058
|
+
gcTime: 5 * 6e4,
|
|
8059
|
+
refetchInterval: refetchIntervalMs ?? false,
|
|
8060
|
+
refetchOnWindowFocus: false,
|
|
8061
|
+
placeholderData: includeOffline ? keepPreviousData : void 0
|
|
8062
|
+
});
|
|
7448
8063
|
return {
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
8064
|
+
players: query.data ?? [],
|
|
8065
|
+
isLoading: query.isLoading,
|
|
8066
|
+
isFetching: query.isFetching,
|
|
8067
|
+
error: query.error ?? null,
|
|
8068
|
+
refresh: () => query.refetch()
|
|
8069
|
+
};
|
|
8070
|
+
}
|
|
8071
|
+
var DEBOUNCE_MS = 300;
|
|
8072
|
+
var ONLINE_COLOR = "#3FA83F";
|
|
8073
|
+
var OFFLINE_COLOR = "#E54141";
|
|
8074
|
+
function PlayerSelect({
|
|
8075
|
+
value,
|
|
8076
|
+
onChange,
|
|
8077
|
+
includeOffline = false,
|
|
8078
|
+
limit = 50,
|
|
8079
|
+
searchable: searchableProp,
|
|
8080
|
+
placeholder,
|
|
8081
|
+
nothingFoundMessage: nothingFoundMessageProp,
|
|
8082
|
+
loadingLabel = "Loading\u2026",
|
|
8083
|
+
onlineLabel = "Online",
|
|
8084
|
+
offlineLabel = "Offline",
|
|
8085
|
+
refreshLabel = "Refresh player list",
|
|
8086
|
+
...rest
|
|
8087
|
+
}) {
|
|
8088
|
+
const theme2 = useMantineTheme();
|
|
8089
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8090
|
+
const [searchInput, setSearchInput] = useState("");
|
|
8091
|
+
const [debouncedSearch, setDebouncedSearch] = useState("");
|
|
8092
|
+
const { players, isFetching, refresh } = usePlayers({
|
|
8093
|
+
includeOffline,
|
|
8094
|
+
search: includeOffline ? debouncedSearch : void 0,
|
|
8095
|
+
limit
|
|
8096
|
+
});
|
|
8097
|
+
const sortedPlayers = useMemo(
|
|
8098
|
+
() => [...players].sort((a, b) => {
|
|
8099
|
+
if (a.online !== b.online) return a.online ? -1 : 1;
|
|
8100
|
+
return a.charName.localeCompare(b.charName);
|
|
8101
|
+
}),
|
|
8102
|
+
[players]
|
|
8103
|
+
);
|
|
8104
|
+
const playerByCitizen = useMemo(() => {
|
|
8105
|
+
const m = /* @__PURE__ */ new Map();
|
|
8106
|
+
for (const p of sortedPlayers) m.set(p.citizenId, p);
|
|
8107
|
+
return m;
|
|
8108
|
+
}, [sortedPlayers]);
|
|
8109
|
+
const data = useMemo(() => {
|
|
8110
|
+
const items = sortedPlayers.map((p) => ({
|
|
8111
|
+
value: p.citizenId,
|
|
8112
|
+
label: formatLabel(p)
|
|
8113
|
+
}));
|
|
8114
|
+
if (value && !items.some((i) => i.value === value)) {
|
|
8115
|
+
items.unshift({ value, label: value });
|
|
7454
8116
|
}
|
|
8117
|
+
return items;
|
|
8118
|
+
}, [sortedPlayers, value]);
|
|
8119
|
+
const selectedPlayer = value ? playerByCitizen.get(value) ?? null : null;
|
|
8120
|
+
const selectedLabel = selectedPlayer ? formatLabel(selectedPlayer) : null;
|
|
8121
|
+
useEffect(() => {
|
|
8122
|
+
if (!includeOffline) return;
|
|
8123
|
+
if (selectedLabel && searchInput === selectedLabel) return;
|
|
8124
|
+
const t3 = setTimeout(() => setDebouncedSearch(searchInput), DEBOUNCE_MS);
|
|
8125
|
+
return () => clearTimeout(t3);
|
|
8126
|
+
}, [searchInput, includeOffline, selectedLabel]);
|
|
8127
|
+
const renderOption = ({ option }) => {
|
|
8128
|
+
const p = playerByCitizen.get(option.value);
|
|
8129
|
+
if (!p) return option.label;
|
|
8130
|
+
return /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", gap: "xs", style: { width: "100%" }, children: [
|
|
8131
|
+
/* @__PURE__ */ jsx(Text, { size: "xs", truncate: true, style: { flex: 1 }, children: formatLabel(p) }),
|
|
8132
|
+
/* @__PURE__ */ jsx(StatusDot, { online: p.online, onlineLabel, offlineLabel })
|
|
8133
|
+
] });
|
|
7455
8134
|
};
|
|
8135
|
+
return /* @__PURE__ */ jsx(
|
|
8136
|
+
Select,
|
|
8137
|
+
{
|
|
8138
|
+
...rest,
|
|
8139
|
+
data,
|
|
8140
|
+
value: value ?? null,
|
|
8141
|
+
onChange: (v) => {
|
|
8142
|
+
if (!v) return onChange(null);
|
|
8143
|
+
const player = playerByCitizen.get(v) ?? null;
|
|
8144
|
+
onChange(player);
|
|
8145
|
+
},
|
|
8146
|
+
searchable: searchableProp ?? true,
|
|
8147
|
+
searchValue: includeOffline ? searchInput : void 0,
|
|
8148
|
+
onSearchChange: includeOffline ? setSearchInput : void 0,
|
|
8149
|
+
placeholder,
|
|
8150
|
+
nothingFoundMessage: isFetching ? loadingLabel : nothingFoundMessageProp ?? "No players found",
|
|
8151
|
+
maxDropdownHeight: 300,
|
|
8152
|
+
renderOption,
|
|
8153
|
+
leftSection: selectedPlayer ? /* @__PURE__ */ jsx(StatusDot, { online: selectedPlayer.online, onlineLabel, offlineLabel }) : void 0,
|
|
8154
|
+
rightSectionWidth: "3.5vh",
|
|
8155
|
+
rightSectionPointerEvents: "all",
|
|
8156
|
+
rightSection: /* @__PURE__ */ jsx(
|
|
8157
|
+
ActionIcon,
|
|
8158
|
+
{
|
|
8159
|
+
variant: "subtle",
|
|
8160
|
+
size: "sm",
|
|
8161
|
+
onClick: (e) => {
|
|
8162
|
+
e.stopPropagation();
|
|
8163
|
+
refresh();
|
|
8164
|
+
},
|
|
8165
|
+
"aria-label": refreshLabel,
|
|
8166
|
+
title: refreshLabel,
|
|
8167
|
+
style: { marginRight: "0.6vh" },
|
|
8168
|
+
children: isFetching ? /* @__PURE__ */ jsx(Loader, { size: "1.2vh", color }) : /* @__PURE__ */ jsx(RefreshCw, { size: "1.4vh", color })
|
|
8169
|
+
}
|
|
8170
|
+
)
|
|
8171
|
+
}
|
|
8172
|
+
);
|
|
7456
8173
|
}
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
}
|
|
7471
|
-
render() {
|
|
7472
|
-
if (!this.state.error) return this.props.children;
|
|
7473
|
-
return /* @__PURE__ */ jsx(
|
|
7474
|
-
Box,
|
|
7475
|
-
{
|
|
7476
|
-
style: {
|
|
7477
|
-
position: "fixed",
|
|
7478
|
-
inset: 0,
|
|
7479
|
-
width: "100vw",
|
|
7480
|
-
height: "100vh",
|
|
7481
|
-
background: "rgba(10, 10, 12, 0.92)",
|
|
7482
|
-
display: "flex",
|
|
7483
|
-
alignItems: "center",
|
|
7484
|
-
justifyContent: "center",
|
|
7485
|
-
padding: "2rem",
|
|
7486
|
-
zIndex: 999999
|
|
7487
|
-
},
|
|
7488
|
-
children: /* @__PURE__ */ jsx(
|
|
7489
|
-
Box,
|
|
7490
|
-
{
|
|
7491
|
-
maw: 900,
|
|
7492
|
-
w: "100%",
|
|
7493
|
-
p: "lg",
|
|
7494
|
-
style: {
|
|
7495
|
-
background: "rgba(20,20,24,0.75)",
|
|
7496
|
-
border: "1px solid rgba(255,255,255,0.08)",
|
|
7497
|
-
borderRadius: "10px",
|
|
7498
|
-
boxShadow: "0 10px 40px rgba(0,0,0,0.6)"
|
|
7499
|
-
},
|
|
7500
|
-
children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
|
|
7501
|
-
/* @__PURE__ */ jsx(Title$1, { order: 2, c: "red.5", children: "Dirk UI Crash" }),
|
|
7502
|
-
/* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: "The interface encountered a fatal error and stopped rendering." }),
|
|
7503
|
-
/* @__PURE__ */ jsx(Code, { block: true, style: { maxHeight: 150, overflow: "auto" }, children: this.state.error?.message }),
|
|
7504
|
-
/* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Check console for full stack trace" })
|
|
7505
|
-
] })
|
|
7506
|
-
}
|
|
7507
|
-
)
|
|
8174
|
+
function StatusDot({ online, onlineLabel, offlineLabel }) {
|
|
8175
|
+
return /* @__PURE__ */ jsx(
|
|
8176
|
+
"span",
|
|
8177
|
+
{
|
|
8178
|
+
title: online ? onlineLabel : offlineLabel,
|
|
8179
|
+
style: {
|
|
8180
|
+
display: "inline-block",
|
|
8181
|
+
width: "0.9vh",
|
|
8182
|
+
height: "0.9vh",
|
|
8183
|
+
borderRadius: "50%",
|
|
8184
|
+
backgroundColor: online ? ONLINE_COLOR : OFFLINE_COLOR,
|
|
8185
|
+
boxShadow: `0 0 0.4vh ${online ? ONLINE_COLOR : OFFLINE_COLOR}`,
|
|
8186
|
+
flexShrink: 0
|
|
7508
8187
|
}
|
|
7509
|
-
|
|
8188
|
+
}
|
|
8189
|
+
);
|
|
8190
|
+
}
|
|
8191
|
+
function formatLabel(p) {
|
|
8192
|
+
const parts = [p.charName || p.citizenId];
|
|
8193
|
+
if (p.online) {
|
|
8194
|
+
if (p.name) parts.push(p.name);
|
|
8195
|
+
if (p.id != null) parts.push(`#${p.id}`);
|
|
7510
8196
|
}
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
function
|
|
7514
|
-
const
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
});
|
|
7526
|
-
}, [overideResourceName]);
|
|
7527
|
-
useEffect(() => {
|
|
7528
|
-
fetchNui("NUI_READY").catch(() => {
|
|
8197
|
+
return parts.join(" \xB7 ");
|
|
8198
|
+
}
|
|
8199
|
+
function usePickDoor() {
|
|
8200
|
+
const begin = useAdminToolStore((s) => s.begin);
|
|
8201
|
+
return async () => {
|
|
8202
|
+
const pending = begin({
|
|
8203
|
+
id: "pickDoor",
|
|
8204
|
+
title: locale("PickDoorTitle"),
|
|
8205
|
+
hint: locale("PickDoorHint"),
|
|
8206
|
+
keys: [
|
|
8207
|
+
{ key: "LMB", action: locale("Toggle") },
|
|
8208
|
+
{ key: "E", action: locale("Confirm") },
|
|
8209
|
+
{ key: "BACKSPACE", action: locale("Cancel") }
|
|
8210
|
+
]
|
|
7529
8211
|
});
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
fetchNui("GET_RESOURCE_VERSION", void 0, { version: "dev" })
|
|
7533
|
-
]).then(([data, resourceInfo]) => {
|
|
7534
|
-
useSettings.setState({
|
|
7535
|
-
...data,
|
|
7536
|
-
resourceVersion: resourceInfo?.version || "dev"
|
|
7537
|
-
});
|
|
7538
|
-
}).catch((err) => {
|
|
7539
|
-
console.error("Failed to fetch initial settings within dirk-cfx-react:", err);
|
|
8212
|
+
fetchNui("ADMIN_TOOL_BEGIN", { id: "pickDoor" }).catch(() => {
|
|
8213
|
+
useAdminToolStore.getState().cancelActive();
|
|
7540
8214
|
});
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
|
|
7545
|
-
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
8215
|
+
return await pending;
|
|
8216
|
+
};
|
|
8217
|
+
}
|
|
8218
|
+
function DoorPickerButton({
|
|
8219
|
+
onPick,
|
|
8220
|
+
compact,
|
|
8221
|
+
label: label2,
|
|
8222
|
+
tooltip
|
|
8223
|
+
}) {
|
|
8224
|
+
const theme2 = useMantineTheme();
|
|
8225
|
+
const color = theme2.colors[theme2.primaryColor][5];
|
|
8226
|
+
const pickDoor = usePickDoor();
|
|
8227
|
+
const onClick = async () => {
|
|
8228
|
+
const picked = await pickDoor();
|
|
8229
|
+
if (picked && picked.doors.length > 0) onPick(picked);
|
|
8230
|
+
};
|
|
8231
|
+
return /* @__PURE__ */ jsx(
|
|
8232
|
+
Tooltip,
|
|
8233
|
+
{
|
|
8234
|
+
label: tooltip ?? locale("PickDoorTooltip"),
|
|
8235
|
+
position: "top",
|
|
8236
|
+
withArrow: true,
|
|
8237
|
+
withinPortal: true,
|
|
8238
|
+
zIndex: 2e3,
|
|
8239
|
+
children: /* @__PURE__ */ jsxs(
|
|
8240
|
+
motion.button,
|
|
8241
|
+
{
|
|
8242
|
+
onClick,
|
|
8243
|
+
whileHover: { background: alpha(color, 0.18) },
|
|
8244
|
+
whileTap: { scale: 0.95 },
|
|
8245
|
+
style: {
|
|
8246
|
+
background: alpha(color, 0.1),
|
|
8247
|
+
border: `0.1vh solid ${alpha(color, 0.35)}`,
|
|
8248
|
+
borderRadius: theme2.radius.xs,
|
|
8249
|
+
padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
|
|
8250
|
+
cursor: "pointer",
|
|
8251
|
+
display: "flex",
|
|
8252
|
+
alignItems: "center",
|
|
8253
|
+
gap: compact ? "0.3vh" : "0.4vh"
|
|
8254
|
+
},
|
|
8255
|
+
children: [
|
|
8256
|
+
/* @__PURE__ */ jsx(DoorOpen, { size: compact ? "1.1vh" : "1.3vh", color }),
|
|
8257
|
+
/* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: label2 ?? locale("PickDoor") })
|
|
8258
|
+
]
|
|
8259
|
+
}
|
|
8260
|
+
)
|
|
8261
|
+
}
|
|
8262
|
+
);
|
|
8263
|
+
}
|
|
8264
|
+
var MapImpl = memo(({
|
|
8265
|
+
children,
|
|
8266
|
+
initialZoom = 2,
|
|
8267
|
+
initialCenter = gameToMap(0, 0),
|
|
8268
|
+
mapStyle = "game"
|
|
8269
|
+
}) => {
|
|
8270
|
+
const mapRef = useRef(null);
|
|
8271
|
+
return /* @__PURE__ */ jsxs(
|
|
8272
|
+
MapContainer,
|
|
8273
|
+
{
|
|
8274
|
+
maxBoundsViscosity: 1,
|
|
8275
|
+
preferCanvas: true,
|
|
8276
|
+
zoom: Math.round(initialZoom),
|
|
8277
|
+
zoomSnap: 1,
|
|
8278
|
+
zoomDelta: 1,
|
|
8279
|
+
zoomControl: false,
|
|
8280
|
+
crs: CRS.Simple,
|
|
8281
|
+
style: {
|
|
8282
|
+
height: "100%",
|
|
8283
|
+
width: "100%",
|
|
8284
|
+
overflow: "hidden",
|
|
8285
|
+
outline: "none !important",
|
|
8286
|
+
border: "none !important",
|
|
8287
|
+
boxShadow: "none !important",
|
|
8288
|
+
backgroundColor: "#384950"
|
|
8289
|
+
},
|
|
8290
|
+
center: initialCenter,
|
|
8291
|
+
attributionControl: false,
|
|
8292
|
+
doubleClickZoom: false,
|
|
8293
|
+
inertia: false,
|
|
8294
|
+
zoomAnimation: false,
|
|
8295
|
+
ref: mapRef,
|
|
8296
|
+
maxBounds: [[-250, -250], [250, 250]],
|
|
8297
|
+
children: [
|
|
8298
|
+
/* @__PURE__ */ jsx(MapLayer, { mapLayer: mapStyle }),
|
|
8299
|
+
children
|
|
8300
|
+
]
|
|
7555
8301
|
}
|
|
7556
8302
|
);
|
|
8303
|
+
});
|
|
8304
|
+
MapImpl.displayName = "DirkMap";
|
|
8305
|
+
var Map2 = MapImpl;
|
|
8306
|
+
var MapLayer = ({ mapLayer }) => {
|
|
8307
|
+
const map = useMap();
|
|
8308
|
+
const layerRef = useRef(null);
|
|
7557
8309
|
useEffect(() => {
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
const inst = getScriptConfigInstance();
|
|
7561
|
-
setScTheme(inst.store.getState()?.theme ?? null);
|
|
7562
|
-
const subscribable = inst.store;
|
|
7563
|
-
if (typeof subscribable.subscribe === "function") {
|
|
7564
|
-
unsubscribe = subscribable.subscribe((s) => {
|
|
7565
|
-
setScTheme(s?.theme ?? null);
|
|
7566
|
-
});
|
|
7567
|
-
}
|
|
7568
|
-
inst.fetchConfig?.().then((full) => {
|
|
7569
|
-
if (full && typeof full === "object") {
|
|
7570
|
-
setScTheme(full.theme ?? null);
|
|
7571
|
-
}
|
|
7572
|
-
}).catch(() => {
|
|
7573
|
-
});
|
|
7574
|
-
} catch {
|
|
8310
|
+
if (layerRef.current) {
|
|
8311
|
+
map.removeLayer(layerRef.current);
|
|
7575
8312
|
}
|
|
8313
|
+
const layer = tileLayer(
|
|
8314
|
+
`https://s.rsg.sc/sc/images/games/GTAV/map/${mapLayer}/{z}/{x}/{y}.jpg`,
|
|
8315
|
+
{
|
|
8316
|
+
maxZoom: 6,
|
|
8317
|
+
minZoom: 4,
|
|
8318
|
+
bounds: latLngBounds(latLng(0, 128), latLng(-192, 0)),
|
|
8319
|
+
tileSize: 256,
|
|
8320
|
+
updateWhenZooming: false,
|
|
8321
|
+
keepBuffer: 2,
|
|
8322
|
+
opacity: 0.75
|
|
8323
|
+
}
|
|
8324
|
+
);
|
|
8325
|
+
layer.addTo(map);
|
|
8326
|
+
layerRef.current = layer;
|
|
7576
8327
|
return () => {
|
|
7577
|
-
|
|
8328
|
+
if (layerRef.current) {
|
|
8329
|
+
map.removeLayer(layerRef.current);
|
|
8330
|
+
}
|
|
7578
8331
|
};
|
|
7579
|
-
}, []);
|
|
7580
|
-
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
const
|
|
7584
|
-
const
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
8332
|
+
}, [mapLayer, map]);
|
|
8333
|
+
return null;
|
|
8334
|
+
};
|
|
8335
|
+
function ZoomControls() {
|
|
8336
|
+
const theme2 = useMantineTheme();
|
|
8337
|
+
const map = useMap();
|
|
8338
|
+
const buttons = [
|
|
8339
|
+
{ Icon: Plus, fn: () => map.zoomIn() },
|
|
8340
|
+
{ Icon: Minus, fn: () => map.zoomOut() }
|
|
8341
|
+
];
|
|
8342
|
+
return /* @__PURE__ */ jsx(
|
|
8343
|
+
motion.div,
|
|
8344
|
+
{
|
|
8345
|
+
style: {
|
|
8346
|
+
position: "absolute",
|
|
8347
|
+
right: "2vh",
|
|
8348
|
+
top: "2vh",
|
|
8349
|
+
display: "flex",
|
|
8350
|
+
flexDirection: "column",
|
|
8351
|
+
zIndex: 999999,
|
|
8352
|
+
boxShadow: `0 0 1vh ${alpha(theme2.colors.dark[9], 0.85)}`,
|
|
8353
|
+
background: alpha(theme2.colors.dark[9], 0.85),
|
|
8354
|
+
borderRadius: theme2.radius.xs
|
|
8355
|
+
},
|
|
8356
|
+
initial: { opacity: 0, y: -20 },
|
|
8357
|
+
animate: { opacity: 1, y: 0 },
|
|
8358
|
+
exit: { opacity: 0, y: -20 },
|
|
8359
|
+
children: buttons.map(({ Icon, fn }, i) => /* @__PURE__ */ jsx(
|
|
8360
|
+
motion.div,
|
|
8361
|
+
{
|
|
8362
|
+
whileHover: { scale: 1.1, filter: "brightness(1.5)" },
|
|
8363
|
+
onClick: fn,
|
|
8364
|
+
style: {
|
|
8365
|
+
padding: theme2.spacing.xs,
|
|
8366
|
+
cursor: "pointer",
|
|
8367
|
+
display: "flex"
|
|
8368
|
+
},
|
|
8369
|
+
children: /* @__PURE__ */ jsx(Icon, { size: 34, color: theme2.colors.gray[5] })
|
|
8370
|
+
},
|
|
8371
|
+
i
|
|
8372
|
+
))
|
|
8373
|
+
}
|
|
7591
8374
|
);
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
8375
|
+
}
|
|
8376
|
+
var DEFAULT_SPRITE = 162;
|
|
8377
|
+
var DEFAULT_COLOR = 5;
|
|
8378
|
+
function BlipMarker({
|
|
8379
|
+
position,
|
|
8380
|
+
sprite,
|
|
8381
|
+
color,
|
|
8382
|
+
scale = 1,
|
|
8383
|
+
onClick,
|
|
8384
|
+
selected,
|
|
8385
|
+
disabled,
|
|
8386
|
+
fallbackSprite = DEFAULT_SPRITE,
|
|
8387
|
+
fallbackColor = DEFAULT_COLOR
|
|
8388
|
+
}) {
|
|
8389
|
+
const [hovered, setHovered] = useState(false);
|
|
8390
|
+
const mapCoords = useMemo(() => gameToMap(position.x, position.y), [position.x, position.y]);
|
|
8391
|
+
const effectiveSprite = sprite ?? fallbackSprite;
|
|
8392
|
+
const effectiveColor = color ?? fallbackColor;
|
|
8393
|
+
const url = blipUrlForSprite(effectiveSprite);
|
|
8394
|
+
const colorHex = getBlipColor(effectiveColor)?.hex ?? "#ffffff";
|
|
8395
|
+
const handleClick = (e) => {
|
|
8396
|
+
e.originalEvent?.stopPropagation?.();
|
|
8397
|
+
if (disabled) return;
|
|
8398
|
+
onClick?.();
|
|
8399
|
+
};
|
|
8400
|
+
const baseSize = 1.8 * scale;
|
|
8401
|
+
const size = `${baseSize}vh`;
|
|
8402
|
+
const ringSize = `${baseSize * 1.6}vh`;
|
|
8403
|
+
return /* @__PURE__ */ jsx(
|
|
8404
|
+
Marker,
|
|
7597
8405
|
{
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
8406
|
+
position: mapCoords,
|
|
8407
|
+
eventHandlers: onClick ? { click: handleClick } : void 0,
|
|
8408
|
+
icon: /* @__PURE__ */ jsxs(
|
|
8409
|
+
motion.div,
|
|
8410
|
+
{
|
|
8411
|
+
onHoverStart: () => setHovered(true),
|
|
8412
|
+
onHoverEnd: () => setHovered(false),
|
|
8413
|
+
style: {
|
|
8414
|
+
position: "relative",
|
|
8415
|
+
display: "flex",
|
|
8416
|
+
alignItems: "center",
|
|
8417
|
+
justifyContent: "center",
|
|
8418
|
+
cursor: disabled ? "not-allowed" : onClick ? "pointer" : "default",
|
|
8419
|
+
opacity: disabled ? 0.35 : 1,
|
|
8420
|
+
width: size,
|
|
8421
|
+
height: size
|
|
8422
|
+
},
|
|
8423
|
+
animate: { scale: hovered && !disabled ? 1.2 : selected ? 1.15 : 1 },
|
|
8424
|
+
transition: { duration: 0.15, ease: "easeOut" },
|
|
8425
|
+
children: [
|
|
8426
|
+
(selected || hovered) && !disabled && /* @__PURE__ */ jsx(
|
|
8427
|
+
motion.div,
|
|
8428
|
+
{
|
|
8429
|
+
style: {
|
|
8430
|
+
position: "absolute",
|
|
8431
|
+
width: ringSize,
|
|
8432
|
+
height: ringSize,
|
|
8433
|
+
borderRadius: "50%",
|
|
8434
|
+
border: `0.18vh solid ${alpha(colorHex, 0.85)}`,
|
|
8435
|
+
boxShadow: `0 0 1vh ${alpha(colorHex, 0.55)}`
|
|
8436
|
+
},
|
|
8437
|
+
initial: { opacity: 0, scale: 0.8 },
|
|
8438
|
+
animate: { opacity: 1, scale: 1 }
|
|
8439
|
+
}
|
|
8440
|
+
),
|
|
8441
|
+
url && /* @__PURE__ */ jsx(
|
|
8442
|
+
"div",
|
|
8443
|
+
{
|
|
8444
|
+
style: {
|
|
8445
|
+
width: size,
|
|
8446
|
+
height: size,
|
|
8447
|
+
backgroundColor: colorHex,
|
|
8448
|
+
WebkitMaskImage: `url(${url})`,
|
|
8449
|
+
maskImage: `url(${url})`,
|
|
8450
|
+
WebkitMaskRepeat: "no-repeat",
|
|
8451
|
+
maskRepeat: "no-repeat",
|
|
8452
|
+
WebkitMaskPosition: "center",
|
|
8453
|
+
maskPosition: "center",
|
|
8454
|
+
WebkitMaskSize: "contain",
|
|
8455
|
+
maskSize: "contain",
|
|
8456
|
+
filter: [
|
|
8457
|
+
"drop-shadow(0.12vh 0 0 #000)",
|
|
8458
|
+
"drop-shadow(-0.12vh 0 0 #000)",
|
|
8459
|
+
"drop-shadow(0 0.12vh 0 #000)",
|
|
8460
|
+
"drop-shadow(0 -0.12vh 0 #000)",
|
|
8461
|
+
`drop-shadow(0 0 0.4vh ${alpha("#000", 0.7)})`
|
|
8462
|
+
].join(" "),
|
|
8463
|
+
pointerEvents: "none",
|
|
8464
|
+
userSelect: "none"
|
|
8465
|
+
}
|
|
8466
|
+
}
|
|
8467
|
+
)
|
|
8468
|
+
]
|
|
8469
|
+
}
|
|
8470
|
+
)
|
|
7602
8471
|
}
|
|
7603
|
-
)
|
|
7604
|
-
|
|
8472
|
+
);
|
|
8473
|
+
}
|
|
8474
|
+
function useTornEdges() {
|
|
8475
|
+
const game = useSettings((state) => state.game);
|
|
8476
|
+
return game === "rdr3" ? "torn-edge-wrapper" : "";
|
|
8477
|
+
}
|
|
8478
|
+
function TornEdgeSVGFilter() {
|
|
8479
|
+
return /* @__PURE__ */ jsx(
|
|
8480
|
+
"svg",
|
|
8481
|
+
{
|
|
8482
|
+
style: { position: "absolute", width: 0, height: 0, pointerEvents: "none" },
|
|
8483
|
+
"aria-hidden": "true",
|
|
8484
|
+
children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("filter", { id: "torn-edge-filter", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
|
|
8485
|
+
/* @__PURE__ */ jsx(
|
|
8486
|
+
"feTurbulence",
|
|
8487
|
+
{
|
|
8488
|
+
type: "fractalNoise",
|
|
8489
|
+
baseFrequency: "0.018 0.022",
|
|
8490
|
+
numOctaves: "5",
|
|
8491
|
+
seed: "9",
|
|
8492
|
+
result: "noise1"
|
|
8493
|
+
}
|
|
8494
|
+
),
|
|
8495
|
+
/* @__PURE__ */ jsx(
|
|
8496
|
+
"feTurbulence",
|
|
8497
|
+
{
|
|
8498
|
+
type: "fractalNoise",
|
|
8499
|
+
baseFrequency: "0.08 0.12",
|
|
8500
|
+
numOctaves: "2",
|
|
8501
|
+
seed: "3",
|
|
8502
|
+
result: "noise2"
|
|
8503
|
+
}
|
|
8504
|
+
),
|
|
8505
|
+
/* @__PURE__ */ jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
|
|
8506
|
+
/* @__PURE__ */ jsx(
|
|
8507
|
+
"feDisplacementMap",
|
|
8508
|
+
{
|
|
8509
|
+
in: "SourceGraphic",
|
|
8510
|
+
in2: "combinedNoise",
|
|
8511
|
+
scale: "52",
|
|
8512
|
+
xChannelSelector: "R",
|
|
8513
|
+
yChannelSelector: "G",
|
|
8514
|
+
result: "displaced"
|
|
8515
|
+
}
|
|
8516
|
+
),
|
|
8517
|
+
/* @__PURE__ */ jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
|
|
8518
|
+
/* @__PURE__ */ jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
|
|
8519
|
+
/* @__PURE__ */ jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
|
|
8520
|
+
/* @__PURE__ */ jsx("feMerge", { children: /* @__PURE__ */ jsx("feMergeNode", { in: "eroded" }) })
|
|
8521
|
+
] }) })
|
|
8522
|
+
}
|
|
8523
|
+
);
|
|
8524
|
+
}
|
|
8525
|
+
var moduleCache = /* @__PURE__ */ new Map();
|
|
8526
|
+
function useValidModels(names) {
|
|
8527
|
+
const cacheKey = useMemo(() => {
|
|
8528
|
+
const unique = Array.from(new Set(names.filter((n) => typeof n === "string" && n.length > 0)));
|
|
8529
|
+
unique.sort();
|
|
8530
|
+
return unique.join("|");
|
|
8531
|
+
}, [names]);
|
|
8532
|
+
const [version, setVersion] = useState(0);
|
|
8533
|
+
const inflight = useRef(/* @__PURE__ */ new Set());
|
|
8534
|
+
useEffect(() => {
|
|
8535
|
+
if (!cacheKey) return;
|
|
8536
|
+
const all = cacheKey.split("|").filter(Boolean);
|
|
8537
|
+
const missing = all.filter((n) => !moduleCache.has(n) && !inflight.current.has(n));
|
|
8538
|
+
if (missing.length === 0) return;
|
|
8539
|
+
missing.forEach((n) => inflight.current.add(n));
|
|
8540
|
+
let cancelled = false;
|
|
8541
|
+
fetchNui(
|
|
8542
|
+
"ADMIN_TOOL_QUERY",
|
|
8543
|
+
{ id: "validateModels", value: missing },
|
|
8544
|
+
// Fallback when running outside FiveM (browser dev) — assume valid so the
|
|
8545
|
+
// dev shell doesn't grey out every row.
|
|
8546
|
+
Object.fromEntries(missing.map((n) => [n, true]))
|
|
8547
|
+
).then((result) => {
|
|
8548
|
+
if (cancelled) return;
|
|
8549
|
+
const map = result && typeof result === "object" ? result : {};
|
|
8550
|
+
missing.forEach((n) => {
|
|
8551
|
+
moduleCache.set(n, !!map[n]);
|
|
8552
|
+
inflight.current.delete(n);
|
|
8553
|
+
});
|
|
8554
|
+
setVersion((v) => v + 1);
|
|
8555
|
+
}).catch(() => {
|
|
8556
|
+
if (cancelled) return;
|
|
8557
|
+
missing.forEach((n) => {
|
|
8558
|
+
inflight.current.delete(n);
|
|
8559
|
+
});
|
|
8560
|
+
});
|
|
8561
|
+
return () => {
|
|
8562
|
+
cancelled = true;
|
|
8563
|
+
};
|
|
8564
|
+
}, [cacheKey]);
|
|
8565
|
+
return useMemo(() => {
|
|
8566
|
+
const out = /* @__PURE__ */ new Set();
|
|
8567
|
+
if (!cacheKey) return out;
|
|
8568
|
+
for (const n of cacheKey.split("|")) {
|
|
8569
|
+
if (n && moduleCache.get(n) === true) out.add(n);
|
|
8570
|
+
}
|
|
8571
|
+
return out;
|
|
8572
|
+
}, [cacheKey, version]);
|
|
7605
8573
|
}
|
|
7606
8574
|
var Vector2Schema = z.object({
|
|
7607
8575
|
x: z.number(),
|
|
@@ -7619,6 +8587,6 @@ var Vector4Schema = z.object({
|
|
|
7619
8587
|
w: z.number()
|
|
7620
8588
|
});
|
|
7621
8589
|
|
|
7622
|
-
export { AccountSelect, AdminPageTitle, AnimPostFxSelect, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, DirkProvider, DiscordRoleSelect, FiveMKeyBindInput, FloatingParticles, FormProvider, GTA_CONTROLS, GTA_CONTROL_GROUP_ORDER, GroupName, GroupRank, GroupSelect, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InfoBox, InputContainer, LevelBanner, LevelPanel, MissingItemsBanner, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, ScenarioSelect, SegmentedControl, SegmentedProgress, SelectItem, SwitchPanel, TestBed, ThemeOverrideSection, Title, TornEdgeSVGFilter, Vector2Schema, Vector3Schema, Vector4DeleteButton, Vector4Display, Vector4Schema, WorldPositionGotoButton, WorldPositionSetButton, colorWithAlpha, copyToClipboard, createFormStore, createScriptConfig, createSkill, extractDefaults, fetchLuaTable, fetchNui, formatGtaControl, gameToMap, getGtaControl, getImageShape, getItemImageUrl, getScriptConfigInstance, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, selectAllGroups, splitFAString, updatePresignedURL, uploadImage, useAudio, useAutoFetcher, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useFrameworkGroups, useItems, useItemsList, useMissingItemsAudit, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, useProfanityStore, useSettings, useTornEdges };
|
|
8590
|
+
export { AccountSelect, AdminPageTitle, AnimPostFxSelect, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BlipMarker, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, DirkProvider, DiscordRoleSelect, DoorPickerButton, FiveMKeyBindInput, FloatingParticles, FormProvider, GTA_CONTROLS, GTA_CONTROL_GROUP_ORDER, GroupName, GroupRank, GroupSelect, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InfoBox, InputContainer, InstructionPanel, LevelBanner, LevelPanel, Map2 as Map, MapLayer, MissingItemsBanner, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PlayerSelect, PositionPicker, PromptModal, ScenarioSelect, SegmentedControl, SegmentedProgress, SelectItem, SwitchPanel, TestBed, ThemeOverrideSection, Title, TornEdgeSVGFilter, Vector2Schema, Vector3Schema, Vector4DeleteButton, Vector4Display, Vector4Schema, WorldPositionGotoButton, WorldPositionPicker, WorldPositionSetButton, ZoomControls, blipUrl, blipUrlForSprite, clearAdminState, colorWithAlpha, copyToClipboard, createFormStore, createScriptConfig, createSkill, dirkQueryClient, ensureFrameworkGroups, extractDefaults, fetchLuaTable, fetchNui, formatGtaControl, gameToMap, getBlipColor, getBlipEntry, getGtaControl, getImageShape, getItemImageUrl, getScriptConfigInstance, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, selectAllGroups, splitFAString, updatePresignedURL, uploadImage, useAdminState, useAdminToolStore, useAudio, useAutoFetcher, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useFrameworkGroups, useItems, useItemsList, useMissingItemsAudit, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, usePickDoor, usePlayers, useProfanityStore, useSettings, useTornEdges, useValidModels };
|
|
7623
8591
|
//# sourceMappingURL=index.js.map
|
|
7624
8592
|
//# sourceMappingURL=index.js.map
|