@rpg-engine/long-bow 0.8.207 → 0.8.208
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 +87 -35
- 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 +87 -35
- package/dist/long-bow.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Marketplace/CharacterDetailModal.tsx +185 -96
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpg-engine/long-bow",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.208",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"@capacitor/core": "^6.1.0",
|
|
86
86
|
"@rollup/plugin-image": "^2.1.1",
|
|
87
|
-
"@rpg-engine/shared": "^0.10.
|
|
87
|
+
"@rpg-engine/shared": "^0.10.115",
|
|
88
88
|
"dayjs": "^1.11.2",
|
|
89
89
|
"font-awesome": "^4.7.0",
|
|
90
90
|
"fs-extra": "^10.1.0",
|
|
@@ -5,6 +5,7 @@ import { FaTimes } from 'react-icons/fa';
|
|
|
5
5
|
import styled, { keyframes } from 'styled-components';
|
|
6
6
|
import ModalPortal from '../Abstractions/ModalPortal';
|
|
7
7
|
import { ConfirmModal } from '../ConfirmModal';
|
|
8
|
+
import { gemColors } from '../Item/Inventory/ItemGem';
|
|
8
9
|
import { CTAButton } from '../shared/CTAButton/CTAButton';
|
|
9
10
|
import { SpriteFromAtlas } from '../shared/SpriteFromAtlas';
|
|
10
11
|
|
|
@@ -34,6 +35,12 @@ const RARITY_COLORS: Record<string, string> = {
|
|
|
34
35
|
const rarityColor = (rarity?: string) =>
|
|
35
36
|
RARITY_COLORS[(rarity ?? '').toLowerCase()] ?? RARITY_COLORS.common;
|
|
36
37
|
|
|
38
|
+
const rarityGlowColor = (rarity?: string): string | null => {
|
|
39
|
+
const key = (rarity ?? '').toLowerCase();
|
|
40
|
+
if (!key || key === 'common') return null;
|
|
41
|
+
return RARITY_COLORS[key] ?? null;
|
|
42
|
+
};
|
|
43
|
+
|
|
37
44
|
const formatEquipmentSlot = (slot?: string) => {
|
|
38
45
|
if (!slot) return 'Unknown';
|
|
39
46
|
|
|
@@ -86,9 +93,9 @@ export const CharacterDetailModal: React.FC<ICharacterDetailModalProps> = ({
|
|
|
86
93
|
if (!isOpen || !listing) return null;
|
|
87
94
|
|
|
88
95
|
const snap = listing.characterSnapshot;
|
|
89
|
-
const topSkills = Object.entries(snap.skills ?? {})
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
const topSkills = Object.entries(snap.skills ?? {}).sort(
|
|
97
|
+
([, a], [, b]) => b - a
|
|
98
|
+
);
|
|
92
99
|
|
|
93
100
|
return (
|
|
94
101
|
<ModalPortal>
|
|
@@ -121,83 +128,101 @@ export const CharacterDetailModal: React.FC<ICharacterDetailModalProps> = ({
|
|
|
121
128
|
</CloseButton>
|
|
122
129
|
</Header>
|
|
123
130
|
|
|
124
|
-
<
|
|
125
|
-
<
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
{snap.mode
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
131
|
+
<ScrollableBody>
|
|
132
|
+
<HeroSection>
|
|
133
|
+
<SpriteContainer>
|
|
134
|
+
<SpriteFromAtlas
|
|
135
|
+
atlasIMG={characterAtlasIMG}
|
|
136
|
+
atlasJSON={characterAtlasJSON}
|
|
137
|
+
spriteKey={`${snap.textureKey}/down/standing/0.png`}
|
|
138
|
+
imgScale={4}
|
|
139
|
+
height={96}
|
|
140
|
+
width={96}
|
|
141
|
+
centered
|
|
142
|
+
/>
|
|
143
|
+
</SpriteContainer>
|
|
144
|
+
<HeroInfo>
|
|
145
|
+
<CharacterName>{snap.name || 'Unknown'}</CharacterName>
|
|
146
|
+
<CharacterClass>
|
|
147
|
+
Lv.{snap.level} · {snap.class}
|
|
148
|
+
</CharacterClass>
|
|
149
|
+
<CharacterOrigin>
|
|
150
|
+
{snap.race} · {snap.faction}
|
|
151
|
+
</CharacterOrigin>
|
|
152
|
+
<ModeBadge $hardcore={snap.mode?.toLowerCase() === 'hardcore'}>
|
|
153
|
+
{snap.mode || 'Standard'}
|
|
154
|
+
</ModeBadge>
|
|
155
|
+
{snap.gold != null && snap.gold > 0 && (
|
|
156
|
+
<GoldRow>
|
|
157
|
+
<GoldLabel>GOLD</GoldLabel>
|
|
158
|
+
<GoldAmount>{snap.gold.toLocaleString()}</GoldAmount>
|
|
159
|
+
</GoldRow>
|
|
160
|
+
)}
|
|
161
|
+
</HeroInfo>
|
|
162
|
+
</HeroSection>
|
|
163
|
+
|
|
164
|
+
<Divider />
|
|
165
|
+
|
|
166
|
+
<MetaColumns>
|
|
167
|
+
{topSkills.length > 0 && (
|
|
168
|
+
<Section>
|
|
169
|
+
<SectionTitle>Skills</SectionTitle>
|
|
170
|
+
<SkillsList>
|
|
171
|
+
{topSkills.map(([name, value]) => (
|
|
172
|
+
<SkillRow key={name}>
|
|
173
|
+
<SkillName>{name}</SkillName>
|
|
174
|
+
<SkillValue>{value}</SkillValue>
|
|
175
|
+
</SkillRow>
|
|
176
|
+
))}
|
|
177
|
+
</SkillsList>
|
|
178
|
+
</Section>
|
|
179
|
+
)}
|
|
180
|
+
|
|
181
|
+
{snap.equipment?.length > 0 && (
|
|
182
|
+
<Section>
|
|
183
|
+
<SectionTitle>Equipment</SectionTitle>
|
|
184
|
+
<EquipmentList>
|
|
185
|
+
{snap.equipment.map((eq, i) => (
|
|
186
|
+
<EquipmentRow key={i}>
|
|
187
|
+
<EquipmentSprite $rarity={eq.rarity}>
|
|
188
|
+
<SpriteFromAtlas
|
|
189
|
+
atlasIMG={atlasIMG}
|
|
190
|
+
atlasJSON={atlasJSON}
|
|
191
|
+
spriteKey={eq.itemKey}
|
|
192
|
+
imgScale={2}
|
|
193
|
+
width={32}
|
|
194
|
+
height={32}
|
|
195
|
+
centered
|
|
196
|
+
/>
|
|
197
|
+
{eq.attachedGems && eq.attachedGems.length > 0 && (
|
|
198
|
+
<GemRow>
|
|
199
|
+
{eq.attachedGems.map((gem, gi) => (
|
|
200
|
+
<GemDot
|
|
201
|
+
key={gi}
|
|
202
|
+
$color={gemColors[gem.key] ?? '#fff'}
|
|
203
|
+
/>
|
|
204
|
+
))}
|
|
205
|
+
</GemRow>
|
|
206
|
+
)}
|
|
207
|
+
</EquipmentSprite>
|
|
208
|
+
<EquipMeta>
|
|
209
|
+
<EquipName>{eq.itemName}</EquipName>
|
|
210
|
+
<EquipDetails>
|
|
211
|
+
<EquipSlot>{formatEquipmentSlot(eq.slot)}</EquipSlot>
|
|
212
|
+
<RarityBadge $rarity={eq.rarity}>
|
|
213
|
+
{eq.rarity || 'Common'}
|
|
214
|
+
</RarityBadge>
|
|
215
|
+
</EquipDetails>
|
|
216
|
+
</EquipMeta>
|
|
217
|
+
</EquipmentRow>
|
|
218
|
+
))}
|
|
219
|
+
</EquipmentList>
|
|
220
|
+
</Section>
|
|
221
|
+
)}
|
|
222
|
+
</MetaColumns>
|
|
223
|
+
</ScrollableBody>
|
|
224
|
+
|
|
225
|
+
<FooterDivider />
|
|
201
226
|
|
|
202
227
|
<Footer>
|
|
203
228
|
<SellerInfo>Listed by {listing.listedByCharacterName}</SellerInfo>
|
|
@@ -257,29 +282,16 @@ const ModalContent = styled.div`
|
|
|
257
282
|
background: #1a1a2e;
|
|
258
283
|
border: 2px solid #f59e0b;
|
|
259
284
|
border-radius: 8px;
|
|
260
|
-
padding: 20px 24px;
|
|
285
|
+
padding: 20px 24px 16px;
|
|
261
286
|
width: 580px;
|
|
262
287
|
max-width: 96%;
|
|
263
288
|
max-height: 85dvh;
|
|
264
289
|
display: flex;
|
|
265
290
|
flex-direction: column;
|
|
266
291
|
gap: 14px;
|
|
267
|
-
overflow
|
|
268
|
-
overflow-x: hidden;
|
|
292
|
+
overflow: hidden;
|
|
269
293
|
pointer-events: auto;
|
|
270
294
|
animation: ${scaleIn} 0.15s ease-out;
|
|
271
|
-
|
|
272
|
-
&::-webkit-scrollbar {
|
|
273
|
-
width: 6px;
|
|
274
|
-
}
|
|
275
|
-
&::-webkit-scrollbar-track {
|
|
276
|
-
background: rgba(0, 0, 0, 0.2);
|
|
277
|
-
border-radius: 4px;
|
|
278
|
-
}
|
|
279
|
-
&::-webkit-scrollbar-thumb {
|
|
280
|
-
background: rgba(245, 158, 11, 0.3);
|
|
281
|
-
border-radius: 4px;
|
|
282
|
-
}
|
|
283
295
|
`;
|
|
284
296
|
|
|
285
297
|
const Header = styled.div`
|
|
@@ -377,6 +389,30 @@ const Divider = styled.hr`
|
|
|
377
389
|
flex-shrink: 0;
|
|
378
390
|
`;
|
|
379
391
|
|
|
392
|
+
const FooterDivider = styled(Divider)``;
|
|
393
|
+
|
|
394
|
+
const ScrollableBody = styled.div`
|
|
395
|
+
flex: 1;
|
|
396
|
+
overflow-y: auto;
|
|
397
|
+
overflow-x: hidden;
|
|
398
|
+
display: flex;
|
|
399
|
+
flex-direction: column;
|
|
400
|
+
gap: 14px;
|
|
401
|
+
min-height: 0;
|
|
402
|
+
|
|
403
|
+
&::-webkit-scrollbar {
|
|
404
|
+
width: 6px;
|
|
405
|
+
}
|
|
406
|
+
&::-webkit-scrollbar-track {
|
|
407
|
+
background: rgba(0, 0, 0, 0.2);
|
|
408
|
+
border-radius: 4px;
|
|
409
|
+
}
|
|
410
|
+
&::-webkit-scrollbar-thumb {
|
|
411
|
+
background: rgba(245, 158, 11, 0.3);
|
|
412
|
+
border-radius: 4px;
|
|
413
|
+
}
|
|
414
|
+
`;
|
|
415
|
+
|
|
380
416
|
const Section = styled.div`
|
|
381
417
|
display: flex;
|
|
382
418
|
flex-direction: column;
|
|
@@ -445,13 +481,66 @@ const EquipmentRow = styled.div`
|
|
|
445
481
|
min-width: 0;
|
|
446
482
|
`;
|
|
447
483
|
|
|
448
|
-
const EquipmentSprite = styled.div
|
|
484
|
+
const EquipmentSprite = styled.div<{ $rarity?: string }>`
|
|
485
|
+
position: relative;
|
|
449
486
|
display: flex;
|
|
450
487
|
align-items: center;
|
|
451
488
|
justify-content: center;
|
|
452
489
|
width: 32px;
|
|
453
490
|
height: 32px;
|
|
454
491
|
flex-shrink: 0;
|
|
492
|
+
border-radius: 3px;
|
|
493
|
+
${({ $rarity }) => {
|
|
494
|
+
const color = rarityGlowColor($rarity);
|
|
495
|
+
return color
|
|
496
|
+
? `box-shadow: 0 0 4px 3px ${color} inset, 0 0 6px 2px ${color};`
|
|
497
|
+
: '';
|
|
498
|
+
}}
|
|
499
|
+
`;
|
|
500
|
+
|
|
501
|
+
const GemRow = styled.div`
|
|
502
|
+
position: absolute;
|
|
503
|
+
bottom: -1px;
|
|
504
|
+
left: 0;
|
|
505
|
+
display: flex;
|
|
506
|
+
gap: 1px;
|
|
507
|
+
pointer-events: none;
|
|
508
|
+
`;
|
|
509
|
+
|
|
510
|
+
const GemDot = styled.div<{ $color: string }>`
|
|
511
|
+
width: 5px;
|
|
512
|
+
height: 5px;
|
|
513
|
+
border-radius: 1px;
|
|
514
|
+
transform: rotate(45deg);
|
|
515
|
+
background: radial-gradient(
|
|
516
|
+
circle at 30% 30%,
|
|
517
|
+
rgba(255, 255, 255, 0.8),
|
|
518
|
+
transparent 40%
|
|
519
|
+
),
|
|
520
|
+
linear-gradient(45deg, ${({ $color }) => $color}, rgba(255, 255, 255, 0.2));
|
|
521
|
+
border: 1px solid rgba(0, 0, 0, 0.6);
|
|
522
|
+
box-shadow: 0 0 3px ${({ $color }) => $color};
|
|
523
|
+
`;
|
|
524
|
+
|
|
525
|
+
const GoldRow = styled.div`
|
|
526
|
+
display: flex;
|
|
527
|
+
align-items: center;
|
|
528
|
+
gap: 4px;
|
|
529
|
+
margin-top: 2px;
|
|
530
|
+
`;
|
|
531
|
+
|
|
532
|
+
const GoldLabel = styled.span`
|
|
533
|
+
font-family: 'Press Start 2P', cursive !important;
|
|
534
|
+
font-size: 0.35rem !important;
|
|
535
|
+
color: #6b7280 !important;
|
|
536
|
+
text-transform: uppercase;
|
|
537
|
+
letter-spacing: 0.5px;
|
|
538
|
+
`;
|
|
539
|
+
|
|
540
|
+
const GoldAmount = styled.span`
|
|
541
|
+
font-family: 'Press Start 2P', cursive !important;
|
|
542
|
+
font-size: 0.38rem !important;
|
|
543
|
+
color: #fde68a !important;
|
|
455
544
|
`;
|
|
456
545
|
|
|
457
546
|
const EquipMeta = styled.div`
|