Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions src/app/vendors/VendorItems.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { PressTip } from 'app/dim-ui/PressTip';
import RichDestinyText from 'app/dim-ui/destiny-symbols/RichDestinyText';
import { t } from 'app/i18next-t';
import { DimItem } from 'app/inventory/item-types';
import { useD2Definitions } from 'app/manifest/selectors';
import FactionIcon from 'app/progress/FactionIcon';
import { ReputationRank } from 'app/progress/ReputationRank';
import { DestinyVendorProgressionType } from 'bungie-api-ts/destiny2';
import focusingItemOutputs from 'data/d2/focusing-item-outputs.json';
import { ReactNode } from 'react';
import BungieImage from '../dim-ui/BungieImage';
import ItemPopupTrigger from '../inventory/ItemPopupTrigger';
import VendorItemComponent from './VendorItemComponent';
import * as styles from './VendorItems.m.scss';
import { D2Vendor } from './d2-vendors';
Expand Down Expand Up @@ -65,8 +68,9 @@ export default function VendorItems({
<div>
<h3 className={styles.categoryTitle}>{t('Vendors.Engram')}</h3>
<div className={styles.vendorItems}>
{factionProgress &&
(vendor.def.vendorProgressionType !== DestinyVendorProgressionType.Default ? (
{/* Clicking the rep track opens the vendor's "help" item popup, if it has one. */}
<RepTrackTrigger item={vendor.helpItem?.item}>
{vendor.def.vendorProgressionType !== DestinyVendorProgressionType.Default ? (
<ReputationRank progress={factionProgress} />
) : (
<PressTip
Expand All @@ -81,7 +85,8 @@ export default function VendorItems({
/>
</div>
</PressTip>
))}
)}
</RepTrackTrigger>
</div>
</div>
)}
Expand Down Expand Up @@ -125,3 +130,19 @@ export default function VendorItems({
</div>
);
}

/** Wraps the rep track so clicking it opens the given "help" item's popup, if there is one. */
function RepTrackTrigger({ item, children }: { item: DimItem | undefined; children: ReactNode }) {
if (!item) {
return children;
}
return (
<ItemPopupTrigger item={item}>
{(ref, onClick) => (
<div ref={ref} role="button" tabIndex={0} onClick={onClick}>
{children}
</div>
)}
</ItemPopupTrigger>
);
}
37 changes: 37 additions & 0 deletions src/app/vendors/d2-vendors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,31 @@ export interface D2Vendor {
place?: DestinyPlaceDefinition;
items: VendorItem[];
currencies: DestinyInventoryItemDefinition[];
/**
* The vendor's "help" item, if it has one. It describes the reputation track and
* is pulled out of the regular sale items so it can be shown alongside the rep
* track instead. Only set when the vendor actually has a rep track.
*/
helpItem?: VendorItem;
}

const vendorOrder = [VendorHashes.AdaTransmog, VendorHashes.Banshee, VendorHashes.Eververse];

/**
* Some vendors contain a "help" item that isn't a real sale item, but instead
* describes the vendor's reputation track. We pull it out of the regular sale
* items and show it alongside the rep track instead.
*
* These items all use the shared "vendor_help" icon (icon def 13580639, foreground
* `.../vendor_help...png`). The more semantic-looking `tooltipStyle: 'vendor_action'`
* can't be used because DIM's manifest trimmer blanks `tooltipStyle` out.
*/
const HELP_ITEM_ICON_HASH = 13580639;

function isHelpVendorItem(vendorItem: VendorItem) {
return vendorItem.displayProperties?.iconHash === HELP_ITEM_ICON_HASH;
}

export function toVendorGroups(
context: ItemCreationContext,
vendorsResponse: DestinyVendorsResponse,
Expand Down Expand Up @@ -105,6 +126,21 @@ export function toVendor(
),
);

// Pull the "help" item out of the regular sale items so it isn't shown as a
// normal tile. Surface it on the rep track (if there is one) instead.
let helpItem: VendorItem | undefined;
const helpIndex = vendorItems.findIndex(isHelpVendorItem);
if (helpIndex >= 0) {
const [extracted] = vendorItems.splice(helpIndex, 1);
if (vendorDef.factionHash && vendor?.progression) {
helpItem = extracted;
if (helpItem.item) {
// It's not a real item, so don't show its placeholder type ("Unknown") in the popup.
helpItem.item.typeName = '';
}
}
}

const destinationHash =
typeof vendor?.vendorLocationIndex === 'number' && vendor.vendorLocationIndex >= 0
? // Unadvertised nullability: DestinyVendorDefinition.locations
Expand Down Expand Up @@ -143,6 +179,7 @@ export function toVendor(
place: placeDef,
items: vendorItems,
currencies,
helpItem,
};
}

Expand Down