Skip to content

Commit d98acc8

Browse files
committed
fix: various null checks and logic bugs
- registerkey_injected: create img element per line item so each row shows the icon, not just the last - app: null-check closest('.game_area_purchase_game') before querying inside it - achievements: fix compare-view icon fallback so unlocked users get the color icon even when icon_gray is missing - achievements: re-enable the sort button when the sort fetch fails - subscriptions: null-check the steamdb link and its id child before mutating - gamehub: null-check .apphub_sectionTab and its regex match before reading the appid - profile: early return when the pathname regex doesn't match - inventory: fix badge-data race by sharing a single in-flight fetch via a promise cache
1 parent 34fb5f9 commit d98acc8

File tree

7 files changed

+71
-57
lines changed

7 files changed

+71
-57
lines changed

scripts/community/achievements.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ function InitAchievements( items, isPersonal )
822822
if( isCompareView )
823823
{
824824
const imageCompare = document.createElement( 'img' );
825-
imageCompare.src = `${applicationConfig.MEDIA_CDN_COMMUNITY_URL}images/apps/${appid}/${player.unlockCompare && achievement.icon_gray ? achievement.icon : achievement.icon_gray}`;
825+
imageCompare.src = `${applicationConfig.MEDIA_CDN_COMMUNITY_URL}images/apps/${appid}/${player.unlockCompare || !achievement.icon_gray ? achievement.icon : achievement.icon_gray}`;
826826
imageCompare.className = 'steamdb_achievement_image steamdb_achievement_image_compare';
827827
element.append( imageCompare );
828828
}
@@ -1627,6 +1627,7 @@ function HookSortButton( sortButton, achievementUpdates, oldAchievementRows, Cre
16271627
{
16281628
WriteLog( ex );
16291629
alert( `Failed to sort achievements: ${ex.message}` );
1630+
sortButton.removeAttribute( 'disabled' );
16301631
} );
16311632
}, { once: true } );
16321633
}

scripts/community/gamehub.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ GetOption( {
1515
{
1616
/** @type {HTMLAnchorElement} */
1717
const sectionTab = document.querySelector( '.apphub_sectionTab' );
18-
19-
const match = sectionTab.href.match( /\/([0-9]+)\/?/ );
20-
CurrentAppID = CurrentAppID ? Number.parseInt( match[ 1 ], 10 ) : -1;
18+
const match = sectionTab?.href.match( /\/([0-9]+)\/?/ );
19+
CurrentAppID = match ? Number.parseInt( match[ 1 ], 10 ) : -1;
2120
}
2221

2322
if( GetCurrentAppID() < 1 )

scripts/community/inventory.js

Lines changed: 36 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -568,17 +568,16 @@
568568
} );
569569
}
570570

571-
let badgesDataLoaded = false;
572-
573-
/** @type {any[]} */
574-
let badgesData = [];
571+
/** @type {Promise<any[]> | null} */
572+
let badgesDataPromise = null;
575573

576574
/**
577575
* @param {HTMLElement} element
578576
* @param {any} description
579577
* @param {string} steamid
578+
* @param {any[]} badges
580579
*/
581-
function AddBadgeInformation( element, description, steamid )
580+
function AddBadgeInformation( element, description, steamid, badges )
582581
{
583582
if( !description.market_fee_app )
584583
{
@@ -607,7 +606,7 @@
607606
const CreateLink = ( foil ) =>
608607
`https://steamcommunity.com/profiles/${steamid}/gamecards/${description.market_fee_app}${foil ? '?border=1' : ''}`;
609608

610-
for( const badge of badgesData )
609+
for( const badge of badges )
611610
{
612611
if( badge.appid !== description.market_fee_app )
613612
{
@@ -656,57 +655,47 @@
656655
*/
657656
function LoadBadgeInformation( element, description, steamid )
658657
{
659-
if( badgesDataLoaded )
658+
if( !badgesDataPromise )
660659
{
661-
if( badgesData.length > 0 )
660+
const applicationConfigElement = document.getElementById( 'application_config' );
661+
662+
if( !applicationConfigElement )
662663
{
663-
AddBadgeInformation( element, description, steamid );
664+
return;
664665
}
665666

666-
return;
667-
}
667+
const applicationConfig = JSON.parse( applicationConfigElement.dataset.config );
668+
const accessToken = JSON.parse( applicationConfigElement.dataset.loyalty_webapi_token );
668669

669-
// TODO: This has a race condition if user switches to another item before the fetch request completes
670-
// but the only problem they will get is no badge info will be displayed.
671-
badgesDataLoaded = true;
672-
673-
const applicationConfigElement = document.getElementById( 'application_config' );
670+
if( !accessToken )
671+
{
672+
return;
673+
}
674674

675-
if( !applicationConfigElement )
676-
{
677-
return;
675+
const params = new URLSearchParams();
676+
params.set( 'origin', location.origin );
677+
params.set( 'format', 'json' );
678+
params.set( 'access_token', accessToken );
679+
params.set( 'steamid', steamid );
680+
params.set( 'x_requested_with', 'SteamDB' );
681+
682+
badgesDataPromise = fetch( `${applicationConfig.WEBAPI_BASE_URL}IPlayerService/GetBadges/v1/?${params.toString()}` )
683+
.then( ( response ) => response.json() )
684+
.then( ( /** @type {any} */ response ) => /** @type {any[]} */ ( response.response?.badges ?? [] ) )
685+
.catch( ( /** @type {any} */ err ) =>
686+
{
687+
console.error( '[SteamDB] Badge info error', err );
688+
return /** @type {any[]} */ ( [] );
689+
} );
678690
}
679691

680-
const applicationConfig = JSON.parse( applicationConfigElement.dataset.config );
681-
const accessToken = JSON.parse( applicationConfigElement.dataset.loyalty_webapi_token );
682-
683-
if( !accessToken )
692+
badgesDataPromise.then( ( badges ) =>
684693
{
685-
return;
686-
}
687-
688-
const params = new URLSearchParams();
689-
params.set( 'origin', location.origin );
690-
params.set( 'format', 'json' );
691-
params.set( 'access_token', accessToken );
692-
params.set( 'steamid', steamid );
693-
params.set( 'x_requested_with', 'SteamDB' );
694-
695-
fetch( `${applicationConfig.WEBAPI_BASE_URL}IPlayerService/GetBadges/v1/?${params.toString()}` )
696-
.then( ( response ) => response.json() )
697-
.then( ( response ) =>
694+
if( badges.length > 0 )
698695
{
699-
if( response.response?.badges )
700-
{
701-
badgesData = response.response.badges;
702-
703-
AddBadgeInformation( element, description, steamid );
704-
}
705-
} )
706-
.catch( ( err ) =>
707-
{
708-
console.error( '[SteamDB] Badge info error', err );
709-
} );
696+
AddBadgeInformation( element, description, steamid, badges );
697+
}
698+
} );
710699
}
711700

712701
/**

scripts/community/profile.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,14 @@ GetOption( {
3737
else
3838
{
3939
// Fallback to url if we can't
40-
steamID = location.pathname.match( /^\/(?:id|profiles)\/([^\s/]+)\/?/ )[ 1 ];
40+
const pathMatch = location.pathname.match( /^\/(?:id|profiles)\/([^\s/]+)\/?/ );
4141

42+
if( !pathMatch )
43+
{
44+
return;
45+
}
46+
47+
steamID = pathMatch[ 1 ];
4248
isCommunityID = /^\/profiles/.test( location.pathname );
4349
}
4450

scripts/store/app.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,14 @@ else
281281

282282
for( const bundleElement of container )
283283
{
284-
InsertPurchaseBlockId( bundleElement.closest( '.game_area_purchase_game' ).querySelector( '.game_purchase_action' ), 'bundle', Number.parseInt( bundleElement.value, 10 ) );
284+
const purchaseGame = bundleElement.closest( '.game_area_purchase_game' );
285+
286+
if( !purchaseGame )
287+
{
288+
continue;
289+
}
290+
291+
InsertPurchaseBlockId( purchaseGame.querySelector( '.game_purchase_action' ), 'bundle', Number.parseInt( bundleElement.value, 10 ) );
285292
}
286293

287294
// We have to inject our JS directly into the page to hook Steam's functionality

scripts/store/registerkey_injected.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@
4242
const fragment = document.createElement( 'div' );
4343
fragment.className = 'steamdb_registerkey_lineitem';
4444

45-
const image = document.createElement( 'img' );
46-
image.src = script.dataset.icon;
47-
4845
for( const item of line_items )
4946
{
5047
const lineitem = document.createElement( 'div' );
5148
lineitem.className = 'registerkey_lineitem';
49+
50+
const image = document.createElement( 'img' );
51+
image.src = script.dataset.icon;
5252
lineitem.append( image );
5353

5454
let link = document.createElement( 'a' );

scripts/store/subscriptions.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,20 @@
2323

2424
/** @type {HTMLAnchorElement} */
2525
const link = cartForm.parentNode.querySelector( '.steamdb_link' );
26+
27+
if( !link )
28+
{
29+
return;
30+
}
31+
2632
link.hidden = false;
2733
link.href = `${homepage}sub/${subId}/`;
28-
link.querySelector( '.steamdb_link_id' ).textContent = subId.toString();
34+
35+
const linkId = link.querySelector( '.steamdb_link_id' );
36+
37+
if( linkId )
38+
{
39+
linkId.textContent = subId.toString();
40+
}
2941
};
3042
} )() );

0 commit comments

Comments
 (0)