@rpg-engine/long-bow 0.7.67 → 0.7.70
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/Item/Inventory/ItemSlot.d.ts +2 -4
- package/dist/components/Item/Inventory/ItemSlotTooltips.d.ts +2 -13
- package/dist/components/Item/Inventory/context/ItemSlotDraggingContext.d.ts +26 -0
- package/dist/components/Item/Inventory/context/ItemSlotTooltipContext.d.ts +28 -0
- package/dist/components/Item/Inventory/hooks/useItemSlotDragAndDrop.d.ts +2 -6
- package/dist/hooks/useCursorPosition.d.ts +1 -1
- package/dist/long-bow.cjs.development.js +465 -421
- package/dist/long-bow.cjs.development.js.map +1 -1
- package/dist/long-bow.cjs.production.min.js +1 -1
- package/dist/long-bow.cjs.production.min.js.map +1 -1
- package/dist/long-bow.esm.js +467 -423
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +3 -2
- package/src/components/Equipment/EquipmentSet.tsx +61 -29
- package/src/components/Item/Inventory/DraggedItem.tsx +2 -2
- package/src/components/Item/Inventory/ItemContainer.tsx +68 -44
- package/src/components/Item/Inventory/ItemSlot.tsx +48 -100
- package/src/components/Item/Inventory/ItemSlotTooltips.tsx +47 -49
- package/src/components/Item/Inventory/context/ItemSlotDraggingContext.tsx +52 -0
- package/src/components/Item/Inventory/context/ItemSlotTooltipContext.tsx +95 -0
- package/src/components/Item/Inventory/hooks/useItemSlotDragAndDrop.ts +57 -40
- package/src/hooks/useCursorPosition.ts +29 -20
- package/src/mocks/skills.mocks.ts +0 -4
- package/dist/components/Item/Inventory/context/DraggingContext.d.ts +0 -11
- package/src/components/Item/Inventory/context/DraggingContext.tsx +0 -26
|
@@ -3,51 +3,62 @@ import React from 'react';
|
|
|
3
3
|
import { RelativeListMenu } from '../../RelativeListMenu';
|
|
4
4
|
import { ItemTooltip } from '../Cards/ItemTooltip';
|
|
5
5
|
import { MobileItemTooltip } from '../Cards/MobileItemTooltip';
|
|
6
|
-
import {
|
|
7
|
-
import type { ContextMenuState, TooltipState } from './ItemSlot';
|
|
6
|
+
import { useItemSlotTooltip } from './context/ItemSlotTooltipContext';
|
|
8
7
|
|
|
9
8
|
interface IProps {
|
|
10
|
-
tooltipState: TooltipState;
|
|
11
|
-
setTooltipState: React.Dispatch<React.SetStateAction<TooltipState>>;
|
|
12
|
-
contextMenuState: ContextMenuState;
|
|
13
|
-
setContextMenuState: React.Dispatch<React.SetStateAction<ContextMenuState>>;
|
|
14
9
|
isFocused: boolean;
|
|
15
10
|
isContextMenuDisabled: boolean;
|
|
16
|
-
|
|
17
|
-
contextActions: IContextMenuItem[];
|
|
11
|
+
|
|
18
12
|
dragScale: number | undefined;
|
|
19
13
|
onSelected?: (optionId: string, item: IItem) => void;
|
|
20
14
|
atlasIMG: any;
|
|
21
15
|
atlasJSON: any;
|
|
22
16
|
equipmentSet?: IEquipmentSet | null;
|
|
23
|
-
isDragging: boolean;
|
|
24
|
-
isSelectingShortcut: boolean;
|
|
25
|
-
showTooltipDelayed: boolean;
|
|
26
17
|
}
|
|
27
18
|
|
|
28
19
|
export const ItemSlotToolTips = ({
|
|
29
|
-
tooltipState,
|
|
30
|
-
setTooltipState,
|
|
31
|
-
contextMenuState,
|
|
32
|
-
setContextMenuState,
|
|
33
20
|
isFocused,
|
|
34
21
|
isContextMenuDisabled,
|
|
35
|
-
|
|
36
|
-
contextActions,
|
|
22
|
+
|
|
37
23
|
dragScale,
|
|
38
24
|
onSelected,
|
|
39
25
|
atlasIMG,
|
|
40
26
|
atlasJSON,
|
|
41
27
|
equipmentSet,
|
|
42
|
-
isDragging,
|
|
43
|
-
isSelectingShortcut,
|
|
44
|
-
showTooltipDelayed,
|
|
45
28
|
}: IProps): JSX.Element => {
|
|
46
|
-
|
|
29
|
+
const { itemDetails, updateItemDetails } = useItemSlotTooltip();
|
|
30
|
+
|
|
31
|
+
const item = itemDetails.item;
|
|
32
|
+
|
|
33
|
+
const handleCloseTooltip = () => {
|
|
34
|
+
updateItemDetails({
|
|
35
|
+
item,
|
|
36
|
+
tooltip: { mobileVisible: false },
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleContextMenuSelect = (optionId: string) => {
|
|
41
|
+
updateItemDetails({
|
|
42
|
+
item,
|
|
43
|
+
contextMenu: { visible: false },
|
|
44
|
+
});
|
|
45
|
+
if (item) {
|
|
46
|
+
onSelected?.(optionId, item);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const handleOutsideClick = () => {
|
|
51
|
+
updateItemDetails({
|
|
52
|
+
item,
|
|
53
|
+
contextMenu: { visible: false },
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// monitor why mobileVisible is not working
|
|
47
58
|
|
|
48
59
|
return (
|
|
49
60
|
<>
|
|
50
|
-
{
|
|
61
|
+
{itemDetails.tooltip?.visible && item && !isFocused && (
|
|
51
62
|
<ItemTooltip
|
|
52
63
|
item={item}
|
|
53
64
|
atlasIMG={atlasIMG}
|
|
@@ -56,42 +67,29 @@ export const ItemSlotToolTips = ({
|
|
|
56
67
|
/>
|
|
57
68
|
)}
|
|
58
69
|
|
|
59
|
-
{
|
|
70
|
+
{itemDetails.tooltip?.mobileVisible && item && (
|
|
60
71
|
<MobileItemTooltip
|
|
61
72
|
item={item}
|
|
62
73
|
atlasIMG={atlasIMG}
|
|
63
74
|
atlasJSON={atlasJSON}
|
|
64
75
|
equipmentSet={equipmentSet}
|
|
65
|
-
closeTooltip={
|
|
66
|
-
setTooltipState(prev => ({ ...prev, mobileVisible: false }));
|
|
67
|
-
}}
|
|
76
|
+
closeTooltip={handleCloseTooltip}
|
|
68
77
|
scale={dragScale}
|
|
69
|
-
options={
|
|
70
|
-
onSelected={
|
|
71
|
-
setContextMenuState(prev => ({ ...prev, visible: false }));
|
|
72
|
-
if (item) {
|
|
73
|
-
onSelected?.(optionId, item);
|
|
74
|
-
}
|
|
75
|
-
}}
|
|
78
|
+
options={itemDetails.contextMenu?.actions || []}
|
|
79
|
+
onSelected={handleContextMenuSelect}
|
|
76
80
|
/>
|
|
77
81
|
)}
|
|
78
82
|
|
|
79
|
-
{!isContextMenuDisabled &&
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
onOutsideClick={() => {
|
|
90
|
-
setContextMenuState(prev => ({ ...prev, visible: false }));
|
|
91
|
-
}}
|
|
92
|
-
pos={contextMenuState.position}
|
|
93
|
-
/>
|
|
94
|
-
)}
|
|
83
|
+
{!isContextMenuDisabled &&
|
|
84
|
+
itemDetails.contextMenu?.visible &&
|
|
85
|
+
itemDetails.contextMenu.actions && (
|
|
86
|
+
<RelativeListMenu
|
|
87
|
+
options={itemDetails.contextMenu.actions}
|
|
88
|
+
onSelected={handleContextMenuSelect}
|
|
89
|
+
onOutsideClick={handleOutsideClick}
|
|
90
|
+
pos={itemDetails.contextMenu.position!}
|
|
91
|
+
/>
|
|
92
|
+
)}
|
|
95
93
|
</>
|
|
96
94
|
);
|
|
97
95
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IItem } from '@rpg-engine/shared';
|
|
2
|
+
import React, { createContext, useContext, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
export interface IDragState {
|
|
5
|
+
isFocused: boolean;
|
|
6
|
+
wasDragged: boolean;
|
|
7
|
+
position: { x: number; y: number };
|
|
8
|
+
dropPosition: { x: number; y: number } | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface IDraggingContextType {
|
|
12
|
+
item: IItem | null;
|
|
13
|
+
setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
|
|
14
|
+
dragState: IDragState;
|
|
15
|
+
setDragState: React.Dispatch<React.SetStateAction<IDragState>>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ItemSlotDraggingContext = createContext<IDraggingContextType>({
|
|
19
|
+
item: null,
|
|
20
|
+
setDraggingItem: () => {},
|
|
21
|
+
dragState: {
|
|
22
|
+
isFocused: false,
|
|
23
|
+
wasDragged: false,
|
|
24
|
+
position: { x: 0, y: 0 },
|
|
25
|
+
dropPosition: null,
|
|
26
|
+
},
|
|
27
|
+
setDragState: () => {},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
interface IProps {
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const ItemSlotDraggingProvider = ({ children }: IProps) => {
|
|
35
|
+
const [item, setDraggingItem] = useState<IItem | null>(null);
|
|
36
|
+
const [dragState, setDragState] = useState<IDragState>({
|
|
37
|
+
isFocused: false,
|
|
38
|
+
wasDragged: false,
|
|
39
|
+
position: { x: 0, y: 0 },
|
|
40
|
+
dropPosition: null,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<ItemSlotDraggingContext.Provider
|
|
45
|
+
value={{ item, setDraggingItem, dragState, setDragState }}
|
|
46
|
+
>
|
|
47
|
+
{children}
|
|
48
|
+
</ItemSlotDraggingContext.Provider>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const useItemSlotDragging = () => useContext(ItemSlotDraggingContext);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { IItem } from '@rpg-engine/shared';
|
|
2
|
+
import React, {
|
|
3
|
+
createContext,
|
|
4
|
+
FC,
|
|
5
|
+
ReactNode,
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useState,
|
|
10
|
+
} from 'react';
|
|
11
|
+
import { IPosition } from '../../../../types/eventTypes';
|
|
12
|
+
import { IContextMenuItem } from '../itemContainerHelper';
|
|
13
|
+
|
|
14
|
+
// Define smaller, focused interfaces for better readability
|
|
15
|
+
interface TooltipState {
|
|
16
|
+
visible?: boolean;
|
|
17
|
+
mobileVisible?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ContextMenuState {
|
|
21
|
+
visible?: boolean;
|
|
22
|
+
position?: IPosition;
|
|
23
|
+
actions?: IContextMenuItem[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ItemDetails {
|
|
27
|
+
item?: IItem | null;
|
|
28
|
+
tooltip?: TooltipState;
|
|
29
|
+
contextMenu?: ContextMenuState;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface ItemSlotTooltipContextProps {
|
|
33
|
+
itemDetails: ItemDetails;
|
|
34
|
+
updateItemDetails: (updates: Partial<ItemDetails>) => void;
|
|
35
|
+
clearItemDetails: () => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Set default state with clearly defined initial values
|
|
39
|
+
const defaultItemDetails: ItemDetails = {
|
|
40
|
+
item: null,
|
|
41
|
+
tooltip: { visible: false, mobileVisible: false },
|
|
42
|
+
contextMenu: { visible: false, position: { x: 0, y: 0 }, actions: [] },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Create context with default values
|
|
46
|
+
const ItemSlotTooltipContext = createContext<ItemSlotTooltipContextProps>({
|
|
47
|
+
itemDetails: defaultItemDetails,
|
|
48
|
+
updateItemDetails: () => {},
|
|
49
|
+
clearItemDetails: () => {},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Provider component
|
|
53
|
+
export const ItemSlotTooltipProvider: FC<{ children: ReactNode }> = ({
|
|
54
|
+
children,
|
|
55
|
+
}) => {
|
|
56
|
+
const [itemDetails, setItemDetails] = useState<ItemDetails>(
|
|
57
|
+
defaultItemDetails
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
console.log('itemDetails', itemDetails);
|
|
62
|
+
}, [itemDetails]);
|
|
63
|
+
|
|
64
|
+
// Memoize the update function to optimize performance
|
|
65
|
+
const updateItemDetails = useCallback((updates: Partial<ItemDetails>) => {
|
|
66
|
+
setItemDetails(prev => ({
|
|
67
|
+
...prev,
|
|
68
|
+
...updates,
|
|
69
|
+
tooltip: { ...prev.tooltip, ...updates.tooltip },
|
|
70
|
+
contextMenu: {
|
|
71
|
+
...prev.contextMenu,
|
|
72
|
+
...updates.contextMenu,
|
|
73
|
+
// Ensure actions are properly merged or overridden
|
|
74
|
+
actions: updates.contextMenu?.actions ?? prev.contextMenu?.actions,
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
const clearItemDetails = useCallback(() => {
|
|
80
|
+
setItemDetails(defaultItemDetails);
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<ItemSlotTooltipContext.Provider
|
|
85
|
+
value={{ itemDetails, updateItemDetails, clearItemDetails }}
|
|
86
|
+
>
|
|
87
|
+
{children}
|
|
88
|
+
</ItemSlotTooltipContext.Provider>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Custom hook for consuming the context
|
|
93
|
+
export const useItemSlotTooltip = (): ItemSlotTooltipContextProps => {
|
|
94
|
+
return useContext(ItemSlotTooltipContext);
|
|
95
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IItem, ItemContainerType, ItemType } from '@rpg-engine/shared';
|
|
2
|
-
import { useCallback, useEffect, useRef
|
|
2
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
3
3
|
import { DraggableEventHandler } from 'react-draggable';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { useItemSlotDragging } from '../context/ItemSlotDraggingContext';
|
|
5
|
+
import { useItemSlotTooltip } from '../context/ItemSlotTooltipContext';
|
|
6
6
|
|
|
7
7
|
interface IUseItemSlotDragAndDrop {
|
|
8
8
|
isDepotSystem: boolean;
|
|
@@ -30,9 +30,6 @@ interface IUseItemSlotDragAndDrop {
|
|
|
30
30
|
onSuccess: (quantity?: number) => void
|
|
31
31
|
) => void;
|
|
32
32
|
isContextMenuDisabled: boolean;
|
|
33
|
-
setTooltipState: React.Dispatch<React.SetStateAction<TooltipState>>;
|
|
34
|
-
setContextMenuState: React.Dispatch<React.SetStateAction<ContextMenuState>>;
|
|
35
|
-
contextMenuState: ContextMenuState;
|
|
36
33
|
}
|
|
37
34
|
|
|
38
35
|
export const useItemSlotDragAndDrop = ({
|
|
@@ -50,18 +47,16 @@ export const useItemSlotDragAndDrop = ({
|
|
|
50
47
|
slotIndex,
|
|
51
48
|
openQuantitySelector,
|
|
52
49
|
isContextMenuDisabled,
|
|
53
|
-
setTooltipState,
|
|
54
|
-
setContextMenuState,
|
|
55
50
|
}: IUseItemSlotDragAndDrop) => {
|
|
56
51
|
const dragContainer = useRef<HTMLDivElement>(null);
|
|
57
|
-
const {
|
|
52
|
+
const {
|
|
53
|
+
item: draggingItem,
|
|
54
|
+
setDraggingItem,
|
|
55
|
+
dragState,
|
|
56
|
+
setDragState,
|
|
57
|
+
} = useItemSlotDragging();
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
isFocused: false,
|
|
61
|
-
wasDragged: false,
|
|
62
|
-
position: { x: 0, y: 0 },
|
|
63
|
-
dropPosition: null,
|
|
64
|
-
});
|
|
59
|
+
const { updateItemDetails, itemDetails } = useItemSlotTooltip();
|
|
65
60
|
|
|
66
61
|
useEffect(() => {
|
|
67
62
|
setDragState(prev => ({
|
|
@@ -69,7 +64,7 @@ export const useItemSlotDragAndDrop = ({
|
|
|
69
64
|
position: { x: 0, y: 0 },
|
|
70
65
|
isFocused: false,
|
|
71
66
|
}));
|
|
72
|
-
}, [item, isDepotSystem]);
|
|
67
|
+
}, [item, isDepotSystem, setDragState]);
|
|
73
68
|
|
|
74
69
|
useEffect(() => {
|
|
75
70
|
if (onDrop && item && dragState.dropPosition) {
|
|
@@ -91,17 +86,24 @@ export const useItemSlotDragAndDrop = ({
|
|
|
91
86
|
}, []);
|
|
92
87
|
|
|
93
88
|
const resetDragState = useCallback(() => {
|
|
94
|
-
|
|
89
|
+
console.log('RESET_DRAG_STATE!');
|
|
95
90
|
setDragState(prev => ({
|
|
96
91
|
...prev,
|
|
97
92
|
wasDragged: false,
|
|
98
93
|
isFocused: false,
|
|
99
94
|
position: { x: 0, y: 0 },
|
|
100
95
|
}));
|
|
101
|
-
|
|
96
|
+
setDraggingItem(null);
|
|
97
|
+
|
|
98
|
+
// Reset tooltip visibility
|
|
99
|
+
updateItemDetails({
|
|
100
|
+
tooltip: { visible: false, mobileVisible: false },
|
|
101
|
+
});
|
|
102
|
+
}, [updateItemDetails, setDragState]);
|
|
102
103
|
|
|
103
104
|
const handleSuccessfulDrag = useCallback(
|
|
104
105
|
(quantity?: number) => {
|
|
106
|
+
console.log('HANDLE_SUCCESSFUL_DRAG!');
|
|
105
107
|
resetDragState();
|
|
106
108
|
if (quantity !== -1 && item) {
|
|
107
109
|
onDragEnd?.(quantity);
|
|
@@ -111,31 +113,35 @@ export const useItemSlotDragAndDrop = ({
|
|
|
111
113
|
);
|
|
112
114
|
|
|
113
115
|
const onDraggableStart: DraggableEventHandler = useCallback(() => {
|
|
116
|
+
console.log('ON_DRAGGABLE_START!');
|
|
114
117
|
if (!item || isSelectingShortcut) return;
|
|
115
118
|
if (onDragStart && containerType) {
|
|
116
119
|
onDragStart(item, slotIndex, containerType);
|
|
117
120
|
}
|
|
121
|
+
|
|
122
|
+
if (!draggingItem && item) {
|
|
123
|
+
console.log('!!! SETTING DRAGGING ITEM ', item._id);
|
|
124
|
+
setDraggingItem(item);
|
|
125
|
+
}
|
|
118
126
|
}, [item, isSelectingShortcut, onDragStart, containerType, slotIndex]);
|
|
119
127
|
|
|
120
128
|
const onDraggableProgress: DraggableEventHandler = useCallback(
|
|
121
129
|
(_e, data) => {
|
|
130
|
+
console.log('ON_DRAGGABLE_PROGRESS!');
|
|
122
131
|
const { x, y } = dragState.position;
|
|
123
132
|
if (Math.abs(data.x - x) > 5 || Math.abs(data.y - y) > 5) {
|
|
124
133
|
setDragState(prev => ({ ...prev, wasDragged: true, isFocused: true }));
|
|
125
134
|
}
|
|
126
|
-
if (!draggingItem) {
|
|
127
|
-
setDraggingItem(item);
|
|
128
|
-
}
|
|
129
135
|
},
|
|
130
|
-
[dragState.position, draggingItem, item, setDraggingItem]
|
|
136
|
+
[dragState.position, draggingItem, item, setDraggingItem, setDragState]
|
|
131
137
|
);
|
|
132
138
|
|
|
133
139
|
const onDraggableStop: DraggableEventHandler = useCallback(
|
|
134
140
|
(e, data) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}, 50);
|
|
141
|
+
console.log('ON_DRAGGABLE_STOP!');
|
|
142
|
+
|
|
138
143
|
const target = e.target as HTMLElement;
|
|
144
|
+
|
|
139
145
|
if (!target) return;
|
|
140
146
|
|
|
141
147
|
target.classList.remove('react-draggable-dragging');
|
|
@@ -178,26 +184,39 @@ export const useItemSlotDragAndDrop = ({
|
|
|
178
184
|
}, 50);
|
|
179
185
|
} else if (item) {
|
|
180
186
|
const isTouch = e.type === 'touchend';
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
isTouch
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
|
|
188
|
+
console.log(`Debug:
|
|
189
|
+
isTouch: ${isTouch},
|
|
190
|
+
isSelectingShortcut: ${isSelectingShortcut},
|
|
191
|
+
draggingItem: ${draggingItem},
|
|
192
|
+
dragginState: ${JSON.stringify(dragState)}
|
|
193
|
+
`);
|
|
194
|
+
|
|
195
|
+
if (!isContextMenuDisabled && isTouch && !isSelectingShortcut) {
|
|
196
|
+
updateItemDetails({
|
|
197
|
+
item,
|
|
198
|
+
tooltip: { mobileVisible: true },
|
|
199
|
+
});
|
|
188
200
|
} else if (!isContextMenuDisabled && !isSelectingShortcut && !isTouch) {
|
|
189
201
|
const event = e as MouseEvent;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
202
|
+
|
|
203
|
+
updateItemDetails({
|
|
204
|
+
item,
|
|
205
|
+
contextMenu: {
|
|
206
|
+
visible: !itemDetails?.contextMenu?.visible,
|
|
207
|
+
position: {
|
|
208
|
+
x: event.clientX - 10,
|
|
209
|
+
y: event.clientY - 5,
|
|
210
|
+
},
|
|
195
211
|
},
|
|
196
|
-
})
|
|
212
|
+
});
|
|
197
213
|
}
|
|
198
214
|
|
|
199
215
|
onPointerDown?.(item.type, containerType ?? null, item);
|
|
200
216
|
}
|
|
217
|
+
|
|
218
|
+
console.log('setting draggingItem to null');
|
|
219
|
+
setDraggingItem(null);
|
|
201
220
|
},
|
|
202
221
|
[
|
|
203
222
|
dragState.wasDragged,
|
|
@@ -209,8 +228,6 @@ export const useItemSlotDragAndDrop = ({
|
|
|
209
228
|
handleSuccessfulDrag,
|
|
210
229
|
resetDragState,
|
|
211
230
|
isContextMenuDisabled,
|
|
212
|
-
setTooltipState,
|
|
213
|
-
setContextMenuState,
|
|
214
231
|
onPointerDown,
|
|
215
232
|
containerType,
|
|
216
233
|
setItemShortcut,
|
|
@@ -6,37 +6,46 @@ interface ICursorPositionProps {
|
|
|
6
6
|
scale?: number;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export const useCursorPosition = ({
|
|
9
|
+
export const useCursorPosition = ({
|
|
10
|
+
scale = 1,
|
|
11
|
+
}: ICursorPositionProps): IPosition => {
|
|
10
12
|
const [position, setPosition] = useState<IPosition>({ x: 0, y: 0 });
|
|
11
13
|
|
|
12
|
-
const scalePosition = useCallback(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const scalePosition = useCallback(
|
|
15
|
+
(x: number, y: number): IPosition => {
|
|
16
|
+
return {
|
|
17
|
+
x: (x - GRID_WIDTH / 2) / scale + GRID_WIDTH / 2,
|
|
18
|
+
y: (y - GRID_HEIGHT / 2) / scale + GRID_HEIGHT / 2,
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
[scale]
|
|
22
|
+
);
|
|
18
23
|
|
|
19
|
-
const setFromEvent = useCallback(
|
|
20
|
-
|
|
24
|
+
const setFromEvent = useCallback(
|
|
25
|
+
(e: MouseEvent | TouchEvent) => {
|
|
26
|
+
let x, y;
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
if ('touches' in e) {
|
|
29
|
+
x = e.touches[0].clientX;
|
|
30
|
+
y = e.touches[0].clientY;
|
|
31
|
+
} else {
|
|
32
|
+
x = e.clientX;
|
|
33
|
+
y = e.clientY;
|
|
34
|
+
}
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
const scaledPosition = scalePosition(x, y);
|
|
37
|
+
setPosition(scaledPosition);
|
|
38
|
+
},
|
|
39
|
+
[scale, scalePosition]
|
|
40
|
+
);
|
|
33
41
|
|
|
34
42
|
const cleanup = useCallback(() => {
|
|
35
43
|
setPosition({ x: 0, y: 0 });
|
|
36
44
|
}, []);
|
|
37
45
|
|
|
38
46
|
useEffect(() => {
|
|
39
|
-
const handleEvent = (e: Event) =>
|
|
47
|
+
const handleEvent = (e: Event) =>
|
|
48
|
+
setFromEvent(e as MouseEvent | TouchEvent);
|
|
40
49
|
|
|
41
50
|
window.addEventListener('mousemove', handleEvent);
|
|
42
51
|
window.addEventListener('touchmove', handleEvent);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { IItem } from '@rpg-engine/shared';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
export declare const useDragging: () => {
|
|
4
|
-
item: IItem | null;
|
|
5
|
-
setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
|
|
6
|
-
};
|
|
7
|
-
interface IProps {
|
|
8
|
-
children: React.ReactNode;
|
|
9
|
-
}
|
|
10
|
-
export declare const DraggingProvider: ({ children }: IProps) => JSX.Element;
|
|
11
|
-
export {};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { IItem } from '@rpg-engine/shared';
|
|
2
|
-
import React, { createContext, useContext, useState } from 'react';
|
|
3
|
-
|
|
4
|
-
const DraggingContext = createContext<{
|
|
5
|
-
item: IItem | null;
|
|
6
|
-
setDraggingItem: React.Dispatch<React.SetStateAction<IItem | null>>;
|
|
7
|
-
}>({
|
|
8
|
-
item: null,
|
|
9
|
-
setDraggingItem: () => {},
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
export const useDragging = () => useContext(DraggingContext);
|
|
13
|
-
|
|
14
|
-
interface IProps {
|
|
15
|
-
children: React.ReactNode;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const DraggingProvider = ({ children }: IProps) => {
|
|
19
|
-
const [item, setDraggingItem] = useState<IItem | null>(null);
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<DraggingContext.Provider value={{ item, setDraggingItem }}>
|
|
23
|
-
{children}
|
|
24
|
-
</DraggingContext.Provider>
|
|
25
|
-
);
|
|
26
|
-
};
|