dirk-cfx-react 1.1.76 → 1.1.78
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.map +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +42 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +42 -9
- package/dist/index.js.map +1 -1
- package/dist/providers/index.cjs +45 -9
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js +46 -10
- package/dist/providers/index.js.map +1 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +0 -1
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
package/dist/providers/index.cjs
CHANGED
|
@@ -281,6 +281,9 @@ function mergeMantineThemeSafe(base, custom, override) {
|
|
|
281
281
|
}
|
|
282
282
|
};
|
|
283
283
|
}
|
|
284
|
+
function getScriptConfigInstance() {
|
|
285
|
+
throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
286
|
+
}
|
|
284
287
|
var DirkErrorBoundary = class extends React__default.default.Component {
|
|
285
288
|
constructor() {
|
|
286
289
|
super(...arguments);
|
|
@@ -345,6 +348,7 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
345
348
|
game
|
|
346
349
|
} = useSettings();
|
|
347
350
|
localeStore((s) => s.locales);
|
|
351
|
+
const [scTheme, setScTheme] = React.useState(null);
|
|
348
352
|
React.useLayoutEffect(() => {
|
|
349
353
|
useSettings.setState({
|
|
350
354
|
overideResourceName
|
|
@@ -367,21 +371,53 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
367
371
|
}, []);
|
|
368
372
|
useNuiEvent("UPDATE_DIRK_LIB_SETTINGS", (data) => {
|
|
369
373
|
if (!data || typeof data !== "object") return;
|
|
370
|
-
const current = useSettings.getState();
|
|
371
|
-
if (current.themeOverride) {
|
|
372
|
-
const { primaryColor: _pc, primaryShade: _ps, customTheme: _ct, ...rest } = data;
|
|
373
|
-
useSettings.setState(rest);
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
374
|
useSettings.setState(data);
|
|
377
375
|
});
|
|
376
|
+
useNuiEvent(
|
|
377
|
+
"UPDATE_SCRIPT_CONFIG",
|
|
378
|
+
(data) => {
|
|
379
|
+
if (!data || !data.config || typeof data.config !== "object") return;
|
|
380
|
+
try {
|
|
381
|
+
const inst = getScriptConfigInstance();
|
|
382
|
+
inst.store.setState((prev) => ({ ...prev, ...data.config }));
|
|
383
|
+
} catch {
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
);
|
|
387
|
+
React.useEffect(() => {
|
|
388
|
+
let unsubscribe;
|
|
389
|
+
try {
|
|
390
|
+
const inst = getScriptConfigInstance();
|
|
391
|
+
setScTheme(inst.store.getState()?.theme ?? null);
|
|
392
|
+
const subscribable = inst.store;
|
|
393
|
+
if (typeof subscribable.subscribe === "function") {
|
|
394
|
+
unsubscribe = subscribable.subscribe((s) => {
|
|
395
|
+
setScTheme(s?.theme ?? null);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
inst.fetchConfig?.().then((full) => {
|
|
399
|
+
if (full && typeof full === "object") {
|
|
400
|
+
setScTheme(full.theme ?? null);
|
|
401
|
+
}
|
|
402
|
+
}).catch(() => {
|
|
403
|
+
});
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
return () => {
|
|
407
|
+
unsubscribe?.();
|
|
408
|
+
};
|
|
409
|
+
}, []);
|
|
410
|
+
const overrideActive = scTheme?.useOverride === true;
|
|
411
|
+
const effectivePrimaryColor = overrideActive ? scTheme.primaryColor ?? primaryColor : primaryColor;
|
|
412
|
+
const effectivePrimaryShade = overrideActive ? scTheme.primaryShade ?? primaryShade : primaryShade;
|
|
413
|
+
const effectiveCustomTheme = overrideActive ? scTheme.customTheme ?? customTheme : customTheme;
|
|
378
414
|
const mergedTheme = React.useMemo(
|
|
379
415
|
() => mergeMantineThemeSafe(
|
|
380
|
-
{ ...theme_default, primaryColor, primaryShade },
|
|
381
|
-
|
|
416
|
+
{ ...theme_default, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade },
|
|
417
|
+
effectiveCustomTheme,
|
|
382
418
|
themeOverride
|
|
383
419
|
),
|
|
384
|
-
[
|
|
420
|
+
[effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]
|
|
385
421
|
);
|
|
386
422
|
React.useEffect(() => {
|
|
387
423
|
document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/theme.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/utils/useSettings.ts","../../src/utils/fetchNui.ts","../../src/utils/locales.ts","../../src/utils/mergeMantineTheme.ts","../../src/providers/DirkErrorBoundary.tsx","../../src/providers/DirkProvider.tsx"],"names":["createTheme","theme","useRef","useEffect","create","React","error","jsx","Box","jsxs","Stack","Title","Text","Code","library","fas","far","fab","useLayoutEffect","useMemo","BackgroundImage","MantineProvider"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ColorInput, createTheme, MantineTheme, MultiSelect, NumberInput, TextInput } from \"@mantine/core\";\r\n\r\nexport const label = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n};\r\nexport const error = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Regular',\r\n};\r\nexport const description = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n};\r\n\r\nexport const genericInputStyles = {\r\n styles: {\r\n label: label,\r\n error: error,\r\n description: description,\r\n \r\n input:{\r\n background: 'rgba(255,255,255,0.04)',\r\n border: '0.1vh solid rgba(255,255,255,0.08)',\r\n color: 'rgba(255,255,255,0.85)',\r\n minHeight: '4vh',\r\n },\r\n },\r\n};\r\n\r\nconst theme = createTheme({\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n defaultRadius: \"xs\",\r\n fontFamily: \"Akrobat Regular, sans-serif\",\r\n\r\n radius:{\r\n xxs: '0.3vh',\r\n xs: '0.5vh',\r\n sm: '0.75vh',\r\n md: '1vh',\r\n lg: '1.5vh',\r\n xl: '2vh',\r\n xxl: '3vh',\r\n },\r\n\r\n fontSizes: {\r\n xxs: '1.2vh',\r\n xs: '1.5vh',\r\n sm: '1.8vh',\r\n md: '2.2vh',\r\n lg: '2.8vh',\r\n xl: '3.3vh',\r\n xxl: '3.8vh',\r\n },\r\n\r\n lineHeights: {\r\n xxs: '1.4vh',\r\n xs: '1.8vh',\r\n sm: '2.2vh',\r\n md: '2.8vh',\r\n lg: '3.3vh',\r\n xl: '3.8vh',\r\n },\r\n\r\n spacing:{\r\n xxs: '0.5vh',\r\n xs: '0.75vh',\r\n sm: '1.5vh',\r\n md: '2vh',\r\n lg: '3vh',\r\n xl: '4vh',\r\n xxl: '5vh',\r\n },\r\n\r\n components:{\r\n Progress:{\r\n styles:{\r\n label: {\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n },\r\n\r\n root:{\r\n backgroundColor: 'rgba(77, 77, 77, 0.4)',\r\n },\r\n \r\n }\r\n },\r\n \r\n \r\n Input: genericInputStyles,\r\n TextInput: genericInputStyles,\r\n NumberInput: genericInputStyles,\r\n Select: genericInputStyles,\r\n MultiSelect: genericInputStyles, \r\n Textarea: genericInputStyles,\r\n ColorInput: genericInputStyles,\r\n DateInput: genericInputStyles,\r\n\r\n Pill: {\r\n styles: (theme: MantineTheme) => ({\r\n root: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)',\r\n height: 'fit-content',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n fontFamily: 'Akrobat Bold',\r\n fontSize: '1.25vh',\r\n borderRadius: theme.defaultRadius,\r\n paddingBottom: '0.5vh',\r\n paddingTop: '0.5vh',\r\n }\r\n })\r\n },\r\n\r\n },\r\n\r\n colors: {\r\n\r\n dirk:[\r\n \"#ffffff\",\r\n \"#f3fce9\",\r\n \"#dbf5bd\",\r\n \"#c3ee91\",\r\n \"#ace765\",\r\n \"#94e039\",\r\n \"#7ac61f\",\r\n \"#5f9a18\",\r\n \"#29420a\",\r\n \"#446e11\",\r\n ],\r\n },\r\n});\r\n\r\n\r\nexport default theme;","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n // When true, the resource has its own theme defined in scriptConfig and\r\n // global dirk_lib UPDATE_DIRK_LIB_SETTINGS pushes must not clobber the\r\n // local primaryColor / primaryShade / customTheme. The consumer's\r\n // GET_SETTINGS callback is responsible for setting this flag.\r\n themeOverride?: boolean;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: [\r\n \"#f0f4ff\",\r\n \"#d9e3ff\",\r\n \"#bfcfff\",\r\n \"#a6bbff\",\r\n \"#8ca7ff\",\r\n \"#7393ff\",\r\n \"#5a7fff\",\r\n \"#406bff\",\r\n \"#2547ff\",\r\n \"#0b33ff\",\r\n ],\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { create } from \"zustand\";\r\nimport { fetchNui, registerInitialFetch } from \"../utils/fetchNui\";\r\n\r\n\r\ntype localeType = (key: string, ...args: string[]) => string;\r\n\r\ntype LocalesProps = {\r\n [key: string]: string;\r\n}\r\n\r\ntype LocaleStoreProps = {\r\n locale: localeType;\r\n locales: LocalesProps;\r\n};\r\n\r\nconst reportedMissing = new Set<string>();\r\nfunction reportMissingLocale(key: string) {\r\n if (!key || reportedMissing.has(key)) return;\r\n reportedMissing.add(key);\r\n fetchNui('REPORT_MISSING_LOCALE', { key }).catch(() => {});\r\n}\r\n\r\n\r\nexport const localeStore = create<LocaleStoreProps>((set, get) => {\r\n return {\r\n locales: {\r\n \"OccupantsDesc\": \"Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant.\",\r\n },\r\n locale: (key: string, ...args: (string|number)[]): string => {\r\n const exists = get().locales[key];\r\n if (!exists) reportMissingLocale(key);\r\n let translation = exists || key;\r\n if (args.length) {\r\n // convert the arg to a string and replace the %s in the translation\r\n \r\n\r\n translation = translation.replace(/%s/g, () => String(args.shift() || ''));\r\n }\r\n return translation;\r\n },\r\n };\r\n});\r\n\r\n// export locale as a standalone function\r\nexport const locale = localeStore.getState().locale;\r\n\r\nregisterInitialFetch<LocalesProps>('GET_LOCALES', undefined).then((data) => {\r\n localeStore.setState({ locales: data });\r\n}).catch(() => {})\r\n\r\n// dirk_lib broadcasts UPDATE_DIRK_LIB_LOCALES whenever an admin changes the\r\n// `language` setting, so the dict updates live without a resource restart.\r\nif (typeof window !== \"undefined\") {\r\n window.addEventListener(\"message\", (event) => {\r\n const msg = event.data;\r\n if (!msg || msg.action !== \"UPDATE_DIRK_LIB_LOCALES\") return;\r\n if (!msg.data || typeof msg.data !== \"object\") return;\r\n localeStore.setState({ locales: msg.data as LocalesProps });\r\n });\r\n}","import type { MantineColorsTuple, MantineThemeOverride } from \"@mantine/core\";\r\n\r\nconst isValidColorScale = (v: unknown): v is MantineColorsTuple =>\r\n Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === \"string\");\r\n\r\nexport function mergeMantineThemeSafe(\r\n base: MantineThemeOverride,\r\n custom?: MantineColorsTuple,\r\n override?: MantineThemeOverride\r\n): MantineThemeOverride {\r\n const colors = { ...base.colors };\r\n\r\n if (custom && isValidColorScale(custom)) {\r\n colors[\"custom\"] = custom;\r\n } else if (!colors[\"custom\"]) {\r\n // Always register a \"custom\" entry so primaryColor === \"custom\" never\r\n // points at undefined and silently falls back to Mantine's default\r\n // (which surfaces as \"the configured palette didn't apply\").\r\n const fallback = (base.colors && (base.colors as any).dirk) as MantineColorsTuple | undefined;\r\n if (fallback && isValidColorScale(fallback)) {\r\n colors[\"custom\"] = fallback;\r\n }\r\n }\r\n\r\n return {\r\n ...base,\r\n ...override,\r\n colors: {\r\n ...colors,\r\n ...(override?.colors ?? {}),\r\n },\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport { Box, Code, Stack, Text, Title } from \"@mantine/core\";\r\n\r\ntype State = {\r\n error: Error | null;\r\n stack?: string;\r\n};\r\n\r\nexport class DirkErrorBoundary extends React.Component<\r\n { children: React.ReactNode },\r\n State\r\n> {\r\n state: State = { error: null, stack: undefined };\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n // We can't get component stack here, so just store the error\r\n return { error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: React.ErrorInfo) {\r\n console.group(\"🔥 Dirk UI Crash\");\r\n console.error(\"Error:\", error);\r\n console.error(\"Component Stack:\", info.componentStack);\r\n console.groupEnd();\r\n\r\n // Only log here, don't call setState — the error state is already captured\r\n }\r\n\r\n render() {\r\n if (!this.state.error) return this.props.children;\r\n\r\n return (\r\n <Box\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n background: \"rgba(10, 10, 12, 0.92)\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n padding: \"2rem\",\r\n zIndex: 999999,\r\n }}\r\n >\r\n <Box\r\n maw={900}\r\n w=\"100%\"\r\n p=\"lg\"\r\n style={{\r\n background: \"rgba(20,20,24,0.75)\",\r\n border: \"1px solid rgba(255,255,255,0.08)\",\r\n borderRadius: \"10px\",\r\n boxShadow: \"0 10px 40px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <Stack gap=\"sm\">\r\n <Title order={2} c=\"red.5\">\r\n Dirk UI Crash\r\n </Title>\r\n\r\n <Text c=\"dimmed\" size=\"sm\">\r\n The interface encountered a fatal error and stopped rendering.\r\n </Text>\r\n\r\n <Code block style={{ maxHeight: 150, overflow: \"auto\" }}>\r\n {this.state.error?.message}\r\n </Code>\r\n\r\n {/* Optional: show component stack if you pass it from props */}\r\n <Text size=\"xs\" c=\"dimmed\">\r\n Check console for full stack trace\r\n </Text>\r\n </Stack>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n}","\"use client\";\r\n\r\nimport \"@mantine/core/styles.css\";\r\nimport \"@mantine/notifications/styles.css\";\r\nimport './styles/fonts.css';\r\nimport './styles/notify.css';\r\nimport './styles/scrollBar.css';\r\nimport './styles/tornEdge.css';\r\n\r\n\r\nimport { library } from \"@fortawesome/fontawesome-svg-core\";\r\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\r\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\r\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\r\nlibrary.add(fas, far, fab);\r\n\r\nimport theme from \"@/theme\";\r\nimport { BackgroundImage, MantineColorShade, MantineProvider } from \"@mantine/core\";\r\nimport { useEffect, useLayoutEffect, useMemo } from \"react\";\r\n\r\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\r\nimport { fetchNui, isEnvBrowser } from \"@/utils\";\r\nimport { localeStore } from \"@/utils/locales\";\r\nimport { mergeMantineThemeSafe } from \"@/utils/mergeMantineTheme\";\r\nimport { SettingsState, useSettings } from \"@/utils/useSettings\";\r\nimport { DirkErrorBoundary } from \"./DirkErrorBoundary\";\r\n\r\nexport type DirkProviderProps = {\r\n children: React.ReactNode;\r\n overideResourceName?: string;\r\n themeOverride?: any;\r\n};\r\n\r\nexport function DirkProvider({ children, overideResourceName, themeOverride }: DirkProviderProps) {\r\n const {\r\n primaryColor,\r\n primaryShade,\r\n customTheme,\r\n game,\r\n } = useSettings();\r\n\r\n // Subscribe to locale changes so the entire tree re-renders when an admin\r\n // updates `language` via dirk_lib's scriptConfig — components calling\r\n // `locale(\"Foo\")` directly (no hook) get fresh strings on the next render.\r\n const _locales = localeStore((s) => s.locales);\r\n void _locales;\r\n\r\n useLayoutEffect(() => {\r\n useSettings.setState({\r\n overideResourceName,\r\n });\r\n }, [overideResourceName]);\r\n\r\n useEffect(() => {\r\n fetchNui('NUI_READY').catch(() => {});\r\n Promise.all([\r\n fetchNui<Partial<SettingsState>>('GET_SETTINGS'),\r\n fetchNui<{ version?: string }>('GET_RESOURCE_VERSION', undefined, { version: 'dev' }),\r\n ]).then(([data, resourceInfo]) => {\r\n useSettings.setState({\r\n ...data,\r\n resourceVersion: resourceInfo?.version || 'dev',\r\n });\r\n }).catch((err) => {\r\n console.error(\"Failed to fetch initial settings within dirk-cfx-react:\", err);\r\n });\r\n }, []);\r\n\r\n // Live updates: dirk_lib broadcasts UPDATE_DIRK_LIB_SETTINGS whenever an admin\r\n // changes appearance/localization via the scriptConfig UI. Merge the partial\r\n // patch into the settings store so theme / currency / branding update live\r\n // without a resource restart.\r\n //\r\n // Per-resource theme override gate: when the local snapshot has\r\n // `themeOverride: true`, the consumer's GET_SETTINGS callback has already\r\n // hydrated us with its own primaryColor / primaryShade / customTheme. Any\r\n // incoming global push for those keys is silently dropped so editing the\r\n // dirk_lib appearance tab doesn't clobber the resource's local theme.\r\n useNuiEvent<Partial<SettingsState>>('UPDATE_DIRK_LIB_SETTINGS', (data) => {\r\n if (!data || typeof data !== 'object') return;\r\n const current = useSettings.getState();\r\n if (current.themeOverride) {\r\n const { primaryColor: _pc, primaryShade: _ps, customTheme: _ct, ...rest } = data;\r\n void _pc; void _ps; void _ct;\r\n useSettings.setState(rest);\r\n return;\r\n }\r\n useSettings.setState(data);\r\n });\r\n\r\n // 🚫 do not render until state is stable\r\n\r\n const mergedTheme = useMemo(\r\n () => mergeMantineThemeSafe(\r\n { ...theme, primaryColor, primaryShade: primaryShade as MantineColorShade },\r\n customTheme,\r\n themeOverride\r\n ),\r\n [primaryColor, primaryShade, customTheme, themeOverride]\r\n );\r\n\r\n useEffect(() => {\r\n document.body.style.fontFamily =\r\n game === \"rdr3\"\r\n ? '\"Red Dead\", sans-serif'\r\n : '\"Akrobat Regular\", sans-serif';\r\n }, [game]);\r\n\r\n const content = isEnvBrowser() ? (\r\n <BackgroundImage\r\n w=\"100vw\"\r\n h=\"100vh\"\r\n src={game === \"fivem\"\r\n ? \"https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg\"\r\n : \"https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg\"}\r\n >\r\n {children}\r\n </BackgroundImage>\r\n ) : (\r\n children\r\n );\r\n\r\n return (\r\n <MantineProvider theme={mergedTheme} defaultColorScheme=\"dark\">\r\n <DirkErrorBoundary>\r\n {content}\r\n </DirkErrorBoundary>\r\n </MantineProvider>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/theme.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/utils/useSettings.ts","../../src/utils/fetchNui.ts","../../src/utils/locales.ts","../../src/utils/mergeMantineTheme.ts","../../src/hooks/useScriptConfig.ts","../../src/providers/DirkErrorBoundary.tsx","../../src/providers/DirkProvider.tsx"],"names":["createTheme","theme","useRef","useEffect","create","React","error","jsx","Box","jsxs","Stack","Title","Text","Code","library","fas","far","fab","useState","useLayoutEffect","useMemo","BackgroundImage","MantineProvider"],"mappings":"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","file":"index.cjs","sourcesContent":["import { ColorInput, createTheme, MantineTheme, MultiSelect, NumberInput, TextInput } from \"@mantine/core\";\r\n\r\nexport const label = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n};\r\nexport const error = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Regular',\r\n};\r\nexport const description = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n};\r\n\r\nexport const genericInputStyles = {\r\n styles: {\r\n label: label,\r\n error: error,\r\n description: description,\r\n \r\n input:{\r\n background: 'rgba(255,255,255,0.04)',\r\n border: '0.1vh solid rgba(255,255,255,0.08)',\r\n color: 'rgba(255,255,255,0.85)',\r\n minHeight: '4vh',\r\n },\r\n },\r\n};\r\n\r\nconst theme = createTheme({\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n defaultRadius: \"xs\",\r\n fontFamily: \"Akrobat Regular, sans-serif\",\r\n\r\n radius:{\r\n xxs: '0.3vh',\r\n xs: '0.5vh',\r\n sm: '0.75vh',\r\n md: '1vh',\r\n lg: '1.5vh',\r\n xl: '2vh',\r\n xxl: '3vh',\r\n },\r\n\r\n fontSizes: {\r\n xxs: '1.2vh',\r\n xs: '1.5vh',\r\n sm: '1.8vh',\r\n md: '2.2vh',\r\n lg: '2.8vh',\r\n xl: '3.3vh',\r\n xxl: '3.8vh',\r\n },\r\n\r\n lineHeights: {\r\n xxs: '1.4vh',\r\n xs: '1.8vh',\r\n sm: '2.2vh',\r\n md: '2.8vh',\r\n lg: '3.3vh',\r\n xl: '3.8vh',\r\n },\r\n\r\n spacing:{\r\n xxs: '0.5vh',\r\n xs: '0.75vh',\r\n sm: '1.5vh',\r\n md: '2vh',\r\n lg: '3vh',\r\n xl: '4vh',\r\n xxl: '5vh',\r\n },\r\n\r\n components:{\r\n Progress:{\r\n styles:{\r\n label: {\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n },\r\n\r\n root:{\r\n backgroundColor: 'rgba(77, 77, 77, 0.4)',\r\n },\r\n \r\n }\r\n },\r\n \r\n \r\n Input: genericInputStyles,\r\n TextInput: genericInputStyles,\r\n NumberInput: genericInputStyles,\r\n Select: genericInputStyles,\r\n MultiSelect: genericInputStyles, \r\n Textarea: genericInputStyles,\r\n ColorInput: genericInputStyles,\r\n DateInput: genericInputStyles,\r\n\r\n Pill: {\r\n styles: (theme: MantineTheme) => ({\r\n root: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)',\r\n height: 'fit-content',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n fontFamily: 'Akrobat Bold',\r\n fontSize: '1.25vh',\r\n borderRadius: theme.defaultRadius,\r\n paddingBottom: '0.5vh',\r\n paddingTop: '0.5vh',\r\n }\r\n })\r\n },\r\n\r\n },\r\n\r\n colors: {\r\n\r\n dirk:[\r\n \"#ffffff\",\r\n \"#f3fce9\",\r\n \"#dbf5bd\",\r\n \"#c3ee91\",\r\n \"#ace765\",\r\n \"#94e039\",\r\n \"#7ac61f\",\r\n \"#5f9a18\",\r\n \"#29420a\",\r\n \"#446e11\",\r\n ],\r\n },\r\n});\r\n\r\n\r\nexport default theme;","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: [\r\n \"#f0f4ff\",\r\n \"#d9e3ff\",\r\n \"#bfcfff\",\r\n \"#a6bbff\",\r\n \"#8ca7ff\",\r\n \"#7393ff\",\r\n \"#5a7fff\",\r\n \"#406bff\",\r\n \"#2547ff\",\r\n \"#0b33ff\",\r\n ],\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { create } from \"zustand\";\r\nimport { fetchNui, registerInitialFetch } from \"../utils/fetchNui\";\r\n\r\n\r\ntype localeType = (key: string, ...args: string[]) => string;\r\n\r\ntype LocalesProps = {\r\n [key: string]: string;\r\n}\r\n\r\ntype LocaleStoreProps = {\r\n locale: localeType;\r\n locales: LocalesProps;\r\n};\r\n\r\nconst reportedMissing = new Set<string>();\r\nfunction reportMissingLocale(key: string) {\r\n if (!key || reportedMissing.has(key)) return;\r\n reportedMissing.add(key);\r\n fetchNui('REPORT_MISSING_LOCALE', { key }).catch(() => {});\r\n}\r\n\r\n\r\nexport const localeStore = create<LocaleStoreProps>((set, get) => {\r\n return {\r\n locales: {\r\n \"OccupantsDesc\": \"Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant.\",\r\n },\r\n locale: (key: string, ...args: (string|number)[]): string => {\r\n const exists = get().locales[key];\r\n if (!exists) reportMissingLocale(key);\r\n let translation = exists || key;\r\n if (args.length) {\r\n // convert the arg to a string and replace the %s in the translation\r\n \r\n\r\n translation = translation.replace(/%s/g, () => String(args.shift() || ''));\r\n }\r\n return translation;\r\n },\r\n };\r\n});\r\n\r\n// export locale as a standalone function\r\nexport const locale = localeStore.getState().locale;\r\n\r\nregisterInitialFetch<LocalesProps>('GET_LOCALES', undefined).then((data) => {\r\n localeStore.setState({ locales: data });\r\n}).catch(() => {})\r\n\r\n// dirk_lib broadcasts UPDATE_DIRK_LIB_LOCALES whenever an admin changes the\r\n// `language` setting, so the dict updates live without a resource restart.\r\nif (typeof window !== \"undefined\") {\r\n window.addEventListener(\"message\", (event) => {\r\n const msg = event.data;\r\n if (!msg || msg.action !== \"UPDATE_DIRK_LIB_LOCALES\") return;\r\n if (!msg.data || typeof msg.data !== \"object\") return;\r\n localeStore.setState({ locales: msg.data as LocalesProps });\r\n });\r\n}","import type { MantineColorsTuple, MantineThemeOverride } from \"@mantine/core\";\r\n\r\nconst isValidColorScale = (v: unknown): v is MantineColorsTuple =>\r\n Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === \"string\");\r\n\r\nexport function mergeMantineThemeSafe(\r\n base: MantineThemeOverride,\r\n custom?: MantineColorsTuple,\r\n override?: MantineThemeOverride\r\n): MantineThemeOverride {\r\n const colors = { ...base.colors };\r\n\r\n if (custom && isValidColorScale(custom)) {\r\n colors[\"custom\"] = custom;\r\n } else if (!colors[\"custom\"]) {\r\n // Always register a \"custom\" entry so primaryColor === \"custom\" never\r\n // points at undefined and silently falls back to Mantine's default\r\n // (which surfaces as \"the configured palette didn't apply\").\r\n const fallback = (base.colors && (base.colors as any).dirk) as MantineColorsTuple | undefined;\r\n if (fallback && isValidColorScale(fallback)) {\r\n colors[\"custom\"] = fallback;\r\n }\r\n }\r\n\r\n return {\r\n ...base,\r\n ...override,\r\n colors: {\r\n ...colors,\r\n ...(override?.colors ?? {}),\r\n },\r\n };\r\n}\r\n","import { fetchNui } from \"@/utils\";\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\nimport { create } from \"zustand\";\n\ntype ScriptConfigUpdateMeta<T> = {\n client_version?: number;\n latestVersion?: number;\n latestData?: Partial<T>;\n changed_paths?: Array<{ path: string; old: unknown; new: unknown }>;\n lastEditor?: { source?: number; name?: string; identifier?: string };\n};\n\nexport type ScriptConfigHistoryChange = {\n path: string;\n old: unknown;\n new: unknown;\n};\n\nexport type ScriptConfigHistoryEntry = {\n at_unix: number;\n at_utc: string;\n script: string;\n admin?: { source?: number; name?: string; identifier?: string };\n expected_version?: number;\n applied_version?: number;\n changes: ScriptConfigHistoryChange[];\n};\n\nexport type ScriptConfigHistoryRequest = {\n offset?: number;\n limit?: number;\n query?: string;\n path?: string;\n admin?: string;\n fromUnix?: number;\n toUnix?: number;\n};\n\nexport type ScriptConfigHistoryResponse = {\n success: boolean;\n _error?: string;\n data?: {\n items: ScriptConfigHistoryEntry[];\n total: number;\n limit: number;\n offset: number;\n nextOffset?: number;\n };\n};\n\ntype NuiResponse<T> = {\n success: boolean;\n message?: string;\n _error?: string;\n meta?: ScriptConfigUpdateMeta<T>;\n};\n\n// ── Singleton registry ────────────────────────────────────────────────────────\n\nexport interface ScriptConfigInstance<T = any> {\n store: { getState: () => T; setState: (partial: Partial<T> | ((prev: T) => T)) => void };\n updateConfig: (newConfig: Partial<T>) => Promise<NuiResponse<T>>;\n resetConfig: () => Promise<{ success: boolean; _error?: string }>;\n getHistory: (params?: ScriptConfigHistoryRequest) => Promise<ScriptConfigHistoryResponse>;\n fetchConfig: () => Promise<T | null>;\n}\n\nlet _instance: ScriptConfigInstance | null = null;\n\nexport function getScriptConfigInstance<T = any>(): ScriptConfigInstance<T> {\n if (!_instance) throw new Error(\"[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel\");\n return _instance as ScriptConfigInstance<T>;\n}\n\nexport function createScriptConfig<T>(defaultValue: T) {\n const store = create<T>(() => defaultValue);\n let clientVersion = 0;\n\n const useScriptConfigHooks = () => {\n useNuiEvent<{ config?: Partial<T>; clientVersion?: number }>(\"UPDATE_SCRIPT_CONFIG\", (data) => {\n if (!data) return;\n\n if (typeof data.clientVersion === \"number\") {\n clientVersion = data.clientVersion as number;\n }\n\n if (data.config && typeof data.config === \"object\") {\n store.setState((prev) => ({ ...prev, ...(data.config as Partial<T>) }));\n }\n });\n };\n\n const fetchScriptConfig = async (): Promise<T | null> => {\n try {\n const response = await fetchNui<{\n success: boolean;\n data?: { config: T; clientVersion: number };\n }>(\"GET_FULL_SCRIPT_CONFIG\");\n\n if (response?.success && response.data?.config) {\n store.setState(() => response.data!.config as T);\n if (typeof response.data.clientVersion === \"number\") {\n clientVersion = response.data.clientVersion;\n }\n return response.data.config;\n }\n } catch { /* fallback to current store state */ }\n return null;\n };\n\n const updateScriptConfig = async (newConfig: Partial<T>): Promise<NuiResponse<T>> => {\n store.setState((prev) => ({ ...prev, ...newConfig }));\n\n const response = await fetchNui<NuiResponse<T>>(\"UPDATE_SCRIPT_CONFIG\", {\n data: newConfig,\n expectedVersion: clientVersion,\n });\n\n if (response?.meta?.client_version != null) {\n clientVersion = response.meta.client_version as number;\n }\n\n if (response?.success === false && response?.meta?.latestData) {\n store.setState((prev) => ({ ...prev, ...(response.meta!.latestData as Partial<T>) }));\n }\n\n return response;\n };\n\n const getScriptConfigHistory = async (\n params: ScriptConfigHistoryRequest = {}\n ): Promise<ScriptConfigHistoryResponse> => {\n return fetchNui<ScriptConfigHistoryResponse>('GET_SCRIPT_CONFIG_HISTORY', params);\n };\n\n const resetConfig = async (): Promise<{ success: boolean; _error?: string }> => {\n const response = await fetchNui<{ success: boolean; _error?: string }>('RESET_SCRIPT_CONFIG');\n if (response?.success) {\n const fresh = await fetchScriptConfig();\n if (fresh) {\n store.setState(() => fresh);\n }\n }\n return response;\n };\n\n _instance = {\n store,\n updateConfig: updateScriptConfig,\n resetConfig,\n getHistory: getScriptConfigHistory,\n fetchConfig: fetchScriptConfig,\n };\n\n return {store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig}\n}\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport { Box, Code, Stack, Text, Title } from \"@mantine/core\";\r\n\r\ntype State = {\r\n error: Error | null;\r\n stack?: string;\r\n};\r\n\r\nexport class DirkErrorBoundary extends React.Component<\r\n { children: React.ReactNode },\r\n State\r\n> {\r\n state: State = { error: null, stack: undefined };\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n // We can't get component stack here, so just store the error\r\n return { error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: React.ErrorInfo) {\r\n console.group(\"🔥 Dirk UI Crash\");\r\n console.error(\"Error:\", error);\r\n console.error(\"Component Stack:\", info.componentStack);\r\n console.groupEnd();\r\n\r\n // Only log here, don't call setState — the error state is already captured\r\n }\r\n\r\n render() {\r\n if (!this.state.error) return this.props.children;\r\n\r\n return (\r\n <Box\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n background: \"rgba(10, 10, 12, 0.92)\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n padding: \"2rem\",\r\n zIndex: 999999,\r\n }}\r\n >\r\n <Box\r\n maw={900}\r\n w=\"100%\"\r\n p=\"lg\"\r\n style={{\r\n background: \"rgba(20,20,24,0.75)\",\r\n border: \"1px solid rgba(255,255,255,0.08)\",\r\n borderRadius: \"10px\",\r\n boxShadow: \"0 10px 40px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <Stack gap=\"sm\">\r\n <Title order={2} c=\"red.5\">\r\n Dirk UI Crash\r\n </Title>\r\n\r\n <Text c=\"dimmed\" size=\"sm\">\r\n The interface encountered a fatal error and stopped rendering.\r\n </Text>\r\n\r\n <Code block style={{ maxHeight: 150, overflow: \"auto\" }}>\r\n {this.state.error?.message}\r\n </Code>\r\n\r\n {/* Optional: show component stack if you pass it from props */}\r\n <Text size=\"xs\" c=\"dimmed\">\r\n Check console for full stack trace\r\n </Text>\r\n </Stack>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n}","\"use client\";\n\nimport \"@mantine/core/styles.css\";\nimport \"@mantine/notifications/styles.css\";\nimport './styles/fonts.css';\nimport './styles/notify.css';\nimport './styles/scrollBar.css';\nimport './styles/tornEdge.css';\n\n\nimport { library } from \"@fortawesome/fontawesome-svg-core\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nlibrary.add(fas, far, fab);\n\nimport theme from \"@/theme\";\nimport { BackgroundImage, MantineColorShade, MantineColorsTuple, MantineProvider } from \"@mantine/core\";\nimport { useEffect, useLayoutEffect, useMemo, useState } from \"react\";\n\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\nimport { fetchNui, isEnvBrowser } from \"@/utils\";\nimport { localeStore } from \"@/utils/locales\";\nimport { mergeMantineThemeSafe } from \"@/utils/mergeMantineTheme\";\nimport { SettingsState, useSettings } from \"@/utils/useSettings\";\nimport { getScriptConfigInstance } from \"@/hooks/useScriptConfig\";\nimport { DirkErrorBoundary } from \"./DirkErrorBoundary\";\n\nexport type DirkProviderProps = {\n children: React.ReactNode;\n overideResourceName?: string;\n themeOverride?: any;\n};\n\n// Shape DirkProvider looks for at `scriptConfig.theme` to detect a per-resource\n// theme override. Consumers opt in by adding a `theme` block to their schema.json\n// with these four fields — DirkProvider auto-detects and applies it. Resources\n// with no `theme` block (or `useOverride: false`) follow the global dirk_lib\n// theme as before. No bridge component, no extra wiring required from consumers.\ntype ScriptConfigThemeOverride = {\n useOverride?: boolean;\n primaryColor?: string;\n primaryShade?: number;\n customTheme?: MantineColorsTuple | string[];\n};\n\nexport function DirkProvider({ children, overideResourceName, themeOverride }: DirkProviderProps) {\n const {\n primaryColor,\n primaryShade,\n customTheme,\n game,\n } = useSettings();\n\n // Subscribe to locale changes so the entire tree re-renders when an admin\n // updates `language` via dirk_lib's scriptConfig — components calling\n // `locale(\"Foo\")` directly (no hook) get fresh strings on the next render.\n const _locales = localeStore((s) => s.locales);\n void _locales;\n\n // Per-resource theme override snapshot, read from `scriptConfig.theme` when\n // the consumer has a scriptConfig registered. Updated by the subscription\n // below; survives Mantine recomputes via useMemo deps.\n const [scTheme, setScTheme] = useState<ScriptConfigThemeOverride | null>(null);\n\n useLayoutEffect(() => {\n useSettings.setState({\n overideResourceName,\n });\n }, [overideResourceName]);\n\n useEffect(() => {\n fetchNui('NUI_READY').catch(() => {});\n Promise.all([\n fetchNui<Partial<SettingsState>>('GET_SETTINGS'),\n fetchNui<{ version?: string }>('GET_RESOURCE_VERSION', undefined, { version: 'dev' }),\n ]).then(([data, resourceInfo]) => {\n useSettings.setState({\n ...data,\n resourceVersion: resourceInfo?.version || 'dev',\n });\n }).catch((err) => {\n console.error(\"Failed to fetch initial settings within dirk-cfx-react:\", err);\n });\n }, []);\n\n // Live updates: dirk_lib broadcasts UPDATE_DIRK_LIB_SETTINGS whenever an admin\n // changes appearance/localization via the scriptConfig UI. Merge the partial\n // patch into the settings store so theme / currency / branding update live\n // without a resource restart. Per-resource theme override is handled below\n // via the scriptConfig subscription — pushes here can flow through unchanged.\n useNuiEvent<Partial<SettingsState>>('UPDATE_DIRK_LIB_SETTINGS', (data) => {\n if (!data || typeof data !== 'object') return;\n useSettings.setState(data);\n });\n\n // ── Per-resource theme auto-detect ────────────────────────────────────────\n // If the consumer has called createScriptConfig() (i.e. has a registered\n // scriptConfig instance) AND their schema has a `theme` block with\n // `useOverride: true`, DirkProvider uses those theme values instead of\n // dirk_lib's global appearance. Consumers don't have to write any glue\n // code — they just add the `theme` block to schema.json and a Theme tab\n // (via ThemeOverrideSection) to their configurator. Everything else is\n // handled here.\n //\n // We also forward UPDATE_SCRIPT_CONFIG pushes into the store so this works\n // whether or not the consumer remembers to call useScriptConfigHooks().\n useNuiEvent<{ config?: Record<string, unknown>; clientVersion?: number }>(\n 'UPDATE_SCRIPT_CONFIG',\n (data) => {\n if (!data || !data.config || typeof data.config !== 'object') return;\n try {\n const inst = getScriptConfigInstance<Record<string, unknown>>();\n inst.store.setState((prev) => ({ ...prev, ...(data.config as Record<string, unknown>) }));\n } catch {\n // No scriptConfig instance registered — consumer doesn't use scriptConfig, ignore.\n }\n }\n );\n\n useEffect(() => {\n let unsubscribe: (() => void) | undefined;\n try {\n const inst = getScriptConfigInstance<{ theme?: ScriptConfigThemeOverride }>();\n\n // Seed from whatever's already in the store (covers cases where the\n // store was hydrated before DirkProvider mounted, e.g. by an upstream\n // ConfigPanel open).\n setScTheme((inst.store.getState() as { theme?: ScriptConfigThemeOverride })?.theme ?? null);\n\n // Subscribe to store mutations so live edits / hydration completion\n // re-trigger the override application.\n const subscribable = inst.store as unknown as {\n subscribe?: (listener: (s: { theme?: ScriptConfigThemeOverride }) => void) => () => void;\n };\n if (typeof subscribable.subscribe === 'function') {\n unsubscribe = subscribable.subscribe((s) => {\n setScTheme(s?.theme ?? null);\n });\n }\n\n // Proactive hydration. The dirk_lib cold-start push that populates the\n // scriptConfig store is timing-sensitive (may fire before the NUI\n // iframe is ready). A single GET_FULL_SCRIPT_CONFIG round-trip on\n // mount removes that race entirely — the server callback blocks until\n // scriptConfig is hydrated, so the override block is guaranteed\n // populated before the first paint that depends on it.\n inst.fetchConfig?.().then((full) => {\n if (full && typeof full === 'object') {\n setScTheme((full as { theme?: ScriptConfigThemeOverride }).theme ?? null);\n }\n }).catch(() => {});\n } catch {\n // No scriptConfig instance — consumer doesn't use scriptConfig at all.\n // Fall through silently; global theme behaviour is unchanged.\n }\n return () => { unsubscribe?.(); };\n }, []);\n\n const overrideActive = scTheme?.useOverride === true;\n const effectivePrimaryColor = overrideActive ? (scTheme!.primaryColor ?? primaryColor) : primaryColor;\n const effectivePrimaryShade = overrideActive ? (scTheme!.primaryShade ?? primaryShade) : primaryShade;\n const effectiveCustomTheme = overrideActive\n ? ((scTheme!.customTheme as MantineColorsTuple | undefined) ?? customTheme)\n : customTheme;\n\n const mergedTheme = useMemo(\n () => mergeMantineThemeSafe(\n { ...theme, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade as MantineColorShade },\n effectiveCustomTheme,\n themeOverride\n ),\n [effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]\n );\n\n useEffect(() => {\n document.body.style.fontFamily =\n game === \"rdr3\"\n ? '\"Red Dead\", sans-serif'\n : '\"Akrobat Regular\", sans-serif';\n }, [game]);\n\n const content = isEnvBrowser() ? (\n <BackgroundImage\n w=\"100vw\"\n h=\"100vh\"\n src={game === \"fivem\"\n ? \"https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg\"\n : \"https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg\"}\n >\n {children}\n </BackgroundImage>\n ) : (\n children\n );\n\n return (\n <MantineProvider theme={mergedTheme} defaultColorScheme=\"dark\">\n <DirkErrorBoundary>\n {content}\n </DirkErrorBoundary>\n </MantineProvider>\n );\n}\n"]}
|
package/dist/providers/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fab } from '@fortawesome/free-brands-svg-icons';
|
|
|
9
9
|
import { far } from '@fortawesome/free-regular-svg-icons';
|
|
10
10
|
import { fas } from '@fortawesome/free-solid-svg-icons';
|
|
11
11
|
import { createTheme, Box, Stack, Title, Text, Code, MantineProvider, BackgroundImage } from '@mantine/core';
|
|
12
|
-
import React, { useLayoutEffect, useEffect, useMemo, useRef } from 'react';
|
|
12
|
+
import React, { useState, useLayoutEffect, useEffect, useMemo, useRef } from 'react';
|
|
13
13
|
import { create } from 'zustand';
|
|
14
14
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
15
15
|
|
|
@@ -275,6 +275,9 @@ function mergeMantineThemeSafe(base, custom, override) {
|
|
|
275
275
|
}
|
|
276
276
|
};
|
|
277
277
|
}
|
|
278
|
+
function getScriptConfigInstance() {
|
|
279
|
+
throw new Error("[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel");
|
|
280
|
+
}
|
|
278
281
|
var DirkErrorBoundary = class extends React.Component {
|
|
279
282
|
constructor() {
|
|
280
283
|
super(...arguments);
|
|
@@ -339,6 +342,7 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
339
342
|
game
|
|
340
343
|
} = useSettings();
|
|
341
344
|
localeStore((s) => s.locales);
|
|
345
|
+
const [scTheme, setScTheme] = useState(null);
|
|
342
346
|
useLayoutEffect(() => {
|
|
343
347
|
useSettings.setState({
|
|
344
348
|
overideResourceName
|
|
@@ -361,21 +365,53 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
|
|
|
361
365
|
}, []);
|
|
362
366
|
useNuiEvent("UPDATE_DIRK_LIB_SETTINGS", (data) => {
|
|
363
367
|
if (!data || typeof data !== "object") return;
|
|
364
|
-
const current = useSettings.getState();
|
|
365
|
-
if (current.themeOverride) {
|
|
366
|
-
const { primaryColor: _pc, primaryShade: _ps, customTheme: _ct, ...rest } = data;
|
|
367
|
-
useSettings.setState(rest);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
368
|
useSettings.setState(data);
|
|
371
369
|
});
|
|
370
|
+
useNuiEvent(
|
|
371
|
+
"UPDATE_SCRIPT_CONFIG",
|
|
372
|
+
(data) => {
|
|
373
|
+
if (!data || !data.config || typeof data.config !== "object") return;
|
|
374
|
+
try {
|
|
375
|
+
const inst = getScriptConfigInstance();
|
|
376
|
+
inst.store.setState((prev) => ({ ...prev, ...data.config }));
|
|
377
|
+
} catch {
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
useEffect(() => {
|
|
382
|
+
let unsubscribe;
|
|
383
|
+
try {
|
|
384
|
+
const inst = getScriptConfigInstance();
|
|
385
|
+
setScTheme(inst.store.getState()?.theme ?? null);
|
|
386
|
+
const subscribable = inst.store;
|
|
387
|
+
if (typeof subscribable.subscribe === "function") {
|
|
388
|
+
unsubscribe = subscribable.subscribe((s) => {
|
|
389
|
+
setScTheme(s?.theme ?? null);
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
inst.fetchConfig?.().then((full) => {
|
|
393
|
+
if (full && typeof full === "object") {
|
|
394
|
+
setScTheme(full.theme ?? null);
|
|
395
|
+
}
|
|
396
|
+
}).catch(() => {
|
|
397
|
+
});
|
|
398
|
+
} catch {
|
|
399
|
+
}
|
|
400
|
+
return () => {
|
|
401
|
+
unsubscribe?.();
|
|
402
|
+
};
|
|
403
|
+
}, []);
|
|
404
|
+
const overrideActive = scTheme?.useOverride === true;
|
|
405
|
+
const effectivePrimaryColor = overrideActive ? scTheme.primaryColor ?? primaryColor : primaryColor;
|
|
406
|
+
const effectivePrimaryShade = overrideActive ? scTheme.primaryShade ?? primaryShade : primaryShade;
|
|
407
|
+
const effectiveCustomTheme = overrideActive ? scTheme.customTheme ?? customTheme : customTheme;
|
|
372
408
|
const mergedTheme = useMemo(
|
|
373
409
|
() => mergeMantineThemeSafe(
|
|
374
|
-
{ ...theme_default, primaryColor, primaryShade },
|
|
375
|
-
|
|
410
|
+
{ ...theme_default, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade },
|
|
411
|
+
effectiveCustomTheme,
|
|
376
412
|
themeOverride
|
|
377
413
|
),
|
|
378
|
-
[
|
|
414
|
+
[effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]
|
|
379
415
|
);
|
|
380
416
|
useEffect(() => {
|
|
381
417
|
document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/theme.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/utils/useSettings.ts","../../src/utils/fetchNui.ts","../../src/utils/locales.ts","../../src/utils/mergeMantineTheme.ts","../../src/providers/DirkErrorBoundary.tsx","../../src/providers/DirkProvider.tsx"],"names":["theme","create","error","useEffect","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import { ColorInput, createTheme, MantineTheme, MultiSelect, NumberInput, TextInput } from \"@mantine/core\";\r\n\r\nexport const label = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n};\r\nexport const error = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Regular',\r\n};\r\nexport const description = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n};\r\n\r\nexport const genericInputStyles = {\r\n styles: {\r\n label: label,\r\n error: error,\r\n description: description,\r\n \r\n input:{\r\n background: 'rgba(255,255,255,0.04)',\r\n border: '0.1vh solid rgba(255,255,255,0.08)',\r\n color: 'rgba(255,255,255,0.85)',\r\n minHeight: '4vh',\r\n },\r\n },\r\n};\r\n\r\nconst theme = createTheme({\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n defaultRadius: \"xs\",\r\n fontFamily: \"Akrobat Regular, sans-serif\",\r\n\r\n radius:{\r\n xxs: '0.3vh',\r\n xs: '0.5vh',\r\n sm: '0.75vh',\r\n md: '1vh',\r\n lg: '1.5vh',\r\n xl: '2vh',\r\n xxl: '3vh',\r\n },\r\n\r\n fontSizes: {\r\n xxs: '1.2vh',\r\n xs: '1.5vh',\r\n sm: '1.8vh',\r\n md: '2.2vh',\r\n lg: '2.8vh',\r\n xl: '3.3vh',\r\n xxl: '3.8vh',\r\n },\r\n\r\n lineHeights: {\r\n xxs: '1.4vh',\r\n xs: '1.8vh',\r\n sm: '2.2vh',\r\n md: '2.8vh',\r\n lg: '3.3vh',\r\n xl: '3.8vh',\r\n },\r\n\r\n spacing:{\r\n xxs: '0.5vh',\r\n xs: '0.75vh',\r\n sm: '1.5vh',\r\n md: '2vh',\r\n lg: '3vh',\r\n xl: '4vh',\r\n xxl: '5vh',\r\n },\r\n\r\n components:{\r\n Progress:{\r\n styles:{\r\n label: {\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n },\r\n\r\n root:{\r\n backgroundColor: 'rgba(77, 77, 77, 0.4)',\r\n },\r\n \r\n }\r\n },\r\n \r\n \r\n Input: genericInputStyles,\r\n TextInput: genericInputStyles,\r\n NumberInput: genericInputStyles,\r\n Select: genericInputStyles,\r\n MultiSelect: genericInputStyles, \r\n Textarea: genericInputStyles,\r\n ColorInput: genericInputStyles,\r\n DateInput: genericInputStyles,\r\n\r\n Pill: {\r\n styles: (theme: MantineTheme) => ({\r\n root: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)',\r\n height: 'fit-content',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n fontFamily: 'Akrobat Bold',\r\n fontSize: '1.25vh',\r\n borderRadius: theme.defaultRadius,\r\n paddingBottom: '0.5vh',\r\n paddingTop: '0.5vh',\r\n }\r\n })\r\n },\r\n\r\n },\r\n\r\n colors: {\r\n\r\n dirk:[\r\n \"#ffffff\",\r\n \"#f3fce9\",\r\n \"#dbf5bd\",\r\n \"#c3ee91\",\r\n \"#ace765\",\r\n \"#94e039\",\r\n \"#7ac61f\",\r\n \"#5f9a18\",\r\n \"#29420a\",\r\n \"#446e11\",\r\n ],\r\n },\r\n});\r\n\r\n\r\nexport default theme;","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n // When true, the resource has its own theme defined in scriptConfig and\r\n // global dirk_lib UPDATE_DIRK_LIB_SETTINGS pushes must not clobber the\r\n // local primaryColor / primaryShade / customTheme. The consumer's\r\n // GET_SETTINGS callback is responsible for setting this flag.\r\n themeOverride?: boolean;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: [\r\n \"#f0f4ff\",\r\n \"#d9e3ff\",\r\n \"#bfcfff\",\r\n \"#a6bbff\",\r\n \"#8ca7ff\",\r\n \"#7393ff\",\r\n \"#5a7fff\",\r\n \"#406bff\",\r\n \"#2547ff\",\r\n \"#0b33ff\",\r\n ],\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { create } from \"zustand\";\r\nimport { fetchNui, registerInitialFetch } from \"../utils/fetchNui\";\r\n\r\n\r\ntype localeType = (key: string, ...args: string[]) => string;\r\n\r\ntype LocalesProps = {\r\n [key: string]: string;\r\n}\r\n\r\ntype LocaleStoreProps = {\r\n locale: localeType;\r\n locales: LocalesProps;\r\n};\r\n\r\nconst reportedMissing = new Set<string>();\r\nfunction reportMissingLocale(key: string) {\r\n if (!key || reportedMissing.has(key)) return;\r\n reportedMissing.add(key);\r\n fetchNui('REPORT_MISSING_LOCALE', { key }).catch(() => {});\r\n}\r\n\r\n\r\nexport const localeStore = create<LocaleStoreProps>((set, get) => {\r\n return {\r\n locales: {\r\n \"OccupantsDesc\": \"Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant.\",\r\n },\r\n locale: (key: string, ...args: (string|number)[]): string => {\r\n const exists = get().locales[key];\r\n if (!exists) reportMissingLocale(key);\r\n let translation = exists || key;\r\n if (args.length) {\r\n // convert the arg to a string and replace the %s in the translation\r\n \r\n\r\n translation = translation.replace(/%s/g, () => String(args.shift() || ''));\r\n }\r\n return translation;\r\n },\r\n };\r\n});\r\n\r\n// export locale as a standalone function\r\nexport const locale = localeStore.getState().locale;\r\n\r\nregisterInitialFetch<LocalesProps>('GET_LOCALES', undefined).then((data) => {\r\n localeStore.setState({ locales: data });\r\n}).catch(() => {})\r\n\r\n// dirk_lib broadcasts UPDATE_DIRK_LIB_LOCALES whenever an admin changes the\r\n// `language` setting, so the dict updates live without a resource restart.\r\nif (typeof window !== \"undefined\") {\r\n window.addEventListener(\"message\", (event) => {\r\n const msg = event.data;\r\n if (!msg || msg.action !== \"UPDATE_DIRK_LIB_LOCALES\") return;\r\n if (!msg.data || typeof msg.data !== \"object\") return;\r\n localeStore.setState({ locales: msg.data as LocalesProps });\r\n });\r\n}","import type { MantineColorsTuple, MantineThemeOverride } from \"@mantine/core\";\r\n\r\nconst isValidColorScale = (v: unknown): v is MantineColorsTuple =>\r\n Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === \"string\");\r\n\r\nexport function mergeMantineThemeSafe(\r\n base: MantineThemeOverride,\r\n custom?: MantineColorsTuple,\r\n override?: MantineThemeOverride\r\n): MantineThemeOverride {\r\n const colors = { ...base.colors };\r\n\r\n if (custom && isValidColorScale(custom)) {\r\n colors[\"custom\"] = custom;\r\n } else if (!colors[\"custom\"]) {\r\n // Always register a \"custom\" entry so primaryColor === \"custom\" never\r\n // points at undefined and silently falls back to Mantine's default\r\n // (which surfaces as \"the configured palette didn't apply\").\r\n const fallback = (base.colors && (base.colors as any).dirk) as MantineColorsTuple | undefined;\r\n if (fallback && isValidColorScale(fallback)) {\r\n colors[\"custom\"] = fallback;\r\n }\r\n }\r\n\r\n return {\r\n ...base,\r\n ...override,\r\n colors: {\r\n ...colors,\r\n ...(override?.colors ?? {}),\r\n },\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport { Box, Code, Stack, Text, Title } from \"@mantine/core\";\r\n\r\ntype State = {\r\n error: Error | null;\r\n stack?: string;\r\n};\r\n\r\nexport class DirkErrorBoundary extends React.Component<\r\n { children: React.ReactNode },\r\n State\r\n> {\r\n state: State = { error: null, stack: undefined };\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n // We can't get component stack here, so just store the error\r\n return { error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: React.ErrorInfo) {\r\n console.group(\"🔥 Dirk UI Crash\");\r\n console.error(\"Error:\", error);\r\n console.error(\"Component Stack:\", info.componentStack);\r\n console.groupEnd();\r\n\r\n // Only log here, don't call setState — the error state is already captured\r\n }\r\n\r\n render() {\r\n if (!this.state.error) return this.props.children;\r\n\r\n return (\r\n <Box\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n background: \"rgba(10, 10, 12, 0.92)\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n padding: \"2rem\",\r\n zIndex: 999999,\r\n }}\r\n >\r\n <Box\r\n maw={900}\r\n w=\"100%\"\r\n p=\"lg\"\r\n style={{\r\n background: \"rgba(20,20,24,0.75)\",\r\n border: \"1px solid rgba(255,255,255,0.08)\",\r\n borderRadius: \"10px\",\r\n boxShadow: \"0 10px 40px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <Stack gap=\"sm\">\r\n <Title order={2} c=\"red.5\">\r\n Dirk UI Crash\r\n </Title>\r\n\r\n <Text c=\"dimmed\" size=\"sm\">\r\n The interface encountered a fatal error and stopped rendering.\r\n </Text>\r\n\r\n <Code block style={{ maxHeight: 150, overflow: \"auto\" }}>\r\n {this.state.error?.message}\r\n </Code>\r\n\r\n {/* Optional: show component stack if you pass it from props */}\r\n <Text size=\"xs\" c=\"dimmed\">\r\n Check console for full stack trace\r\n </Text>\r\n </Stack>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n}","\"use client\";\r\n\r\nimport \"@mantine/core/styles.css\";\r\nimport \"@mantine/notifications/styles.css\";\r\nimport './styles/fonts.css';\r\nimport './styles/notify.css';\r\nimport './styles/scrollBar.css';\r\nimport './styles/tornEdge.css';\r\n\r\n\r\nimport { library } from \"@fortawesome/fontawesome-svg-core\";\r\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\r\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\r\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\r\nlibrary.add(fas, far, fab);\r\n\r\nimport theme from \"@/theme\";\r\nimport { BackgroundImage, MantineColorShade, MantineProvider } from \"@mantine/core\";\r\nimport { useEffect, useLayoutEffect, useMemo } from \"react\";\r\n\r\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\r\nimport { fetchNui, isEnvBrowser } from \"@/utils\";\r\nimport { localeStore } from \"@/utils/locales\";\r\nimport { mergeMantineThemeSafe } from \"@/utils/mergeMantineTheme\";\r\nimport { SettingsState, useSettings } from \"@/utils/useSettings\";\r\nimport { DirkErrorBoundary } from \"./DirkErrorBoundary\";\r\n\r\nexport type DirkProviderProps = {\r\n children: React.ReactNode;\r\n overideResourceName?: string;\r\n themeOverride?: any;\r\n};\r\n\r\nexport function DirkProvider({ children, overideResourceName, themeOverride }: DirkProviderProps) {\r\n const {\r\n primaryColor,\r\n primaryShade,\r\n customTheme,\r\n game,\r\n } = useSettings();\r\n\r\n // Subscribe to locale changes so the entire tree re-renders when an admin\r\n // updates `language` via dirk_lib's scriptConfig — components calling\r\n // `locale(\"Foo\")` directly (no hook) get fresh strings on the next render.\r\n const _locales = localeStore((s) => s.locales);\r\n void _locales;\r\n\r\n useLayoutEffect(() => {\r\n useSettings.setState({\r\n overideResourceName,\r\n });\r\n }, [overideResourceName]);\r\n\r\n useEffect(() => {\r\n fetchNui('NUI_READY').catch(() => {});\r\n Promise.all([\r\n fetchNui<Partial<SettingsState>>('GET_SETTINGS'),\r\n fetchNui<{ version?: string }>('GET_RESOURCE_VERSION', undefined, { version: 'dev' }),\r\n ]).then(([data, resourceInfo]) => {\r\n useSettings.setState({\r\n ...data,\r\n resourceVersion: resourceInfo?.version || 'dev',\r\n });\r\n }).catch((err) => {\r\n console.error(\"Failed to fetch initial settings within dirk-cfx-react:\", err);\r\n });\r\n }, []);\r\n\r\n // Live updates: dirk_lib broadcasts UPDATE_DIRK_LIB_SETTINGS whenever an admin\r\n // changes appearance/localization via the scriptConfig UI. Merge the partial\r\n // patch into the settings store so theme / currency / branding update live\r\n // without a resource restart.\r\n //\r\n // Per-resource theme override gate: when the local snapshot has\r\n // `themeOverride: true`, the consumer's GET_SETTINGS callback has already\r\n // hydrated us with its own primaryColor / primaryShade / customTheme. Any\r\n // incoming global push for those keys is silently dropped so editing the\r\n // dirk_lib appearance tab doesn't clobber the resource's local theme.\r\n useNuiEvent<Partial<SettingsState>>('UPDATE_DIRK_LIB_SETTINGS', (data) => {\r\n if (!data || typeof data !== 'object') return;\r\n const current = useSettings.getState();\r\n if (current.themeOverride) {\r\n const { primaryColor: _pc, primaryShade: _ps, customTheme: _ct, ...rest } = data;\r\n void _pc; void _ps; void _ct;\r\n useSettings.setState(rest);\r\n return;\r\n }\r\n useSettings.setState(data);\r\n });\r\n\r\n // 🚫 do not render until state is stable\r\n\r\n const mergedTheme = useMemo(\r\n () => mergeMantineThemeSafe(\r\n { ...theme, primaryColor, primaryShade: primaryShade as MantineColorShade },\r\n customTheme,\r\n themeOverride\r\n ),\r\n [primaryColor, primaryShade, customTheme, themeOverride]\r\n );\r\n\r\n useEffect(() => {\r\n document.body.style.fontFamily =\r\n game === \"rdr3\"\r\n ? '\"Red Dead\", sans-serif'\r\n : '\"Akrobat Regular\", sans-serif';\r\n }, [game]);\r\n\r\n const content = isEnvBrowser() ? (\r\n <BackgroundImage\r\n w=\"100vw\"\r\n h=\"100vh\"\r\n src={game === \"fivem\"\r\n ? \"https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg\"\r\n : \"https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg\"}\r\n >\r\n {children}\r\n </BackgroundImage>\r\n ) : (\r\n children\r\n );\r\n\r\n return (\r\n <MantineProvider theme={mergedTheme} defaultColorScheme=\"dark\">\r\n <DirkErrorBoundary>\r\n {content}\r\n </DirkErrorBoundary>\r\n </MantineProvider>\r\n );\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/theme.ts","../../src/utils/misc.ts","../../src/hooks/useNuiEvent.ts","../../src/utils/useSettings.ts","../../src/utils/fetchNui.ts","../../src/utils/locales.ts","../../src/utils/mergeMantineTheme.ts","../../src/hooks/useScriptConfig.ts","../../src/providers/DirkErrorBoundary.tsx","../../src/providers/DirkProvider.tsx"],"names":["theme","create","error","useEffect","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import { ColorInput, createTheme, MantineTheme, MultiSelect, NumberInput, TextInput } from \"@mantine/core\";\r\n\r\nexport const label = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n};\r\nexport const error = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Regular',\r\n};\r\nexport const description = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n};\r\n\r\nexport const genericInputStyles = {\r\n styles: {\r\n label: label,\r\n error: error,\r\n description: description,\r\n \r\n input:{\r\n background: 'rgba(255,255,255,0.04)',\r\n border: '0.1vh solid rgba(255,255,255,0.08)',\r\n color: 'rgba(255,255,255,0.85)',\r\n minHeight: '4vh',\r\n },\r\n },\r\n};\r\n\r\nconst theme = createTheme({\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n defaultRadius: \"xs\",\r\n fontFamily: \"Akrobat Regular, sans-serif\",\r\n\r\n radius:{\r\n xxs: '0.3vh',\r\n xs: '0.5vh',\r\n sm: '0.75vh',\r\n md: '1vh',\r\n lg: '1.5vh',\r\n xl: '2vh',\r\n xxl: '3vh',\r\n },\r\n\r\n fontSizes: {\r\n xxs: '1.2vh',\r\n xs: '1.5vh',\r\n sm: '1.8vh',\r\n md: '2.2vh',\r\n lg: '2.8vh',\r\n xl: '3.3vh',\r\n xxl: '3.8vh',\r\n },\r\n\r\n lineHeights: {\r\n xxs: '1.4vh',\r\n xs: '1.8vh',\r\n sm: '2.2vh',\r\n md: '2.8vh',\r\n lg: '3.3vh',\r\n xl: '3.8vh',\r\n },\r\n\r\n spacing:{\r\n xxs: '0.5vh',\r\n xs: '0.75vh',\r\n sm: '1.5vh',\r\n md: '2vh',\r\n lg: '3vh',\r\n xl: '4vh',\r\n xxl: '5vh',\r\n },\r\n\r\n components:{\r\n Progress:{\r\n styles:{\r\n label: {\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n },\r\n\r\n root:{\r\n backgroundColor: 'rgba(77, 77, 77, 0.4)',\r\n },\r\n \r\n }\r\n },\r\n \r\n \r\n Input: genericInputStyles,\r\n TextInput: genericInputStyles,\r\n NumberInput: genericInputStyles,\r\n Select: genericInputStyles,\r\n MultiSelect: genericInputStyles, \r\n Textarea: genericInputStyles,\r\n ColorInput: genericInputStyles,\r\n DateInput: genericInputStyles,\r\n\r\n Pill: {\r\n styles: (theme: MantineTheme) => ({\r\n root: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)',\r\n height: 'fit-content',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n fontFamily: 'Akrobat Bold',\r\n fontSize: '1.25vh',\r\n borderRadius: theme.defaultRadius,\r\n paddingBottom: '0.5vh',\r\n paddingTop: '0.5vh',\r\n }\r\n })\r\n },\r\n\r\n },\r\n\r\n colors: {\r\n\r\n dirk:[\r\n \"#ffffff\",\r\n \"#f3fce9\",\r\n \"#dbf5bd\",\r\n \"#c3ee91\",\r\n \"#ace765\",\r\n \"#94e039\",\r\n \"#7ac61f\",\r\n \"#5f9a18\",\r\n \"#29420a\",\r\n \"#446e11\",\r\n ],\r\n },\r\n});\r\n\r\n\r\nexport default theme;","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { MutableRefObject, useEffect, useRef } from \"react\";\r\nimport { noop } from \"../utils/misc\";\r\n\r\nexport interface NuiMessageData<T = unknown> {\r\n action: string;\r\n data: T;\r\n}\r\n\r\nexport type NuiHandlerSignature<T> = ( data: T) => void;\r\n\r\n/**\r\n * A hook that manage events listeners for receiving data from the client scripts\r\n * @param action The specific `action` that should be listened for.\r\n * @param handler The callback function that will handle data relayed by this hook\r\n *\r\n * @example\r\n * useNuiEvent<{visibility: true, wasVisible: 'something'}>('setVisible', (data) => {\r\n * // whatever logic you want\r\n * })\r\n *\r\n **/\r\n\r\nexport const useNuiEvent = <T = unknown>(\r\n action: string,\r\n handler: ( data: T) => void,\r\n) => {\r\n const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);\r\n\r\n // Make sure we handle for a reactive handler\r\n useEffect(() => {\r\n savedHandler.current = handler;\r\n }, [handler]);\r\n\r\n useEffect(() => {\r\n const eventListener = (event: MessageEvent<NuiMessageData<T>>) => {\r\n const { action: eventAction, data } = event.data;\r\n\r\n if (savedHandler.current) {\r\n if (eventAction === action) {\r\n savedHandler.current( data);\r\n }\r\n }\r\n };\r\n\r\n window.addEventListener(\"message\", eventListener);\r\n // Remove Event Listener on component dirkup\r\n return () => window.removeEventListener(\"message\", eventListener);\r\n }, [action]);\r\n};\r\n","import { MantineColorsTuple } from \"@mantine/core\";\r\nimport { create } from \"zustand\";\r\n\r\nexport type SettingsState = {\r\n game: \"fivem\" | \"rdr3\";\r\n currency: string;\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n resourceVersion?: string;\r\n customTheme?: MantineColorsTuple;\r\n overideResourceName?: string;\r\n serverName?: string;\r\n logo?: string;\r\n language?: string;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n currency: \"$\",\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n resourceVersion: \"dev\",\r\n customTheme: [\r\n \"#f0f4ff\",\r\n \"#d9e3ff\",\r\n \"#bfcfff\",\r\n \"#a6bbff\",\r\n \"#8ca7ff\",\r\n \"#7393ff\",\r\n \"#5a7fff\",\r\n \"#406bff\",\r\n \"#2547ff\",\r\n \"#0b33ff\",\r\n ],\r\n}));\r\n\r\n// registerInitialFetch<Partial<SettingsState>>('GET_SETTINGS', undefined).then((data) => {\r\n// if (!data) {\r\n// console.warn('No settings data received from GET_SETTINGS fetch.');\r\n// return;\r\n// }\r\n// useSettings.setState({\r\n// ...data,\r\n// });\r\n// })\r\n","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\nimport { useSettings } from \"./useSettings\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData !== undefined) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const overrideResourceName = useSettings.getState().overideResourceName;\r\n\r\n // Resource-name resolution:\r\n // 1. NUI iframes expose `window.GetParentResourceName` — use that.\r\n // 2. DUIs don't have it, but DirkProvider sets `overideResourceName`\r\n // once it mounts, so consumer DUIs that wait until then resolve fine.\r\n // 3. If NEITHER is available (e.g. a DUI before its DirkProvider has\r\n // mounted, which happens for module-level `registerInitialFetch`\r\n // calls in `locales.ts`), there's no valid resource to call. Skip\r\n // the fetch entirely — firing it against a placeholder URL just\r\n // produces a doomed network request + an \"Uncaught (in promise)\r\n // TypeError: Failed to fetch\" in older consumer builds that\r\n // lacked the try/catch fallback below. Caller can rely on the\r\n // mockData return or refetch once context is established.\r\n const hasResourceContext =\r\n typeof (window as any).GetParentResourceName === \"function\" ||\r\n !!overrideResourceName;\r\n\r\n if (!hasResourceContext) {\r\n return (mockData ?? ({} as T));\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : overrideResourceName as string;\r\n\r\n try {\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n } catch {\r\n return (mockData ?? ({} as T));\r\n }\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n runFetches().catch(() => {});\r\n }, []);\r\n};\r\n\r\n\r\nexport const fetchLuaTable = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return fetchNui<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\nexport const registerInitialLuaTableFetch = <T>(tableName: string, mockData?: T): Promise<T> => { \r\n return registerInitialFetch<T>('FETCH_LUA_TABLE', { tableName }, mockData);\r\n} \r\n\r\n\r\n\r\n// useage example:\r\n// registerInitialLuaTableFetch<{ [key: string]: string }>('my_lua_table', { key1: 'value1', key2: 'value2' }); \r\n","import { create } from \"zustand\";\r\nimport { fetchNui, registerInitialFetch } from \"../utils/fetchNui\";\r\n\r\n\r\ntype localeType = (key: string, ...args: string[]) => string;\r\n\r\ntype LocalesProps = {\r\n [key: string]: string;\r\n}\r\n\r\ntype LocaleStoreProps = {\r\n locale: localeType;\r\n locales: LocalesProps;\r\n};\r\n\r\nconst reportedMissing = new Set<string>();\r\nfunction reportMissingLocale(key: string) {\r\n if (!key || reportedMissing.has(key)) return;\r\n reportedMissing.add(key);\r\n fetchNui('REPORT_MISSING_LOCALE', { key }).catch(() => {});\r\n}\r\n\r\n\r\nexport const localeStore = create<LocaleStoreProps>((set, get) => {\r\n return {\r\n locales: {\r\n \"OccupantsDesc\": \"Here you can view and manage the occupants of your traphouse. These occupants can be used mainly for selling drugs to the NPCs surrounding your traphouse. However they have other uses to so be careful who you add as an occupant.\",\r\n },\r\n locale: (key: string, ...args: (string|number)[]): string => {\r\n const exists = get().locales[key];\r\n if (!exists) reportMissingLocale(key);\r\n let translation = exists || key;\r\n if (args.length) {\r\n // convert the arg to a string and replace the %s in the translation\r\n \r\n\r\n translation = translation.replace(/%s/g, () => String(args.shift() || ''));\r\n }\r\n return translation;\r\n },\r\n };\r\n});\r\n\r\n// export locale as a standalone function\r\nexport const locale = localeStore.getState().locale;\r\n\r\nregisterInitialFetch<LocalesProps>('GET_LOCALES', undefined).then((data) => {\r\n localeStore.setState({ locales: data });\r\n}).catch(() => {})\r\n\r\n// dirk_lib broadcasts UPDATE_DIRK_LIB_LOCALES whenever an admin changes the\r\n// `language` setting, so the dict updates live without a resource restart.\r\nif (typeof window !== \"undefined\") {\r\n window.addEventListener(\"message\", (event) => {\r\n const msg = event.data;\r\n if (!msg || msg.action !== \"UPDATE_DIRK_LIB_LOCALES\") return;\r\n if (!msg.data || typeof msg.data !== \"object\") return;\r\n localeStore.setState({ locales: msg.data as LocalesProps });\r\n });\r\n}","import type { MantineColorsTuple, MantineThemeOverride } from \"@mantine/core\";\r\n\r\nconst isValidColorScale = (v: unknown): v is MantineColorsTuple =>\r\n Array.isArray(v) && v.length === 10 && v.every((shade) => typeof shade === \"string\");\r\n\r\nexport function mergeMantineThemeSafe(\r\n base: MantineThemeOverride,\r\n custom?: MantineColorsTuple,\r\n override?: MantineThemeOverride\r\n): MantineThemeOverride {\r\n const colors = { ...base.colors };\r\n\r\n if (custom && isValidColorScale(custom)) {\r\n colors[\"custom\"] = custom;\r\n } else if (!colors[\"custom\"]) {\r\n // Always register a \"custom\" entry so primaryColor === \"custom\" never\r\n // points at undefined and silently falls back to Mantine's default\r\n // (which surfaces as \"the configured palette didn't apply\").\r\n const fallback = (base.colors && (base.colors as any).dirk) as MantineColorsTuple | undefined;\r\n if (fallback && isValidColorScale(fallback)) {\r\n colors[\"custom\"] = fallback;\r\n }\r\n }\r\n\r\n return {\r\n ...base,\r\n ...override,\r\n colors: {\r\n ...colors,\r\n ...(override?.colors ?? {}),\r\n },\r\n };\r\n}\r\n","import { fetchNui } from \"@/utils\";\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\nimport { create } from \"zustand\";\n\ntype ScriptConfigUpdateMeta<T> = {\n client_version?: number;\n latestVersion?: number;\n latestData?: Partial<T>;\n changed_paths?: Array<{ path: string; old: unknown; new: unknown }>;\n lastEditor?: { source?: number; name?: string; identifier?: string };\n};\n\nexport type ScriptConfigHistoryChange = {\n path: string;\n old: unknown;\n new: unknown;\n};\n\nexport type ScriptConfigHistoryEntry = {\n at_unix: number;\n at_utc: string;\n script: string;\n admin?: { source?: number; name?: string; identifier?: string };\n expected_version?: number;\n applied_version?: number;\n changes: ScriptConfigHistoryChange[];\n};\n\nexport type ScriptConfigHistoryRequest = {\n offset?: number;\n limit?: number;\n query?: string;\n path?: string;\n admin?: string;\n fromUnix?: number;\n toUnix?: number;\n};\n\nexport type ScriptConfigHistoryResponse = {\n success: boolean;\n _error?: string;\n data?: {\n items: ScriptConfigHistoryEntry[];\n total: number;\n limit: number;\n offset: number;\n nextOffset?: number;\n };\n};\n\ntype NuiResponse<T> = {\n success: boolean;\n message?: string;\n _error?: string;\n meta?: ScriptConfigUpdateMeta<T>;\n};\n\n// ── Singleton registry ────────────────────────────────────────────────────────\n\nexport interface ScriptConfigInstance<T = any> {\n store: { getState: () => T; setState: (partial: Partial<T> | ((prev: T) => T)) => void };\n updateConfig: (newConfig: Partial<T>) => Promise<NuiResponse<T>>;\n resetConfig: () => Promise<{ success: boolean; _error?: string }>;\n getHistory: (params?: ScriptConfigHistoryRequest) => Promise<ScriptConfigHistoryResponse>;\n fetchConfig: () => Promise<T | null>;\n}\n\nlet _instance: ScriptConfigInstance | null = null;\n\nexport function getScriptConfigInstance<T = any>(): ScriptConfigInstance<T> {\n if (!_instance) throw new Error(\"[dirk-cfx-react] createScriptConfig must be called before using ConfigPanel\");\n return _instance as ScriptConfigInstance<T>;\n}\n\nexport function createScriptConfig<T>(defaultValue: T) {\n const store = create<T>(() => defaultValue);\n let clientVersion = 0;\n\n const useScriptConfigHooks = () => {\n useNuiEvent<{ config?: Partial<T>; clientVersion?: number }>(\"UPDATE_SCRIPT_CONFIG\", (data) => {\n if (!data) return;\n\n if (typeof data.clientVersion === \"number\") {\n clientVersion = data.clientVersion as number;\n }\n\n if (data.config && typeof data.config === \"object\") {\n store.setState((prev) => ({ ...prev, ...(data.config as Partial<T>) }));\n }\n });\n };\n\n const fetchScriptConfig = async (): Promise<T | null> => {\n try {\n const response = await fetchNui<{\n success: boolean;\n data?: { config: T; clientVersion: number };\n }>(\"GET_FULL_SCRIPT_CONFIG\");\n\n if (response?.success && response.data?.config) {\n store.setState(() => response.data!.config as T);\n if (typeof response.data.clientVersion === \"number\") {\n clientVersion = response.data.clientVersion;\n }\n return response.data.config;\n }\n } catch { /* fallback to current store state */ }\n return null;\n };\n\n const updateScriptConfig = async (newConfig: Partial<T>): Promise<NuiResponse<T>> => {\n store.setState((prev) => ({ ...prev, ...newConfig }));\n\n const response = await fetchNui<NuiResponse<T>>(\"UPDATE_SCRIPT_CONFIG\", {\n data: newConfig,\n expectedVersion: clientVersion,\n });\n\n if (response?.meta?.client_version != null) {\n clientVersion = response.meta.client_version as number;\n }\n\n if (response?.success === false && response?.meta?.latestData) {\n store.setState((prev) => ({ ...prev, ...(response.meta!.latestData as Partial<T>) }));\n }\n\n return response;\n };\n\n const getScriptConfigHistory = async (\n params: ScriptConfigHistoryRequest = {}\n ): Promise<ScriptConfigHistoryResponse> => {\n return fetchNui<ScriptConfigHistoryResponse>('GET_SCRIPT_CONFIG_HISTORY', params);\n };\n\n const resetConfig = async (): Promise<{ success: boolean; _error?: string }> => {\n const response = await fetchNui<{ success: boolean; _error?: string }>('RESET_SCRIPT_CONFIG');\n if (response?.success) {\n const fresh = await fetchScriptConfig();\n if (fresh) {\n store.setState(() => fresh);\n }\n }\n return response;\n };\n\n _instance = {\n store,\n updateConfig: updateScriptConfig,\n resetConfig,\n getHistory: getScriptConfigHistory,\n fetchConfig: fetchScriptConfig,\n };\n\n return {store, updateScriptConfig, resetConfig, getScriptConfigHistory, useScriptConfigHooks, fetchScriptConfig}\n}\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport { Box, Code, Stack, Text, Title } from \"@mantine/core\";\r\n\r\ntype State = {\r\n error: Error | null;\r\n stack?: string;\r\n};\r\n\r\nexport class DirkErrorBoundary extends React.Component<\r\n { children: React.ReactNode },\r\n State\r\n> {\r\n state: State = { error: null, stack: undefined };\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n // We can't get component stack here, so just store the error\r\n return { error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: React.ErrorInfo) {\r\n console.group(\"🔥 Dirk UI Crash\");\r\n console.error(\"Error:\", error);\r\n console.error(\"Component Stack:\", info.componentStack);\r\n console.groupEnd();\r\n\r\n // Only log here, don't call setState — the error state is already captured\r\n }\r\n\r\n render() {\r\n if (!this.state.error) return this.props.children;\r\n\r\n return (\r\n <Box\r\n style={{\r\n position: \"fixed\",\r\n inset: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n background: \"rgba(10, 10, 12, 0.92)\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n padding: \"2rem\",\r\n zIndex: 999999,\r\n }}\r\n >\r\n <Box\r\n maw={900}\r\n w=\"100%\"\r\n p=\"lg\"\r\n style={{\r\n background: \"rgba(20,20,24,0.75)\",\r\n border: \"1px solid rgba(255,255,255,0.08)\",\r\n borderRadius: \"10px\",\r\n boxShadow: \"0 10px 40px rgba(0,0,0,0.6)\",\r\n }}\r\n >\r\n <Stack gap=\"sm\">\r\n <Title order={2} c=\"red.5\">\r\n Dirk UI Crash\r\n </Title>\r\n\r\n <Text c=\"dimmed\" size=\"sm\">\r\n The interface encountered a fatal error and stopped rendering.\r\n </Text>\r\n\r\n <Code block style={{ maxHeight: 150, overflow: \"auto\" }}>\r\n {this.state.error?.message}\r\n </Code>\r\n\r\n {/* Optional: show component stack if you pass it from props */}\r\n <Text size=\"xs\" c=\"dimmed\">\r\n Check console for full stack trace\r\n </Text>\r\n </Stack>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n}","\"use client\";\n\nimport \"@mantine/core/styles.css\";\nimport \"@mantine/notifications/styles.css\";\nimport './styles/fonts.css';\nimport './styles/notify.css';\nimport './styles/scrollBar.css';\nimport './styles/tornEdge.css';\n\n\nimport { library } from \"@fortawesome/fontawesome-svg-core\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nlibrary.add(fas, far, fab);\n\nimport theme from \"@/theme\";\nimport { BackgroundImage, MantineColorShade, MantineColorsTuple, MantineProvider } from \"@mantine/core\";\nimport { useEffect, useLayoutEffect, useMemo, useState } from \"react\";\n\nimport { useNuiEvent } from \"@/hooks/useNuiEvent\";\nimport { fetchNui, isEnvBrowser } from \"@/utils\";\nimport { localeStore } from \"@/utils/locales\";\nimport { mergeMantineThemeSafe } from \"@/utils/mergeMantineTheme\";\nimport { SettingsState, useSettings } from \"@/utils/useSettings\";\nimport { getScriptConfigInstance } from \"@/hooks/useScriptConfig\";\nimport { DirkErrorBoundary } from \"./DirkErrorBoundary\";\n\nexport type DirkProviderProps = {\n children: React.ReactNode;\n overideResourceName?: string;\n themeOverride?: any;\n};\n\n// Shape DirkProvider looks for at `scriptConfig.theme` to detect a per-resource\n// theme override. Consumers opt in by adding a `theme` block to their schema.json\n// with these four fields — DirkProvider auto-detects and applies it. Resources\n// with no `theme` block (or `useOverride: false`) follow the global dirk_lib\n// theme as before. No bridge component, no extra wiring required from consumers.\ntype ScriptConfigThemeOverride = {\n useOverride?: boolean;\n primaryColor?: string;\n primaryShade?: number;\n customTheme?: MantineColorsTuple | string[];\n};\n\nexport function DirkProvider({ children, overideResourceName, themeOverride }: DirkProviderProps) {\n const {\n primaryColor,\n primaryShade,\n customTheme,\n game,\n } = useSettings();\n\n // Subscribe to locale changes so the entire tree re-renders when an admin\n // updates `language` via dirk_lib's scriptConfig — components calling\n // `locale(\"Foo\")` directly (no hook) get fresh strings on the next render.\n const _locales = localeStore((s) => s.locales);\n void _locales;\n\n // Per-resource theme override snapshot, read from `scriptConfig.theme` when\n // the consumer has a scriptConfig registered. Updated by the subscription\n // below; survives Mantine recomputes via useMemo deps.\n const [scTheme, setScTheme] = useState<ScriptConfigThemeOverride | null>(null);\n\n useLayoutEffect(() => {\n useSettings.setState({\n overideResourceName,\n });\n }, [overideResourceName]);\n\n useEffect(() => {\n fetchNui('NUI_READY').catch(() => {});\n Promise.all([\n fetchNui<Partial<SettingsState>>('GET_SETTINGS'),\n fetchNui<{ version?: string }>('GET_RESOURCE_VERSION', undefined, { version: 'dev' }),\n ]).then(([data, resourceInfo]) => {\n useSettings.setState({\n ...data,\n resourceVersion: resourceInfo?.version || 'dev',\n });\n }).catch((err) => {\n console.error(\"Failed to fetch initial settings within dirk-cfx-react:\", err);\n });\n }, []);\n\n // Live updates: dirk_lib broadcasts UPDATE_DIRK_LIB_SETTINGS whenever an admin\n // changes appearance/localization via the scriptConfig UI. Merge the partial\n // patch into the settings store so theme / currency / branding update live\n // without a resource restart. Per-resource theme override is handled below\n // via the scriptConfig subscription — pushes here can flow through unchanged.\n useNuiEvent<Partial<SettingsState>>('UPDATE_DIRK_LIB_SETTINGS', (data) => {\n if (!data || typeof data !== 'object') return;\n useSettings.setState(data);\n });\n\n // ── Per-resource theme auto-detect ────────────────────────────────────────\n // If the consumer has called createScriptConfig() (i.e. has a registered\n // scriptConfig instance) AND their schema has a `theme` block with\n // `useOverride: true`, DirkProvider uses those theme values instead of\n // dirk_lib's global appearance. Consumers don't have to write any glue\n // code — they just add the `theme` block to schema.json and a Theme tab\n // (via ThemeOverrideSection) to their configurator. Everything else is\n // handled here.\n //\n // We also forward UPDATE_SCRIPT_CONFIG pushes into the store so this works\n // whether or not the consumer remembers to call useScriptConfigHooks().\n useNuiEvent<{ config?: Record<string, unknown>; clientVersion?: number }>(\n 'UPDATE_SCRIPT_CONFIG',\n (data) => {\n if (!data || !data.config || typeof data.config !== 'object') return;\n try {\n const inst = getScriptConfigInstance<Record<string, unknown>>();\n inst.store.setState((prev) => ({ ...prev, ...(data.config as Record<string, unknown>) }));\n } catch {\n // No scriptConfig instance registered — consumer doesn't use scriptConfig, ignore.\n }\n }\n );\n\n useEffect(() => {\n let unsubscribe: (() => void) | undefined;\n try {\n const inst = getScriptConfigInstance<{ theme?: ScriptConfigThemeOverride }>();\n\n // Seed from whatever's already in the store (covers cases where the\n // store was hydrated before DirkProvider mounted, e.g. by an upstream\n // ConfigPanel open).\n setScTheme((inst.store.getState() as { theme?: ScriptConfigThemeOverride })?.theme ?? null);\n\n // Subscribe to store mutations so live edits / hydration completion\n // re-trigger the override application.\n const subscribable = inst.store as unknown as {\n subscribe?: (listener: (s: { theme?: ScriptConfigThemeOverride }) => void) => () => void;\n };\n if (typeof subscribable.subscribe === 'function') {\n unsubscribe = subscribable.subscribe((s) => {\n setScTheme(s?.theme ?? null);\n });\n }\n\n // Proactive hydration. The dirk_lib cold-start push that populates the\n // scriptConfig store is timing-sensitive (may fire before the NUI\n // iframe is ready). A single GET_FULL_SCRIPT_CONFIG round-trip on\n // mount removes that race entirely — the server callback blocks until\n // scriptConfig is hydrated, so the override block is guaranteed\n // populated before the first paint that depends on it.\n inst.fetchConfig?.().then((full) => {\n if (full && typeof full === 'object') {\n setScTheme((full as { theme?: ScriptConfigThemeOverride }).theme ?? null);\n }\n }).catch(() => {});\n } catch {\n // No scriptConfig instance — consumer doesn't use scriptConfig at all.\n // Fall through silently; global theme behaviour is unchanged.\n }\n return () => { unsubscribe?.(); };\n }, []);\n\n const overrideActive = scTheme?.useOverride === true;\n const effectivePrimaryColor = overrideActive ? (scTheme!.primaryColor ?? primaryColor) : primaryColor;\n const effectivePrimaryShade = overrideActive ? (scTheme!.primaryShade ?? primaryShade) : primaryShade;\n const effectiveCustomTheme = overrideActive\n ? ((scTheme!.customTheme as MantineColorsTuple | undefined) ?? customTheme)\n : customTheme;\n\n const mergedTheme = useMemo(\n () => mergeMantineThemeSafe(\n { ...theme, primaryColor: effectivePrimaryColor, primaryShade: effectivePrimaryShade as MantineColorShade },\n effectiveCustomTheme,\n themeOverride\n ),\n [effectivePrimaryColor, effectivePrimaryShade, effectiveCustomTheme, themeOverride]\n );\n\n useEffect(() => {\n document.body.style.fontFamily =\n game === \"rdr3\"\n ? '\"Red Dead\", sans-serif'\n : '\"Akrobat Regular\", sans-serif';\n }, [game]);\n\n const content = isEnvBrowser() ? (\n <BackgroundImage\n w=\"100vw\"\n h=\"100vh\"\n src={game === \"fivem\"\n ? \"https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg\"\n : \"https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg\"}\n >\n {children}\n </BackgroundImage>\n ) : (\n children\n );\n\n return (\n <MantineProvider theme={mergedTheme} defaultColorScheme=\"dark\">\n <DirkErrorBoundary>\n {content}\n </DirkErrorBoundary>\n </MantineProvider>\n );\n}\n"]}
|