@rpg-engine/long-bow 0.8.27 → 0.8.28
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/long-bow.cjs.development.js +35 -62
- 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 +35 -62
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/InformationCenter/InformationCenter.tsx +5 -19
- package/src/components/InformationCenter/sections/bestiary/InformationCenterBestiarySection.tsx +26 -28
- package/src/components/InformationCenter/sections/items/InformationCenterItemsSection.tsx +26 -21
- package/src/components/InformationCenter/shared/BaseInformationDetails.tsx +17 -6
package/package.json
CHANGED
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
} from '@rpg-engine/shared';
|
|
10
10
|
import { DraggableContainer } from '../DraggableContainer';
|
|
11
11
|
import { InternalTabs } from '../InternalTabs/InternalTabs';
|
|
12
|
+
import { RPGUIContainerTypes } from '../RPGUI/RPGUIContainer';
|
|
12
13
|
import { InformationCenterBestiarySection } from './sections/bestiary/InformationCenterBestiarySection';
|
|
13
14
|
import { InformationCenterFAQSection } from './sections/faq/InformationCenterFaqSection';
|
|
14
|
-
import { InformationCenterItemDetails } from './sections/items/InformationCenterItemDetails';
|
|
15
15
|
import { InformationCenterItemsSection } from './sections/items/InformationCenterItemsSection';
|
|
16
16
|
import { InformationCenterTutorialsSection } from './sections/tutorials/InformationCenterTutorialsSection';
|
|
17
17
|
|
|
@@ -47,10 +47,6 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
|
47
47
|
initialSearchQuery = '',
|
|
48
48
|
}) => {
|
|
49
49
|
const [activeTab, setActiveTab] = useState('bestiary');
|
|
50
|
-
const [
|
|
51
|
-
selectedItem,
|
|
52
|
-
setSelectedItem,
|
|
53
|
-
] = useState<IInformationCenterItem | null>(null);
|
|
54
50
|
|
|
55
51
|
if (loading) {
|
|
56
52
|
return <LoadingMessage>Loading...</LoadingMessage>;
|
|
@@ -117,7 +113,10 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
|
117
113
|
];
|
|
118
114
|
|
|
119
115
|
return (
|
|
120
|
-
<DraggableContainer
|
|
116
|
+
<DraggableContainer
|
|
117
|
+
title="Information Center"
|
|
118
|
+
type={RPGUIContainerTypes.Framed}
|
|
119
|
+
>
|
|
121
120
|
<Container>
|
|
122
121
|
<InternalTabs
|
|
123
122
|
tabs={tabs}
|
|
@@ -129,19 +128,6 @@ export const InformationCenter: React.FC<IInformationCenterProps> = ({
|
|
|
129
128
|
borderColor="#f59e0b"
|
|
130
129
|
hoverColor="#fef3c7"
|
|
131
130
|
/>
|
|
132
|
-
{selectedItem && (
|
|
133
|
-
<InformationCenterItemDetails
|
|
134
|
-
item={selectedItem}
|
|
135
|
-
itemsAtlasJSON={itemsAtlasJSON}
|
|
136
|
-
itemsAtlasIMG={itemsAtlasIMG}
|
|
137
|
-
droppedBy={bestiaryItems.filter(npc =>
|
|
138
|
-
npc.loots?.some(
|
|
139
|
-
loot => loot.itemBlueprintKey === selectedItem.key
|
|
140
|
-
)
|
|
141
|
-
)}
|
|
142
|
-
onBack={() => setSelectedItem(null)}
|
|
143
|
-
/>
|
|
144
|
-
)}
|
|
145
131
|
</Container>
|
|
146
132
|
</DraggableContainer>
|
|
147
133
|
);
|
package/src/components/InformationCenter/sections/bestiary/InformationCenterBestiarySection.tsx
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IInformationCenterNPC,
|
|
3
|
+
NPCAlignment,
|
|
4
|
+
isMobileOrTablet,
|
|
5
|
+
} from '@rpg-engine/shared';
|
|
2
6
|
import React, { useMemo, useState } from 'react';
|
|
3
7
|
import styled from 'styled-components';
|
|
4
8
|
import { IOptionsProps } from '../../../Dropdown';
|
|
@@ -8,6 +12,7 @@ import { InformationCenterCell } from '../../InformationCenterCell';
|
|
|
8
12
|
import { formatItemType } from '../items/InformationCenterItemsSection';
|
|
9
13
|
import { InformationCenterNPCDetails } from './InformationCenterNPCDetails';
|
|
10
14
|
import { InformationCenterNPCTooltip } from './InformationCenterNPCTooltip';
|
|
15
|
+
|
|
11
16
|
interface IBestiarySectionProps {
|
|
12
17
|
bestiaryItems: IInformationCenterNPC[];
|
|
13
18
|
itemsAtlasJSON: Record<string, any>;
|
|
@@ -31,6 +36,7 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
31
36
|
initialSearchQuery,
|
|
32
37
|
tabId,
|
|
33
38
|
}) => {
|
|
39
|
+
const isMobile = isMobileOrTablet();
|
|
34
40
|
const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
|
|
35
41
|
const [tooltipData, setTooltipData] = useState<{
|
|
36
42
|
npc: IInformationCenterNPC;
|
|
@@ -40,13 +46,12 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
40
46
|
selectedMonster,
|
|
41
47
|
setSelectedMonster,
|
|
42
48
|
] = useState<IInformationCenterNPC | null>(null);
|
|
43
|
-
const [isTouchDevice] = useState('ontouchstart' in window);
|
|
44
49
|
|
|
45
50
|
const handleMouseEnter = (
|
|
46
51
|
monster: IInformationCenterNPC,
|
|
47
52
|
event: React.MouseEvent
|
|
48
53
|
) => {
|
|
49
|
-
if (!
|
|
54
|
+
if (!isMobile && !selectedMonster) {
|
|
50
55
|
setTooltipData({
|
|
51
56
|
npc: monster,
|
|
52
57
|
position: { x: event.clientX, y: event.clientY },
|
|
@@ -55,13 +60,13 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
const handleMouseLeave = () => {
|
|
58
|
-
if (!
|
|
63
|
+
if (!isMobile) {
|
|
59
64
|
setTooltipData(null);
|
|
60
65
|
}
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
const handleMouseMove = (event: React.MouseEvent) => {
|
|
64
|
-
if (!
|
|
69
|
+
if (!isMobile && tooltipData) {
|
|
65
70
|
setTooltipData({
|
|
66
71
|
...tooltipData,
|
|
67
72
|
position: { x: event.clientX, y: event.clientY },
|
|
@@ -73,18 +78,9 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
73
78
|
monster: IInformationCenterNPC,
|
|
74
79
|
event: React.TouchEvent
|
|
75
80
|
) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (tooltipData?.npc.id === monster.id) {
|
|
80
|
-
setTooltipData(null);
|
|
81
|
-
} else {
|
|
82
|
-
setTooltipData({
|
|
83
|
-
npc: monster,
|
|
84
|
-
position: { x: touch.clientX, y: touch.clientY },
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
setSelectedMonster(monster);
|
|
83
|
+
setTooltipData(null);
|
|
88
84
|
};
|
|
89
85
|
|
|
90
86
|
const handleMonsterClick = (monster: IInformationCenterNPC) => {
|
|
@@ -170,7 +166,7 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
170
166
|
dependencies={[selectedBestiaryCategory]}
|
|
171
167
|
itemHeight="180px"
|
|
172
168
|
/>
|
|
173
|
-
{tooltipData && (
|
|
169
|
+
{!isMobile && tooltipData && (
|
|
174
170
|
<Portal>
|
|
175
171
|
<TooltipWrapper
|
|
176
172
|
style={{
|
|
@@ -188,16 +184,18 @@ export const InformationCenterBestiarySection: React.FC<IBestiarySectionProps> =
|
|
|
188
184
|
</Portal>
|
|
189
185
|
)}
|
|
190
186
|
{selectedMonster && (
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
187
|
+
<Portal>
|
|
188
|
+
<InformationCenterNPCDetails
|
|
189
|
+
npc={selectedMonster}
|
|
190
|
+
itemsAtlasJSON={itemsAtlasJSON}
|
|
191
|
+
itemsAtlasIMG={itemsAtlasIMG}
|
|
192
|
+
iconAtlasIMG={iconsAtlasIMG}
|
|
193
|
+
iconAtlasJSON={iconsAtlasJSON}
|
|
194
|
+
entitiesAtlasJSON={entitiesAtlasJSON}
|
|
195
|
+
entitiesAtlasIMG={entitiesAtlasIMG}
|
|
196
|
+
onBack={() => setSelectedMonster(null)}
|
|
197
|
+
/>
|
|
198
|
+
</Portal>
|
|
201
199
|
)}
|
|
202
200
|
</>
|
|
203
201
|
);
|
|
@@ -2,11 +2,13 @@ import {
|
|
|
2
2
|
IInformationCenterItem,
|
|
3
3
|
IInformationCenterNPC,
|
|
4
4
|
ItemType,
|
|
5
|
+
isMobileOrTablet,
|
|
5
6
|
} from '@rpg-engine/shared';
|
|
6
7
|
import React, { useState } from 'react';
|
|
7
8
|
import styled from 'styled-components';
|
|
8
9
|
import { IOptionsProps } from '../../../Dropdown';
|
|
9
10
|
import { PaginatedContent } from '../../../shared/PaginatedContent/PaginatedContent';
|
|
11
|
+
import { Portal } from '../../../shared/Portal/Portal';
|
|
10
12
|
import { InformationCenterCell } from '../../InformationCenterCell';
|
|
11
13
|
import { InformationCenterItemDetails } from './InformationCenterItemDetails';
|
|
12
14
|
import { InformationCenterItemTooltip } from './InformationCenterItemTooltip';
|
|
@@ -47,6 +49,7 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
|
|
|
47
49
|
initialSearchQuery,
|
|
48
50
|
tabId,
|
|
49
51
|
}) => {
|
|
52
|
+
const isMobile = isMobileOrTablet();
|
|
50
53
|
const [searchQuery, setSearchQuery] = useState(initialSearchQuery);
|
|
51
54
|
const [selectedItemCategory, setSelectedItemCategory] = useState<string>(
|
|
52
55
|
'all'
|
|
@@ -90,15 +93,17 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
|
|
|
90
93
|
e: React.MouseEvent,
|
|
91
94
|
item: IInformationCenterItem
|
|
92
95
|
) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
if (!isMobile) {
|
|
97
|
+
setTooltipPosition({
|
|
98
|
+
x: e.clientX + TOOLTIP_OFFSET,
|
|
99
|
+
y: e.clientY,
|
|
100
|
+
});
|
|
101
|
+
setHoveredItem(item);
|
|
102
|
+
}
|
|
98
103
|
};
|
|
99
104
|
|
|
100
105
|
const handleMouseMove = (e: React.MouseEvent) => {
|
|
101
|
-
if (hoveredItem) {
|
|
106
|
+
if (!isMobile && hoveredItem) {
|
|
102
107
|
setTooltipPosition({
|
|
103
108
|
x: e.clientX + TOOLTIP_OFFSET,
|
|
104
109
|
y: e.clientY,
|
|
@@ -107,19 +112,17 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
|
|
|
107
112
|
};
|
|
108
113
|
|
|
109
114
|
const handleMouseLeave = () => {
|
|
110
|
-
|
|
115
|
+
if (!isMobile) {
|
|
116
|
+
setHoveredItem(null);
|
|
117
|
+
}
|
|
111
118
|
};
|
|
112
119
|
|
|
113
120
|
const handleTouchStart = (
|
|
114
121
|
e: React.TouchEvent,
|
|
115
122
|
item: IInformationCenterItem
|
|
116
123
|
) => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
x: touch.clientX + TOOLTIP_OFFSET,
|
|
120
|
-
y: touch.clientY,
|
|
121
|
-
});
|
|
122
|
-
setHoveredItem(item);
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
setSelectedItem(item);
|
|
123
126
|
};
|
|
124
127
|
|
|
125
128
|
const handleItemClick = (item: IInformationCenterItem) => {
|
|
@@ -170,7 +173,7 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
|
|
|
170
173
|
layout="grid"
|
|
171
174
|
itemHeight="180px"
|
|
172
175
|
/>
|
|
173
|
-
{hoveredItem && (
|
|
176
|
+
{!isMobile && hoveredItem && (
|
|
174
177
|
<TooltipWrapper
|
|
175
178
|
style={{ top: tooltipPosition.y, left: tooltipPosition.x }}
|
|
176
179
|
>
|
|
@@ -178,13 +181,15 @@ export const InformationCenterItemsSection: React.FC<IItemsSectionProps> = ({
|
|
|
178
181
|
</TooltipWrapper>
|
|
179
182
|
)}
|
|
180
183
|
{selectedItem && (
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
<Portal>
|
|
185
|
+
<InformationCenterItemDetails
|
|
186
|
+
item={selectedItem}
|
|
187
|
+
itemsAtlasJSON={itemsAtlasJSON}
|
|
188
|
+
itemsAtlasIMG={itemsAtlasIMG}
|
|
189
|
+
droppedBy={getDroppedByNPCs(selectedItem.key, bestiaryItems)}
|
|
190
|
+
onBack={() => setSelectedItem(null)}
|
|
191
|
+
/>
|
|
192
|
+
</Portal>
|
|
188
193
|
)}
|
|
189
194
|
</>
|
|
190
195
|
);
|
|
@@ -49,24 +49,29 @@ export const BaseInformationDetails: React.FC<IBaseInformationDetailsProps> = ({
|
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
const Container = styled.div`
|
|
52
|
-
position:
|
|
52
|
+
position: fixed;
|
|
53
53
|
inset: 0;
|
|
54
54
|
display: flex;
|
|
55
55
|
justify-content: center;
|
|
56
56
|
align-items: center;
|
|
57
|
-
z-index:
|
|
57
|
+
z-index: 9999;
|
|
58
58
|
`;
|
|
59
59
|
|
|
60
60
|
const Overlay = styled.div`
|
|
61
|
-
position:
|
|
61
|
+
position: fixed;
|
|
62
62
|
inset: 0;
|
|
63
63
|
background-color: rgba(0, 0, 0, 0.8);
|
|
64
64
|
`;
|
|
65
65
|
|
|
66
66
|
const Modal = styled.div`
|
|
67
|
-
position:
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
position: fixed;
|
|
68
|
+
top: 50%;
|
|
69
|
+
left: 50%;
|
|
70
|
+
transform: translate(-50%, -50%);
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
max-width: 90%;
|
|
74
|
+
max-height: 90%;
|
|
70
75
|
background-color: rgba(0, 0, 0, 0.95);
|
|
71
76
|
border-radius: 4px;
|
|
72
77
|
padding: 16px;
|
|
@@ -76,6 +81,12 @@ const Modal = styled.div`
|
|
|
76
81
|
border: 1px solid ${uiColors.darkGray};
|
|
77
82
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
78
83
|
|
|
84
|
+
@media (max-width: 768px) {
|
|
85
|
+
max-width: 100%;
|
|
86
|
+
max-height: 100%;
|
|
87
|
+
border-radius: 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
79
90
|
&::-webkit-scrollbar {
|
|
80
91
|
width: 2px;
|
|
81
92
|
}
|