@rpg-engine/long-bow 0.8.220 → 0.8.222

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpg-engine/long-bow",
3
- "version": "0.8.220",
3
+ "version": "0.8.222",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -181,6 +181,12 @@ const Container = styled.div<IContainerProps>`
181
181
  &.rpgui-container {
182
182
  padding-top: 1.5rem;
183
183
  }
184
+
185
+ @media (max-width: 600px) {
186
+ width: 100vw !important;
187
+ min-width: unset !important;
188
+ height: 100dvh !important;
189
+ }
184
190
  `;
185
191
 
186
192
  const CloseButton = styled.div`
@@ -1,6 +1,6 @@
1
1
  import { IProductBlueprint, MetadataType } from '@rpg-engine/shared';
2
2
  import React, { useState } from 'react';
3
- import { FaCoins, FaInfoCircle, FaShoppingBag, FaTimes, FaTrash } from 'react-icons/fa';
3
+ import { FaInfoCircle, FaShoppingBag, FaTimes, FaTrash } from 'react-icons/fa';
4
4
  import styled from 'styled-components';
5
5
  import characterAtlasJSON from '../../mocks/atlas/entities/entities.json';
6
6
  import characterAtlasIMG from '../../mocks/atlas/entities/entities.png';
@@ -27,8 +27,6 @@ export interface ICartViewProps {
27
27
  paymentMethodLabel?: string;
28
28
  trustSignals?: ITrustSignal[];
29
29
  onCloseStore?: () => void;
30
- /** Called when user taps the "Buy DC" nudge — open wallet/DC purchase flow */
31
- onBuyDC?: () => void;
32
30
  /** Fires when user taps the pay button — before the purchase resolves */
33
31
  onCheckoutStart?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
34
32
  /** Fires after a successful purchase */
@@ -69,7 +67,6 @@ export const CartView: React.FC<ICartViewProps> = ({
69
67
  paymentMethodLabel,
70
68
  trustSignals,
71
69
  onCloseStore,
72
- onBuyDC,
73
70
  onCheckoutStart,
74
71
  onPurchaseSuccess,
75
72
  onPurchaseError,
@@ -118,10 +115,6 @@ export const CartView: React.FC<ICartViewProps> = ({
118
115
  }
119
116
  };
120
117
 
121
- // Show DC discount nudge when items have DC pricing and user might benefit
122
- const hasDCItems = cartItems.some(ci => (ci.item as any).dcPrice);
123
- const showDCNudge = hasDCItems && onBuyDC;
124
-
125
118
  if (purchasedItems) {
126
119
  return (
127
120
  <PurchaseSuccess
@@ -150,100 +143,95 @@ export const CartView: React.FC<ICartViewProps> = ({
150
143
  </CloseButton>
151
144
  </Header>
152
145
 
153
- <CartItems>
154
- {cartItems.length === 0 ? (
155
- <EmptyCart>Your cart is empty</EmptyCart>
156
- ) : (
157
- cartItems.map(cartItem => {
158
- console.log('Item metadataType: , texturePath:', cartItem.item.metadataType , cartItem.item.texturePath);
159
- const getSpriteKey = (textureKey: string) => {
160
- return textureKey + '/down/standing/0.png';
161
- };
162
-
163
- return (
164
- <CartItemRow key={cartItem.item.key}>
165
- <ItemIconContainer>
166
- <SpriteFromAtlas
167
- atlasJSON={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasJSON : atlasJSON}
168
- atlasIMG={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasIMG : atlasIMG}
169
- spriteKey={cartItem.item.metadataType === MetadataType.CharacterSkin && cartItem.metadata?.selectedSkinTextureKey ? getSpriteKey(cartItem.metadata.selectedSkinTextureKey) : cartItem.item.texturePath}
170
- width={24}
171
- height={24}
172
- imgScale={1.5}
173
- centered
174
- />
175
- </ItemIconContainer>
176
- <ItemDetails>
177
- <ItemName>{cartItem.item.name}</ItemName>
178
- {cartItem.metadata?.inputValue && (
179
- <CartMeta>{cartItem.metadata.inputValue}</CartMeta>
180
- )}
181
- <ItemInfo>
182
- <span>{currencySymbol}{formatPrice((cartItem.item as any).regionalPrice ?? cartItem.item.price)}</span>
183
- <span>×</span>
184
- <span>{cartItem.quantity}</span>
185
- <span>=</span>
186
- <span>
187
- {currencySymbol}{formatPrice(((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity)}
188
- </span>
189
- </ItemInfo>
190
-
191
- {cartItem.metadata && cartItem.item.metadataType && (
192
- <MetadataDisplay
193
- type={cartItem.item.metadataType}
194
- metadata={cartItem.metadata}
146
+ <MainContent>
147
+ <CartItems>
148
+ {cartItems.length === 0 ? (
149
+ <EmptyCart>Your cart is empty</EmptyCart>
150
+ ) : (
151
+ cartItems.map(cartItem => {
152
+ const getSpriteKey = (textureKey: string) => {
153
+ return textureKey + '/down/standing/0.png';
154
+ };
155
+
156
+ return (
157
+ <CartItemRow key={cartItem.item.key}>
158
+ <ItemIconContainer>
159
+ <SpriteFromAtlas
160
+ atlasJSON={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasJSON : atlasJSON}
161
+ atlasIMG={cartItem.item.metadataType === MetadataType.CharacterSkin ? characterAtlasIMG : atlasIMG}
162
+ spriteKey={cartItem.item.metadataType === MetadataType.CharacterSkin && cartItem.metadata?.selectedSkinTextureKey ? getSpriteKey(cartItem.metadata.selectedSkinTextureKey) : cartItem.item.texturePath}
163
+ width={24}
164
+ height={24}
165
+ imgScale={1.5}
166
+ centered
195
167
  />
196
- )}
197
- </ItemDetails>
198
-
199
- <CTAButton
200
- icon={<FaTrash />}
201
- onClick={e => {
202
- e.stopPropagation();
203
- onRemoveFromCart(cartItem.item.key);
204
- }}
205
- />
206
- </CartItemRow>
207
- );
208
- })
209
- )}
210
- </CartItems>
168
+ </ItemIconContainer>
169
+ <ItemDetails>
170
+ <ItemName>{cartItem.item.name}</ItemName>
171
+ {cartItem.metadata?.inputValue && (
172
+ <CartMeta>{cartItem.metadata.inputValue}</CartMeta>
173
+ )}
174
+ <ItemInfo>
175
+ <span>{currencySymbol}{formatPrice((cartItem.item as any).regionalPrice ?? cartItem.item.price)}</span>
176
+ <span>×</span>
177
+ <span>{cartItem.quantity}</span>
178
+ <span>=</span>
179
+ <span>
180
+ {currencySymbol}{formatPrice(((cartItem.item as any).regionalPrice ?? cartItem.item.price) * cartItem.quantity)}
181
+ </span>
182
+ </ItemInfo>
183
+
184
+ {cartItem.metadata && cartItem.item.metadataType && (
185
+ <MetadataDisplay
186
+ type={cartItem.item.metadataType}
187
+ metadata={cartItem.metadata}
188
+ />
189
+ )}
190
+ </ItemDetails>
191
+
192
+ <CTAButton
193
+ icon={<FaTrash />}
194
+ onClick={e => {
195
+ e.stopPropagation();
196
+ onRemoveFromCart(cartItem.item.key);
197
+ }}
198
+ />
199
+ </CartItemRow>
200
+ );
201
+ })
202
+ )}
203
+ </CartItems>
211
204
 
212
- <Footer>
213
- {showDCNudge && (
214
- <DCNudge onPointerDown={onBuyDC}>
215
- <FaCoins />
216
- <span>Save more with DC — volume discounts available</span>
217
- <DCNudgeLink>Buy DC →</DCNudgeLink>
218
- </DCNudge>
205
+ {cartItems.length > 0 && (
206
+ <OrderSummaryPanel>
207
+ <OrderSummaryLabel>Order Summary</OrderSummaryLabel>
208
+ <TotalRow>
209
+ <span>Subtotal:</span>
210
+ <span>{currencySymbol}{formatPrice(total)}</span>
211
+ </TotalRow>
212
+ {dcTotal > 0 && (
213
+ <TotalRow>
214
+ <span>DC:</span>
215
+ <span><MMORPGNumber value={dcTotal} /> DC</span>
216
+ </TotalRow>
217
+ )}
218
+ <TotalRow $isTotal>
219
+ <span>Total:</span>
220
+ <span>{currencySymbol}{formatPrice(total)}</span>
221
+ </TotalRow>
222
+ {paymentMethodLabel && (
223
+ <PaymentMethodRow>
224
+ <span>Paying with:</span>
225
+ <span>{paymentMethodLabel}</span>
226
+ </PaymentMethodRow>
227
+ )}
228
+ </OrderSummaryPanel>
219
229
  )}
230
+ </MainContent>
220
231
 
232
+ <Footer>
221
233
  <TrustBar signals={trustSignals} />
222
-
223
- <TotalInfo>
224
- <OrderSummaryLabel>Order Summary</OrderSummaryLabel>
225
- <TotalRow>
226
- <span>Subtotal:</span>
227
- <span>{currencySymbol}{formatPrice(total)}</span>
228
- </TotalRow>
229
- {dcTotal > 0 && (
230
- <TotalRow>
231
- <span>DC:</span>
232
- <span><MMORPGNumber value={dcTotal} /> DC</span>
233
- </TotalRow>
234
- )}
235
- <TotalRow $isTotal>
236
- <span>Total:</span>
237
- <span>{currencySymbol}{formatPrice(total)}</span>
238
- </TotalRow>
239
- {paymentMethodLabel && (
240
- <PaymentMethodRow>
241
- <span>Paying with:</span>
242
- <span>{paymentMethodLabel}</span>
243
- </PaymentMethodRow>
244
- )}
245
- {error && <ErrorMessage>{error}</ErrorMessage>}
246
- </TotalInfo>
234
+ {error && <ErrorMessage>{error}</ErrorMessage>}
247
235
  <CTAButton
248
236
  icon={<FaShoppingBag />}
249
237
  label={isLoading ? 'Processing...' : `Pay ${currencySymbol}${formatPrice(total)}`}
@@ -264,6 +252,10 @@ const Container = styled.div`
264
252
  padding: 1rem;
265
253
  overflow: hidden;
266
254
  box-sizing: border-box;
255
+
256
+ @media (max-width: 480px) {
257
+ padding: 0.75rem 0.5rem;
258
+ }
267
259
  `;
268
260
 
269
261
  const Header = styled.div`
@@ -292,14 +284,26 @@ const CloseButton = styled.div`
292
284
  justify-content: center;
293
285
  `;
294
286
 
287
+ const MainContent = styled.div`
288
+ display: grid;
289
+ grid-template-columns: 1fr 260px;
290
+ gap: 1rem;
291
+ flex: 1;
292
+ min-height: 0;
293
+ margin: 1rem 0;
294
+
295
+ @media (max-width: 700px) {
296
+ grid-template-columns: 1fr;
297
+ gap: 0.75rem;
298
+ }
299
+ `;
300
+
295
301
  const CartItems = styled.div`
296
302
  display: flex;
297
303
  flex-direction: column;
298
304
  gap: 0.5rem;
299
- flex: 1;
300
305
  min-height: 0;
301
306
  overflow-y: auto;
302
- margin: 1rem 0;
303
307
  padding-right: 0.5rem;
304
308
 
305
309
  &::-webkit-scrollbar {
@@ -312,13 +316,28 @@ const CartItems = styled.div`
312
316
  &::-webkit-scrollbar-thumb {
313
317
  background: #f59e0b;
314
318
  border-radius: 4px;
315
-
319
+
316
320
  &:hover {
317
321
  background: #fbbf24;
318
322
  }
319
323
  }
320
324
  `;
321
325
 
326
+ const OrderSummaryPanel = styled.div`
327
+ display: flex;
328
+ flex-direction: column;
329
+ gap: 0.5rem;
330
+ padding: 1rem;
331
+ background: rgba(0, 0, 0, 0.25);
332
+ border: 1px solid rgba(255, 255, 255, 0.08);
333
+ border-radius: 6px;
334
+ align-self: start;
335
+
336
+ @media (max-width: 480px) {
337
+ padding: 0.75rem;
338
+ }
339
+ `;
340
+
322
341
  const EmptyCart = styled.div`
323
342
  display: flex;
324
343
  align-items: center;
@@ -337,6 +356,11 @@ const CartItemRow = styled.div`
337
356
  padding: 0.5rem 0.75rem;
338
357
  background: rgba(0, 0, 0, 0.2);
339
358
  border-radius: 4px;
359
+
360
+ @media (max-width: 480px) {
361
+ gap: 0.5rem;
362
+ padding: 0.4rem 0.5rem;
363
+ }
340
364
  `;
341
365
 
342
366
  const ItemIconContainer = styled.div`
@@ -365,6 +389,7 @@ const ItemName = styled.div`
365
389
  const ItemInfo = styled.div`
366
390
  display: flex;
367
391
  align-items: center;
392
+ flex-wrap: wrap;
368
393
  gap: 0.4rem;
369
394
  font-family: 'Press Start 2P', cursive;
370
395
  font-size: 0.55rem;
@@ -385,12 +410,6 @@ const Footer = styled.div`
385
410
  }
386
411
  `;
387
412
 
388
- const TotalInfo = styled.div`
389
- display: flex;
390
- flex-direction: column;
391
- gap: 0.5rem;
392
- `;
393
-
394
413
  const OrderSummaryLabel = styled.div`
395
414
  font-family: 'Press Start 2P', cursive;
396
415
  font-size: 0.55rem;
@@ -417,6 +436,11 @@ const TotalRow = styled.div<{ $isTotal?: boolean }>`
417
436
  span:last-child {
418
437
  color: #fef08a;
419
438
  }
439
+
440
+ @media (max-width: 480px) {
441
+ font-size: ${p => p.$isTotal ? '0.7rem' : '0.55rem'};
442
+ gap: 0.5rem;
443
+ }
420
444
  `;
421
445
 
422
446
  const PaymentMethodRow = styled.div`
@@ -434,37 +458,6 @@ const PaymentMethodRow = styled.div`
434
458
  }
435
459
  `;
436
460
 
437
- const DCNudge = styled.div`
438
- display: flex;
439
- align-items: center;
440
- gap: 0.5rem;
441
- padding: 0.5rem 0.75rem;
442
- background: rgba(245, 158, 11, 0.1);
443
- border: 1px solid rgba(245, 158, 11, 0.3);
444
- border-radius: 4px;
445
- cursor: pointer;
446
- font-family: 'Press Start 2P', cursive;
447
- font-size: 0.45rem;
448
- color: #fbbf24;
449
- transition: background 0.15s;
450
- line-height: 1.4;
451
- flex-wrap: wrap;
452
-
453
- &:hover {
454
- background: rgba(245, 158, 11, 0.18);
455
- }
456
-
457
- svg { flex-shrink: 0; font-size: 0.7rem; }
458
- span { flex: 1; min-width: 140px; }
459
- `;
460
-
461
- const DCNudgeLink = styled.span`
462
- color: #f59e0b;
463
- white-space: nowrap;
464
- text-decoration: underline;
465
- flex: 0 0 auto !important;
466
- `;
467
-
468
461
  const ErrorMessage = styled.div`
469
462
  color: #ef4444;
470
463
  font-size: 0.875rem;
@@ -61,7 +61,6 @@ export interface IStoreProps {
61
61
  onCheckoutStart?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
62
62
  onPurchaseSuccess?: (items: Array<{ key: string; name: string; quantity: number }>, total: number) => void;
63
63
  onPurchaseError?: (error: string) => void;
64
- onBuyDC?: () => void;
65
64
  currencySymbol?: string;
66
65
  onRedeem?: (code: string) => Promise<{ success: boolean; dcAmount?: number; error?: string }>;
67
66
  onRedeemInputFocus?: () => void;
@@ -114,7 +113,6 @@ export const Store: React.FC<IStoreProps> = ({
114
113
  onCheckoutStart,
115
114
  onPurchaseSuccess,
116
115
  onPurchaseError,
117
- onBuyDC,
118
116
  currencySymbol = '$',
119
117
  onRedeem,
120
118
  onRedeemInputFocus,
@@ -321,7 +319,6 @@ export const Store: React.FC<IStoreProps> = ({
321
319
  onCheckoutStart={onCheckoutStart}
322
320
  onPurchaseSuccess={onPurchaseSuccess}
323
321
  onPurchaseError={onPurchaseError}
324
- onBuyDC={onBuyDC}
325
322
  currencySymbol={currencySymbol}
326
323
  />
327
324
  ) : selectedPack ? (