@rpg-engine/long-bow 0.8.154 → 0.8.156

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.154",
3
+ "version": "0.8.156",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -19,7 +19,7 @@ import { MarketplaceBuyModal, MarketplacePaymentMethod } from './MarketplaceBuyM
19
19
  import { GroupedMarketplaceRow } from './MarketplaceRows';
20
20
  import { itemRarityOptions, itemTypeOptions, orderByOptions } from './filters';
21
21
 
22
- type MarketplaceBrowseMode = 'all' | 'sell' | 'buy';
22
+ type MarketplaceBrowseMode = 'sell' | 'buy';
23
23
 
24
24
  const BUY_REQUESTS_PER_PAGE = 5;
25
25
 
@@ -48,6 +48,7 @@ export interface IBuyPanelProps {
48
48
  equipmentSet?: IEquipmentSet | null;
49
49
  onMarketPlaceItemBuy?: (marketPlaceItemId: string, paymentMethod?: MarketplacePaymentMethod) => void;
50
50
  onFulfillBuyOrder?: (buyOrderId: string) => void;
51
+ onDCCoinClick?: () => void;
51
52
  characterId: string;
52
53
  enableHotkeys?: () => void;
53
54
  disableHotkeys?: () => void;
@@ -78,6 +79,7 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
78
79
  equipmentSet,
79
80
  onMarketPlaceItemBuy,
80
81
  onFulfillBuyOrder,
82
+ onDCCoinClick,
81
83
  characterId,
82
84
  enableHotkeys,
83
85
  disableHotkeys,
@@ -91,11 +93,12 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
91
93
  openBuyOrdersTotal = 0,
92
94
  openBuyOrdersPage = 1,
93
95
  onOpenBuyOrdersPageChange,
96
+ isLoading = false,
94
97
 
95
98
  }) => {
96
99
  const [name, setName] = useState('');
97
100
  const [showFilters, setShowFilters] = useState(false);
98
- const [browseMode, setBrowseMode] = useState<MarketplaceBrowseMode>('all');
101
+ const [browseMode, setBrowseMode] = useState<MarketplaceBrowseMode>('sell');
99
102
  const [selectedRarity, setSelectedRarity] = useState('');
100
103
  const [mainLevel, setMainLevel] = useState<
101
104
  [number | undefined, number | undefined]
@@ -170,8 +173,8 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
170
173
  });
171
174
  }, [name, openBuyOrders, price, selectedRarity]);
172
175
 
173
- const showSellSection = browseMode === 'all' || browseMode === 'sell';
174
- const showBuySection = browseMode === 'all' || browseMode === 'buy';
176
+ const showSellSection = browseMode === 'sell';
177
+ const showBuySection = browseMode === 'buy';
175
178
  const hasVisibleContent =
176
179
  (showSellSection && groupedItems.length > 0) ||
177
180
  (showBuySection && visibleBuyOrders.length > 0);
@@ -219,7 +222,6 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
219
222
  activeId={browseMode}
220
223
  onChange={value => setBrowseMode(value as MarketplaceBrowseMode)}
221
224
  options={[
222
- { id: 'all', label: 'All' },
223
225
  { id: 'sell', label: 'Sell Offers' },
224
226
  { id: 'buy', label: 'Buy Requests' },
225
227
  ]}
@@ -371,11 +373,15 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
371
373
  )}
372
374
 
373
375
  <ItemComponentScrollWrapper id="MarketContainer" ref={itemsContainer}>
374
- {!hasVisibleContent ? (
376
+ {isLoading ? (
375
377
  <LoadingState>
376
378
  <Spinner />
377
379
  <LoadingText>Loading marketplace...</LoadingText>
378
380
  </LoadingState>
381
+ ) : !hasVisibleContent ? (
382
+ <LoadingState>
383
+ <LoadingText>No items listed.</LoadingText>
384
+ </LoadingState>
379
385
  ) : (
380
386
  <>
381
387
  {showSellSection && (
@@ -399,19 +405,10 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
399
405
  getDCEquivalentPrice={getDCEquivalentPrice}
400
406
  characterId={characterId}
401
407
  onBuy={setBuyingItemId}
408
+ onDCCoinClick={onDCCoinClick}
402
409
  />
403
410
  ))
404
411
  )}
405
- {totalItems > itemsPerPage && (
406
- <SectionPager>
407
- <Pager
408
- totalItems={totalItems}
409
- currentPage={currentPage}
410
- itemsPerPage={itemsPerPage}
411
- onPageChange={onPageChange}
412
- />
413
- </SectionPager>
414
- )}
415
412
  </MarketSection>
416
413
  )}
417
414
 
@@ -435,21 +432,30 @@ export const BuyPanel: React.FC<IBuyPanelProps> = ({
435
432
  />
436
433
  ))
437
434
  )}
438
- {openBuyOrdersTotal > BUY_REQUESTS_PER_PAGE && (
439
- <SectionPager>
440
- <Pager
441
- totalItems={openBuyOrdersTotal}
442
- currentPage={openBuyOrdersPage}
443
- itemsPerPage={BUY_REQUESTS_PER_PAGE}
444
- onPageChange={onOpenBuyOrdersPageChange ?? (() => {})}
445
- />
446
- </SectionPager>
447
- )}
448
435
  </MarketSection>
449
436
  )}
450
437
  </>
451
438
  )}
452
439
  </ItemComponentScrollWrapper>
440
+
441
+ <PagerFooter>
442
+ {showSellSection && totalItems > itemsPerPage && (
443
+ <Pager
444
+ totalItems={totalItems}
445
+ currentPage={currentPage}
446
+ itemsPerPage={itemsPerPage}
447
+ onPageChange={onPageChange}
448
+ />
449
+ )}
450
+ {showBuySection && openBuyOrdersTotal > BUY_REQUESTS_PER_PAGE && (
451
+ <Pager
452
+ totalItems={openBuyOrdersTotal}
453
+ currentPage={openBuyOrdersPage}
454
+ itemsPerPage={BUY_REQUESTS_PER_PAGE}
455
+ onPageChange={onOpenBuyOrdersPageChange ?? (() => {})}
456
+ />
457
+ )}
458
+ </PagerFooter>
453
459
  </>
454
460
  );
455
461
  };
@@ -632,10 +638,14 @@ const SectionEmpty = styled.div`
632
638
  `;
633
639
 
634
640
 
635
- const SectionPager = styled.div`
641
+ const PagerFooter = styled.div`
636
642
  display: flex;
637
643
  justify-content: center;
638
- margin-top: 10px;
644
+ align-items: center;
645
+ padding: 8px 0 4px;
646
+ min-height: 36px;
647
+ width: 95%;
648
+ margin: 0 auto;
639
649
  `;
640
650
 
641
651
  const StyledDropdown = styled(Dropdown)`
@@ -46,6 +46,7 @@ export interface IMarketPlaceProps {
46
46
  equipmentSet?: IEquipmentSet | null;
47
47
  onMarketPlaceItemBuy?: (marketPlaceItemId: string, paymentMethod?: MarketplacePaymentMethod) => void;
48
48
  onFulfillBuyOrder?: (buyOrderId: string) => void;
49
+ onDCCoinClick?: () => void;
49
50
  onMarketPlaceItemRemove?: (marketPlaceItemId: string) => void;
50
51
  availableGold: number;
51
52
  selectedItemToSell: IItem | null;
@@ -28,6 +28,7 @@ export interface IMarketPlaceRowsPropos {
28
28
  scale?: number;
29
29
  onMarketPlaceItemBuy?: () => void;
30
30
  onMarketPlaceItemRemove?: () => void;
31
+ onDCCoinClick?: () => void;
31
32
  disabled?: boolean;
32
33
  }
33
34
 
@@ -41,6 +42,7 @@ export const MarketplaceRows: React.FC<IMarketPlaceRowsPropos> = ({
41
42
  scale,
42
43
  onMarketPlaceItemBuy,
43
44
  onMarketPlaceItemRemove,
45
+ onDCCoinClick,
44
46
  disabled,
45
47
  }) => {
46
48
  const renderGems = (item: IItem) => {
@@ -105,9 +107,9 @@ export const MarketplaceRows: React.FC<IMarketPlaceRowsPropos> = ({
105
107
  <GoldPrice>{itemPrice}</GoldPrice>
106
108
  </GoldPriceRow>
107
109
  {dcEquivalentPrice !== undefined && (
108
- <DCPriceRow>
110
+ <DCPriceRow $clickable={!!onDCCoinClick} onPointerDown={onDCCoinClick}>
109
111
  <DCCoinWrapper>
110
- <SimpleTooltip content="Definya Coin" direction="top">
112
+ <SimpleTooltip content={onDCCoinClick ? 'Buy Definya Coin' : 'Definya Coin'} direction="top">
111
113
  <SpriteFromAtlas
112
114
  atlasIMG={atlasIMG}
113
115
  atlasJSON={atlasJSON}
@@ -150,6 +152,7 @@ export interface IGroupedMarketplaceRowProps {
150
152
  getDCEquivalentPrice: (goldPrice: number) => number;
151
153
  characterId: string;
152
154
  onBuy: (id: string) => void;
155
+ onDCCoinClick?: () => void;
153
156
  }
154
157
 
155
158
  export const GroupedMarketplaceRow: React.FC<IGroupedMarketplaceRowProps> = ({
@@ -162,6 +165,7 @@ export const GroupedMarketplaceRow: React.FC<IGroupedMarketplaceRowProps> = ({
162
165
  getDCEquivalentPrice,
163
166
  characterId,
164
167
  onBuy,
168
+ onDCCoinClick,
165
169
  }) => {
166
170
  const [expanded, setExpanded] = useState(false);
167
171
  const totalOffers = otherListings.length + 1;
@@ -185,6 +189,7 @@ export const GroupedMarketplaceRow: React.FC<IGroupedMarketplaceRowProps> = ({
185
189
  }
186
190
  equipmentSet={equipmentSet}
187
191
  onMarketPlaceItemBuy={() => onBuy(bestListing._id)}
192
+ onDCCoinClick={onDCCoinClick}
188
193
  disabled={bestListing.owner === characterId}
189
194
  />
190
195
  {hasMultiple && (
@@ -211,6 +216,7 @@ export const GroupedMarketplaceRow: React.FC<IGroupedMarketplaceRowProps> = ({
211
216
  }
212
217
  equipmentSet={equipmentSet}
213
218
  onMarketPlaceItemBuy={() => onBuy(listing._id)}
219
+ onDCCoinClick={onDCCoinClick}
214
220
  disabled={listing.owner === characterId}
215
221
  />
216
222
  ))}
@@ -347,11 +353,18 @@ const GoldPrice = styled.span`
347
353
  line-height: 1;
348
354
  `;
349
355
 
350
- const DCPriceRow = styled.div`
356
+ const DCPriceRow = styled.div<{ $clickable?: boolean }>`
351
357
  display: flex;
352
358
  align-items: center;
353
359
  gap: 0.3rem;
354
360
  margin-left: 0.5rem;
361
+ cursor: ${({ $clickable }) => ($clickable ? 'pointer' : 'default')};
362
+ border-radius: 4px;
363
+ transition: opacity 0.15s;
364
+
365
+ &:hover {
366
+ opacity: ${({ $clickable }) => ($clickable ? '0.75' : '1')};
367
+ }
355
368
  `;
356
369
 
357
370
  const DCCoinWrapper = styled.span`
@@ -46,6 +46,11 @@ const mockOpenBuyOrders: IMarketplaceBuyOrderItem[] = [
46
46
  { _id: 'obo-1', owner: 'player-2', itemBlueprintKey: 'items/abyssal-tide-staff', itemRarity: 'Epic', maxPrice: 1500, escrowedGold: 1500, fee: 75, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(1), updatedAt: daysAgo(1) },
47
47
  { _id: 'obo-2', owner: 'player-3', itemBlueprintKey: 'items/wooden-shield', maxPrice: 200, escrowedGold: 200, fee: 10, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(5), updatedAt: daysAgo(5) },
48
48
  { _id: 'obo-3', owner: 'player-4', itemBlueprintKey: 'items/fire-wand', itemRarity: 'Rare', maxPrice: 800, escrowedGold: 800, fee: 40, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(2), updatedAt: daysAgo(2) },
49
+ { _id: 'obo-4', owner: 'player-5', itemBlueprintKey: 'items/broad-sword', maxPrice: 350, escrowedGold: 350, fee: 17, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(3), updatedAt: daysAgo(3) },
50
+ { _id: 'obo-5', owner: 'player-6', itemBlueprintKey: 'items/barbarian-helmet', itemRarity: 'Uncommon', maxPrice: 600, escrowedGold: 600, fee: 30, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(1), updatedAt: daysAgo(1) },
51
+ { _id: 'obo-6', owner: 'player-7', itemBlueprintKey: 'items/leather-armor', maxPrice: 420, escrowedGold: 420, fee: 21, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(4), updatedAt: daysAgo(4) },
52
+ { _id: 'obo-7', owner: 'player-8', itemBlueprintKey: 'items/angelic-sword', itemRarity: 'Legendary', maxPrice: 5000, escrowedGold: 5000, fee: 250, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(6), updatedAt: daysAgo(6) },
53
+ { _id: 'obo-8', owner: 'player-9', itemBlueprintKey: 'items/greater-life-potion', maxPrice: 90, stackQty: 10, escrowedGold: 900, fee: 45, status: MarketplaceBuyOrderStatus.Active, createdAt: daysAgo(2), updatedAt: daysAgo(2) },
49
54
  ];
50
55
 
51
56
  const mockTransactions: IMarketplaceTransaction[] = [
@@ -111,6 +116,7 @@ const Template: Story = () => {
111
116
  }))}
112
117
  equipmentSet={equipmentSetMock}
113
118
  onMarketPlaceItemBuy={tradeId => console.log(tradeId)}
119
+ onDCCoinClick={() => console.log('open store: packs tab')}
114
120
  onFulfillBuyOrder={buyOrderId => console.log('fulfill buy order:', buyOrderId)}
115
121
  availableGold={0}
116
122
  selectedItemToSell={null}
@@ -163,7 +169,7 @@ const Template: Story = () => {
163
169
  onYourBuyOrdersPageChange={p => console.log('your orders page:', p)}
164
170
  onCancelBuyOrder={id => setYourBuyOrders(prev => prev.filter(o => o._id !== id))}
165
171
  openBuyOrders={mockOpenBuyOrders}
166
- openBuyOrdersTotal={mockOpenBuyOrders.length}
172
+ openBuyOrdersTotal={mockOpenBuyOrders.length} // 8 items → pagination shows (page size = 5)
167
173
  openBuyOrdersPage={1}
168
174
  onOpenBuyOrdersPageChange={(p: number) => console.log('open orders page:', p)}
169
175
  // Blueprint Search props