diff --git a/src/lib/components/inventory/selected_item_info.ts b/src/lib/components/inventory/selected_item_info.ts index 0d4ea3c..7317d03 100644 --- a/src/lib/components/inventory/selected_item_info.ts +++ b/src/lib/components/inventory/selected_item_info.ts @@ -1,11 +1,19 @@ import {FloatElement} from '../custom'; import {CustomElement, InjectAfter, InjectionMode} from '../injectors'; -import {html, css, TemplateResult, HTMLTemplateResult, nothing} from 'lit'; +import {html, css, TemplateResult, HTMLTemplateResult} from 'lit'; import {state} from 'lit/decorators.js'; import {InventoryAsset} from '../../types/steam'; import {gFloatFetcher} from '../../services/float_fetcher'; import {ItemInfo} from '../../bridge/handlers/fetch_inspect_info'; -import {formatSeed, getFadePercentage, isSkin, renderClickableRank, floor, isCharm} from '../../utils/skin'; +import { + formatSeed, + getFadePercentage, + isSkin, + renderClickableRank, + floor, + isCharm, + isSellableOnCSFloat, +} from '../../utils/skin'; import {Observe} from '../../utils/observers'; import {FetchStallResponse} from '../../bridge/handlers/fetch_stall'; import {gStallFetcher} from '../../services/stall_fetcher'; @@ -86,33 +94,40 @@ export class SelectedItemInfo extends FloatElement { return html`
Loading...
`; } - if (!this.itemInfo || !this.asset?.description) { + if (!this.asset?.description) { return html``; } - if (isSkin(this.asset.description)) { - const fadePercentage = this.asset && getFadePercentage(this.asset.description, this.itemInfo); - - return html` -
-
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
-
Paint Seed: ${formatSeed(this.itemInfo)}
- ${fadePercentage !== undefined ? html`
Fade: ${floor(fadePercentage, 5)}%
` : nothing} - ${this.renderListOnCSFloat()} ${this.renderFloatMarketListing()} -
- `; - } else if (isCharm(this.asset.description)) { - return html` -
-
- Pattern: - #${this.itemInfo.keychains?.length > 0 ? this.itemInfo.keychains[0].pattern : 'Unknown'} -
-
- `; - } else { + const containerChildren: TemplateResult[] = []; + + if (isSkin(this.asset.description) && this.itemInfo) { + containerChildren.push( + html`
Float: ${this.itemInfo.floatvalue.toFixed(14)} ${renderClickableRank(this.itemInfo)}
` + ); + + containerChildren.push(html`
Paint Seed: ${formatSeed(this.itemInfo)}
`); + + const fadePercentage = getFadePercentage(this.asset.description, this.itemInfo); + if (fadePercentage !== undefined) { + containerChildren.push(html`
Fade: ${floor(fadePercentage, 5)}%
`); + } + } else if (isCharm(this.asset.description) && this.itemInfo) { + containerChildren.push( + html`
+ Pattern: #${this.itemInfo.keychains?.length > 0 ? this.itemInfo.keychains[0].pattern : 'Unknown'} +
` + ); + } + + if (isSellableOnCSFloat(this.asset.description)) { + containerChildren.push(html`${this.renderListOnCSFloat()} ${this.renderFloatMarketListing()}`); + } + + if (containerChildren.length === 0) { return html``; } + + return html`
${containerChildren}
`; } renderFloatMarketListing(): TemplateResult<1> { @@ -146,7 +161,7 @@ export class SelectedItemInfo extends FloatElement { return html`
- + List on @@ -160,21 +175,19 @@ export class SelectedItemInfo extends FloatElement { if (!this.asset) return; - if (!isSkin(this.asset.description) && !isCharm(this.asset.description)) return; + // Guarantees a re-render for items without inspect links + this.loading = true; - // Commodities won't have inspect links - if (!this.inspectLink) return; - - try { - this.loading = true; - this.itemInfo = await gFloatFetcher.fetch({ - link: this.inspectLink, - }); - } catch (e: any) { - console.error(`Failed to fetch float for ${this.asset.assetid}: ${e.toString()}`); - } finally { - this.loading = false; + if (this.inspectLink && (isSkin(this.asset.description) || isCharm(this.asset.description))) { + try { + this.itemInfo = await gFloatFetcher.fetch({ + link: this.inspectLink, + }); + } catch (e: any) { + console.error(`Failed to fetch float for ${this.asset.assetid}: ${e.toString()}`); + } } + this.loading = false; } connectedCallback() { diff --git a/src/lib/utils/skin.ts b/src/lib/utils/skin.ts index 5ef0c78..b398255 100644 --- a/src/lib/utils/skin.ts +++ b/src/lib/utils/skin.ts @@ -104,6 +104,10 @@ export function renderClickableRank(info: ItemInfo): TemplateResult<1> { `; } +export function isSellableOnCSFloat(asset: rgAsset): boolean { + return isSkin(asset) || isCharm(asset) || isAgent(asset) || isSticker(asset) || isPatch(asset) || isCase(asset); +} + export function isSkin(asset: rgAsset): boolean { return asset.tags ? asset.tags.some((a) => a.category === 'Weapon' || (a.category === 'Type' && a.internal_name === 'Type_Hands')) @@ -113,8 +117,27 @@ export function isSkin(asset: rgAsset): boolean { } export function isCharm(asset: rgAsset): boolean { - if (asset.market_hash_name.startsWith('Charm')) { - // Tags aren't available on SCM items, so use a MHN heuristic instead + return isAbstractType(asset, 'Charm', 'CSGO_Type_Charm'); +} + +export function isAgent(asset: rgAsset): boolean { + return isAbstractType(asset, 'Agent', 'Type_CustomPlayer'); +} + +export function isSticker(asset: rgAsset): boolean { + return isAbstractType(asset, 'Sticker', 'CSGO_Tool_Sticker'); +} + +export function isPatch(asset: rgAsset): boolean { + return isAbstractType(asset, 'Patch', 'CSGO_Type_Patch'); +} + +export function isCase(asset: rgAsset): boolean { + return isAbstractType(asset, 'Container', 'CSGO_Type_WeaponCase'); +} + +function isAbstractType(asset: rgAsset, type: string, internalName: string): boolean { + if (asset.type.endsWith(type)) { return true; } @@ -122,7 +145,7 @@ export function isCharm(asset: rgAsset): boolean { return false; } - return asset.tags.some((e) => e.category === 'Type' && e.internal_name === 'CSGO_Tool_Keychain'); + return asset.tags.some((e) => e.category === 'Type' && e.internal_name === internalName); } export function getFadeCalculatorAndSupportedWeapon(