dirk-cfx-react 1.0.34 → 1.0.35

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/index.cjs CHANGED
@@ -2,20 +2,21 @@
2
2
 
3
3
  var reactFontawesome = require('@fortawesome/react-fontawesome');
4
4
  var core = require('@mantine/core');
5
- var jsxRuntime = require('react/jsx-runtime');
6
- var framerMotion = require('framer-motion');
7
5
  var react = require('react');
8
- var zustand = require('zustand');
9
- var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
10
- var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
11
6
  require('@mantine/core/styles.css');
12
7
  require('@mantine/notifications/styles.css');
13
8
  require('./styles/fonts.css');
14
9
  require('./styles/scrollBar.css');
10
+ require('./styles/tornEdge.css');
15
11
  var fontawesomeSvgCore = require('@fortawesome/fontawesome-svg-core');
16
12
  var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons');
17
13
  var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
18
14
  var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
15
+ var zustand = require('zustand');
16
+ var jsxRuntime = require('react/jsx-runtime');
17
+ var framerMotion = require('framer-motion');
18
+ var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
19
+ var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
19
20
 
20
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
22
 
@@ -191,15 +192,347 @@ function colorWithAlpha(color, alpha) {
191
192
  }
192
193
  return color;
193
194
  }
195
+
196
+ // src/utils/misc.ts
197
+ var isEnvBrowser = () => !window.invokeNative;
198
+ var noop = () => {
199
+ };
200
+ var splitFAString = (faString) => {
201
+ const [prefix, newIcon] = faString.split("-");
202
+ if (!prefix || !newIcon) return { prefix: "fas", newIcon: "question" };
203
+ return { prefix, newIcon };
204
+ };
205
+ var numberToRoman = (num) => {
206
+ const romanNumerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX"];
207
+ return romanNumerals[num];
208
+ };
209
+ var copyToClipboard = (text) => {
210
+ const el = document.createElement("textarea");
211
+ el.value = text;
212
+ document.body.appendChild(el);
213
+ el.select();
214
+ document.execCommand("copy");
215
+ document.body.removeChild(el);
216
+ };
217
+ var openLink = (url) => {
218
+ if (isEnvBrowser()) {
219
+ window.open(url, "_blank");
220
+ } else {
221
+ window.invokeNative("openLink", url);
222
+ }
223
+ };
224
+
225
+ // src/hooks/useNuiEvent.ts
226
+ var useNuiEvent = (action, handler) => {
227
+ const savedHandler = react.useRef(noop);
228
+ react.useEffect(() => {
229
+ savedHandler.current = handler;
230
+ }, [handler]);
231
+ react.useEffect(() => {
232
+ const eventListener = (event) => {
233
+ const { action: eventAction, data } = event.data;
234
+ if (savedHandler.current) {
235
+ if (eventAction === action) {
236
+ savedHandler.current(data);
237
+ }
238
+ }
239
+ };
240
+ window.addEventListener("message", eventListener);
241
+ return () => window.removeEventListener("message", eventListener);
242
+ }, [action]);
243
+ };
244
+
245
+ // src/utils/fetchNui.ts
246
+ async function fetchNui(eventName, data, mockData) {
247
+ const options = {
248
+ method: "post",
249
+ headers: {
250
+ "Content-Type": "application/json; charset=UTF-8"
251
+ },
252
+ body: JSON.stringify(data)
253
+ };
254
+ if (isEnvBrowser() && mockData !== void 0) return mockData;
255
+ if (isEnvBrowser()) {
256
+ console.warn(
257
+ `[fetchNui] Called fetchNui for event "${eventName}" in browser environment without mockData. Returning empty object.`
258
+ );
259
+ return {};
260
+ }
261
+ const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
262
+ const resp = await fetch(`https://${resourceName}/${eventName}`, options);
263
+ const respFormatted = await resp.json();
264
+ return respFormatted;
265
+ }
266
+ function fetchOnLoad(eventName, data, mockData) {
267
+ return fetchNui(eventName, data, mockData).catch((err) => {
268
+ console.error(`[fetchOnLoad] Failed for ${eventName}:`, err);
269
+ throw err;
270
+ });
271
+ }
272
+ var fetchLuaTable = (tableName) => () => {
273
+ if (isEnvBrowser()) {
274
+ return Promise.resolve({});
275
+ }
276
+ return fetchNui("GET_LUA_TABLE", { tableName });
277
+ };
278
+
279
+ // src/utils/internalEvent.ts
280
+ var internalEvent = (events, timer = 1e3) => {
281
+ if (isEnvBrowser()) {
282
+ for (const event of events) {
283
+ setTimeout(() => {
284
+ window.dispatchEvent(
285
+ new MessageEvent("message", {
286
+ data: {
287
+ action: event.action,
288
+ data: event.data
289
+ }
290
+ })
291
+ );
292
+ }, timer);
293
+ }
294
+ }
295
+ };
296
+ var localeStore = zustand.create((set, get) => {
297
+ return {
298
+ locales: {
299
+ "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."
300
+ },
301
+ locale: (key, ...args) => {
302
+ const exists = get().locales[key];
303
+ let translation = exists || key;
304
+ if (args.length) {
305
+ translation = translation.replace(/%s/g, () => String(args.shift() || ""));
306
+ }
307
+ return translation;
308
+ }
309
+ };
310
+ });
311
+ var locale = localeStore.getState().locale;
312
+ fetchOnLoad("GET_LOCALES").then((data) => {
313
+ localeStore.setState({ locales: data });
314
+ });
315
+ var theme = core.createTheme({
316
+ primaryColor: "dirk",
317
+ primaryShade: 9,
318
+ defaultRadius: "xxs",
319
+ fontFamily: "Akrobat Regular, sans-serif",
320
+ radius: {
321
+ xxs: "0.2vh",
322
+ xs: "0.4vh",
323
+ sm: "0.75vh",
324
+ md: "1vh",
325
+ lg: "1.5vh",
326
+ xl: "2vh",
327
+ xxl: "3vh"
328
+ },
329
+ fontSizes: {
330
+ xxs: "1.2vh",
331
+ xs: "1.5vh",
332
+ sm: "1.8vh",
333
+ md: "2.2vh",
334
+ lg: "2.8vh",
335
+ xl: "3.3vh",
336
+ xxl: "3.8vh"
337
+ },
338
+ spacing: {
339
+ xxs: "0.5vh",
340
+ xs: "0.75vh",
341
+ sm: "1.5vh",
342
+ md: "2vh",
343
+ lg: "3vh",
344
+ xl: "4vh",
345
+ xxl: "5vh"
346
+ },
347
+ components: {
348
+ Progress: {
349
+ styles: {
350
+ root: {
351
+ backgroundColor: "rgba(77, 77, 77, 0.4)"
352
+ }
353
+ }
354
+ },
355
+ Select: {
356
+ styles: {
357
+ dropdown: {
358
+ borderRadius: "var(--mantine-radius-xxs)"
359
+ },
360
+ input: {
361
+ padding: "var(--mantine-spacing-sm)"
362
+ },
363
+ item: {
364
+ borderRadius: "var(--mantine-radius-xxs)"
365
+ },
366
+ wrapper: {
367
+ borderRadius: "var(--mantine-radius-xxs)"
368
+ },
369
+ option: {
370
+ borderRadius: "var(--mantine-radius-xxs)"
371
+ }
372
+ }
373
+ },
374
+ MultiSelect: {
375
+ styles: {
376
+ dropdown: {
377
+ borderRadius: "var(--mantine-radius-xxs)"
378
+ },
379
+ pill: {
380
+ borderRadius: "var(--mantine-radius-xxs)"
381
+ },
382
+ item: {
383
+ borderRadius: "var(--mantine-radius-xxs)"
384
+ },
385
+ wrapper: {
386
+ borderRadius: "var(--mantine-radius-xxs)"
387
+ },
388
+ option: {
389
+ borderRadius: "var(--mantine-radius-xxs)"
390
+ }
391
+ }
392
+ },
393
+ TextInput: {
394
+ styles: {
395
+ section: {
396
+ marginRight: "0.2vh"
397
+ },
398
+ input: {
399
+ padding: "var(--mantine-spacing-sm)"
400
+ }
401
+ }
402
+ }
403
+ },
404
+ colors: {
405
+ dark: [
406
+ "#ffffff",
407
+ "#e2e2e2",
408
+ "#c6c6c6",
409
+ "#aaaaaa",
410
+ "#8d8d8d",
411
+ "#717171",
412
+ "#555555",
413
+ "#393939",
414
+ "#1c1c1c",
415
+ "#000000"
416
+ ],
417
+ dirk: [
418
+ "#ffffff",
419
+ "#f3fce9",
420
+ "#dbf5bd",
421
+ "#c3ee91",
422
+ "#ace765",
423
+ "#94e039",
424
+ "#7ac61f",
425
+ "#5f9a18",
426
+ "#29420a",
427
+ "#446e11"
428
+ ]
429
+ }
430
+ });
431
+ var theme_default = theme;
432
+ fontawesomeSvgCore.library.add(freeSolidSvgIcons.fas, freeRegularSvgIcons.far, freeBrandsSvgIcons.fab);
433
+ var useSettings = zustand.create((set) => ({
434
+ game: "rdr3",
435
+ primaryColor: "teal",
436
+ primaryShade: 6,
437
+ customTheme: {}
438
+ }));
439
+ function DirkProvider(props) {
440
+ const primaryColor = useSettings((data) => data.primaryColor);
441
+ const primaryShade = useSettings((data) => data.primaryShade);
442
+ const customTheme = useSettings((data) => data.customTheme);
443
+ const game = useSettings((data) => data.game);
444
+ const mergedTheme = react.useMemo(() => ({
445
+ ...theme_default,
446
+ primaryColor,
447
+ primaryShade,
448
+ colors: {
449
+ ...theme_default.colors,
450
+ ...customTheme
451
+ // Custom theme colors will override/extend base colors
452
+ }
453
+ }), [primaryColor, primaryShade, customTheme]);
454
+ react.useEffect(() => {
455
+ document.fonts.ready.then(() => {
456
+ document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : game === "fivem" ? '"Akrobat Regular", sans-serif' : "sans-serif";
457
+ console.log(`Game set to ${game}, applied corresponding font family.: ${document.body.style.fontFamily}`);
458
+ });
459
+ }, [game]);
460
+ return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { children: props.children }) });
461
+ }
462
+ function Wrapper({ children }) {
463
+ const game = useSettings((data) => data.game);
464
+ return isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
465
+ core.BackgroundImage,
466
+ {
467
+ w: "100vw",
468
+ h: "100vh",
469
+ style: { overflow: "hidden" },
470
+ src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
471
+ children
472
+ }
473
+ ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
474
+ }
475
+ function useTornEdges() {
476
+ const game = useSettings((state) => state.game);
477
+ return game === "rdr3" ? "torn-edge-wrapper" : "";
478
+ }
479
+ function TornEdgeSVGFilter() {
480
+ return /* @__PURE__ */ jsxRuntime.jsx(
481
+ "svg",
482
+ {
483
+ style: { position: "absolute", width: 0, height: 0, pointerEvents: "none" },
484
+ "aria-hidden": "true",
485
+ children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: "torn-edge-filter", x: "-50%", y: "-50%", width: "200%", height: "200%", children: [
486
+ /* @__PURE__ */ jsxRuntime.jsx(
487
+ "feTurbulence",
488
+ {
489
+ type: "fractalNoise",
490
+ baseFrequency: "0.018 0.022",
491
+ numOctaves: "5",
492
+ seed: "9",
493
+ result: "noise1"
494
+ }
495
+ ),
496
+ /* @__PURE__ */ jsxRuntime.jsx(
497
+ "feTurbulence",
498
+ {
499
+ type: "fractalNoise",
500
+ baseFrequency: "0.08 0.12",
501
+ numOctaves: "2",
502
+ seed: "3",
503
+ result: "noise2"
504
+ }
505
+ ),
506
+ /* @__PURE__ */ jsxRuntime.jsx("feBlend", { in: "noise1", in2: "noise2", mode: "multiply", result: "combinedNoise" }),
507
+ /* @__PURE__ */ jsxRuntime.jsx(
508
+ "feDisplacementMap",
509
+ {
510
+ in: "SourceGraphic",
511
+ in2: "combinedNoise",
512
+ scale: "52",
513
+ xChannelSelector: "R",
514
+ yChannelSelector: "G",
515
+ result: "displaced"
516
+ }
517
+ ),
518
+ /* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { stdDeviation: "0.8", in: "displaced", result: "blurred" }),
519
+ /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: "blurred", result: "alphaFade", children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "gamma", amplitude: "1", exponent: "1.3", offset: "-0.05" }) }),
520
+ /* @__PURE__ */ jsxRuntime.jsx("feMorphology", { operator: "erode", radius: "0.4", in: "alphaFade", result: "eroded" }),
521
+ /* @__PURE__ */ jsxRuntime.jsx("feMerge", { children: /* @__PURE__ */ jsxRuntime.jsx("feMergeNode", { in: "eroded" }) })
522
+ ] }) })
523
+ }
524
+ );
525
+ }
194
526
  function BorderedIcon(props) {
195
527
  const theme2 = core.useMantineTheme();
528
+ const tornEdgeCSS = useTornEdges();
196
529
  return /* @__PURE__ */ jsxRuntime.jsx(
197
- reactFontawesome.FontAwesomeIcon,
530
+ core.Flex,
198
531
  {
199
- icon: props.icon,
200
- color: colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][theme2.primaryShade], props.hovered ? 0.9 : 0.9),
532
+ className: tornEdgeCSS,
533
+ justify: "center",
534
+ align: "center",
201
535
  style: {
202
- // backgroundColor: colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][7 as number], (props.hoverable ? (props.hovered ? 0.3 : 0.2) : 0.2)),
203
536
  backgroundColor: "rgba(0, 0, 0, 0.5)",
204
537
  padding: props.p || theme2.spacing.xs,
205
538
  transition: "all 0.2s ease-in-out",
@@ -207,9 +540,19 @@ function BorderedIcon(props) {
207
540
  fontSize: props.fontSize ? props.fontSize : "2.5vh",
208
541
  borderRadius: theme2.radius.xs,
209
542
  // border: `2px solid var(--mantine-primary-color-9)`,
210
- outline: `0.2vh solid ${colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][9], 0.8)}`,
543
+ // outline: `0.2vh solid ${colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][9], 0.8)}`,
211
544
  boxShadow: `inset 0 0 2vh ${colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][7], 0.5)}`
212
- }
545
+ },
546
+ children: /* @__PURE__ */ jsxRuntime.jsx(
547
+ reactFontawesome.FontAwesomeIcon,
548
+ {
549
+ icon: props.icon,
550
+ color: colorWithAlpha(props.color ? props.color : theme2.colors[theme2.primaryColor][theme2.primaryShade], props.hovered ? 0.9 : 0.9),
551
+ style: {
552
+ // backgroundColor: colorWithAlpha(props.color ? props.color : theme.colors[theme.primaryColor][7 as number], (props.hoverable ? (props.hovered ? 0.3 : 0.2) : 0.2)),
553
+ }
554
+ }
555
+ )
213
556
  }
214
557
  );
215
558
  }
@@ -537,175 +880,75 @@ function InputContainer(props) {
537
880
  style: {
538
881
  lineHeight: "1.25vh",
539
882
  fontFamily: "Akrobat Bold",
540
- letterSpacing: "0.05em",
541
- textTransform: "uppercase"
542
- },
543
- children: props.title
544
- }
545
- ),
546
- props.description && /* @__PURE__ */ jsxRuntime.jsx(
547
- core.Text,
548
- {
549
- size: "xs",
550
- c: "rgba(255, 255, 255, 0.8)",
551
- fw: 400,
552
- children: props.description
553
- }
554
- )
555
- ]
556
- }
557
- ),
558
- props.error && /* @__PURE__ */ jsxRuntime.jsx(
559
- core.Text,
560
- {
561
- size: "xs",
562
- c: theme2.colors.red[9],
563
- fw: 600,
564
- mb: "auto",
565
- lh: "0.8",
566
- children: props.error
567
- }
568
- ),
569
- /* @__PURE__ */ jsxRuntime.jsx(
570
- core.Flex,
571
- {
572
- ml: "auto",
573
- children: props.rightSection
574
- }
575
- )
576
- ]
577
- }
578
- ),
579
- props.children
580
- ]
581
- }
582
- );
583
- }
584
- var useAudio = zustand.create(() => {
585
- const audioRefs = {};
586
- const sounds = {
587
- click: clickSoundUrl__default.default,
588
- hover: hoverSoundUrl__default.default
589
- };
590
- for (const [key, src] of Object.entries(sounds)) {
591
- audioRefs[key] = new Audio(src);
592
- }
593
- return {
594
- play: (sound) => {
595
- const audio = audioRefs[sound];
596
- if (!audio) return console.warn(`Sound '${sound}' not found.`);
597
- audio.currentTime = 0;
598
- audio.volume = 0.1;
599
- audio.play();
600
- },
601
- stop: (sound) => {
602
- const audio = audioRefs[sound];
603
- if (!audio) return console.warn(`Sound '${sound}' not found.`);
604
- audio.pause();
605
- audio.currentTime = 0;
606
- }
607
- };
608
- });
609
-
610
- // src/utils/misc.ts
611
- var isEnvBrowser = () => !window.invokeNative;
612
- var noop = () => {
613
- };
614
- var splitFAString = (faString) => {
615
- const [prefix, newIcon] = faString.split("-");
616
- if (!prefix || !newIcon) return { prefix: "fas", newIcon: "question" };
617
- return { prefix, newIcon };
618
- };
619
- var numberToRoman = (num) => {
620
- const romanNumerals = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX"];
621
- return romanNumerals[num];
622
- };
623
- var copyToClipboard = (text) => {
624
- const el = document.createElement("textarea");
625
- el.value = text;
626
- document.body.appendChild(el);
627
- el.select();
628
- document.execCommand("copy");
629
- document.body.removeChild(el);
630
- };
631
- var openLink = (url) => {
632
- if (isEnvBrowser()) {
633
- window.open(url, "_blank");
634
- } else {
635
- window.invokeNative("openLink", url);
636
- }
637
- };
638
-
639
- // src/utils/fetchNui.ts
640
- async function fetchNui(eventName, data, mockData) {
641
- const options = {
642
- method: "post",
643
- headers: {
644
- "Content-Type": "application/json; charset=UTF-8"
645
- },
646
- body: JSON.stringify(data)
647
- };
648
- if (isEnvBrowser() && mockData !== void 0) return mockData;
649
- if (isEnvBrowser()) {
650
- console.warn(
651
- `[fetchNui] Called fetchNui for event "${eventName}" in browser environment without mockData. Returning empty object.`
652
- );
653
- return {};
654
- }
655
- const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
656
- const resp = await fetch(`https://${resourceName}/${eventName}`, options);
657
- const respFormatted = await resp.json();
658
- return respFormatted;
659
- }
660
- function fetchOnLoad(eventName, data, mockData) {
661
- return fetchNui(eventName, data, mockData).catch((err) => {
662
- console.error(`[fetchOnLoad] Failed for ${eventName}:`, err);
663
- throw err;
664
- });
665
- }
666
- var fetchLuaTable = (tableName) => () => {
667
- if (isEnvBrowser()) {
668
- return Promise.resolve({});
669
- }
670
- return fetchNui("GET_LUA_TABLE", { tableName });
671
- };
672
-
673
- // src/utils/internalEvent.ts
674
- var internalEvent = (events, timer = 1e3) => {
675
- if (isEnvBrowser()) {
676
- for (const event of events) {
677
- setTimeout(() => {
678
- window.dispatchEvent(
679
- new MessageEvent("message", {
680
- data: {
681
- action: event.action,
682
- data: event.data
683
- }
684
- })
685
- );
686
- }, timer);
883
+ letterSpacing: "0.05em",
884
+ textTransform: "uppercase"
885
+ },
886
+ children: props.title
887
+ }
888
+ ),
889
+ props.description && /* @__PURE__ */ jsxRuntime.jsx(
890
+ core.Text,
891
+ {
892
+ size: "xs",
893
+ c: "rgba(255, 255, 255, 0.8)",
894
+ fw: 400,
895
+ children: props.description
896
+ }
897
+ )
898
+ ]
899
+ }
900
+ ),
901
+ props.error && /* @__PURE__ */ jsxRuntime.jsx(
902
+ core.Text,
903
+ {
904
+ size: "xs",
905
+ c: theme2.colors.red[9],
906
+ fw: 600,
907
+ mb: "auto",
908
+ lh: "0.8",
909
+ children: props.error
910
+ }
911
+ ),
912
+ /* @__PURE__ */ jsxRuntime.jsx(
913
+ core.Flex,
914
+ {
915
+ ml: "auto",
916
+ children: props.rightSection
917
+ }
918
+ )
919
+ ]
920
+ }
921
+ ),
922
+ props.children
923
+ ]
687
924
  }
925
+ );
926
+ }
927
+ var useAudio = zustand.create(() => {
928
+ const audioRefs = {};
929
+ const sounds = {
930
+ click: clickSoundUrl__default.default,
931
+ hover: hoverSoundUrl__default.default
932
+ };
933
+ for (const [key, src] of Object.entries(sounds)) {
934
+ audioRefs[key] = new Audio(src);
688
935
  }
689
- };
690
- var localeStore = zustand.create((set, get) => {
691
936
  return {
692
- locales: {
693
- "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."
937
+ play: (sound) => {
938
+ const audio = audioRefs[sound];
939
+ if (!audio) return console.warn(`Sound '${sound}' not found.`);
940
+ audio.currentTime = 0;
941
+ audio.volume = 0.1;
942
+ audio.play();
694
943
  },
695
- locale: (key, ...args) => {
696
- const exists = get().locales[key];
697
- let translation = exists || key;
698
- if (args.length) {
699
- translation = translation.replace(/%s/g, () => String(args.shift() || ""));
700
- }
701
- return translation;
944
+ stop: (sound) => {
945
+ const audio = audioRefs[sound];
946
+ if (!audio) return console.warn(`Sound '${sound}' not found.`);
947
+ audio.pause();
948
+ audio.currentTime = 0;
702
949
  }
703
950
  };
704
951
  });
705
- var locale = localeStore.getState().locale;
706
- fetchOnLoad("GET_LOCALES").then((data) => {
707
- localeStore.setState({ locales: data });
708
- });
709
952
  function SegmentedControl(props) {
710
953
  const theme2 = core.useMantineTheme();
711
954
  const play = useAudio((state) => state.play);
@@ -978,6 +1221,7 @@ function SegmentedProgress(props) {
978
1221
  );
979
1222
  }
980
1223
  function Title(props) {
1224
+ const game = useSettings((state) => state.game);
981
1225
  const theme2 = core.useMantineTheme();
982
1226
  return /* @__PURE__ */ jsxRuntime.jsx(
983
1227
  core.Flex,
@@ -1021,7 +1265,7 @@ function Title(props) {
1021
1265
  children: [
1022
1266
  /* @__PURE__ */ jsxRuntime.jsx(core.Text, { p: "0", size: "sm", style: {
1023
1267
  lineHeight: theme2.fontSizes.md,
1024
- fontFamily: "Akrobat Bold",
1268
+ fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
1025
1269
  letterSpacing: "0.05em",
1026
1270
  textTransform: "uppercase"
1027
1271
  }, children: props.title }),
@@ -1055,184 +1299,6 @@ function Title(props) {
1055
1299
  }
1056
1300
  );
1057
1301
  }
1058
- var useNuiEvent = (action, handler) => {
1059
- const savedHandler = react.useRef(noop);
1060
- react.useEffect(() => {
1061
- savedHandler.current = handler;
1062
- }, [handler]);
1063
- react.useEffect(() => {
1064
- const eventListener = (event) => {
1065
- const { action: eventAction, data } = event.data;
1066
- if (savedHandler.current) {
1067
- if (eventAction === action) {
1068
- savedHandler.current(data);
1069
- }
1070
- }
1071
- };
1072
- window.addEventListener("message", eventListener);
1073
- return () => window.removeEventListener("message", eventListener);
1074
- }, [action]);
1075
- };
1076
- var theme = core.createTheme({
1077
- primaryColor: "dirk",
1078
- primaryShade: 9,
1079
- defaultRadius: "xxs",
1080
- fontFamily: "Akrobat Regular, sans-serif",
1081
- radius: {
1082
- xxs: "0.2vh",
1083
- xs: "0.4vh",
1084
- sm: "0.75vh",
1085
- md: "1vh",
1086
- lg: "1.5vh",
1087
- xl: "2vh",
1088
- xxl: "3vh"
1089
- },
1090
- fontSizes: {
1091
- xxs: "1.2vh",
1092
- xs: "1.5vh",
1093
- sm: "1.8vh",
1094
- md: "2.2vh",
1095
- lg: "2.8vh",
1096
- xl: "3.3vh",
1097
- xxl: "3.8vh"
1098
- },
1099
- spacing: {
1100
- xxs: "0.5vh",
1101
- xs: "0.75vh",
1102
- sm: "1.5vh",
1103
- md: "2vh",
1104
- lg: "3vh",
1105
- xl: "4vh",
1106
- xxl: "5vh"
1107
- },
1108
- components: {
1109
- Progress: {
1110
- styles: {
1111
- root: {
1112
- backgroundColor: "rgba(77, 77, 77, 0.4)"
1113
- }
1114
- }
1115
- },
1116
- Select: {
1117
- styles: {
1118
- dropdown: {
1119
- borderRadius: "var(--mantine-radius-xxs)"
1120
- },
1121
- input: {
1122
- padding: "var(--mantine-spacing-sm)"
1123
- },
1124
- item: {
1125
- borderRadius: "var(--mantine-radius-xxs)"
1126
- },
1127
- wrapper: {
1128
- borderRadius: "var(--mantine-radius-xxs)"
1129
- },
1130
- option: {
1131
- borderRadius: "var(--mantine-radius-xxs)"
1132
- }
1133
- }
1134
- },
1135
- MultiSelect: {
1136
- styles: {
1137
- dropdown: {
1138
- borderRadius: "var(--mantine-radius-xxs)"
1139
- },
1140
- pill: {
1141
- borderRadius: "var(--mantine-radius-xxs)"
1142
- },
1143
- item: {
1144
- borderRadius: "var(--mantine-radius-xxs)"
1145
- },
1146
- wrapper: {
1147
- borderRadius: "var(--mantine-radius-xxs)"
1148
- },
1149
- option: {
1150
- borderRadius: "var(--mantine-radius-xxs)"
1151
- }
1152
- }
1153
- },
1154
- TextInput: {
1155
- styles: {
1156
- section: {
1157
- marginRight: "0.2vh"
1158
- },
1159
- input: {
1160
- padding: "var(--mantine-spacing-sm)"
1161
- }
1162
- }
1163
- }
1164
- },
1165
- colors: {
1166
- dark: [
1167
- "#ffffff",
1168
- "#e2e2e2",
1169
- "#c6c6c6",
1170
- "#aaaaaa",
1171
- "#8d8d8d",
1172
- "#717171",
1173
- "#555555",
1174
- "#393939",
1175
- "#1c1c1c",
1176
- "#000000"
1177
- ],
1178
- dirk: [
1179
- "#ffffff",
1180
- "#f3fce9",
1181
- "#dbf5bd",
1182
- "#c3ee91",
1183
- "#ace765",
1184
- "#94e039",
1185
- "#7ac61f",
1186
- "#5f9a18",
1187
- "#29420a",
1188
- "#446e11"
1189
- ]
1190
- }
1191
- });
1192
- var theme_default = theme;
1193
- fontawesomeSvgCore.library.add(freeSolidSvgIcons.fas, freeRegularSvgIcons.far, freeBrandsSvgIcons.fab);
1194
- var useSettings = zustand.create((set) => ({
1195
- game: "rdr3",
1196
- primaryColor: "teal",
1197
- primaryShade: 6,
1198
- customTheme: {}
1199
- }));
1200
- function DirkProvider(props) {
1201
- const primaryColor = useSettings((data) => data.primaryColor);
1202
- const primaryShade = useSettings((data) => data.primaryShade);
1203
- const customTheme = useSettings((data) => data.customTheme);
1204
- const game = useSettings((data) => data.game);
1205
- const mergedTheme = react.useMemo(() => ({
1206
- ...theme_default,
1207
- primaryColor,
1208
- primaryShade,
1209
- colors: {
1210
- ...theme_default.colors,
1211
- ...customTheme
1212
- // Custom theme colors will override/extend base colors
1213
- }
1214
- }), [primaryColor, primaryShade, customTheme]);
1215
- react.useEffect(() => {
1216
- document.fonts.ready.then(() => {
1217
- document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : game === "fivem" ? '"Akrobat Regular", sans-serif' : "sans-serif";
1218
- console.log(`Game set to ${game}, applied corresponding font family.: ${document.body.style.fontFamily}`);
1219
- });
1220
- }, [game]);
1221
- return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { children: props.children }) });
1222
- }
1223
- function Wrapper({ children }) {
1224
- const game = useSettings((data) => data.game);
1225
- return isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
1226
- core.BackgroundImage,
1227
- {
1228
- w: "100vw",
1229
- h: "100vh",
1230
- style: { overflow: "hidden" },
1231
- src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
1232
- children
1233
- }
1234
- ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
1235
- }
1236
1302
 
1237
1303
  exports.BorderedIcon = BorderedIcon;
1238
1304
  exports.Counter = Counter;
@@ -1251,6 +1317,7 @@ exports.Segment = Segment;
1251
1317
  exports.SegmentedControl = SegmentedControl;
1252
1318
  exports.SegmentedProgress = SegmentedProgress;
1253
1319
  exports.Title = Title;
1320
+ exports.TornEdgeSVGFilter = TornEdgeSVGFilter;
1254
1321
  exports.colorWithAlpha = colorWithAlpha;
1255
1322
  exports.copyToClipboard = copyToClipboard;
1256
1323
  exports.fetchLuaTable = fetchLuaTable;
@@ -1268,5 +1335,6 @@ exports.useNavigation = useNavigation;
1268
1335
  exports.useNavigationStore = useNavigationStore;
1269
1336
  exports.useNuiEvent = useNuiEvent;
1270
1337
  exports.useSettings = useSettings;
1338
+ exports.useTornEdges = useTornEdges;
1271
1339
  //# sourceMappingURL=index.cjs.map
1272
1340
  //# sourceMappingURL=index.cjs.map