dirk-cfx-react 1.1.70 → 1.1.71

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.
@@ -852,6 +852,26 @@ type PositionPickerProps = {
852
852
  showHeading?: boolean;
853
853
  };
854
854
  declare function PositionPicker(props: PositionPickerProps): react_jsx_runtime.JSX.Element;
855
+ /** Read-only `vector4(x, y, z, w)` line in the same boxed style as PositionPicker. */
856
+ declare function Vector4Display({ value }: {
857
+ value: Vector4Value;
858
+ }): react_jsx_runtime.JSX.Element;
859
+ /** Grabs the player's current world coords+heading via `GET_POSITION`. */
860
+ declare function WorldPositionSetButton({ value, onChange, compact, }: {
861
+ value: Vector4Value;
862
+ onChange: (v: Vector4Value) => void;
863
+ compact?: boolean;
864
+ }): react_jsx_runtime.JSX.Element;
865
+ /** Teleports the player to the stored coords via `GOTO_POSITION`. */
866
+ declare function WorldPositionGotoButton({ value, compact, }: {
867
+ value: Vector4Value;
868
+ compact?: boolean;
869
+ }): react_jsx_runtime.JSX.Element;
870
+ /** Red-tinted Delete button matching the Set/Goto styling. */
871
+ declare function Vector4DeleteButton({ onClick, compact, }: {
872
+ onClick: () => void;
873
+ compact?: boolean;
874
+ }): react_jsx_runtime.JSX.Element;
855
875
 
856
876
  type GroupValue = {
857
877
  name?: string;
@@ -956,4 +976,4 @@ interface TestBedProps {
956
976
  }
957
977
  declare function TestBed({ items, storageKey, disablePersistence, title, }: TestBedProps): react_jsx_runtime.JSX.Element | null;
958
978
 
959
- export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, type Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore };
979
+ export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, Vector4DeleteButton, Vector4Display, type Vector4Value, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
@@ -852,6 +852,26 @@ type PositionPickerProps = {
852
852
  showHeading?: boolean;
853
853
  };
854
854
  declare function PositionPicker(props: PositionPickerProps): react_jsx_runtime.JSX.Element;
855
+ /** Read-only `vector4(x, y, z, w)` line in the same boxed style as PositionPicker. */
856
+ declare function Vector4Display({ value }: {
857
+ value: Vector4Value;
858
+ }): react_jsx_runtime.JSX.Element;
859
+ /** Grabs the player's current world coords+heading via `GET_POSITION`. */
860
+ declare function WorldPositionSetButton({ value, onChange, compact, }: {
861
+ value: Vector4Value;
862
+ onChange: (v: Vector4Value) => void;
863
+ compact?: boolean;
864
+ }): react_jsx_runtime.JSX.Element;
865
+ /** Teleports the player to the stored coords via `GOTO_POSITION`. */
866
+ declare function WorldPositionGotoButton({ value, compact, }: {
867
+ value: Vector4Value;
868
+ compact?: boolean;
869
+ }): react_jsx_runtime.JSX.Element;
870
+ /** Red-tinted Delete button matching the Set/Goto styling. */
871
+ declare function Vector4DeleteButton({ onClick, compact, }: {
872
+ onClick: () => void;
873
+ compact?: boolean;
874
+ }): react_jsx_runtime.JSX.Element;
855
875
 
856
876
  type GroupValue = {
857
877
  name?: string;
@@ -956,4 +976,4 @@ interface TestBedProps {
956
976
  }
957
977
  declare function TestBed({ items, storageKey, disablePersistence, title, }: TestBedProps): react_jsx_runtime.JSX.Element | null;
958
978
 
959
- export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, type Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore };
979
+ export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, Vector4DeleteButton, Vector4Display, type Vector4Value, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
@@ -7,6 +7,7 @@ import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
7
7
  import { Info, X, AlertTriangle, Trash2, MapPin, Crosshair, EyeOff, Eye, RotateCcw, Check, FlaskConical, ChevronUp, ChevronDown, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
8
8
  import clickSoundUrl from '../click_sound-PNCRRTM4.mp3';
9
9
  import hoverSoundUrl from '../hover_sound-NBUA222C.mp3';
10
+ import { notifications } from '@mantine/notifications';
10
11
  import { QueryClient, QueryClientProvider, useInfiniteQuery } from '@tanstack/react-query';
11
12
 
12
13
  // src/components/BlipSelect.tsx
@@ -4075,12 +4076,25 @@ function ConfigPanel(props) {
4075
4076
  if (result?.success) {
4076
4077
  form.reinitialize(cloneConfig(form.values));
4077
4078
  configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
4079
+ notifications.show({
4080
+ color: "green",
4081
+ title: locale("ConfigSaveSuccessTitle"),
4082
+ message: locale("ConfigSaveSuccessBody"),
4083
+ autoClose: 3e3
4084
+ });
4078
4085
  return;
4079
4086
  }
4080
4087
  form.reinitialize(cloneConfig(store.getState()));
4081
- if (result?._error) {
4082
- console.warn(`[ConfigPanel] config save failed: ${result._error}`);
4083
- }
4088
+ const err = result?._error || "Unknown";
4089
+ console.warn(`[ConfigPanel] config save failed: ${err}`);
4090
+ const titleKey = err === "NoPermission" ? "ConfigSaveNoPermissionTitle" : err === "VersionConflict" ? "ConfigSaveVersionConflictTitle" : err === "NotReady" ? "ConfigSaveNotReadyTitle" : "ConfigSaveFailedTitle";
4091
+ const bodyKey = err === "NoPermission" ? "ConfigSaveNoPermissionBody" : err === "VersionConflict" ? "ConfigSaveVersionConflictBody" : err === "NotReady" ? "ConfigSaveNotReadyBody" : "ConfigSaveFailedBody";
4092
+ notifications.show({
4093
+ color: "red",
4094
+ title: locale(titleKey),
4095
+ message: locale(bodyKey, err),
4096
+ autoClose: 6e3
4097
+ });
4084
4098
  } finally {
4085
4099
  setIsSaving(false);
4086
4100
  }
@@ -4381,6 +4395,148 @@ function PickerButton({
4381
4395
  }
4382
4396
  ) });
4383
4397
  }
4398
+ function fmtV4(n) {
4399
+ return Number.isFinite(n) ? n.toFixed(2) : "0.00";
4400
+ }
4401
+ function Vector4Display({ value }) {
4402
+ const theme = useMantineTheme();
4403
+ return /* @__PURE__ */ jsx(
4404
+ Flex,
4405
+ {
4406
+ align: "center",
4407
+ gap: "xs",
4408
+ p: "xs",
4409
+ style: {
4410
+ background: alpha(theme.colors.dark[5], 0.35),
4411
+ border: "0.1vh solid rgba(255,255,255,0.05)",
4412
+ borderRadius: theme.radius.xs
4413
+ },
4414
+ children: /* @__PURE__ */ jsxs(
4415
+ Text,
4416
+ {
4417
+ ff: "monospace",
4418
+ size: "xxs",
4419
+ c: "rgba(255,255,255,0.85)",
4420
+ style: { flex: 1, letterSpacing: "0.02em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
4421
+ children: [
4422
+ "vector4(",
4423
+ fmtV4(value.x),
4424
+ ", ",
4425
+ fmtV4(value.y),
4426
+ ", ",
4427
+ fmtV4(value.z),
4428
+ ", ",
4429
+ fmtV4(value.w),
4430
+ ")"
4431
+ ]
4432
+ }
4433
+ )
4434
+ }
4435
+ );
4436
+ }
4437
+ function Vector4ActionButton({
4438
+ icon,
4439
+ label,
4440
+ tooltip,
4441
+ onClick,
4442
+ color,
4443
+ compact
4444
+ }) {
4445
+ const theme = useMantineTheme();
4446
+ return /* @__PURE__ */ jsx(Tooltip, { label: tooltip, position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxs(
4447
+ motion.button,
4448
+ {
4449
+ onClick,
4450
+ whileHover: { background: alpha(color, 0.18) },
4451
+ whileTap: { scale: 0.95 },
4452
+ style: {
4453
+ background: alpha(color, 0.1),
4454
+ border: `0.1vh solid ${alpha(color, 0.35)}`,
4455
+ borderRadius: theme.radius.xs,
4456
+ padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
4457
+ cursor: "pointer",
4458
+ display: "flex",
4459
+ alignItems: "center",
4460
+ gap: compact ? "0.3vh" : "0.4vh"
4461
+ },
4462
+ children: [
4463
+ icon,
4464
+ /* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: label })
4465
+ ]
4466
+ }
4467
+ ) });
4468
+ }
4469
+ function WorldPositionSetButton({
4470
+ value,
4471
+ onChange,
4472
+ compact
4473
+ }) {
4474
+ const theme = useMantineTheme();
4475
+ const color = theme.colors[theme.primaryColor][5];
4476
+ const grab = async () => {
4477
+ try {
4478
+ const resp = await fetchNui("GET_POSITION", {}, value);
4479
+ if (!resp || typeof resp !== "object") return;
4480
+ onChange({
4481
+ x: Number(resp.x ?? 0),
4482
+ y: Number(resp.y ?? 0),
4483
+ z: Number(resp.z ?? 0),
4484
+ w: Number(resp.w ?? 0)
4485
+ });
4486
+ } catch {
4487
+ }
4488
+ };
4489
+ return /* @__PURE__ */ jsx(
4490
+ Vector4ActionButton,
4491
+ {
4492
+ icon: /* @__PURE__ */ jsx(Crosshair, { size: compact ? "1.1vh" : "1.3vh", color }),
4493
+ label: locale("Set"),
4494
+ tooltip: locale("SetWorldTooltip"),
4495
+ onClick: grab,
4496
+ color,
4497
+ compact
4498
+ }
4499
+ );
4500
+ }
4501
+ function WorldPositionGotoButton({
4502
+ value,
4503
+ compact
4504
+ }) {
4505
+ const theme = useMantineTheme();
4506
+ const color = theme.colors[theme.primaryColor][5];
4507
+ const goto = () => {
4508
+ fetchNui("GOTO_POSITION", value).catch(() => {
4509
+ });
4510
+ };
4511
+ return /* @__PURE__ */ jsx(
4512
+ Vector4ActionButton,
4513
+ {
4514
+ icon: /* @__PURE__ */ jsx(MapPin, { size: compact ? "1.1vh" : "1.3vh", color }),
4515
+ label: locale("Goto"),
4516
+ tooltip: locale("GotoWorldTooltip"),
4517
+ onClick: goto,
4518
+ color,
4519
+ compact
4520
+ }
4521
+ );
4522
+ }
4523
+ function Vector4DeleteButton({
4524
+ onClick,
4525
+ compact
4526
+ }) {
4527
+ const color = "#ef4444";
4528
+ return /* @__PURE__ */ jsx(
4529
+ Vector4ActionButton,
4530
+ {
4531
+ icon: /* @__PURE__ */ jsx(Trash2, { size: compact ? "1.1vh" : "1.3vh", color }),
4532
+ label: locale("Delete"),
4533
+ tooltip: locale("Delete"),
4534
+ onClick,
4535
+ color,
4536
+ compact
4537
+ }
4538
+ );
4539
+ }
4384
4540
  var GroupSelectContext = createContext(null);
4385
4541
  function GroupSelect({
4386
4542
  value,
@@ -4832,6 +4988,6 @@ function TestBed({
4832
4988
  );
4833
4989
  }
4834
4990
 
4835
- export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, useModal, useModalActions, useNavigation, useNavigationStore };
4991
+ export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
4836
4992
  //# sourceMappingURL=index.js.map
4837
4993
  //# sourceMappingURL=index.js.map