class Home { static start() { this.cache = { items: undefined, item: new Map(), }; this.config = new Config(); this.itemQuery = this.config.itemQuery; this.coverOptions = { type: "Backdrop", maxWidth: 3000 }; this.logoOptions = { type: "Logo", maxWidth: 3000 }; // this.initStart = false; let isStatic = 2; let isLoad = true; this.HomeInterval = setInterval(() => { if (window.ApiClient != undefined) { //获取ApiClientuserView if (ApiClient._userViewsPromise != null) { ApiClient._userViewsPromise.then(vlaue => { let itemId = new Array(); vlaue.Items.forEach(item => { itemId.push(item.Id) }); this.config.parentIds = this.config.parentIds.filter(value => itemId.includes(value)); //this.initStart = false; isStatic = isStatic & 1; if (this.config.parentIds.length !== 0) { isStatic = isStatic | 1; } else { clearInterval(this.HomeInterval); isLoad = false; $(".misty-loading").fadeOut(5, () => $(".misty-loading").remove()); } }); } } if (window.location.href.indexOf("!/home") != -1) { if ($(".view:not(.hide) .misty-banner").length == 0 && $(".misty-loading").length == 0) { //this.initStart = false; //0 isStatic = isStatic & 1; if (isLoad) { this.initLoading(); } } if (window.ApiClient == undefined) { //this.initStart = true; //1 isStatic = isStatic | 2; } if (isStatic & 1 == 1 && $(".hide .misty-banner").length != 0) { //1 $(".hide .misty-banner").remove(); } if (isStatic == 1 && $(".section0 .card").length != 0 && $(".view:not(.hide) .misty-banner").length == 0) { //this.initStart = true; //1 1 isStatic = isStatic | 2; this.init(); } } else { if ($(".misty-loading").length == 1) { $(".misty-loading").fadeOut(5, () => $(".misty-loading").remove()); } } }, 233); } static async init() { // Beta $(".view:not(.hide)").attr("data-type", "home"); // Loading const serverName = await this.injectCall("serverName", ""); $(".misty-loading h1").text(serverName).addClass("active"); // Banner await this.initBanner(); this.initEvent(); } /* 插入Loading */ static initLoading() { const load = `

`; $("body").append(load); } static injectCode(code) { let hash = md5(code + Math.random().toString()); return new Promise((resolve, reject) => { if ("BroadcastChannel" in window) { const channel = new BroadcastChannel(hash); channel.addEventListener("message", (event) => resolve(event.data)); } else if ("postMessage" in window) { window.addEventListener("message", (event) => { if (event.data.channel === hash) { resolve(event.data.message); } }); } const script = ` `; $(document.head || document.documentElement).append(script); }); } static injectCall(func, arg) { const script = ` // const client = (await window.require(["ApiClient"]))[0]; const client = await new Promise((resolve, reject) => { setInterval(() => { if (window.ApiClient != undefined) resolve(window.ApiClient); }, 16); }); return await client.${func}(${arg}) `; return this.injectCode(script); } static getItems(query) { //由于要合并多个媒体库所以放弃做临时缓存 //if (this.cache.items == undefined) { // this.cache.items = this.injectCall("getItems", "client.getCurrentUserId(), " + JSON.stringify(query)); //} //return this.cache.items; return this.injectCall("getItems", "client.getCurrentUserId(), " + JSON.stringify(query)); } static itemsRandom(array) { let res = [], random; while (array.length > 0) { random = Math.floor(Math.random() * array.length); res.push(array[random]); array.splice(random, 1); } return res; } static async getItem(itemId) { // 双缓存 优先使用 WebStorage if (typeof Storage !== "undefined" && !localStorage.getItem("CACHE|" + itemId) && !this.cache.item.has(itemId)) { const data = JSON.stringify(await this.injectCall("getItem", `client.getCurrentUserId(), "${itemId}"`)); if (typeof Storage !== "undefined") localStorage.setItem("CACHE|" + itemId, data); else this.cache.item.set(itemId, data); } return JSON.parse(typeof Storage !== "undefined" ? localStorage.getItem("CACHE|" + itemId) : this.cache.item.get(itemId)); } static getImageUrl(itemId, options) { return this.injectCall("getImageUrl", itemId + ", " + JSON.stringify(options)); } static async appendItem(i) { const detail = await this.getItem(this.data.Items[i].Id), itemHtml = `
Backdrop

${detail.Name}

${detail.Overview}

`, logoHtml = ` `; if (detail.ImageTags && detail.ImageTags.Logo) { $(".misty-banner-logos").append(logoHtml); } $(".misty-banner-body").append(itemHtml); console.log(this.data.Items[i].Id, detail); } static async bannerRoll() { if (!window.location.href.endsWith("home")) { return; } // 背景切换 this.index += this.index + 1 == $(".misty-banner-item").length ? -this.index : 1; //已经切换到最后且总数大于10 if (this.index == 0 && this.data.Items.length >= 10) { clearInterval(this.bannerInterval); let l = $(".misty-banner-item").length; //剩余小于10张直接舍弃,从头开始 if (this.count + 1 == this.data.Items.length || this.data.Items.length - this.count - 1 < 10) this.count = -1; //向后添加,剩余10张以上添加10张 for (let i = this.count + 1; i < this.count + 1 + (this.data.Items.length - this.count - 1 < 10 ? this.data.Items.length - this.count - 1 : 10); i++) { await this.appendItem(i) } //切换到第一张 $(".misty-banner-body").css("left", "0%"); $(".misty-banner-item.active").removeClass("active"); let id = $(".misty-banner-item").eq(l).addClass("active").attr("id"); $(".misty-banner-logo.active").removeClass("active"); $(`.misty-banner-logo[id=${id}]`).addClass("active"); //从dom中移除上一轮次的横幅 for (let i = 0; i < l; i++) { $(".misty-banner-item").eq(0).remove(); } this.bannerInterval = setInterval(this.bannerRoll.bind(this), this.config.interval); } else { $(".misty-banner-body").css("left", -(this.index * 100).toString() + "%"); // 信息切换 $(".misty-banner-item.active").removeClass("active"); let id = $(".misty-banner-item").eq(this.index).addClass("active").attr("id"); // LOGO切换 $(".misty-banner-logo.active").removeClass("active"); $(`.misty-banner-logo[id=${id}]`).addClass("active"); } this.count++; } /* 插入Banner */ static async initBanner() { const banner = `
`; $(".view:not(.hide) .homeSectionsContainer").prepend(banner); // $(".view:not(.hide) .section0").detach().appendTo(".view:not(.hide) .misty-banner-library"); // 插入数据 this.data = { Items: [] } //配置的媒体库不为空 if (this.config.parentIds[0] != "") { console.log(this.config.parentIds); //合并所有配置的媒体库的结果 for (let parentId of this.config.parentIds) { this.itemQuery.ParentId = parentId; let res = await this.getItems(this.itemQuery); this.data.Items = this.data.Items.concat(res.Items); } } else { //查询所有媒体库 this.itemQuery = { ImageTypes: "Backdrop", EnableImageTypes: "Logo,Backdrop", IncludeItemTypes: "Movie,Series", SortBy: "ProductionYear, PremiereDate, SortName", Recursive: true, ImageTypeLimit: 1, Limit: 10, Fields: "ProductionYear", SortOrder: "Descending", EnableUserData: false, EnableTotalRecordCount: false }; this.data = await this.getItems(this.itemQuery); } console.log(this.data); if (this.config.random == true) { this.data.Items = this.itemsRandom(this.data.Items); } //大于10时添加10张 for (let i = 0; i < (this.data.Items.length < 10 ? this.data.Items.length : 10); i++) { await this.appendItem(i) } // 只判断第一张海报加载完毕, 优化加载速度 await new Promise((resolve, reject) => { let waitLoading = setInterval(() => { if (document.querySelector(".misty-banner-cover")?.complete) { clearInterval(waitLoading); resolve(); } }, 16); }); // 判断section0加载完毕 await new Promise((resolve, reject) => { let waitsection0 = setInterval(() => { if ($(".view:not(.hide) .section0 .emby-scrollbuttons").length > 0 && $(".view:not(.hide) .section0.hide").length == 0) { clearInterval(waitsection0); resolve(); } }, 16); }); $(".view:not(.hide) .section0 .emby-scrollbuttons").remove(); const items = $(".view:not(.hide) .section0 .emby-scroller .itemsContainer")[0].items; if (CommonUtils.checkType() === 'pc') { $(".view:not(.hide) .section0").detach().appendTo(".view:not(.hide) .misty-banner-library"); } $(".misty-loading").fadeOut(500, () => $(".misty-loading").remove()); await CommonUtils.sleep(150); $(".view:not(.hide) .section0 .emby-scroller .itemsContainer")[0].items = items; // 置入场动画 let delay = 80; // 动媒体库画间隔 let id = $(".misty-banner-item").eq(0).addClass("active").attr("id"); // 初次信息动画 $(`.misty-banner-logo[id=${id}]`).addClass("active"); await CommonUtils.sleep(200); // 间隔动画 $(".section0 > div").addClass("misty-banner-library-overflow"); // 关闭overflow 防止媒体库动画溢出 $(".misty-banner .card").each((i, dom) => setTimeout(() => $(dom).addClass("misty-banner-library-show"), i * delay)); // 媒体库动画 await CommonUtils.sleep(delay * 8 + 1000); // 等待媒体库动画完毕 $(".section0 > div").removeClass("misty-banner-library-overflow"); // 开启overflow 防止无法滚动 // 滚屏逻辑 this.index = 0; this.count = 0; clearInterval(this.bannerInterval); this.bannerInterval = setInterval(this.bannerRoll.bind(this), this.config.interval); } /* 初始事件 */ static initEvent() { // 通过注入方式, 方可调用appRouter函数, 以解决Content-Script window对象不同步问题 const script = ` // 挂载appRouter if (!window.appRouter) window.appRouter = (await window.require(["appRouter"]))[0]; /* // 修复library事件参数 const serverId = ApiClient._serverInfo.Id, librarys = document.querySelectorAll(".view:not(.hide) .section0 .card"); librarys.forEach(library => { library.setAttribute("data-serverid", serverId); library.setAttribute("data-type", "CollectionFolder"); }); */ `; this.injectCode(script); } } // 运行 if ("BroadcastChannel" in window || "postMessage" in window) { if ($("meta[name=application-name]").attr("content") == "Emby" || $(".accent-emby") != undefined) { Home.start(); } }