',{'class': 'hero_tags_ctn'});
for( var i=0; i < rgItemData.tags.length; i++)
{
$elTagContainer.append($J('
', {'class': 'hero_tag'}).text( rgItemData.tags[i] ));
}
HeroContent.append($elTagContainer);
}
HeroData.append( HeroContent );
var AddToCartCtn = $J( '
', {'class': 'hero_add_to_cart' } );
AddToCartCtn.append( $J( '
', {'class': 'btn_green_white_innerfade btn_medium', } ).click( function( e ){ eval( purchaseAction ); } ).append( $J( '
' ).text( 'Add to Cart' ) ) );
HeroData.append( AddToCartCtn );
$Cap.append( HeroData );
$Cap.append( $J( rgItemData.discount_block ).addClass( 'discount_block_inline hero_discount' ) );
return $Cap;
}
function HomeSaleFilterHeroes( $Parent, rgHeroItems )
{
var Settings = { games_already_in_library: false, localized: true, only_current_platform: true, enforce_minimum: true };
var $HeroItemCtn = $Parent.find('.carousel_items' );
var rgFilteredHeroes = GHomepage.FilterItemsForDisplay( rgHeroItems, 'home', 3, 42, Settings );
GDynamicStore.MarkItemsAsDisplayed( rgFilteredHeroes );
// generate carousel based on sorted and filtered hero capsules
GHomepage.FillPagedCapsuleCarousel( rgFilteredHeroes, $Parent.find('.carousel_container'), function( oItem, strFeature, rgOptions ) { return fnRenderHeroCapsule( oItem ); }, 'sale-hero', 3 );
$HeroItemCtn.find('.hero_capsule:not(.hidden)').children('a').each( function() {
ModifyLinkSNR( $J(this), function( snr ) { return GStoreItemData.rgNavParams['sale_heroes_priority'] } );
});
$J('.hero_capsule').on( 'mouseenter vgp_onfocus touchstart', function() {
$J(this).find('.hero_screenshot_load').each( function() { $J(this).css( 'backgroundImage', $J(this).data('background') ); } );
} );
$J('.hero_capsule:not(.valveindex)').on( 'mouseenter vgp_onfocus', function() {
if ( $J(this).find('video.hero_video').length )
$J(this).find('video.hero_video')[0].play();
} );
$J('.hero_capsule:not(.valveindex)').on( 'mouseleave vgp_onblur', function() {
if ( $J(this).find('video.hero_video').length )
$J(this).find('video.hero_video')[0].pause();
} );
$HeroItemCtn.css('minHeight', '' );
}
function HomeSaleSteamAwardWinners( $Parent, rgSteamAwardWinners, rgSteamAwardDefs )
{
const rgSteamAwardWinnerFiltered = GHomepage.FilterItemsForDisplay( rgSteamAwardWinners, 'home', 0, 11, { games_already_in_library: true, localized: true, displayed_elsewhere: false, only_current_platform: false, virtual_reality: true } );
GDynamicStore.MarkAppDisplayed( rgSteamAwardWinnerFiltered );
if ( !rgSteamAwardWinnerFiltered.length )
{
$Parent.hide();
return;
}
const mapFilteredAppIDs = new Map();
for( let i = 0; i < rgSteamAwardWinnerFiltered.length; i++ )
{
const item = rgSteamAwardWinnerFiltered[i];
mapFilteredAppIDs.set( item.appid, true );
}
let $WinnerCapsules = $Parent.find('.winner_grid' );
rgSteamAwardDefs.forEach( function ( def, i ) {
if ( !def.winner_appid )
return;
if ( !mapFilteredAppIDs.has( def.winner_appid ) )
return;
let params = { 'class': 'winner_ctn' };
const rgItemData = GStoreItemData.GetCapParams( 'sale_steamawards', def.winner_appid, null, null, params );
if ( !rgItemData )
return;
let purchaseAction = 'addToCart( %subid% )'.replace( '%subid%', rgItemData.pricing_subid );
let $Cap = $J( '
', {'class': 'winner_ctn', 'data-panel': '{"clickOnActivate":"firstChild","onOptionsActionDescription":"Add to Cart","onOptionsButton":"%onOptionsButton%","flow-children":"column"}'.replace( '%onOptionsButton%', purchaseAction ) } );
$Cap.append( $J('
', {'class': 'hero_click_overlay', 'href': params['href'], 'aria-label': rgItemData.name } ) );
$Cap.append( $J('
', {'class': 'category_background', 'style': 'background-image: url( \'https://cdn.cloudflare.steamstatic.com/store/promo/steamawards2023/backgrounds/awardbg_' + def.voteid +'.jpg\');' } ) );
let $Content = $J('
', {'class': 'category_content' } );
$Content.append( $J('
', {'class': 'category_title' } ).append( def.localization.title_linebreak.replace( '<1>1>', '
' ).replace( '<2>2>', '
' ) ) );
let $Images = $J('
', {'class': 'game_capsule' } );
$Images.append( $J('
', {'src': rgItemData.hero_capsule } ) );
$Images.append( $J('
', {'src': rgItemData.main_capsule } ) );
$Content.append( $Images );
$Cap.append( $Content );
$Cap.append( $J( rgItemData.discount_block ).addClass( 'discount_block_inline' ) );
$WinnerCapsules.append( $Cap );
} );
}
function HomeRenderFeaturedItems( rgDisplayLists, rgTagData, rgFranchiseData, rgSteamAwardDefs )
{
var k_nTier1ItemsMin = 14;
var k_nTier1ItemsMax = 14;
var k_nTier2ItemsMin = 14;
var k_nTier2ItemsMax = 14;
if ( rgDisplayLists.steam_award_winners && rgSteamAwardDefs )
{
HomeSaleSteamAwardWinners( $J( '.home_steamawards_ctn' ), rgDisplayLists.steam_award_winners, rgSteamAwardDefs );
}
else
{
HomeSaleFilterHeroes( $J('.hero_parent_ctn'), SortItemListByPriorityList( rgDisplayLists.heros, 'tier1' ) );
}
var rgAllTier1Items = GHomepage.MergeLists( rgDisplayLists.sale_tier1, false, rgDisplayLists.sale_tier1_fallback, false );
var rgTier1 = GHomepage.FilterItemsForDisplay(
SortItemListByPriorityList( rgAllTier1Items, 'tier1' ), 'home', k_nTier1ItemsMin, k_nTier1ItemsMax, { games_already_in_library: false, localized: true, displayed_elsewhere: false, only_current_platform: true, enforce_minimum: true }
);
GDynamicStore.MarkAppDisplayed( rgTier1 );
var rgAllTier2Items = GHomepage.MergeLists( rgDisplayLists.sale_tier2, false, rgDisplayLists.sale_tier2_fallback, false );
var rgTier2 = GHomepage.FilterItemsForDisplay(
SortItemListByPriorityList( rgAllTier2Items, 'tier2' ), 'home', k_nTier2ItemsMin, k_nTier2ItemsMax, { games_already_in_library: false, localized: true, displayed_elsewhere: false, only_current_platform: true, enforce_minimum: true }
);
GDynamicStore.MarkAppDisplayed( rgTier2 );
HomeSaleBlock( rgTier1, $J('#tier1_target' ), 'sale_dailydeals_priority' );
var $FranchiseBlock = $J('#franchise_target' );
new CScrollOffsetWatcher( $FranchiseBlock, function() {
SaleFranchiseBlock( $FranchiseBlock, rgFranchiseData );
});
var $Tier2 = $J('#tier2_target' );
new CScrollOffsetWatcher( $Tier2, function() { HomeSaleBlock( rgTier2, $Tier2, 'sale_dailydeals_t2_priority' ); } );
var $UserArea = $J('#home_sale_account_ctn');
if ( $UserArea.length )
{
if ( g_AccountID )
{
new CScrollOffsetWatcher( $UserArea, function() {
$J.get( 'https://store.steampowered.com/default/home_sale_data', {u: g_AccountID } ).done( function( data ) {
GStoreItemData.AddStoreItemDataSet( data.StoreItemData );
RenderWishlistAndDLCArea( $UserArea, data.rgWishlistOnSale, data.rgDLCOnSale );
}).fail( function() {
$UserArea.hide();
});
});
}
else
{
$UserArea.hide();
}
}
var $DiscountsArea = $J('#sale_discounts_area');
new CScrollOffsetWatcher( $DiscountsArea, function() {
SaleRenderDiscountsArea( rgDisplayLists.under10, rgDisplayLists.sale_deals );
$DiscountsArea.css('height', '' );
} );
// process tag sections first, pulling in featured items into the tag blocks we display
var $TagBlock = $J('#sale_tag_categories');
if ( $TagBlock.length )
{
new CScrollOffsetWatcher( $TagBlock, function() {
var rgPersonalizedTagData = GenerateTagBlocks( rgTagData, rgDisplayLists.sale_tier1, rgDisplayLists.sale_tier2 );
for ( var iTag = 0; iTag < rgPersonalizedTagData.length; iTag++ )
{
SaleTagBlock( $TagBlock, rgPersonalizedTagData[iTag] );
}
});
}
// filter dupes from tab lists
GDynamicStorePage.FilterCapsules( 16, 16, $J( '#popular_new_releases_content .tab_content_items' ).children('.sale_capsule'), $J( '#popular_new_releases_content' ), { only_current_platform: true, games_already_in_library: false, localized: true, enforce_minimum: true } );
GDynamicStorePage.FilterCapsules( 16, 16, $J( '#tab_upcoming_content .tab_content_items' ).children('.sale_capsule'), $J( '#tab_upcoming_content' ), { prepurchase: true, games_already_in_library: true, localized: true, enforce_minimum: true } );
GDynamicStorePage.FilterCapsules( 16, 16, $J( '#topsellers_tier' ).children('.sale_capsule'), $J( '#topsellers_tier' ), {dlc_for_you: true, games_already_in_library: true, localized: true, enforce_minimum: true } );
// NOTE: If we are already using home.js, then we don't need this. Found we were doubling up the streams
// GSteamBroadcasts.Init( GHomepage.FilterItemsForDisplay );
AddMicrotrailersToStaticCaps( $J('.home_topsellers_games_ctn' ) );
AddMicrotrailersToStaticCaps( $J('.home_newupcoming_games_ctn') );
// Render the featured events section
// RenderSeasonalSaleInGameEventsCarousel( rgFeaturedSeasonEvents, rgDisplayLists.feature_event_apps );
}
function TryPopulateSaleItems( rgDisplayedItems, rgOriginalItemList, cMinItems, cMaxItems )
{
if ( rgDisplayedItems.length < cMinItems )
{
// fill with items that the user might already own
AddItemsIfNotPresent( rgDisplayedItems, GHomepage.FilterItemsForDisplay(
rgOriginalItemList, 'home', cMinItems, cMaxItems, { games_already_in_library: true, localized: true, displayed_elsewhere: true, only_current_platform: true }
), cMinItems );
}
if ( rgDisplayedItems.length < cMinItems )
{
AddItemsIfNotPresent( rgDisplayedItems, rgOriginalItemList, cMinItems );
}
}
function HomeSaleBlock( rgItems, $Parent, strFeatureContext )
{
var rgRemainingItems = rgItems;
if ( !strFeatureContext )
strFeatureContext = 'sale_dailydeals';
var bFourRow = true;
while( rgRemainingItems.length )
{
if ( rgRemainingItems.length < 4 || rgRemainingItems.length == 6 || rgRemainingItems.length == 9 )
bFourRow = false;
else if ( rgRemainingItems.length == 4 )
bFourRow = true;
rgRemainingItems = SaleRow( rgRemainingItems, $Parent, bFourRow ? 4 : 3, strFeatureContext, SaleCap );
bFourRow = !bFourRow;
}
BindSaleCapAutoSizeEvents( $Parent );
GDynamicStore.DecorateDynamicItems( $Parent );
$Parent.css('height','');
}
function HomeSaleCapsuleCategory( rgItems, $Parent, strFeatureContext )
{
if ( !rgItems )
{
$Parent.hide();
return;
}
if ( !strFeatureContext )
strFeatureContext = 'sale_categories';
var rgCapsules = GHomepage.FilterItemsForDisplay(
rgItems, 'home', 4, 16, { games_already_in_library: false, localized: true, displayed_elsewhere: false, only_current_platform: true }
);
if ( rgCapsules.length < 4 )
{
rgCapsules = GHomepage.FilterItemsForDisplay(
rgItems, 'home', 4, 16, { games_already_in_library: false, localized: true, only_current_platform: true }
);
}
if ( rgCapsules.length >= 4 )
{
GHomepage.FillPagedCapsuleCarousel( rgCapsules, $Parent.find('.carousel_container'), function( oItem, strFeature, rgOptions ) {
return GHomepage.BuildHomePageGenericCap(strFeature, oItem.appid, oItem.packageid, oItem.bundleid, rgOptions);
} , strFeatureContext, 4 );
}
else
{
$Parent.hide();
}
}
function SaleRow( rgItems, $Parent, nItems, strFeatureContext, fnRenderFunc )
{
var rgItemsThisRow = rgItems.slice( 0, nItems );
if ( !fnRenderFunc )
fnRenderFunc = SaleCap;
if ( rgItemsThisRow.length <= 3 )
{
var $Row = $J('
', {'class': 'salerow salerow3' } );
$Row.append(
rgItemsThisRow[0] && fnRenderFunc( rgItemsThisRow[0], strFeatureContext, 'discount_block_inline' ),
rgItemsThisRow[1] && fnRenderFunc( rgItemsThisRow[1], strFeatureContext, 'discount_block_inline' ),
rgItemsThisRow[2] && fnRenderFunc( rgItemsThisRow[2], strFeatureContext, 'discount_block_inline' )
);
$Parent.append( $Row );
}
else
{
var $Row = $J('
', {'class': 'salerow salerow4' } );
$Row.append(
fnRenderFunc( rgItemsThisRow[0], strFeatureContext, 'discount_block_inline' ),
fnRenderFunc( rgItemsThisRow[1], strFeatureContext, 'discount_block_inline' ),
fnRenderFunc( rgItemsThisRow[2], strFeatureContext, 'discount_block_inline' ),
fnRenderFunc( rgItemsThisRow[3], strFeatureContext, 'discount_block_inline' )
);
$Parent.append( $Row );
}
return rgItems.slice( rgItemsThisRow.length );
}
function SaleCap( item, strFeatureContext, strDiscountClass, bUseSmallCap, bPreferHeaderImg )
{
var params = { 'class': 'sale_capsule' };
if( item && item.feature && item.feature.length > 0 )
{
strFeatureContext = item.feature;
}
var rgItemData = GStoreItemData.GetCapParamsForItem( strFeatureContext, item, params );
if ( !rgItemData )
return;
var $CapCtn = $J('
', params );
GStoreItemData.BindHoverEventsForItem( $CapCtn, item );
var $Img;
if ( bUseSmallCap )
{
$Img = $J( '
', {'class': 'sale_capsule_image', 'src': rgItemData['small_capsule'] } );
}
else
{
if ( bPreferHeaderImg && typeof rgItemData['header'] !== 'undefined' )
{
$Img = $J( '
', {'class': 'sale_capsule_image autosize', 'src': 'https://store.cloudflare.steamstatic.com/public/images/v6/home/header_placeholder_460x215.gif' } );
$Img.data('src-header', rgItemData['header'] );
}
else
{
$Img = $J( '
', {'class': 'sale_capsule_image autosize', 'src': 'https://store.cloudflare.steamstatic.com/public/images/v6/home/maincap_placeholder_616x353.gif' } );
$Img.data('src-maincap', rgItemData['main_capsule'] );
}
$Img.data('src-smallcap', rgItemData['small_capsule'] );
}
$Img.attr( 'alt', rgItemData['name'] );
$CapCtn.append( $J('
', {'class': 'sale_capsule_image_ctn' } ).append( $J('
', {'class': 'sale_capsule_image_hover'} ), $Img ) );
$CapCtn.append( rgItemData.discount_block ? $J(rgItemData.discount_block).addClass( strDiscountClass ) : '' );
var rgAppInfo = GStoreItemData.rgAppData[ item.appid ];
if ( rgAppInfo && rgAppInfo.has_live_broadcast )
{
$CapCtn.append(
$J('
', {'class': 'broadcast_live_stream_icon' } ).append( 'Live')
);
}
AddMicrotrailer( $CapCtn, rgItemData.microtrailer );
return $CapCtn;
}
function AddMicrotrailer( $CapCtn, microtrailer )
{
if ( !microtrailer )
return;
$CapCtn.addClass( 'with_microtrailer' );
$CapCtn.data('hoverDisableScreenshots', true );
var $ImgCtn = $CapCtn.children('.sale_capsule_image_ctn');
$CapCtn.one( 'mouseenter vgp_onfocus', function()
{
let $Video = null;
if ( !$ImgCtn.children( '.sale_capsule_video' ).length )
{
$Video = $J('
', {'class': 'sale_capsule_video', loop: true, preload: 'none' }).prop( "muted", true )
.append($J("