diff --git a/src/js/Content/Features/Store/Wishlist/CWishlist.js b/src/js/Content/Features/Store/Wishlist/CWishlist.js index dec1f0157..e9cb2fc3e 100644 --- a/src/js/Content/Features/Store/Wishlist/CWishlist.js +++ b/src/js/Content/Features/Store/Wishlist/CWishlist.js @@ -11,6 +11,7 @@ import FEmptyWishlist from "./FEmptyWishlist"; import FExportWishlist from "./FExportWishlist"; import FKeepEditableRanking from "./FKeepEditableRanking"; import FOneClickRemoveFromWishlist from "./FOneClickRemoveFromWishlist"; +import FWishlistDemoLink from "./FWishlistDemoLink"; export class CWishlist extends CStoreBase { @@ -35,6 +36,7 @@ export class CWishlist extends CStoreBase { FExportWishlist, FKeepEditableRanking, FOneClickRemoveFromWishlist, + FWishlistDemoLink, ]); this.wishlistData = wishlistData; diff --git a/src/js/Content/Features/Store/Wishlist/FWishlistDemoLink.js b/src/js/Content/Features/Store/Wishlist/FWishlistDemoLink.js new file mode 100644 index 000000000..07df6682a --- /dev/null +++ b/src/js/Content/Features/Store/Wishlist/FWishlistDemoLink.js @@ -0,0 +1,44 @@ +import {Localization} from "../../../../modulesCore"; +import {CallbackFeature, RequestData} from "../../../modulesContent"; + +export default class FWishlistDemoLink extends CallbackFeature { + + async checkPrerequisites() { + + this._info = []; + + const appids = this.context.wishlistData.map(({appid}) => `appids[]=${appid}`); + + // https://stackoverflow.com/questions/8495687/split-array-into-chunks + const chunkSize = 400; // Split params into chunks as Steam may throw `HTTP 414 Request-URI Too Large` + + for (let i = 0; i < appids.length; i += chunkSize) { + const params = appids.slice(i, i + chunkSize).join("&"); + + const data = await RequestData.getJson(`https://store.steampowered.com/saleaction/ajaxgetdemoevents?${params}`).catch(err => console.error(err)); + if (!data || !data.success || !data.info) { continue; } + + this._info = this._info.concat(data.info.filter(val => Boolean(val.demo_appid))); + } + + return this._info.length > 0; + } + + callback(nodes) { + + for (const node of nodes) { + + if (node.querySelector(".as_wl_demo_link") !== null) { continue; } + + const rowAppid = Number(node.dataset.appId); + const demoAppid = this._info.find(({appid}) => appid === rowAppid)?.demo_appid; + if (typeof demoAppid === "undefined") { continue; } + + const link = document.createElement("a"); + link.href = `steam://install/${demoAppid}`; + link.textContent = Localization.str.download_demo; + link.classList.add("as_wl_demo_link", "earlyaccess"); + node.querySelector(".platform_icons").prepend(link); + } + } +} diff --git a/src/localization/en.json b/src/localization/en.json index 855b5d64b..782ae20c1 100644 --- a/src/localization/en.json +++ b/src/localization/en.json @@ -8,6 +8,7 @@ "continue": "Yes, continue shopping" }, "download_demo_header": "Download __gamename__ Demo", + "download_demo": "Download Demo", "deck_compat": { "header": "Steam Deck Compatibility", "unknown": "Unknown",