Skip to content

Commit

Permalink
Merge pull request #10163 from DestinyItemManager/catalyst-search
Browse files Browse the repository at this point in the history
Associate catalyst records with collections items
  • Loading branch information
bhollis authored Dec 18, 2023
2 parents 72bf5b1 + 1594635 commit 9a57d2c
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/app/records/PresentationNodeRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useSelector } from 'react-redux';
import PresentationNode from './PresentationNode';
import styles from './PresentationNodeRoot.m.scss';
import PresentationNodeSearchResults from './PresentationNodeSearchResults';
import { makeItemsForCatalystRecords } from './catalysts';
import {
filterPresentationNodesToSearch,
hideCompletedRecords,
Expand Down Expand Up @@ -93,12 +94,15 @@ export default function PresentationNodeRoot({
}

if (searchQuery && searchFilter) {
const catalystItemsByRecordHash = makeItemsForCatalystRecords(itemCreationContext);

const searchResults = filterPresentationNodesToSearch(
nodeTree,
searchQuery.toLowerCase(),
searchFilter,
undefined,
defs,
catalystItemsByRecordHash,
);

return (
Expand Down
7 changes: 6 additions & 1 deletion src/app/records/Record.m.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
align-items: flex-start;
box-sizing: border-box;
user-select: text;
gap: 8px;

@include phone-portrait {
width: 100%;
Expand Down Expand Up @@ -196,13 +197,17 @@
}

.icon {
display: block;
width: 40px;
height: auto;
flex-shrink: 0;
margin-right: 8px;
background: var(--theme-icon-tile);
}

.clickable {
cursor: pointer;
}

.info {
flex: 1;
position: relative;
Expand Down
1 change: 1 addition & 0 deletions src/app/records/Record.m.scss.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions src/app/records/Record.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { trackTriumph } from 'app/dim-api/basic-actions';
import { trackedTriumphsSelector } from 'app/dim-api/selectors';
import RichDestinyText from 'app/dim-ui/destiny-symbols/RichDestinyText';
import { t } from 'app/i18next-t';
import ItemPopupTrigger from 'app/inventory/ItemPopupTrigger';
import { createItemContextSelector } from 'app/inventory/selectors';
import { isBooleanObjective } from 'app/inventory/store/objectives';
import { useD2Definitions } from 'app/manifest/selectors';
import { Reward } from 'app/progress/Reward';
Expand All @@ -27,6 +29,7 @@ import BungieImage from '../dim-ui/BungieImage';
import ExternalLink from '../dim-ui/ExternalLink';
import Objective from '../progress/Objective';
import styles from './Record.m.scss';
import { makeItemForCatalystRecord } from './catalysts';
import { DimRecord } from './presentation-nodes';

interface RecordInterval {
Expand Down Expand Up @@ -75,10 +78,11 @@ function Record({
? recordDef.stateInfo.obscuredString
: recordDef.displayProperties.description;

const recordIcon =
recordHash in catalystIconsTable
? catalystIconsTable[recordHash]
: recordDef.displayProperties.icon;
const isCatalyst = recordHash in catalystIconsTable;
const recordIcon = isCatalyst ? catalystIconsTable[recordHash] : recordDef.displayProperties.icon;

const itemCreationContext = useSelector(createItemContextSelector);
const catalystTarget = isCatalyst && makeItemForCatalystRecord(recordHash, itemCreationContext);

const intervals = getIntervals(recordDef, recordComponent);
const intervalBarStyle = {
Expand Down Expand Up @@ -173,7 +177,17 @@ function Record({
})}
>
{recordShouldGlow && <div className={styles.glow} />}
{recordIcon && <BungieImage className={styles.icon} src={recordIcon} />}
{catalystTarget && recordIcon ? (
<ItemPopupTrigger item={catalystTarget}>
{(ref, onClick) => (
<div className={styles.clickable} ref={ref} onClick={onClick}>
<BungieImage className={styles.icon} src={recordIcon} />
</div>
)}
</ItemPopupTrigger>
) : (
recordIcon && <BungieImage className={styles.icon} src={recordIcon} />
)}
<div className={styles.info}>
{!obscured && recordDef.completionInfo && <div className={styles.score}>{scoreValue}</div>}
<h3>{name}</h3>
Expand Down
22 changes: 22 additions & 0 deletions src/app/records/catalysts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ItemCreationContext, makeFakeItem } from 'app/inventory/store/d2-item-factory';
import exoticToCatalystRecordHash from 'data/d2/exotic-to-catalyst-record.json';
import _ from 'lodash';

export function makeItemsForCatalystRecords(itemCreationContext: ItemCreationContext) {
return new Map(
Object.entries(exoticToCatalystRecordHash).map(([itemHash, recordHash]) => [
recordHash!,
makeFakeItem(itemCreationContext, parseInt(itemHash, 10))!,
]),
);
}

export function makeItemForCatalystRecord(
recordHash: number,
itemCreationContext: ItemCreationContext,
) {
const exoticHash = _.invert(exoticToCatalystRecordHash)[recordHash];
if (exoticHash) {
return makeFakeItem(itemCreationContext, parseInt(exoticHash, 10))!;
}
}
22 changes: 20 additions & 2 deletions src/app/records/presentation-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ export function filterPresentationNodesToSearch(
filterItems: ItemFilter,
path: DimPresentationNode[] = [],
defs: D2ManifestDefinitions,
catalystItemsByRecordHash: Map<number, DimItem>,
): DimPresentationNodeSearchResult[] {
// If the node itself matches
if (searchNode(node, searchQuery)) {
Expand All @@ -313,7 +314,14 @@ export function filterPresentationNodesToSearch(
if (node.childPresentationNodes) {
// TODO: build up the tree?
return node.childPresentationNodes.flatMap((c) =>
filterPresentationNodesToSearch(c, searchQuery, filterItems, [...path, node], defs),
filterPresentationNodesToSearch(
c,
searchQuery,
filterItems,
[...path, node],
defs,
catalystItemsByRecordHash,
),
);
}

Expand All @@ -334,7 +342,8 @@ export function filterPresentationNodesToSearch(
const records = node.records.filter(
(r) =>
searchDisplayProperties(r.recordDef.displayProperties, searchQuery) ||
searchRewards(r.recordDef, searchQuery, defs),
searchRewards(r.recordDef, searchQuery, defs) ||
searchCatalysts(r.recordDef.hash, filterItems, catalystItemsByRecordHash),
);

return records.length
Expand Down Expand Up @@ -594,3 +603,12 @@ function getMetricComponent(
): DestinyMetricComponent | undefined {
return profileResponse.metrics?.data?.metrics[metricDef.hash];
}

function searchCatalysts(
recordHash: number,
filterItems: ItemFilter,
catalystItemsByRecordHash: Map<number, DimItem>,
): unknown {
const exoticForCatalyst = catalystItemsByRecordHash.get(recordHash);
return exoticForCatalyst && filterItems(exoticForCatalyst);
}

0 comments on commit 9a57d2c

Please sign in to comment.