dirk-cfx-react 1.1.56 → 1.1.62
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 +251 -48
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +64 -16
- package/dist/components/index.d.ts +64 -16
- package/dist/components/index.js +252 -50
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +35 -24
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +27 -19
- package/dist/hooks/index.d.ts +27 -19
- package/dist/hooks/index.js +34 -23
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +345 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +287 -76
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/utils/index.cjs +4 -4
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +4 -4
- package/dist/utils/index.js.map +1 -1
- package/package.json +6 -7
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var core = require('@mantine/core');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React5 = require('react');
|
|
6
6
|
var zustand = require('zustand');
|
|
7
7
|
var axios = require('axios');
|
|
8
8
|
var reactFontawesome = require('@fortawesome/react-fontawesome');
|
|
@@ -24,7 +24,7 @@ var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
|
|
|
24
24
|
|
|
25
25
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var React5__default = /*#__PURE__*/_interopDefault(React5);
|
|
28
28
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
29
29
|
var clickSoundUrl__default = /*#__PURE__*/_interopDefault(clickSoundUrl);
|
|
30
30
|
var hoverSoundUrl__default = /*#__PURE__*/_interopDefault(hoverSoundUrl);
|
|
@@ -1333,12 +1333,10 @@ async function runFetches() {
|
|
|
1333
1333
|
);
|
|
1334
1334
|
}
|
|
1335
1335
|
var useAutoFetcher = () => {
|
|
1336
|
-
|
|
1336
|
+
React5.useEffect(() => {
|
|
1337
1337
|
if (isEnvBrowser()) return;
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
};
|
|
1341
|
-
run();
|
|
1338
|
+
runFetches().catch(() => {
|
|
1339
|
+
});
|
|
1342
1340
|
}, []);
|
|
1343
1341
|
};
|
|
1344
1342
|
var fetchLuaTable = (tableName, mockData) => {
|
|
@@ -1383,6 +1381,7 @@ var localeStore = zustand.create((set, get) => {
|
|
|
1383
1381
|
var locale = localeStore.getState().locale;
|
|
1384
1382
|
registerInitialFetch("GET_LOCALES", void 0).then((data) => {
|
|
1385
1383
|
localeStore.setState({ locales: data });
|
|
1384
|
+
}).catch(() => {
|
|
1386
1385
|
});
|
|
1387
1386
|
|
|
1388
1387
|
// src/utils/map.ts
|
|
@@ -1814,7 +1813,7 @@ function createSkill(defaultSettings) {
|
|
|
1814
1813
|
}));
|
|
1815
1814
|
const useSkill = (xp) => {
|
|
1816
1815
|
const { settings, levelMap } = useStore4();
|
|
1817
|
-
return
|
|
1816
|
+
return React5.useMemo(() => {
|
|
1818
1817
|
const currentLevel = getLevelFromXP(xp, levelMap, settings);
|
|
1819
1818
|
const nextLevel = Math.min(currentLevel + 1, settings.maxLevel);
|
|
1820
1819
|
const currentLevelXP = levelMap[currentLevel.toString()] || 0;
|
|
@@ -1900,6 +1899,7 @@ registerInitialFetch("FETCH_ALL_ITEMS", null, {
|
|
|
1900
1899
|
}).then((fetchedItems) => {
|
|
1901
1900
|
if (!fetchedItems) return;
|
|
1902
1901
|
useItems.setState(fetchedItems);
|
|
1902
|
+
}).catch(() => {
|
|
1903
1903
|
});
|
|
1904
1904
|
|
|
1905
1905
|
// src/utils/inputMapper.ts
|
|
@@ -2270,8 +2270,8 @@ var FloatingParticles = ({
|
|
|
2270
2270
|
mouseRepelStrength = 50,
|
|
2271
2271
|
backgroundColor = "transparent"
|
|
2272
2272
|
}) => {
|
|
2273
|
-
const containerRef =
|
|
2274
|
-
const [particles, setParticles] =
|
|
2273
|
+
const containerRef = React5.useRef(null);
|
|
2274
|
+
const [particles, setParticles] = React5.useState([]);
|
|
2275
2275
|
const mouseX = framerMotion.useMotionValue(0);
|
|
2276
2276
|
const mouseY = framerMotion.useMotionValue(0);
|
|
2277
2277
|
const durationMap = {
|
|
@@ -2284,7 +2284,7 @@ var FloatingParticles = ({
|
|
|
2284
2284
|
const x = Math.sin(seed) * 1e4;
|
|
2285
2285
|
return x - Math.floor(x);
|
|
2286
2286
|
};
|
|
2287
|
-
|
|
2287
|
+
React5.useEffect(() => {
|
|
2288
2288
|
if (!containerRef.current) return;
|
|
2289
2289
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
2290
2290
|
const newParticles = [...Array(particleCount)].map((_, i) => {
|
|
@@ -2305,7 +2305,7 @@ var FloatingParticles = ({
|
|
|
2305
2305
|
});
|
|
2306
2306
|
setParticles(newParticles);
|
|
2307
2307
|
}, [particleCount, icons.length, duration.base, duration.variance]);
|
|
2308
|
-
|
|
2308
|
+
React5.useEffect(() => {
|
|
2309
2309
|
if (!containerRef.current) return;
|
|
2310
2310
|
const handleMouseMove = (e) => {
|
|
2311
2311
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
@@ -2354,7 +2354,7 @@ var FloatingParticles = ({
|
|
|
2354
2354
|
container.removeEventListener("mouseleave", handleMouseLeave);
|
|
2355
2355
|
};
|
|
2356
2356
|
}, [mouseX, mouseY, mouseRepelDistance, mouseRepelStrength]);
|
|
2357
|
-
|
|
2357
|
+
React5.useEffect(() => {
|
|
2358
2358
|
const handleResize = () => {
|
|
2359
2359
|
if (!containerRef.current) return;
|
|
2360
2360
|
const bounds = containerRef.current.getBoundingClientRect();
|
|
@@ -2782,23 +2782,23 @@ function Segment(props) {
|
|
|
2782
2782
|
}
|
|
2783
2783
|
);
|
|
2784
2784
|
}
|
|
2785
|
-
var NavigationContext =
|
|
2785
|
+
var NavigationContext = React5.createContext(null);
|
|
2786
2786
|
function useNavigation(selector) {
|
|
2787
|
-
const navigation =
|
|
2787
|
+
const navigation = React5.useContext(NavigationContext);
|
|
2788
2788
|
if (!navigation) {
|
|
2789
2789
|
throw new Error("useNavigation must be used within a NavigationProvider");
|
|
2790
2790
|
}
|
|
2791
2791
|
return zustand.useStore(navigation, selector);
|
|
2792
2792
|
}
|
|
2793
2793
|
function useNavigationStore() {
|
|
2794
|
-
const navigation =
|
|
2794
|
+
const navigation = React5.useContext(NavigationContext);
|
|
2795
2795
|
if (!navigation) {
|
|
2796
2796
|
throw new Error("useNavigationStore must be used within a NavigationProvider");
|
|
2797
2797
|
}
|
|
2798
2798
|
return navigation;
|
|
2799
2799
|
}
|
|
2800
2800
|
function NavigationProvider({ children, defaultPage }) {
|
|
2801
|
-
const storeRef =
|
|
2801
|
+
const storeRef = React5.useRef(
|
|
2802
2802
|
zustand.create(() => ({
|
|
2803
2803
|
pageId: defaultPage || "home"
|
|
2804
2804
|
}))
|
|
@@ -3155,6 +3155,7 @@ function Modal({
|
|
|
3155
3155
|
children
|
|
3156
3156
|
}) {
|
|
3157
3157
|
const theme2 = core.useMantineTheme();
|
|
3158
|
+
const pointerDownOnOverlay = React5.useRef(false);
|
|
3158
3159
|
return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3159
3160
|
framerMotion.motion.div,
|
|
3160
3161
|
{
|
|
@@ -3170,7 +3171,14 @@ function Modal({
|
|
|
3170
3171
|
justifyContent: "center",
|
|
3171
3172
|
background: "rgba(0,0,0,0.65)"
|
|
3172
3173
|
},
|
|
3173
|
-
|
|
3174
|
+
onPointerDown: (e) => {
|
|
3175
|
+
pointerDownOnOverlay.current = e.target === e.currentTarget;
|
|
3176
|
+
},
|
|
3177
|
+
onClick: (e) => {
|
|
3178
|
+
if (clickOutside && e.target === e.currentTarget && pointerDownOnOverlay.current) {
|
|
3179
|
+
onClose();
|
|
3180
|
+
}
|
|
3181
|
+
},
|
|
3174
3182
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3175
3183
|
framerMotion.motion.div,
|
|
3176
3184
|
{
|
|
@@ -3178,7 +3186,6 @@ function Modal({
|
|
|
3178
3186
|
animate: { opacity: 1, scale: 1, y: 0 },
|
|
3179
3187
|
exit: { opacity: 0, scale: 0.96, y: 8 },
|
|
3180
3188
|
transition: { duration: 0.18, ease: "easeOut" },
|
|
3181
|
-
onClick: (e) => e.stopPropagation(),
|
|
3182
3189
|
style: {
|
|
3183
3190
|
background: core.alpha(theme2.colors.dark[9], 0.98),
|
|
3184
3191
|
border: `0.1vh solid ${theme2.colors.dark[7]}`,
|
|
@@ -3275,7 +3282,7 @@ function Modal({
|
|
|
3275
3282
|
children: description2
|
|
3276
3283
|
}
|
|
3277
3284
|
) }),
|
|
3278
|
-
children
|
|
3285
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }, children })
|
|
3279
3286
|
]
|
|
3280
3287
|
}
|
|
3281
3288
|
)
|
|
@@ -3329,9 +3336,9 @@ function PromptModal(props) {
|
|
|
3329
3336
|
}
|
|
3330
3337
|
);
|
|
3331
3338
|
}
|
|
3332
|
-
var ModalContext =
|
|
3339
|
+
var ModalContext = React5.createContext(null);
|
|
3333
3340
|
function useModal(selector) {
|
|
3334
|
-
const modal =
|
|
3341
|
+
const modal = React5.useContext(ModalContext);
|
|
3335
3342
|
if (!modal) {
|
|
3336
3343
|
throw new Error("useModal must be used within a ModalProvider");
|
|
3337
3344
|
}
|
|
@@ -3359,7 +3366,7 @@ function StoreModal() {
|
|
|
3359
3366
|
) });
|
|
3360
3367
|
}
|
|
3361
3368
|
function ModalProvider({ children }) {
|
|
3362
|
-
const storeRef =
|
|
3369
|
+
const storeRef = React5.useRef(
|
|
3363
3370
|
zustand.create(() => ({
|
|
3364
3371
|
active: null
|
|
3365
3372
|
}))
|
|
@@ -3370,7 +3377,7 @@ function ModalProvider({ children }) {
|
|
|
3370
3377
|
] });
|
|
3371
3378
|
}
|
|
3372
3379
|
function useModalActions() {
|
|
3373
|
-
const modal =
|
|
3380
|
+
const modal = React5.useContext(ModalContext);
|
|
3374
3381
|
if (!modal) throw new Error("useModalActions must be used within a ModalProvider");
|
|
3375
3382
|
const showModal = (openModal) => {
|
|
3376
3383
|
modal.setState({ active: openModal });
|
|
@@ -3390,7 +3397,7 @@ function ConfirmModal({
|
|
|
3390
3397
|
zIndex = 200
|
|
3391
3398
|
}) {
|
|
3392
3399
|
const theme2 = core.useMantineTheme();
|
|
3393
|
-
const [typed, setTyped] =
|
|
3400
|
+
const [typed, setTyped] = React5.useState("");
|
|
3394
3401
|
const canConfirm = !confirmText || typed === confirmText;
|
|
3395
3402
|
return /* @__PURE__ */ jsxRuntime.jsx(core.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3396
3403
|
framerMotion.motion.div,
|
|
@@ -3868,38 +3875,38 @@ function createFormStore(initialValues, validationRules, onSubmit) {
|
|
|
3868
3875
|
}
|
|
3869
3876
|
}));
|
|
3870
3877
|
}
|
|
3871
|
-
var FormContext =
|
|
3878
|
+
var FormContext = React5.createContext(null);
|
|
3872
3879
|
function FormProvider({
|
|
3873
3880
|
initialValues,
|
|
3874
3881
|
validate,
|
|
3875
3882
|
onSubmit,
|
|
3876
3883
|
children
|
|
3877
3884
|
}) {
|
|
3878
|
-
const storeRef =
|
|
3885
|
+
const storeRef = React5.useRef(
|
|
3879
3886
|
createFormStore(initialValues, validate, onSubmit)
|
|
3880
3887
|
);
|
|
3881
3888
|
return /* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: storeRef.current, children });
|
|
3882
3889
|
}
|
|
3883
3890
|
function useForm() {
|
|
3884
|
-
const store =
|
|
3891
|
+
const store = React5.useContext(FormContext);
|
|
3885
3892
|
if (!store) {
|
|
3886
3893
|
throw new Error("useForm must be used inside <FormProvider>");
|
|
3887
3894
|
}
|
|
3888
3895
|
const state = zustand.useStore(store);
|
|
3889
|
-
const changedFields =
|
|
3896
|
+
const changedFields = React5.useMemo(() => {
|
|
3890
3897
|
return collectChangedPaths(state.values, state.initialValues);
|
|
3891
3898
|
}, [state.values, state.initialValues]);
|
|
3892
3899
|
return { ...state, changedFields, changedCount: changedFields.length };
|
|
3893
3900
|
}
|
|
3894
3901
|
function useFormField(path) {
|
|
3895
|
-
const store =
|
|
3902
|
+
const store = React5.useContext(FormContext);
|
|
3896
3903
|
if (!store) {
|
|
3897
3904
|
throw new Error("useFormField must be used inside <FormProvider>");
|
|
3898
3905
|
}
|
|
3899
3906
|
return zustand.useStore(store, (s) => getNested(s.values, path));
|
|
3900
3907
|
}
|
|
3901
3908
|
function useFormFields(...paths) {
|
|
3902
|
-
const store =
|
|
3909
|
+
const store = React5.useContext(FormContext);
|
|
3903
3910
|
if (!store) {
|
|
3904
3911
|
throw new Error("useFormFields must be used inside <FormProvider>");
|
|
3905
3912
|
}
|
|
@@ -3912,14 +3919,14 @@ function useFormFields(...paths) {
|
|
|
3912
3919
|
});
|
|
3913
3920
|
}
|
|
3914
3921
|
function useFormError(path) {
|
|
3915
|
-
const store =
|
|
3922
|
+
const store = React5.useContext(FormContext);
|
|
3916
3923
|
if (!store) {
|
|
3917
3924
|
throw new Error("useFormError must be used inside <FormProvider>");
|
|
3918
3925
|
}
|
|
3919
3926
|
return zustand.useStore(store, (s) => s.errors[path]);
|
|
3920
3927
|
}
|
|
3921
3928
|
function useFormErrors(...paths) {
|
|
3922
|
-
const store =
|
|
3929
|
+
const store = React5.useContext(FormContext);
|
|
3923
3930
|
if (!store) {
|
|
3924
3931
|
throw new Error("useFormErrors must be used inside <FormProvider>");
|
|
3925
3932
|
}
|
|
@@ -3932,18 +3939,18 @@ function useFormErrors(...paths) {
|
|
|
3932
3939
|
});
|
|
3933
3940
|
}
|
|
3934
3941
|
function useFormActions() {
|
|
3935
|
-
const store =
|
|
3942
|
+
const store = React5.useContext(FormContext);
|
|
3936
3943
|
if (!store) {
|
|
3937
3944
|
throw new Error("useFormActions must be used inside <FormProvider>");
|
|
3938
3945
|
}
|
|
3939
3946
|
return store.getState();
|
|
3940
3947
|
}
|
|
3941
3948
|
var useNuiEvent = (action, handler) => {
|
|
3942
|
-
const savedHandler =
|
|
3943
|
-
|
|
3949
|
+
const savedHandler = React5.useRef(noop);
|
|
3950
|
+
React5.useEffect(() => {
|
|
3944
3951
|
savedHandler.current = handler;
|
|
3945
3952
|
}, [handler]);
|
|
3946
|
-
|
|
3953
|
+
React5.useEffect(() => {
|
|
3947
3954
|
const eventListener = (event) => {
|
|
3948
3955
|
const { action: eventAction, data } = event.data;
|
|
3949
3956
|
if (savedHandler.current) {
|
|
@@ -3957,42 +3964,42 @@ var useNuiEvent = (action, handler) => {
|
|
|
3957
3964
|
}, [action]);
|
|
3958
3965
|
};
|
|
3959
3966
|
var _instance = null;
|
|
3960
|
-
function
|
|
3961
|
-
if (!_instance) throw new Error("[dirk-cfx-react]
|
|
3967
|
+
function getScriptConfigInstance() {
|
|
3968
|
+
if (!_instance) throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
3962
3969
|
return _instance;
|
|
3963
3970
|
}
|
|
3964
|
-
function
|
|
3971
|
+
function createScriptConfig(defaultValue) {
|
|
3965
3972
|
const store = zustand.create(() => defaultValue);
|
|
3966
3973
|
let clientVersion = 0;
|
|
3967
|
-
const
|
|
3968
|
-
useNuiEvent("
|
|
3974
|
+
const useScriptConfigHooks = () => {
|
|
3975
|
+
useNuiEvent("UPDATE_SCRIPT_CONFIG", (data) => {
|
|
3969
3976
|
if (!data) return;
|
|
3970
3977
|
if (typeof data.clientVersion === "number") {
|
|
3971
3978
|
clientVersion = data.clientVersion;
|
|
3972
3979
|
}
|
|
3973
|
-
if (data.
|
|
3974
|
-
store.setState((prev) => ({ ...prev, ...data.
|
|
3980
|
+
if (data.config && typeof data.config === "object") {
|
|
3981
|
+
store.setState((prev) => ({ ...prev, ...data.config }));
|
|
3975
3982
|
}
|
|
3976
3983
|
});
|
|
3977
3984
|
};
|
|
3978
|
-
const
|
|
3985
|
+
const fetchScriptConfig = async () => {
|
|
3979
3986
|
try {
|
|
3980
|
-
const response = await fetchNui("
|
|
3981
|
-
if (response?.success && response.data?.
|
|
3982
|
-
store.setState(() => response.data.
|
|
3987
|
+
const response = await fetchNui("GET_FULL_SCRIPT_CONFIG");
|
|
3988
|
+
if (response?.success && response.data?.config) {
|
|
3989
|
+
store.setState(() => response.data.config);
|
|
3983
3990
|
if (typeof response.data.clientVersion === "number") {
|
|
3984
3991
|
clientVersion = response.data.clientVersion;
|
|
3985
3992
|
}
|
|
3986
|
-
return response.data.
|
|
3993
|
+
return response.data.config;
|
|
3987
3994
|
}
|
|
3988
3995
|
} catch {
|
|
3989
3996
|
}
|
|
3990
3997
|
return null;
|
|
3991
3998
|
};
|
|
3992
|
-
const
|
|
3993
|
-
store.setState((prev) => ({ ...prev, ...
|
|
3994
|
-
const response = await fetchNui("
|
|
3995
|
-
data:
|
|
3999
|
+
const updateScriptConfig = async (newConfig) => {
|
|
4000
|
+
store.setState((prev) => ({ ...prev, ...newConfig }));
|
|
4001
|
+
const response = await fetchNui("UPDATE_SCRIPT_CONFIG", {
|
|
4002
|
+
data: newConfig,
|
|
3996
4003
|
expectedVersion: clientVersion
|
|
3997
4004
|
});
|
|
3998
4005
|
if (response?.meta?.client_version != null) {
|
|
@@ -4003,18 +4010,29 @@ function createScriptSettings(defaultValue) {
|
|
|
4003
4010
|
}
|
|
4004
4011
|
return response;
|
|
4005
4012
|
};
|
|
4006
|
-
const
|
|
4007
|
-
return fetchNui("
|
|
4013
|
+
const getScriptConfigHistory = async (params = {}) => {
|
|
4014
|
+
return fetchNui("GET_SCRIPT_CONFIG_HISTORY", params);
|
|
4015
|
+
};
|
|
4016
|
+
const resetConfig = async () => {
|
|
4017
|
+
const response = await fetchNui("RESET_SCRIPT_CONFIG");
|
|
4018
|
+
if (response?.success) {
|
|
4019
|
+
const fresh = await fetchScriptConfig();
|
|
4020
|
+
if (fresh) {
|
|
4021
|
+
store.setState(() => fresh);
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
4024
|
+
return response;
|
|
4008
4025
|
};
|
|
4009
4026
|
_instance = {
|
|
4010
4027
|
store,
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4028
|
+
updateConfig: updateScriptConfig,
|
|
4029
|
+
resetConfig,
|
|
4030
|
+
getHistory: getScriptConfigHistory,
|
|
4031
|
+
fetchConfig: fetchScriptConfig
|
|
4014
4032
|
};
|
|
4015
|
-
return { store,
|
|
4033
|
+
return { store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig };
|
|
4016
4034
|
}
|
|
4017
|
-
var
|
|
4035
|
+
var configPanelQueryClient = new reactQuery.QueryClient({
|
|
4018
4036
|
defaultOptions: { queries: { staleTime: 3e4, gcTime: 5 * 6e4 } }
|
|
4019
4037
|
});
|
|
4020
4038
|
function NavItemButton({
|
|
@@ -4058,15 +4076,15 @@ function NavItemButton({
|
|
|
4058
4076
|
}
|
|
4059
4077
|
);
|
|
4060
4078
|
}
|
|
4061
|
-
function
|
|
4079
|
+
function ConfigJsonModal({
|
|
4062
4080
|
onClose,
|
|
4063
4081
|
schema
|
|
4064
4082
|
}) {
|
|
4065
4083
|
const theme2 = core.useMantineTheme();
|
|
4066
4084
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4067
4085
|
const form = useForm();
|
|
4068
|
-
const [json, setJson] =
|
|
4069
|
-
const [error2, setError] =
|
|
4086
|
+
const [json, setJson] = React5.useState(() => JSON.stringify(form.values, null, 2));
|
|
4087
|
+
const [error2, setError] = React5.useState(null);
|
|
4070
4088
|
const handleSave = () => {
|
|
4071
4089
|
try {
|
|
4072
4090
|
const parsed = JSON.parse(json);
|
|
@@ -4095,7 +4113,7 @@ function SettingsJsonModal({
|
|
|
4095
4113
|
setError(e.message);
|
|
4096
4114
|
}
|
|
4097
4115
|
};
|
|
4098
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "
|
|
4116
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Config JSON", icon: lucideReact.Code2, iconColor: color, onClose, width: "60vh", maxHeight: "80vh", zIndex: 200, children: [
|
|
4099
4117
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Box, { flex: 1, p: "0.8vh", style: { overflowY: "auto" }, children: [
|
|
4100
4118
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4101
4119
|
core.JsonInput,
|
|
@@ -4237,22 +4255,22 @@ function HistoryTableHeader() {
|
|
|
4237
4255
|
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.45)", children: "Version" })
|
|
4238
4256
|
] });
|
|
4239
4257
|
}
|
|
4240
|
-
function
|
|
4258
|
+
function ConfigHistoryModal({
|
|
4241
4259
|
onClose
|
|
4242
4260
|
}) {
|
|
4243
|
-
const { getHistory } =
|
|
4261
|
+
const { getHistory } = getScriptConfigInstance();
|
|
4244
4262
|
const theme2 = core.useMantineTheme();
|
|
4245
4263
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4246
|
-
const [queryInput, setQueryInput] =
|
|
4247
|
-
const [pathInput, setPathInput] =
|
|
4248
|
-
const [adminInput, setAdminInput] =
|
|
4249
|
-
const [query, setQuery] =
|
|
4250
|
-
const [path, setPath] =
|
|
4251
|
-
const [admin, setAdmin] =
|
|
4252
|
-
const [expandedKey, setExpandedKey] =
|
|
4253
|
-
const filters =
|
|
4264
|
+
const [queryInput, setQueryInput] = React5.useState("");
|
|
4265
|
+
const [pathInput, setPathInput] = React5.useState("");
|
|
4266
|
+
const [adminInput, setAdminInput] = React5.useState("");
|
|
4267
|
+
const [query, setQuery] = React5.useState("");
|
|
4268
|
+
const [path, setPath] = React5.useState("");
|
|
4269
|
+
const [admin, setAdmin] = React5.useState("");
|
|
4270
|
+
const [expandedKey, setExpandedKey] = React5.useState(null);
|
|
4271
|
+
const filters = React5.useMemo(() => ({ query, path, admin }), [query, path, admin]);
|
|
4254
4272
|
const historyQuery = reactQuery.useInfiniteQuery({
|
|
4255
|
-
queryKey: ["
|
|
4273
|
+
queryKey: ["scriptConfigHistory", filters],
|
|
4256
4274
|
initialPageParam: 0,
|
|
4257
4275
|
queryFn: async ({ pageParam }) => {
|
|
4258
4276
|
const response = await getHistory({
|
|
@@ -4263,7 +4281,7 @@ function SettingsHistoryModal({
|
|
|
4263
4281
|
admin: filters.admin || void 0
|
|
4264
4282
|
});
|
|
4265
4283
|
if (!response?.success || !response.data) {
|
|
4266
|
-
throw new Error(response?._error || "Failed to load
|
|
4284
|
+
throw new Error(response?._error || "Failed to load config history");
|
|
4267
4285
|
}
|
|
4268
4286
|
return response.data;
|
|
4269
4287
|
},
|
|
@@ -4277,7 +4295,7 @@ function SettingsHistoryModal({
|
|
|
4277
4295
|
historyQuery.fetchNextPage();
|
|
4278
4296
|
}
|
|
4279
4297
|
};
|
|
4280
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "
|
|
4298
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { title: "Config History", icon: lucideReact.History, iconColor: color, onClose, width: "88vh", maxHeight: "82vh", zIndex: 260, children: [
|
|
4281
4299
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { flex: 1, minHeight: 0 }, children: [
|
|
4282
4300
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xs", p: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[7], 0.8)}` }, children: [
|
|
4283
4301
|
/* @__PURE__ */ jsxRuntime.jsx(core.TextInput, { leftSection: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { size: "1.4vh" }), placeholder: "Search path/admin/value", value: queryInput, onChange: (e) => setQueryInput(e.currentTarget.value), size: "xs", style: { flex: 1 } }),
|
|
@@ -4326,7 +4344,7 @@ function SettingsHistoryModal({
|
|
|
4326
4344
|
) })
|
|
4327
4345
|
] });
|
|
4328
4346
|
}
|
|
4329
|
-
function
|
|
4347
|
+
function ConfigPanelInner({
|
|
4330
4348
|
navItems,
|
|
4331
4349
|
title,
|
|
4332
4350
|
subtitle,
|
|
@@ -4335,28 +4353,37 @@ function SettingsPanelInner({
|
|
|
4335
4353
|
onClose,
|
|
4336
4354
|
schema,
|
|
4337
4355
|
resetConfirmText,
|
|
4338
|
-
|
|
4356
|
+
defaultConfig,
|
|
4339
4357
|
width,
|
|
4340
4358
|
height
|
|
4341
4359
|
}) {
|
|
4342
|
-
const {
|
|
4360
|
+
const { updateConfig, resetConfig, getHistory } = getScriptConfigInstance();
|
|
4343
4361
|
const form = useForm();
|
|
4344
4362
|
const theme2 = core.useMantineTheme();
|
|
4345
4363
|
const color = theme2.colors[theme2.primaryColor][5];
|
|
4346
4364
|
const version = useSettings((s) => s.resourceVersion);
|
|
4347
|
-
const [activeTab, setActiveTab] =
|
|
4348
|
-
const
|
|
4349
|
-
const [
|
|
4350
|
-
const [
|
|
4351
|
-
const [
|
|
4365
|
+
const [activeTab, setActiveTab] = React5.useState(navItems[0]?.id ?? "");
|
|
4366
|
+
const firstMountRef = React5.useRef(true);
|
|
4367
|
+
const [jsonOpen, setJsonOpen] = React5.useState(false);
|
|
4368
|
+
const [historyOpen, setHistoryOpen] = React5.useState(false);
|
|
4369
|
+
const [resetOpen, setResetOpen] = React5.useState(false);
|
|
4370
|
+
const [pendingAction, setPendingAction] = React5.useState(null);
|
|
4352
4371
|
const changedCount = form.changedCount ?? 0;
|
|
4353
4372
|
const isDirty = changedCount > 0;
|
|
4354
|
-
|
|
4373
|
+
const goBack = () => fetchNui("CONFIG_PANEL_BACK");
|
|
4374
|
+
const handleBack = () => {
|
|
4375
|
+
if (isDirty) {
|
|
4376
|
+
setPendingAction("back");
|
|
4377
|
+
return;
|
|
4378
|
+
}
|
|
4379
|
+
goBack();
|
|
4380
|
+
};
|
|
4381
|
+
React5.useEffect(() => {
|
|
4355
4382
|
function handleKeyDown(e) {
|
|
4356
4383
|
if (e.key !== "Escape") return;
|
|
4357
4384
|
if (isDirty) {
|
|
4358
4385
|
e.preventDefault();
|
|
4359
|
-
|
|
4386
|
+
setPendingAction("close");
|
|
4360
4387
|
return;
|
|
4361
4388
|
}
|
|
4362
4389
|
onClose();
|
|
@@ -4365,34 +4392,40 @@ function SettingsPanelInner({
|
|
|
4365
4392
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
4366
4393
|
}, [isDirty, onClose]);
|
|
4367
4394
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
4368
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsonOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4369
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: historyOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4395
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: jsonOpen && /* @__PURE__ */ jsxRuntime.jsx(ConfigJsonModal, { onClose: () => setJsonOpen(false), schema }) }),
|
|
4396
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: historyOpen && /* @__PURE__ */ jsxRuntime.jsx(ConfigHistoryModal, { onClose: () => setHistoryOpen(false) }) }),
|
|
4370
4397
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: resetOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4371
4398
|
ConfirmModal,
|
|
4372
4399
|
{
|
|
4373
4400
|
title: "Reset to Defaults",
|
|
4374
|
-
description: "This will permanently reset ALL
|
|
4375
|
-
confirmLabel: "Reset
|
|
4401
|
+
description: "This will permanently reset ALL config back to the defaults. Every value you have configured will be overwritten. This cannot be undone.",
|
|
4402
|
+
confirmLabel: "Reset Config",
|
|
4376
4403
|
confirmText: resetConfirmText,
|
|
4377
|
-
onConfirm: () => {
|
|
4378
|
-
updateSettings(defaultSettings).then(() => form.reinitialize(cloneSettings(defaultSettings)));
|
|
4404
|
+
onConfirm: async () => {
|
|
4379
4405
|
setResetOpen(false);
|
|
4406
|
+
const result = await resetConfig();
|
|
4407
|
+
if (result?.success) {
|
|
4408
|
+
const { store } = getScriptConfigInstance();
|
|
4409
|
+
form.reinitialize(cloneConfig(store.getState()));
|
|
4410
|
+
}
|
|
4380
4411
|
},
|
|
4381
4412
|
onClose: () => setResetOpen(false),
|
|
4382
4413
|
zIndex: 300
|
|
4383
4414
|
}
|
|
4384
4415
|
) }),
|
|
4385
|
-
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children:
|
|
4416
|
+
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: pendingAction !== null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4386
4417
|
ConfirmModal,
|
|
4387
4418
|
{
|
|
4388
4419
|
title: "Discard Unsaved Changes?",
|
|
4389
|
-
description: "You have unsaved changes. Closing now will discard them.",
|
|
4390
|
-
confirmLabel: "Close Without Saving",
|
|
4420
|
+
description: pendingAction === "back" ? "You have unsaved changes. Going back now will discard them." : "You have unsaved changes. Closing now will discard them.",
|
|
4421
|
+
confirmLabel: pendingAction === "back" ? "Go Back Without Saving" : "Close Without Saving",
|
|
4391
4422
|
onConfirm: () => {
|
|
4392
|
-
|
|
4393
|
-
|
|
4423
|
+
const action = pendingAction;
|
|
4424
|
+
setPendingAction(null);
|
|
4425
|
+
if (action === "back") goBack();
|
|
4426
|
+
else onClose();
|
|
4394
4427
|
},
|
|
4395
|
-
onClose: () =>
|
|
4428
|
+
onClose: () => setPendingAction(null),
|
|
4396
4429
|
zIndex: 300
|
|
4397
4430
|
}
|
|
4398
4431
|
) }),
|
|
@@ -4419,9 +4452,33 @@ function SettingsPanelInner({
|
|
|
4419
4452
|
exit: { scale: 0.3, opacity: 0, transform: "translate(-50%, -50%)" },
|
|
4420
4453
|
children: [
|
|
4421
4454
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { width: "18vh", flexShrink: 0, borderRight: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.8)}`, background: core.alpha(theme2.colors.dark[8], 0.6), overflow: "hidden" }, children: [
|
|
4422
|
-
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "
|
|
4423
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4424
|
-
|
|
4455
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "0.6vh", px: "sm", py: "sm", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.5)}`, flexShrink: 0 }, children: [
|
|
4456
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4457
|
+
framerMotion.motion.button,
|
|
4458
|
+
{
|
|
4459
|
+
title: "Back to script list",
|
|
4460
|
+
onClick: handleBack,
|
|
4461
|
+
whileHover: { background: core.alpha(color, 0.16), borderColor: core.alpha(color, 0.45) },
|
|
4462
|
+
whileTap: { scale: 0.95 },
|
|
4463
|
+
style: {
|
|
4464
|
+
aspectRatio: "1 / 1",
|
|
4465
|
+
height: "2.4vh",
|
|
4466
|
+
background: core.alpha(color, 0.08),
|
|
4467
|
+
border: `0.1vh solid ${core.alpha(color, 0.3)}`,
|
|
4468
|
+
borderRadius: theme2.radius.xs,
|
|
4469
|
+
cursor: "pointer",
|
|
4470
|
+
display: "flex",
|
|
4471
|
+
alignItems: "center",
|
|
4472
|
+
justifyContent: "center",
|
|
4473
|
+
flexShrink: 0
|
|
4474
|
+
},
|
|
4475
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: "1.4vh", color })
|
|
4476
|
+
}
|
|
4477
|
+
),
|
|
4478
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, lineHeight: 1 }, children: [
|
|
4479
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "lg", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
|
|
4480
|
+
subtitle && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.08em", c: color, truncate: true, children: subtitle })
|
|
4481
|
+
] })
|
|
4425
4482
|
] }),
|
|
4426
4483
|
/* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xxs", px: "xs", py: "xs", style: { borderBottom: `0.1vh solid ${core.alpha(theme2.colors.dark[6], 0.4)}`, flexShrink: 0 }, children: [
|
|
4427
4484
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4524,7 +4581,7 @@ function SettingsPanelInner({
|
|
|
4524
4581
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4525
4582
|
framerMotion.motion.div,
|
|
4526
4583
|
{
|
|
4527
|
-
initial: { opacity: 0, y: 4 },
|
|
4584
|
+
initial: firstMountRef.current ? (firstMountRef.current = false, false) : { opacity: 0, y: 4 },
|
|
4528
4585
|
animate: { opacity: 1, y: 0 },
|
|
4529
4586
|
exit: { opacity: 0, y: -4 },
|
|
4530
4587
|
transition: { duration: 0.15 },
|
|
@@ -4538,15 +4595,15 @@ function SettingsPanelInner({
|
|
|
4538
4595
|
)
|
|
4539
4596
|
] });
|
|
4540
4597
|
}
|
|
4541
|
-
function
|
|
4598
|
+
function cloneConfig(value) {
|
|
4542
4599
|
return JSON.parse(JSON.stringify(value));
|
|
4543
4600
|
}
|
|
4544
4601
|
function ServerOnlyFetcher() {
|
|
4545
|
-
const {
|
|
4602
|
+
const { fetchConfig } = getScriptConfigInstance();
|
|
4546
4603
|
const { reinitialize } = useFormActions();
|
|
4547
|
-
|
|
4604
|
+
React5.useEffect(() => {
|
|
4548
4605
|
let cancelled = false;
|
|
4549
|
-
|
|
4606
|
+
fetchConfig().then((full) => {
|
|
4550
4607
|
if (!cancelled && full) reinitialize(full);
|
|
4551
4608
|
}).catch(() => {
|
|
4552
4609
|
});
|
|
@@ -4557,28 +4614,28 @@ function ServerOnlyFetcher() {
|
|
|
4557
4614
|
return null;
|
|
4558
4615
|
}
|
|
4559
4616
|
var defaultOnClose = () => fetchNui("CLOSE_ADMIN_SECTION");
|
|
4560
|
-
function
|
|
4617
|
+
function ConfigPanel(props) {
|
|
4561
4618
|
const { open, onClose = defaultOnClose } = props;
|
|
4562
|
-
const { store,
|
|
4563
|
-
const [isSaving, setIsSaving] =
|
|
4619
|
+
const { store, updateConfig } = getScriptConfigInstance();
|
|
4620
|
+
const [isSaving, setIsSaving] = React5.useState(false);
|
|
4564
4621
|
if (!open) return null;
|
|
4565
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client:
|
|
4622
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: configPanelQueryClient, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4566
4623
|
FormProvider,
|
|
4567
4624
|
{
|
|
4568
|
-
initialValues:
|
|
4625
|
+
initialValues: cloneConfig(store.getState()),
|
|
4569
4626
|
onSubmit: async (form) => {
|
|
4570
4627
|
if (isSaving) return;
|
|
4571
4628
|
setIsSaving(true);
|
|
4572
4629
|
try {
|
|
4573
|
-
const result = await
|
|
4630
|
+
const result = await updateConfig(form.values);
|
|
4574
4631
|
if (result?.success) {
|
|
4575
|
-
form.reinitialize(
|
|
4576
|
-
|
|
4632
|
+
form.reinitialize(cloneConfig(form.values));
|
|
4633
|
+
configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
|
|
4577
4634
|
return;
|
|
4578
4635
|
}
|
|
4579
|
-
form.reinitialize(
|
|
4636
|
+
form.reinitialize(cloneConfig(store.getState()));
|
|
4580
4637
|
if (result?._error) {
|
|
4581
|
-
console.warn(`[
|
|
4638
|
+
console.warn(`[ConfigPanel] config save failed: ${result._error}`);
|
|
4582
4639
|
}
|
|
4583
4640
|
} finally {
|
|
4584
4641
|
setIsSaving(false);
|
|
@@ -4587,7 +4644,7 @@ function SettingsPanel(props) {
|
|
|
4587
4644
|
children: [
|
|
4588
4645
|
/* @__PURE__ */ jsxRuntime.jsx(ServerOnlyFetcher, {}),
|
|
4589
4646
|
/* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4590
|
-
|
|
4647
|
+
ConfigPanelInner,
|
|
4591
4648
|
{
|
|
4592
4649
|
...props,
|
|
4593
4650
|
onClose,
|
|
@@ -4599,9 +4656,9 @@ function SettingsPanel(props) {
|
|
|
4599
4656
|
) });
|
|
4600
4657
|
}
|
|
4601
4658
|
function LazyImage({ src, alt, style }) {
|
|
4602
|
-
const [visible, setVisible] =
|
|
4603
|
-
const ref =
|
|
4604
|
-
|
|
4659
|
+
const [visible, setVisible] = React5.useState(false);
|
|
4660
|
+
const ref = React5.useRef(null);
|
|
4661
|
+
React5.useEffect(() => {
|
|
4605
4662
|
const observer = new IntersectionObserver(([entry]) => {
|
|
4606
4663
|
if (entry.isIntersecting) {
|
|
4607
4664
|
setVisible(true);
|
|
@@ -4615,7 +4672,7 @@ function LazyImage({ src, alt, style }) {
|
|
|
4615
4672
|
}
|
|
4616
4673
|
function SelectItem(props) {
|
|
4617
4674
|
const invItems = useItems();
|
|
4618
|
-
const formattedItems =
|
|
4675
|
+
const formattedItems = React5.useMemo(() => {
|
|
4619
4676
|
const seen = /* @__PURE__ */ new Set();
|
|
4620
4677
|
return useItemsList(props.excludeItemNames ?? []).filter((item) => {
|
|
4621
4678
|
if (seen.has(item.name)) return false;
|
|
@@ -4667,9 +4724,9 @@ function SelectItem(props) {
|
|
|
4667
4724
|
}
|
|
4668
4725
|
);
|
|
4669
4726
|
}
|
|
4670
|
-
var KeyBindContext =
|
|
4727
|
+
var KeyBindContext = React5.createContext(null);
|
|
4671
4728
|
function useKeyBindContext() {
|
|
4672
|
-
const ctx =
|
|
4729
|
+
const ctx = React5.useContext(KeyBindContext);
|
|
4673
4730
|
if (!ctx) {
|
|
4674
4731
|
throw new Error("FiveMKeyBindInput.* must be used inside <FiveMKeyBindInput>");
|
|
4675
4732
|
}
|
|
@@ -4748,7 +4805,7 @@ function AsyncSaveButton({
|
|
|
4748
4805
|
style
|
|
4749
4806
|
}) {
|
|
4750
4807
|
const theme2 = core.useMantineTheme();
|
|
4751
|
-
const [state, setState] =
|
|
4808
|
+
const [state, setState] = React5.useState("idle");
|
|
4752
4809
|
const handleClick = async () => {
|
|
4753
4810
|
if (state === "pending") return;
|
|
4754
4811
|
setState("pending");
|
|
@@ -4795,6 +4852,160 @@ function AdminPageTitle(props) {
|
|
|
4795
4852
|
/* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
|
|
4796
4853
|
] });
|
|
4797
4854
|
}
|
|
4855
|
+
var loadPersistedState = (storageKey) => {
|
|
4856
|
+
try {
|
|
4857
|
+
const raw = localStorage.getItem(storageKey);
|
|
4858
|
+
return raw ? JSON.parse(raw) : {};
|
|
4859
|
+
} catch {
|
|
4860
|
+
return {};
|
|
4861
|
+
}
|
|
4862
|
+
};
|
|
4863
|
+
var savePersistedState = (storageKey, state) => {
|
|
4864
|
+
try {
|
|
4865
|
+
localStorage.setItem(storageKey, JSON.stringify(state));
|
|
4866
|
+
} catch {
|
|
4867
|
+
}
|
|
4868
|
+
};
|
|
4869
|
+
function TestBed({
|
|
4870
|
+
items,
|
|
4871
|
+
storageKey = "testbed:open-state",
|
|
4872
|
+
disablePersistence = false,
|
|
4873
|
+
title = "TestBed"
|
|
4874
|
+
}) {
|
|
4875
|
+
const [open, setOpen] = React5.useState(false);
|
|
4876
|
+
const itemsRef = React5.useRef(items);
|
|
4877
|
+
itemsRef.current = items;
|
|
4878
|
+
React5.useEffect(() => {
|
|
4879
|
+
if (!isEnvBrowser() || disablePersistence) return;
|
|
4880
|
+
const persisted = loadPersistedState(storageKey);
|
|
4881
|
+
itemsRef.current.forEach((item) => {
|
|
4882
|
+
const persistedValue = persisted[item.key];
|
|
4883
|
+
if (typeof persistedValue === "boolean" && persistedValue !== item.active) {
|
|
4884
|
+
item.onToggle(persistedValue);
|
|
4885
|
+
}
|
|
4886
|
+
});
|
|
4887
|
+
}, []);
|
|
4888
|
+
if (!isEnvBrowser()) return null;
|
|
4889
|
+
const toggle = (item) => {
|
|
4890
|
+
const next = !item.active;
|
|
4891
|
+
item.onToggle(next);
|
|
4892
|
+
if (!disablePersistence) {
|
|
4893
|
+
const persisted = loadPersistedState(storageKey);
|
|
4894
|
+
persisted[item.key] = next;
|
|
4895
|
+
savePersistedState(storageKey, persisted);
|
|
4896
|
+
}
|
|
4897
|
+
};
|
|
4898
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4899
|
+
"div",
|
|
4900
|
+
{
|
|
4901
|
+
style: {
|
|
4902
|
+
position: "fixed",
|
|
4903
|
+
top: "1vh",
|
|
4904
|
+
left: "1vh",
|
|
4905
|
+
zIndex: 2147483647,
|
|
4906
|
+
pointerEvents: "auto",
|
|
4907
|
+
fontSize: "1.4vh"
|
|
4908
|
+
},
|
|
4909
|
+
children: [
|
|
4910
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4911
|
+
core.Flex,
|
|
4912
|
+
{
|
|
4913
|
+
align: "center",
|
|
4914
|
+
gap: "xs",
|
|
4915
|
+
px: "sm",
|
|
4916
|
+
py: "xs",
|
|
4917
|
+
onClick: () => setOpen((v) => !v),
|
|
4918
|
+
style: {
|
|
4919
|
+
cursor: "pointer",
|
|
4920
|
+
background: "rgba(0,0,0,0.55)",
|
|
4921
|
+
backdropFilter: "blur(0.6vh)",
|
|
4922
|
+
WebkitBackdropFilter: "blur(0.6vh)",
|
|
4923
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4924
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
4925
|
+
userSelect: "none",
|
|
4926
|
+
minWidth: "16vh"
|
|
4927
|
+
},
|
|
4928
|
+
children: [
|
|
4929
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.FlaskConical, { size: 14, color: "rgba(255,255,255,0.7)" }),
|
|
4930
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4931
|
+
core.Text,
|
|
4932
|
+
{
|
|
4933
|
+
size: "xs",
|
|
4934
|
+
ff: "Akrobat Bold",
|
|
4935
|
+
tt: "uppercase",
|
|
4936
|
+
lts: "0.08em",
|
|
4937
|
+
c: "rgba(255,255,255,0.85)",
|
|
4938
|
+
style: { flex: 1 },
|
|
4939
|
+
children: title
|
|
4940
|
+
}
|
|
4941
|
+
),
|
|
4942
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.ActionIcon, { size: "xs", variant: "transparent", c: "rgba(255,255,255,0.6)", children: open ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14 }) })
|
|
4943
|
+
]
|
|
4944
|
+
}
|
|
4945
|
+
),
|
|
4946
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4947
|
+
core.Stack,
|
|
4948
|
+
{
|
|
4949
|
+
gap: 4,
|
|
4950
|
+
mt: "xxs",
|
|
4951
|
+
p: "xs",
|
|
4952
|
+
style: {
|
|
4953
|
+
background: "rgba(0,0,0,0.55)",
|
|
4954
|
+
backdropFilter: "blur(0.6vh)",
|
|
4955
|
+
WebkitBackdropFilter: "blur(0.6vh)",
|
|
4956
|
+
border: "0.1vh solid rgba(255,255,255,0.1)",
|
|
4957
|
+
borderRadius: "var(--mantine-radius-sm)",
|
|
4958
|
+
minWidth: "16vh",
|
|
4959
|
+
maxHeight: "80vh",
|
|
4960
|
+
overflowY: "auto"
|
|
4961
|
+
},
|
|
4962
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4963
|
+
core.Flex,
|
|
4964
|
+
{
|
|
4965
|
+
align: "center",
|
|
4966
|
+
justify: "space-between",
|
|
4967
|
+
gap: "xs",
|
|
4968
|
+
px: "xs",
|
|
4969
|
+
py: "xxs",
|
|
4970
|
+
onClick: () => toggle(item),
|
|
4971
|
+
style: {
|
|
4972
|
+
cursor: "pointer",
|
|
4973
|
+
borderRadius: "var(--mantine-radius-xs)",
|
|
4974
|
+
background: item.active ? "rgba(245,158,11,0.15)" : "rgba(255,255,255,0.03)",
|
|
4975
|
+
border: `0.1vh solid ${item.active ? "rgba(245,158,11,0.35)" : "rgba(255,255,255,0.05)"}`,
|
|
4976
|
+
userSelect: "none"
|
|
4977
|
+
},
|
|
4978
|
+
children: [
|
|
4979
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4980
|
+
core.Text,
|
|
4981
|
+
{
|
|
4982
|
+
size: "xs",
|
|
4983
|
+
ff: "Akrobat Bold",
|
|
4984
|
+
c: item.active ? "#f59e0b" : "rgba(255,255,255,0.75)",
|
|
4985
|
+
children: item.label
|
|
4986
|
+
}
|
|
4987
|
+
),
|
|
4988
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4989
|
+
core.Text,
|
|
4990
|
+
{
|
|
4991
|
+
size: "xxs",
|
|
4992
|
+
ff: "Akrobat Bold",
|
|
4993
|
+
tt: "uppercase",
|
|
4994
|
+
lts: "0.06em",
|
|
4995
|
+
c: item.active ? "#f59e0b" : "rgba(255,255,255,0.35)",
|
|
4996
|
+
children: item.active ? "On" : "Off"
|
|
4997
|
+
}
|
|
4998
|
+
)
|
|
4999
|
+
]
|
|
5000
|
+
},
|
|
5001
|
+
item.key
|
|
5002
|
+
))
|
|
5003
|
+
}
|
|
5004
|
+
)
|
|
5005
|
+
]
|
|
5006
|
+
}
|
|
5007
|
+
);
|
|
5008
|
+
}
|
|
4798
5009
|
function useTornEdges() {
|
|
4799
5010
|
const game = useSettings((state) => state.game);
|
|
4800
5011
|
return game === "rdr3" ? "torn-edge-wrapper" : "";
|
|
@@ -4985,7 +5196,7 @@ function mergeMantineThemeSafe(base, custom, override) {
|
|
|
4985
5196
|
}
|
|
4986
5197
|
};
|
|
4987
5198
|
}
|
|
4988
|
-
var DirkErrorBoundary = class extends
|
|
5199
|
+
var DirkErrorBoundary = class extends React5__default.default.Component {
|
|
4989
5200
|
constructor() {
|
|
4990
5201
|
super(...arguments);
|
|
4991
5202
|
__publicField(this, "state", { error: null, stack: void 0 });
|
|
@@ -5048,12 +5259,12 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
5048
5259
|
customTheme,
|
|
5049
5260
|
game
|
|
5050
5261
|
} = useSettings();
|
|
5051
|
-
|
|
5262
|
+
React5.useLayoutEffect(() => {
|
|
5052
5263
|
useSettings.setState({
|
|
5053
5264
|
overideResourceName
|
|
5054
5265
|
});
|
|
5055
5266
|
}, [overideResourceName]);
|
|
5056
|
-
|
|
5267
|
+
React5.useEffect(() => {
|
|
5057
5268
|
fetchNui("NUI_READY").catch(() => {
|
|
5058
5269
|
});
|
|
5059
5270
|
Promise.all([
|
|
@@ -5068,7 +5279,7 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
5068
5279
|
console.error("Failed to fetch initial settings within dirk-cfx-react:", err);
|
|
5069
5280
|
});
|
|
5070
5281
|
}, []);
|
|
5071
|
-
const mergedTheme =
|
|
5282
|
+
const mergedTheme = React5.useMemo(
|
|
5072
5283
|
() => mergeMantineThemeSafe(
|
|
5073
5284
|
{ ...theme_default, primaryColor, primaryShade },
|
|
5074
5285
|
customTheme,
|
|
@@ -5076,7 +5287,7 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
5076
5287
|
),
|
|
5077
5288
|
[primaryColor, primaryShade, customTheme, themeOverride]
|
|
5078
5289
|
);
|
|
5079
|
-
|
|
5290
|
+
React5.useEffect(() => {
|
|
5080
5291
|
document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
|
|
5081
5292
|
}, [game]);
|
|
5082
5293
|
const content = isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5096,6 +5307,7 @@ exports.AsyncSaveButton = AsyncSaveButton;
|
|
|
5096
5307
|
exports.BlipColorSelect = BlipColorSelect;
|
|
5097
5308
|
exports.BlipIconSelect = BlipIconSelect;
|
|
5098
5309
|
exports.BorderedIcon = BorderedIcon;
|
|
5310
|
+
exports.ConfigPanel = ConfigPanel;
|
|
5099
5311
|
exports.ConfirmModal = ConfirmModal;
|
|
5100
5312
|
exports.Counter = Counter;
|
|
5101
5313
|
exports.DirkProvider = DirkProvider;
|
|
@@ -5122,13 +5334,13 @@ exports.PromptModal = PromptModal;
|
|
|
5122
5334
|
exports.SegmentedControl = SegmentedControl;
|
|
5123
5335
|
exports.SegmentedProgress = SegmentedProgress;
|
|
5124
5336
|
exports.SelectItem = SelectItem;
|
|
5125
|
-
exports.
|
|
5337
|
+
exports.TestBed = TestBed;
|
|
5126
5338
|
exports.Title = Title;
|
|
5127
5339
|
exports.TornEdgeSVGFilter = TornEdgeSVGFilter;
|
|
5128
5340
|
exports.colorWithAlpha = colorWithAlpha;
|
|
5129
5341
|
exports.copyToClipboard = copyToClipboard;
|
|
5130
5342
|
exports.createFormStore = createFormStore;
|
|
5131
|
-
exports.
|
|
5343
|
+
exports.createScriptConfig = createScriptConfig;
|
|
5132
5344
|
exports.createSkill = createSkill;
|
|
5133
5345
|
exports.extractDefaults = extractDefaults;
|
|
5134
5346
|
exports.fetchLuaTable = fetchLuaTable;
|
|
@@ -5136,7 +5348,7 @@ exports.fetchNui = fetchNui;
|
|
|
5136
5348
|
exports.gameToMap = gameToMap;
|
|
5137
5349
|
exports.getImageShape = getImageShape;
|
|
5138
5350
|
exports.getItemImageUrl = getItemImageUrl;
|
|
5139
|
-
exports.
|
|
5351
|
+
exports.getScriptConfigInstance = getScriptConfigInstance;
|
|
5140
5352
|
exports.initialFetches = initialFetches;
|
|
5141
5353
|
exports.internalEvent = internalEvent;
|
|
5142
5354
|
exports.isEnvBrowser = isEnvBrowser;
|