Skip to content

Commit

Permalink
Merge pull request #9756 from robojumper/filter-silver-items
Browse files Browse the repository at this point in the history
Add Hide Silver items toggle to Vendors page
  • Loading branch information
bhollis authored Aug 23, 2023
2 parents 5534f55 + 30c1471 commit de1079c
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 24 deletions.
1 change: 1 addition & 0 deletions config/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@
"Collections": "Collections",
"Engram": "Reward Engram",
"FilterToUnacquired": "Only show uncollected items",
"HideSilverItems": "Hide Silver items",
"NoItems": "This Vendor is currently not offering any items.",
"Vendors": "Vendors",
"RefreshTime": "Inventory refreshes in:"
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Next

* You can choose between a number of different themes for DIM's interface in settings.
* The Vendors page now has a toggle to hide all items sold for Silver.

## 7.82.1 <span class="changelog-date">(2023-08-22)</span>

Expand Down
3 changes: 3 additions & 0 deletions src/app/search/d2-known-values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ export const pinnacleSources = [
73143230, // InventoryItem "Pinnacle Gear"
];

/** The premium Eververse currency */
export const silverItemHash = 3147280338; // InventoryItem "Silver"

// For loadout mods obliterated from the defs, we instead return this def
export const deprecatedPlaceholderArmorModHash = 3947616002; // InventoryItem "Deprecated Armor Mod"

Expand Down
2 changes: 2 additions & 0 deletions src/app/settings/initial-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface Settings extends DimApiSettings {
loIncludeVendorItems: boolean;
theme: string;
sortRecordProgression: boolean;
vendorsHideSilverItems: boolean;
}

export const initialSettingsState: Settings = {
Expand All @@ -17,4 +18,5 @@ export const initialSettingsState: Settings = {
language: defaultLanguage(),
theme: 'default',
sortRecordProgression: false,
vendorsHideSilverItems: false,
};
13 changes: 13 additions & 0 deletions src/app/vendors/Vendors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useLoadStores } from 'app/inventory/store/hooks';
import { getCurrentStore } from 'app/inventory/stores-helpers';
import { useD2Definitions } from 'app/manifest/selectors';
import { searchFilterSelector } from 'app/search/search-filter';
import { useSetting } from 'app/settings/hooks';
import ErrorPanel from 'app/shell/ErrorPanel';
import { querySelector, useIsPhonePortrait } from 'app/shell/selectors';
import { usePageTitle } from 'app/utils/hooks';
Expand All @@ -22,6 +23,7 @@ import styles from './Vendors.m.scss';
import VendorsMenu from './VendorsMenu';
import {
D2VendorGroup,
filterVendorGroupsToNoSilver,
filterVendorGroupsToSearch,
filterVendorGroupsToUnacquired,
} from './d2-vendors';
Expand All @@ -45,6 +47,7 @@ export default function Vendors({ account }: { account: DestinyAccount }) {
usePageTitle(t('Vendors.Vendors'));

const [filterToUnacquired, setFilterToUnacquired] = useState(false);
const [hideSilverItems, setHideSilverItems] = useSetting('vendorsHideSilverItems');

// once the page is loaded, user can select this
const [userSelectedStoreId, setUserSelectedStoreId] = useState<string>();
Expand Down Expand Up @@ -103,6 +106,9 @@ export default function Vendors({ account }: { account: DestinyAccount }) {
if (vendorGroups && filterToUnacquired) {
vendorGroups = filterVendorGroupsToUnacquired(vendorGroups, ownedItemHashes);
}
if (vendorGroups && hideSilverItems) {
vendorGroups = filterVendorGroupsToNoSilver(vendorGroups);
}
if (vendorGroups && searchQuery.length) {
vendorGroups = filterVendorGroupsToSearch(vendorGroups, searchQuery, filterItems);
}
Expand All @@ -126,6 +132,13 @@ export default function Vendors({ account }: { account: DestinyAccount }) {
>
{t('Vendors.FilterToUnacquired')}
</CheckButton>
<CheckButton
name="vendorsHideSilverItems"
checked={hideSilverItems}
onChange={setHideSilverItems}
>
{t('Vendors.HideSilverItems')}
</CheckButton>
</div>
)}
{!isPhonePortrait && vendorGroups && <VendorsMenu groups={vendorGroups} />}
Expand Down
66 changes: 42 additions & 24 deletions src/app/vendors/d2-vendors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { D2ManifestDefinitions } from 'app/destiny2/d2-definitions';
import { ItemCreationContext } from 'app/inventory/store/d2-item-factory';
import { VENDORS } from 'app/search/d2-known-values';
import { VENDORS, silverItemHash } from 'app/search/d2-known-values';
import { ItemFilter } from 'app/search/filter-types';
import { compareBy } from 'app/utils/comparators';
import { filterMap } from 'app/utils/util';
Expand Down Expand Up @@ -189,46 +189,64 @@ function getVendorItems(
}
}

export function filterVendorGroupsToUnacquired(
function filterVendorGroups(
vendorGroups: readonly D2VendorGroup[],
ownedItemHashes: Set<number>
predicate: (item: VendorItem, vendor: D2Vendor) => boolean | null | undefined
) {
return vendorGroups
.map((group) => ({
...group,
vendors: group.vendors
.map((vendor) => ({
...vendor,
items: vendor.items.filter(
({ item, collectibleState }) =>
item &&
(collectibleState !== undefined
? collectibleState & DestinyCollectibleState.NotAcquired
: item.itemCategoryHashes.includes(ItemCategoryHashes.Mods_Mod) &&
!ownedItemHashes.has(item.hash))
),
items: vendor.items.filter((item) => predicate(item, vendor)),
}))
.filter((v) => v.items.length),
}))
.filter((g) => g.vendors.length);
}

export function filterVendorGroupsToUnacquired(
vendorGroups: readonly D2VendorGroup[],
ownedItemHashes: Set<number>
) {
return filterVendorGroups(
vendorGroups,
({ item, collectibleState }) =>
item &&
(collectibleState !== undefined
? (collectibleState & DestinyCollectibleState.NotAcquired) !== 0
: item.itemCategoryHashes.includes(ItemCategoryHashes.Mods_Mod) &&
!ownedItemHashes.has(item.hash))
);
}

export function filterVendorGroupsToNoSilver(vendorGroups: readonly D2VendorGroup[]) {
return filterVendorGroups(vendorGroups, ({ costs, displayCategoryIndex }, vendor) => {
if (costs.some((c) => c.itemHash === silverItemHash)) {
return false;
}
const categoryIdentifier =
displayCategoryIndex !== undefined &&
displayCategoryIndex >= 0 &&
vendor.def.displayCategories[displayCategoryIndex].identifier;
return !(
categoryIdentifier &&
(categoryIdentifier.startsWith('categories.campaigns') ||
categoryIdentifier.startsWith('categories.featured.carousel'))
);
});
}

export function filterVendorGroupsToSearch(
vendorGroups: readonly D2VendorGroup[],
searchQuery: string,
filterItems: ItemFilter
) {
return vendorGroups
.map((group) => ({
...group,
vendors: group.vendors
.map((vendor) => ({
...vendor,
items: vendor.def.displayProperties.name.toLowerCase().includes(searchQuery.toLowerCase())
? vendor.items
: vendor.items.filter(({ item }) => item && filterItems(item)),
}))
.filter((v) => v.items.length),
}))
.filter((g) => g.vendors.length);
return filterVendorGroups(
vendorGroups,
({ item }, vendor) =>
vendor.def.displayProperties.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
(item && filterItems(item))
);
}
1 change: 1 addition & 0 deletions src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,7 @@
"Collections": "Collections",
"Engram": "Reward Engram",
"FilterToUnacquired": "Only show uncollected items",
"HideSilverItems": "Hide Silver items",
"NoItems": "This Vendor is currently not offering any items.",
"RefreshTime": "Inventory refreshes in:",
"Vendors": "Vendors"
Expand Down

0 comments on commit de1079c

Please sign in to comment.