try { /* Add AM Lyrics Font JP, JR */ var headID = document.getElementsByTagName('head')[0]; var link = document.createElement('link'); link.type = 'text/css'; link.rel = 'stylesheet'; link.setAttribute('name','fonts'); headID.appendChild(link); link.href = "//www.apple.com/wss/fonts?families=SF+Pro,v3|SF+Pro+Icons,v3|SF+Pro+KR,v2|SF+Pro+JP,v1"; function GetXPath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } var setInnerHTML = function (elm, html) { elm.innerHTML = html; Array.from(elm.querySelectorAll("script")).forEach(oldScript => { const newScript = document.createElement("script"); Array.from(oldScript.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value)); newScript.appendChild(document.createTextNode(oldScript.innerHTML)); oldScript.parentNode.replaceChild(newScript, oldScript); }); }; function matchRuleShort(str, rule) { var escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); return new RegExp("^" + rule.split("*").map(escapeRegex).join(".*") + "$").test(str); } if (typeof activeEventListeners == "undefined") { var activeEventListeners = {} } var preferences = ipcRenderer.sendSync('getStore'); /* Variables that are utilised by the renderer */ if (typeof AM == "undefined") { var AM = { acrylicSupported: false, themesListing: [], } } /* Create the miniPlayer Functions */ if (typeof _miniPlayer == "undefined") { var _miniPlayer = { active: false, init() { const webChrome = document.querySelector(".web-chrome"); const elements = { artwork: document.createElement("div"), webNavContainer: document.querySelector("#web-navigation-container"), menuicon: document.querySelector(".menuicon") }; elements.artwork.classList.add("miniPlayerArtwork"); elements.artwork.style.display = "none"; elements.artwork.addEventListener("contextmenu", () => { ipcRenderer.send("show-miniplayer-menu"); }); elements.artwork.addEventListener("click", () => { if (webChrome.style.display === "") { webChrome.style.display = "flex"; } else { webChrome.style.display = ""; } }); document.querySelector("#web-main").appendChild(elements.artwork); if (window.innerWidth < 500) { /* Resize if window was closed in Mini Player */ ipcRenderer.send("resize-window", 1024, 600); } }, setMiniPlayer(val) { const webChrome = document.querySelector(".web-chrome"); const artwork = document.querySelector(".miniPlayerArtwork"); if (val) { self.active = true; document.body.setAttribute("data-miniplayer", 1); artwork.style.display = "block"; } else { self.active = false; webChrome.style.display = ""; document.body.removeAttribute("data-miniplayer"); artwork.style.display = "none"; } } }; } /* Lyrics Functions */ if (typeof _lyrics == "undefined") { var _lyrics = { current: [], events: [], onchange (fn = ()=>{}) { this.events.push(fn) }, setLyrics(lyrics) { this.current = lyrics; this.events.forEach((event)=>{ event(lyrics); }); }, CreateButton: () => { const mediaControlsElement = document.querySelector('.web-chrome-controls-container'); /* Chromecast / Airplay Button */ if (!document.querySelector('#airplayButton') && mediaControlsElement) { const lyricsButton = document.createElement("div"); lyricsButton.style.height = "22px"; lyricsButton.style.width = "30px"; lyricsButton.style.marginInlineEnd = "12px"; lyricsButton.style.zIndex = "9999"; lyricsButton.innerHTML = ``; lyricsButton.id = "airplayButton"; lyricsButton.className = "web-chrome-playback-controls__platter-toggle-buttons web-chrome-playback-controls__meta-btn"; mediaControlsElement.insertBefore(lyricsButton, mediaControlsElement.childNodes[4]); } /* Create the Button */ if (!document.querySelector('[aria-label="Lyrics"]') && mediaControlsElement) { const lyricsButton = document.createElement("div"); lyricsButton.classList.add('web-chrome-playback-controls__platter-toggle-buttons', 'web-chrome-playback-control__lyrics-button'); lyricsButton.style.marginInlineEnd = "0"; lyricsButton.style.width = "auto"; lyricsButton.style.zIndex = "9999"; lyricsButton.innerHTML = ` `; mediaControlsElement.insertBefore(lyricsButton, mediaControlsElement.childNodes[5]); let clonedElement2; clonedElement2 = document.querySelector('#airplayButton').cloneNode(true); document.querySelector('#airplayButton').replaceWith(clonedElement2); document.getElementById("airplayButton").addEventListener('click', function () { try{AudioOutputs.castUI(); }catch(e){} }); /* Lyric View for MV */ if (!document.querySelector('#MVLyricsBox')){ const lyricsMV = document.createElement("div"); lyricsMV.id = "MVLyricsBox"; lyricsMV.style.zIndex = 9999999; lyricsMV.style.backgroundColor= "rgba(0,0,0,0.7)"; lyricsMV.style.display = "none"; lyricsMV.style.color = "yellow"; try{ document.body.appendChild(lyricsMV);} catch(e){} lyricsMV.innerHTML = `
`; } /* Lyrics Button Click Event Handling */ const upNextSideBarToggle = mediaControlsElement.childNodes[6].getElementsByTagName('button')[0]; let clonedElement; if (document.querySelector("#lyricsButton") && upNextSideBarToggle) { function openLyrics() { document.body.classList.add("web-chrome-drawer-open"); document.body.classList.remove("web-chrome-drawer-opening"); document.querySelector('.web-chrome-drawer').removeEventListener('animationend', openLyrics, true); document.querySelector('#lyricsButton').style.fill = 'var(--playerPlatterButtonIconFill)'; document.querySelector('#lyricsButton').style.boxShadow = '0 1px 1px rgb(0 0 0 / 10%)'; document.querySelector('#lyricsButton').style.background = 'var(--playerPlatterButtonBGFill)'; if (MusicKit.getInstance().nowPlayingItem == null) { try { document.getElementById('lyrics_none').classList.remove('lyrics_none_hidden'); } catch (e) { } } else { try { document.getElementById('lyrics_none').classList.add('lyrics_none_hidden'); } catch (e) { } } if (document.getElementById('lyricer').childNodes[0].childNodes.length == null || document.getElementById('lyricer').childNodes[0].childNodes.length <= 1) { _lyrics.GetLyrics(1, false); } } function closeLyrics() { document.body.classList.remove("web-chrome-drawer-open"); document.body.classList.remove("web-chrome-drawer-closing"); document.querySelector('.web-chrome-drawer').removeEventListener('animationend', closeLyrics, true); document.querySelector('#lyricsButton').style.fill = 'var(--systemSecondary)'; document.querySelector('#lyricsButton').style.boxShadow = 'none'; document.querySelector('#lyricsButton').style.background = '0 0'; } clonedElement = document.querySelector('#lyricsButton').cloneNode(true); document.querySelector('#lyricsButton').replaceWith(clonedElement); if (!document.getElementById("lyricer")) { const sidebar = document.querySelector('.web-chrome-drawer'); if (sidebar) { sidebar.innerHTML = `
Play a song to see the lyrics here.
`; } let text = ""; let lrc = new Lyricer(); ipcRenderer.on('truelyrics', function (event, lrcfile) { if (lrcfile.startsWith("netease=")) { ipcRenderer.send('NetEaseLyricsHandler', lrcfile); } else { if (lrcfile!= null && lrcfile.length > 0) lrc.setLrc(lrcfile); } }); ipcRenderer.on('lyricstranslation', function (event, data) { lrc.setMXMTranslation(data); }); ipcRenderer.on('backuplyrics', function (_event, _data) { _lyrics.GetLyrics(1, true); }); ipcRenderer.on('backuplyricsMV', function (_event, _data) { _lyrics.GetLyrics(1, false); }); ipcRenderer.on('ProgressTimeUpdate', function (event, data) { if (data < 0) { data = 0 } lrc.move(data); }); lrc.setLrc(text); document.addEventListener("lyricerclick", function (e) { ipcRenderer.send('ProgressTimeUpdateFromLyrics', e.detail.time); document.body.setAttribute("background-color", `var(--systemToolbarTitlebarMaterialSover-inactive)`); }); _lyrics.GetLyrics(2, false); } document.getElementById("lyricsButton").addEventListener('click', function () { if (document.querySelector('.web-chrome-drawer').querySelector('.web-navigation__up-next.web-chrome-up-next.up-next') == null) { if (document.getElementsByClassName("web-chrome-drawer-open").length === 0) { document.querySelector('.web-chrome-drawer').addEventListener('animationend', openLyrics, true); document.body.classList.add("web-chrome-drawer-opening"); } else { document.querySelector('.web-chrome-drawer').addEventListener('animationend', closeLyrics, true); document.body.classList.add("web-chrome-drawer-closing"); } } else { try { /* Checks for clicks on the up next sidebar toggle button */ if (upNextSideBarToggle.classList.contains('active')) { upNextSideBarToggle.click(); document.querySelector('.web-chrome-drawer').addEventListener('animationend', openLyrics, true); document.body.classList.add("web-chrome-drawer-opening"); } else { document.querySelector('.web-chrome-drawer').style.backgroundColor = ""; document.querySelector('.web-chrome-drawer').removeEventListener('animationend', openLyrics, true); document.querySelector('.web-chrome-drawer').removeEventListener('animationend', closeLyrics, true); } } catch (e) { console.error(e); } } if (!document.getElementById("lyricer")) { const sidebar = document.querySelector('.web-chrome-drawer'); if (sidebar) { sidebar.innerHTML = `
Play a song to see the lyrics here.
`; } let text = ""; let lrc = new Lyricer(); ipcRenderer.on('truelyrics', function (event, lrcfile) { if (lrcfile.startsWith("netease=")) { ipcRenderer.send('NetEaseLyricsHandler', lrcfile); } else { if (lrcfile!= null && lrcfile.length > 0) lrc.setLrc(lrcfile); } }); ipcRenderer.on('lyricstranslation', function (event, data) { lrc.setMXMTranslation(data); }); ipcRenderer.on('backuplyrics', function (_event, _data) { _lyrics.GetLyrics(1, true); }); ipcRenderer.on('backuplyricsMV', function (_event, _data) { _lyrics.GetLyrics(1, false); }); ipcRenderer.on('ProgressTimeUpdate', function (event, data) { if (data < 0) { data = 0 } lrc.move(data); }); lrc.setLrc(text); document.addEventListener("lyricerclick", function (e) { ipcRenderer.send('ProgressTimeUpdateFromLyrics', e.detail.time); document.body.setAttribute("background-color", `var(--systemToolbarTitlebarMaterialSover-inactive)`); }); _lyrics.GetLyrics(2, false); } }, false); upNextSideBarToggle.addEventListener('click', function () { if (document.querySelector('#lyricsButton').style.fill === "var(--playerPlatterButtonIconFill)") { document.querySelector('#lyricsButton').style.fill = 'var(--systemSecondary)'; document.querySelector('#lyricsButton').style.boxShadow = 'none'; document.querySelector('#lyricsButton').style.background = '0 0'; } }, false); } }}, GetLyrics: (mode, mxmfail) => { const musicType = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["type"] ?? '' : ''; const trackName = encodeURIComponent((MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem.title ?? '' : ''); const artistName = encodeURIComponent((MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem.artistName ?? '' : ''); const songID = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["_songId"] ?? -1 : -1; const duration = encodeURIComponent(Math.round(MusicKitInterop.getAttributes()["durationInMillis"] / 1000)); if (trackName !== '' && !(trackName === "No Title Found" && artistName === '')) { /* MusixMatch Lyrics*/ if(musicType === "musicVideo" && preferences.visual.yton){ ipcRenderer.send('YTTranslation', trackName, artistName, preferences.visual.mxmlanguage); } else/* MusixMatch Lyrics*/ if (!mxmfail && preferences.visual.mxmon) { ipcRenderer.send('MXMTranslation', trackName, artistName, preferences.visual.mxmlanguage, duration); } /* Apple Lyrics (from api lyric query) */ else if (songID !== -1) { MusicKit.getInstance().api.lyric(songID) .then((response) => { let seconds, minutes, hours, rawTime, milliseconds, lrcTime; try { const ttmlLyrics = response["ttml"]; let lyrics = ""; let synced = true; const parser = new DOMParser(); const doc = parser.parseFromString(ttmlLyrics, "text/xml"); console.log('sdx',doc.getElementsByTagName('tt')[0].getAttribute("itunes:timing") === "None"); if (doc.getElementsByTagName('tt')[0].getAttribute("itunes:timing") === "None"){ synced = false; } const lyricsLines = doc.getElementsByTagName('p'); const endTime = [0]; if (synced) { try { for (let element of lyricsLines) { rawTime = element.getAttribute('begin').match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); hours = (rawTime[2] != null) ? (rawTime[1].replace(":", "")) : "0"; minutes = (rawTime[2] != null) ? (hours * 60 + rawTime[2].replace(":", "") * 1 + ":") : ((rawTime[1] != null) ? rawTime[1] : "00:"); seconds = (rawTime[3] != null) ? (rawTime[3]) : "00"; milliseconds = (rawTime[4] != null) ? (rawTime[4]) : ".000"; lrcTime = minutes + seconds + milliseconds; const rawTime2 = element.getAttribute('end').match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); const hours2 = (rawTime2[2] != null) ? (rawTime2[1].replace(":", "")) : "0"; const minutes2 = (rawTime2[2] != null) ? (hours2 * 60 + rawTime2[2].replace(":", "") * 1 + ":") : ((rawTime2[1] != null) ? rawTime2[1] : "00:"); const seconds2 = (rawTime2[3] != null) ? (rawTime2[3]) : "00"; const milliseconds2 = (rawTime2[4] != null) ? (rawTime2[4]) : ".000"; const lrcTime2 = minutes2 + seconds2 + milliseconds2; if (minutes.replace(":", "") * 60 + seconds * 1 - endTime[endTime.length - 1] > 10) { const time = endTime[endTime.length - 1]; const minutes = Math.floor(time / 60); const secs = time - minutes * 60; lyrics = lyrics.concat(`[${minutes}:${secs}]lrcInstrumental` + "\r\n"); } endTime.push(minutes2.replace(":", "") * 60 + seconds2 * 1); lyrics = lyrics.concat(`[${lrcTime}]${element.textContent}` + "\r\n"); } } catch { lyrics = ""; for (let element of lyricsLines) { rawTime = element.getAttribute('begin').match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); hours = (rawTime[2] != null) ? (rawTime[1].replace(":", "")) : "0"; minutes = (rawTime[2] != null) ? (hours * 60 + rawTime[2].replace(":", "") * 1 + ":") : ((rawTime[1] != null) ? rawTime[1] : "00:"); seconds = (rawTime[3] != null) ? (rawTime[3]) : "00"; milliseconds = (rawTime[4] != null) ? (rawTime[4]) : ".000"; lrcTime = minutes + seconds + milliseconds; lyrics = lyrics.concat(`[${lrcTime}]${element.textContent}` + "\r\n"); } }} else { try{ var body = doc.getElementsByTagName('body')[0].innerHTML; if (document.getElementById("lyricer")) { var u = document.createElement('div'); u.id = "unsynced"; u.innerHTML = body; if (!document.getElementById("unsynced")){ document.getElementById("lyricer").appendChild(u);} else {console.log('duped')} } } catch(e){} } let artworkURL = ((MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem.artworkURL : '').replace("{w}", 256).replace("{h}", 256); if (artworkURL == null) { artworkURL = "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"; } if (mode === 1) { ipcRenderer.send('LyricsUpdate', lyrics, artworkURL); } else { ipcRenderer.send('LyricsHandler', lyrics, artworkURL); } } catch (e) { console.error(e); if (mode === 1) { ipcRenderer.send('LyricsUpdate', "netease=" + trackName + " " + artistName, artworkURL); } else { ipcRenderer.send('LyricsHandler', "netease=" + trackName + " " + artistName, artworkURL); } } }) .catch((err) => { console.log(err); let artworkURL = (MusicKitInterop.getAttributes()["artwork"]["url"]).replace("{w}", 256).replace("{h}", 256); if (artworkURL == null) { artworkURL = "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"; } if (mode === 1) { ipcRenderer.send('LyricsUpdate', "netease=" + trackName + " " + artistName, artworkURL); } else { ipcRenderer.send('LyricsHandler', "netease=" + trackName + " " + artistName, artworkURL); } }); } /* Apple Lyrics (from api song query */ else { try { MusicKit.getInstance().api.library.song(MusicKit.getInstance().nowPlayingItem.id).then((data) => { try { if (data != null && data !== "") { artworkURL = data["artwork"]["url"]; } else { artworkURL = "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"; } } catch (e) { artworkURL = "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg"; } if (mode === 1) { ipcRenderer.send('LyricsUpdate', "netease=" + trackName + " " + artistName, artworkURL); } else { ipcRenderer.send('LyricsHandler', "netease=" + trackName + " " + artistName, artworkURL); } }); } catch (e) { console.error(e); if (mode === 1) { ipcRenderer.send('LyricsUpdate', "netease=" + trackName + " " + artistName, ''); } else { ipcRenderer.send('LyricsHandler', "netease=" + trackName + " " + artistName, ''); } } } } } } } /* Create the AMStyling Functions */ if (typeof AMStyling == "undefined") { var AMStyling = { _styleSheets: { Transparency: new CSSStyleSheet(), Theme: new CSSStyleSheet(), Meta: new CSSStyleSheet(), Metrics: new CSSStyleSheet(), Scaling: new CSSStyleSheet() }, wallpaper: "", lastTheme: "", micaActive: false, metrics: { lastScreenX: 0, lastScreenY: 0 }, showThemeOptions() { function throwNoTheme() { new AMEModal({ content: `
This theme has no available options.
`, Style: { width: "325px", height: "200px" } }); } if (this.lastTheme === "default" || this.lastTheme === "") { throwNoTheme(); return; } if (AM.themesListing[AMStyling.lastTheme]["options"].length === 0) { throwNoTheme(); return; } AMJavaScript.getRequest("ameres://html/theme-options.html", (content) => { var vm = new Vue({ data: { options: AM.themesListing[AMStyling.lastTheme]["options"], userOptions: AMStyling.getThemeOptions(AMStyling.lastTheme), theme: AM.themesListing[AMStyling.lastTheme]["name"] }, methods: { saveOptions() { AMStyling.setThemeOptions(AMStyling.lastTheme, this.userOptions); }, close() { modal.close(); } } }); var modal = new AMEModal({ content: content, CloseButton: false, OnCreate() { vm.$mount("#themeOptions-vue") }, OnClose() { _vues.destroy(vm) }, Style: { width: "50%", height: "80%" } }) }); }, getThemeOptions(theme) { if (!localStorage.getItem("ThemeOptions")) { localStorage.setItem("ThemeOptions", "{}"); } var userOptions = JSON.parse(localStorage.getItem("ThemeOptions")); if (!userOptions[theme]) { userOptions[theme] = {}; } function parseBool(val) { return !(val === 0 || val === "false" || val === false); } AM.themesListing[theme]["options"].forEach((option) => { if (typeof userOptions[theme][option.key] == "undefined" || userOptions[theme][option.key] == null) { userOptions[theme][option.key] = parseBool(option.defaultValue); } }); localStorage.setItem("ThemeOptions", JSON.stringify(userOptions)); return userOptions[theme]; }, setThemeOptions(theme, options = {}) { if (!localStorage.getItem("ThemeOptions")) { localStorage.setItem("ThemeOptions", "{}"); } let userOptions = JSON.parse(localStorage.getItem("ThemeOptions")); if (!userOptions[theme]) { userOptions[theme] = {}; } userOptions[theme] = options; localStorage.setItem("ThemeOptions", JSON.stringify(userOptions)); this.refresh(); }, getWallpaper() { this.wallpaper = ipcRenderer.sendSync("get-wallpaper"); this.updateMetrics() }, updateMetrics() { this._styleSheets.Metrics.replaceSync(` :root { --user-wallpaper: url('${this.wallpaper}'); --screenX: ${window.screenX}px; --screenY: ${window.screenY}px; --screenHeight: ${screen.height}px; --screenWidth: ${screen.width}px; } body::before { display: none; } `); this.refresh(); }, windowsWallpaperStyles: { fill: 10, fit: 6, stretch: 2, tile: 0, span: 22 }, updateMica() { if (!this.micaActive) { return; } var micaElement = document.querySelector(".micaBackground"); var style = ipcRenderer.sendSync("get-wallpaper-style"); switch (style) { default: case 0: case 2: case 6: case 10: micaElement.style.backgroundSize = "repeat"; break; case 22: micaElement.style.backgroundSize = "cover"; break; } }, setMica(val = false) { if (val) { this.enableMica(); } else { this.disableMica(); } }, disableMica() { if (!this.micaActive) { return; } this.micaActive = false; document.querySelector(".micaBackground").remove(); }, enableMica() { let self = this; if (this.micaActive) { console.log("Mica is already active"); return; } if (this.lastTheme !== "winui") { if (confirm("This feature currently requires the Eleven theme, enable now?")) { this.loadTheme("winui"); } } this.micaActive = true; var micaDOM = document.createElement("div"); micaDOM.classList.add("micaBackground"); document.body.appendChild(micaDOM); this.getWallpaper(); this.setTransparency(false); function onScreenMove(cb) { let lastScreenX; let lastScreenY; function detectScreenMove() { if (lastScreenY !== window.screenY || lastScreenX !== window.screenX) { lastScreenY = window.screenY; lastScreenX = window.screenX; cb(); } if (self.micaActive) { requestAnimationFrame(detectScreenMove); } } if (self.micaActive) { requestAnimationFrame(detectScreenMove); } } onScreenMove(function () { micaDOM.style.backgroundPosition = `${window.screenX * -1}px ${window.screenY * -1}px`; /**micaDOM.style.backgroundSize = `${screen.width}px ${screen.height}px`;**/ micaDOM.style.backgroundSize = `cover`; }); }, loadTheme(path = "", reload = false) { if (path === this.lastTheme && !reload) { return; } this.lastTheme = path; let self = this; if (path === "" || path === " " || path === "default") { self._styleSheets.Theme.replaceSync(""); self.refresh(); return; } ipcRenderer.invoke('themeFileExists', path).then((r) => { if (r) { const xhttp = new XMLHttpRequest(); xhttp.onload = function () { self._styleSheets.Theme.replaceSync(this.responseText); self.refresh(); }; xhttp.open("GET", `themes://${path}.css`, true); xhttp.send(); console.warn("[Custom] Applied Theme"); } else { console.error(`[Custom] ${path} does not exist.`) } }) }, updateMeta() { if (MusicKit.getInstance().nowPlayingItem == null) { try { document.getElementById('lyrics_none').classList.remove('lyrics_none_hidden'); } catch (e) { } } else { try { document.getElementById('lyrics_none').classList.add('lyrics_none_hidden'); } catch (e) { } } console.warn("[Custom] Refreshed Meta CSS"); /** Exposes artwork and other metadata to CSS for themes */ let artwork = MusicKit.getInstance().nowPlayingItem["attributes"]["artwork"]["url"]; /* Fix Itunes Match album arts not showing */ if (artwork === '' || !artwork) { try { MusicKit.getInstance().api.library.song(MusicKit.getInstance().nowPlayingItem.id).then((data) => { if (data !== "") { artwork = data["artwork"]["url"]; document.querySelector('#ember13').getElementsByTagName('img')[0].src = artwork; this._styleSheets.Meta.replaceSync(` :root { --musicKit-artwork-64: url("${artwork.replace("{w}", 64).replace("{h}", 64)}"); --musicKit-artwork-256: url("${artwork.replace("{w}", 256).replace("{h}", 256)}"); --musicKit-artwork-512: url("${artwork.replace("{w}", 512).replace("{h}", 512)}"); --musicKit-artwork: url("${artwork.replace("{w}", 2000).replace("{h}", 2000)}"); } `); if (MusicKit.getInstance().nowPlayingItem.title != "" & !(MusicKit.getInstance().nowPlayingItem.title == "No Title Found" && MusicKit.getInstance().nowPlayingItem.artistName == "")){ ipcRenderer.send('updateMiniPlayerArt',artwork.replace("{w}", 2000).replace("{h}", 2000)); ipcRenderer.send('updateMiniPlayerMetaData',MusicKit.getInstance().nowPlayingItem.title,MusicKit.getInstance().nowPlayingItem.artistName,MusicKit.getInstance().nowPlayingItem.albumName); ipcRenderer.send('setupNewTrack',MusicKit.getInstance().nowPlayingItem.title,MusicKit.getInstance().nowPlayingItem.artistName,MusicKit.getInstance().nowPlayingItem.albumName,artwork.replace("{w}", 256).replace("{h}", 256));} this.refresh(); } }); } catch (e) { console.error(e); } } this._styleSheets.Meta.replaceSync(` :root { --musicKit-artwork-64: url("${artwork.replace("{w}", 64).replace("{h}", 64)}"); --musicKit-artwork-256: url("${artwork.replace("{w}", 256).replace("{h}", 256)}"); --musicKit-artwork-512: url("${artwork.replace("{w}", 512).replace("{h}", 512)}"); --musicKit-artwork: url("${artwork.replace("{w}", 2000).replace("{h}", 2000)}"); } `); if ( (artwork === '' || !artwork) && MusicKit.getInstance().nowPlayingItem.title != "" & !(MusicKit.getInstance().nowPlayingItem.title == "No Title Found" && MusicKit.getInstance().nowPlayingItem.artistName == "")){ ipcRenderer.send('updateMiniPlayerArt',artwork.replace("{w}", 2000).replace("{h}", 2000)); ipcRenderer.send('updateMiniPlayerMetaData',MusicKit.getInstance().nowPlayingItem.title,MusicKit.getInstance().nowPlayingItem.artistName,MusicKit.getInstance().nowPlayingItem.albumName); ipcRenderer.send('setupNewTrack',MusicKit.getInstance().nowPlayingItem.title,MusicKit.getInstance().nowPlayingItem.artistName,MusicKit.getInstance().nowPlayingItem.albumName,artwork.replace("{w}", 256).replace("{h}", 256));} this.refresh(); }, setTransparency(val) { let self = this; if (val) { const xhttp = new XMLHttpRequest(); xhttp.onload = function () { self._styleSheets.Transparency.replaceSync(this.responseText); self.refresh(); }; xhttp.open("GET", `ameres://css/transparency.css`, true); xhttp.send(); } else { self._styleSheets.Transparency.replaceSync(`html body { background-color: var(--pageBG) !important; }`); } }, refresh() { document.adoptedStyleSheets = Object.values(this._styleSheets); /** Theme Options **/ if (AM.themesListing[this.lastTheme]) { var themeOptions = (this.getThemeOptions(this.lastTheme)); Object.keys(themeOptions).forEach((option) => { if (themeOptions[option]) { document.body.setAttribute(`theme-${option}`, 1); } else { document.body.removeAttribute(`theme-${option}`); } }) } }, lerp: (start, end, l) => { return start + (end - start) * l; } }; } /* Bulk AME JavaScript Functions */ if (typeof AMJavaScript == "undefined") { var AMJavaScript = { getQuery(q) { return (window.location.search.match(new RegExp('[?&]' + q + '=([^&]+)')) || [undefined, null])[1]; }, getRequest: (url, callback = () => { }) => { const xhttp = new XMLHttpRequest(); xhttp.onload = function () { callback(this.responseText); }; xhttp.open("GET", url, true); xhttp.send(); }, LoadCustomStartup: async () => { const preferences = ipcRenderer.sendSync('getStore'); /** Plugins */ if (typeof _plugins != "undefined") { await ipcRenderer.invoke("fetchPluginsListing").then((plugins) => { console.log(plugins); plugins.forEach((plugin) => { _plugins.loadPlugin(plugin); }); }) } /** End Plugins */ /** Expose platform to CSS */ document.body.setAttribute("platform", navigator.platform); if (preferences.visual.frameType === "") { document.body.setAttribute("frame-type", "disabled"); } else { document.body.setAttribute("frame-type", preferences.visual.frameType); } /* MiniPlayer Event Listener */ MusicKit.getInstance().addEventListener(MusicKit.Events.mediaElementCreated, () => { if (!document.querySelector('.media-artwork-v2__image').classList.contains('media-artwork-v2__image--fallback')) { const artwork = document.querySelector('#ember13'); artwork.onclick = function () { ipcRenderer.send("set-miniplayer", true); }; /* Picture-in-picture icon should be overlayed over artwork when mouse over */ } }); /* Audio Quality Selector */ if (preferences.audio.audioQuality === 'extreme') { console.warn("[Custom] Setting bitrate to 990."); MusicKit.getInstance().bitrate = 990; } else if (preferences.audio.audioQuality === 'high') { console.warn("[Custom] Setting bitrate to 256."); MusicKit.getInstance().bitrate = 256; } else if (preferences.audio.audioQuality === 'standard') { console.warn("[Custom] Setting bitrate to 64."); MusicKit.getInstance().bitrate = 64; } /* Seamless (Apple dont know how to spell) Audio Playback */ if (preferences.audio.seamlessAudioTransitions) { console.warn("[Custom] Seamless Audio Transitions enabled."); MusicKit.getInstance()._bag.features["seamless-audio-transitions"] = true; } /* Incognito Mode */ if (preferences.general.incognitoMode) { MusicKit.privateEnabled = true } /* Event Listener for Lyrics Update */ MusicKit.getInstance().addEventListener(MusicKit.Events.playbackTimeDidChange, function () { ipcRenderer.send('LyricsTimeUpdate', MusicKit.getInstance().currentPlaybackTime + 0.250); }); MusicKit.getInstance().addEventListener(MusicKit.Events.nowPlayingItemDidChange, function () { var EAtmpdisable = false; var tempOutputID = -1; try{ if (MusicKit.getInstance().nowPlayingItem["type"] === "musicVideo") { try{ if(!GCOverride ){ MVsource = AMEx.context.createMediaElementSource(document.querySelector('apple-music-video-player').shadowRoot.querySelector('amp-video-player-internal').shadowRoot.querySelector('amp-video-player').shadowRoot.getElementById('apple-music-video-player')); MVsource.connect(windowAudioNode); } } catch(e){console.log(e);} } else{ if (!GCOverride ) { try{ AMEx.result.source.connect(windowAudioNode);} catch(e){}} } }catch(e){} try{ if (MusicKit.getInstance().nowPlayingItem["type"] === "musicVideo") { document.querySelector(`#MVLyricsBox`).style.display = 'block'; } else { document.querySelector(`#MVLyricsBox`).style.display = 'none'; } document.querySelector(`#MVLyricsBox`).childNodes[0].innerHTML= ""; document.querySelector(`#MVLyricsBox`).childNodes[1].innerHTML= ""; } catch (e){} try { GetXPath("/html/body/div[4]/div[3]/div[3]/div/div[2]/div[1]/img").src = "https://music.apple.com/assets/product/MissingArtworkMusic.svg"; } catch (e) { } try { let lrc = new Lyricer(); lrc.setLrc(""); lrc = null; } catch (e) { } const sidebar = document.querySelector('.web-chrome-drawer'); if ((sidebar && document.body.classList.contains('web-chrome-drawer-open')) || (MusicKit.getInstance().nowPlayingItem != null && MusicKit.getInstance().nowPlayingItem["type"] == "musicVideo")) { _lyrics.GetLyrics(1, false); } }); /* Mutation Observer to disable "seek error" alert */ let observer = new MutationObserver(function (mutationList) { for (const mutation of mutationList) { for (const child of mutation.addedNodes) { try { if (document.getElementById("mk-dialog-title").textContent === "cancelled" || document.getElementById("mk-dialog-title").textContent.includes("The play") || document.getElementById("mk-dialog-title").textContent.includes("MEDIA_KEY")) { document.getElementById("musickit-dialog").remove(); document.getElementById("musickit-dialog-scrim").remove(); break; } } catch (e) { break; } } } }); observer.observe(document.body, {childList: true}); /* Load Themes and Transparency */ AMStyling.loadTheme(preferences["visual"]["theme"]); if (preferences["visual"]["transparencyEffect"] !== "" && preferences["visual"]["transparencyEffect"] !== "mica") { AMStyling.setTransparency(true); } else { AMStyling.setTransparency(false); } if (preferences["visual"]["transparencyEffect"] === "mica") { AMStyling.setMica(true); } else { AMStyling.setMica(false); } AM.themesListing = await ipcRenderer.invoke('updateThemesListing'); AM.acrylicSupported = await ipcRenderer.invoke('isAcrylicSupported'); if (await ipcRenderer.invoke('getStoreValue', 'general.storefront') !== MusicKit.getInstance().storefrontId) { await ipcRenderer.invoke('setStoreValue', 'general.storefront', MusicKit.getInstance().storefrontId); } /** Need a better way to find the user menu asap, this is embarrassing **/ if(MusicKit.getInstance().authorizationStatus !== 0) { var checkForUserMenu = setInterval(function () { if (document.querySelectorAll(".web-chrome-controls-container>.web-navigation__auth").length) { _tests.usermenuinit(); clearInterval(checkForUserMenu); } }, 100); } }, LoadCustom: () => { const preferences = ipcRenderer.sendSync('getStore'); /* Execute plugins OnNavigation */ if (typeof _plugins != "undefined") { _plugins.execute("OnNavigation"); } /* Remove the Region Banner */ while (document.getElementsByClassName('locale-switcher-banner').length > 0) { document.getElementsByClassName('locale-switcher-banner')[0].remove() } /* Create the Custom Settings Context Menu */ const buttonPath = (preferences.visual.frameType === 'mac-right' ? '//*[@id="web-main"]/div[4]/div/div[3]/div[3]/button' : '//*[@id="web-main"]/div[3]/div/div[3]/div[3]/button'); if (GetXPath(buttonPath)) { GetXPath(buttonPath).addEventListener('click', function () { try { if (document.querySelector('.context-menu__option--app-settings')) { if (preferences.advanced.verboseLogging) console.log("[settingsInit] Preventing second button."); return; } const ul = GetXPath("/html/body/div[6]/ul"); const amPreferences = GetXPath('/html/body/div[6]/ul/li[2]'); GetXPath('/html/body/div[6]/ul/li[2]/span/span').innerHTML = 'Preferences'; ul.insertBefore(amPreferences, ul.childNodes[9]); const amSettings = document.createElement("li"); amSettings.innerHTML = ` Account Settings `; amSettings.classList.add("context-menu__option--am-settings"); amSettings.classList.add("context-menu__option"); amSettings.onclick = function () { window.open(`https://music.apple.com/account/settings`) }; ul.insertBefore(amSettings, ul.childNodes[8]); const amDiscord = document.createElement("li"); amDiscord.innerHTML = ` Discord `; amDiscord.classList.add("context-menu__option--am-discord"); amDiscord.classList.add("context-menu__option"); amDiscord.onclick = function () { window.open(`https://discord.gg/CezHYdXHEM`) }; ul.insertBefore(amDiscord, ul.childNodes[4]); if (typeof _plugins != "undefined") { /** Plugin menu items */ _plugins.menuitems.forEach((item) => { var element = document.createElement("li"); var textSpan = document.createElement("span"); textSpan.classList.add("context-menu__option-text"); element.appendChild(textSpan); textSpan.innerHTML = item.Text; element.addEventListener("click", item.OnClick); element.addEventListener("click", () => { document.querySelector(".context-menu-outside-click-area").dispatchEvent(new Event("click")); }); element.classList.add("context-menu__option"); ul.appendChild(element); }); /** End plugin menu items */ } } catch (e) {}}); } /* Scroll Volume */ if (document.querySelector('.web-chrome-playback-lcd__volume') && typeof volumeChange === 'undefined' && document.querySelector('.web-chrome-playback-lcd__volume').getAttribute('listener') !== 'true' && !activeEventListeners['web-chrome-playback-lcd__volume']) { function checkScrollDirectionIsUp(event) { if (event.wheelDelta) { return event.wheelDelta > 0; } return event.deltaY < 0; } function volumeChange(event) { if (checkScrollDirectionIsUp(event)) { if (MusicKit.getInstance().volume <= 1) { if ((MusicKit.getInstance().volume + 0.05) > 1) { MusicKit.getInstance().volume = 1 } else { MusicKit.getInstance().volume += 0.05; } } } else { if (MusicKit.getInstance().volume >= 0) { if ((MusicKit.getInstance().volume - 0.05) < 0) { MusicKit.getInstance().volume = 0; } else { MusicKit.getInstance().volume -= 0.05; } } } } document.getElementsByClassName('web-chrome-playback-lcd__volume')[0].addEventListener('wheel', volumeChange); activeEventListeners['web-chrome-playback-lcd__volume'] = true } /* Context Menu Creation (From PR #221 by @SiverDX) */ const SongContextMenu = { simulateClick: (element, clientX, clientY) => { let event = new MouseEvent('click', { clientX: clientX, clientY: clientY }); element.dispatchEvent(event); }, createListeners: () => { /* Check if the user is on the library song list or on playlist/album */ const clickRegion = (document.getElementsByClassName("songs-list-row").length === 0 ? document.getElementsByClassName("library-track") : document.getElementsByClassName("songs-list-row")); /* Loop through each row/song and add event listener */ for (let area of clickRegion) { area.addEventListener('contextmenu', function (event) { event.preventDefault(); let control = area.getElementsByClassName("context-menu__overflow ")[0]; if (control) { SongContextMenu.simulateClick(control, event.clientX, event.clientY); } }); } } }; SongContextMenu.createListeners(); /* Remove Apple Logo */ if (preferences['visual']['removeAppleLogo']) { while (document.getElementsByClassName('web-navigation__header web-navigation__header--logo').length > 0) { document.getElementsByClassName('web-navigation__header web-navigation__header--logo')[0].remove(); } } /* Remove Footer */ if (!matchRuleShort(window.location.href, '*settings*') && document.getElementsByClassName('application-preferences').length === 0) { if (preferences['visual']['removeFooter'] && document.querySelector('footer').style.display !== "none") { document.querySelector('.dt-footer').style.display = "none"; } else if (!preferences['visual']['removeFooter'] && document.querySelector('footer').style.display === "none") { document.querySelector('.dt-footer').style.display = "block"; } } /* Remove Upsell */ if (preferences['visual']['removeUpsell']) { while (document.getElementsByClassName('web-navigation__native-upsell').length > 0) { document.getElementsByClassName('web-navigation__native-upsell')[0].remove(); } } /* Initialize the miniPlayer */ _miniPlayer.init(); /* Create the Lyrics Button */ _lyrics.CreateButton(); if(typeof wsapi !== "undefined") { _lyrics.onchange((lyrics)=>{ ipcRenderer.send('wsapi-returnLyrics', JSON.stringify(lyrics)); }); }else{ console.warn("WSAPI not found"); } } }; /* Load the Startup Files as This is the First Time its been Run */ AMJavaScript.LoadCustomStartup().catch((e) => console.error(e)); } /* Functions used in Settings Page */ if (typeof AMSettings == "undefined") { var AMSettings = { revealCollapse: () => { const elem = document.querySelector('#advanced'); if (elem.classList.contains('revealed')) { /* Collapse Category */ elem.classList.remove('revealed'); document.querySelector('.header-nav-image').src = 'ameres://icons/webui/down.svg'; } else { /* Reveal the Category */ elem.classList.add('revealed'); document.querySelector('.header-nav-image').src = 'ameres://icons/webui/up.svg'; } }, lastfm: { LastFMDeauthorize: () => { ipcRenderer.invoke('setStoreValue', 'general.lastfm', false).catch((e) => console.error(e)); ipcRenderer.invoke('setStoreValue', 'tokens.lastfm', '').catch((e) => console.error(e)); const element = document.getElementById('lfmConnect'); element.innerHTML = 'Connect'; element.onclick = AMSettings.lastfm.LastFMAuthenticate; }, LastFMAuthenticate: () => { const element = document.getElementById('lfmConnect'); window.open('https://www.last.fm/api/auth?api_key=174905d201451602407b428a86e8344d&cb=ame://auth/lastfm'); element.innerText = 'Connecting...'; /* Just a timeout for the button */ setTimeout(() => { if (element.innerText === 'Connecting...') { element.innerText = 'Connect'; console.warn('[LastFM] Attempted connection timed out.'); } }, 20000); ipcRenderer.on('LastfmAuthenticated', function (_event, lfmAuthKey) { element.innerHTML = `Disconnect\n

(Authed: ${lfmAuthKey})

`; element.onclick = AMSettings.lastfm.LastFMDeauthorize; }); } }, createNotification: (changed) => { if (typeof changed !== 'object' || !changed || (Object.keys(changed).length === 0 && changed.constructor === Object)) { return; } let changedHTML = ``, changedFull = ``, addedHTML = ``, addedFull = ``; for (let [key, value] of Object.entries(changed)) { key = key.split('.')[0]; key = key.charAt(0).toUpperCase() + key.slice(1); if (value === 'updated') { changedHTML += `
  • ${key}
  • `; } else if (value === 'added') { addedHTML += `
  • ${key}
  • `; } } if (changedHTML !== '') { changedFull = `

    The following themes have been updated:

    ` } if (addedHTML !== '') { addedFull = `

    The following themes have been added:

    ` } new AMEModal({ content: `
    ${changedFull} ${addedFull}
    `, Style: { width: "auto", minWidth: "386px", maxWidth: "100%", minHeight: "300px", maxHeight: "100%", height: "auto", padding: "46px", } }); }, themes: { updateThemesListing: (listing) => { let themesListingHTML = `\n`; for (const [fileName, theme] of Object.entries(listing)) { themesListingHTML = themesListingHTML + `\n`; } document.getElementById('theme').innerHTML = themesListingHTML; console.warn('[Custom][updateThemes] Themes Listing Updated!'); }, updateThemes: () => { document.getElementById('updateThemes').innerText = 'Updating...'; ipcRenderer.invoke('updateThemes').then(listing => { setTimeout(async () => { AM.themesListing = await ipcRenderer.invoke('updateThemesListing'); AMSettings.themes.updateThemesListing(AM.themesListing); document.querySelector('#updateThemes').innerHTML = (AM.themesListing ? 'Themes Updated' : 'Error'); document.querySelector('#updateThemes').classList.add(AM.themesListing ? 'success' : 'failure'); AMSettings.createNotification(listing); }, 2000) }) } }, copyLogFile: () => { const returnValue = ipcRenderer.sendSync('copyLogFile'); document.querySelector('#copyLogFile').innerHTML = (returnValue ? 'Copied to Clipboard' : 'Copy Failed'); document.querySelector('#copyLogFile').classList.add(returnValue ? 'success' : 'failure'); }, hasParentClass: (child, classname) => { if (child.className.split(' ').indexOf(classname) >= 0) return true; try { return child.parentNode && AMSettings.hasParentClass(child.parentNode, classname); } catch (TypeError) { return false; } }, HandleField: (element) => { const field = document.getElementById(element); if (!field) { console.error('[HandleField] Element Not Found'); return; } let category; if (AMSettings.hasParentClass(field, 'general')) { category = 'general'; } else if (AMSettings.hasParentClass(field, 'visual')) { category = 'visual'; } else if (AMSettings.hasParentClass(field, 'audio')) { category = 'audio'; } else if (AMSettings.hasParentClass(field, 'window')) { category = 'window'; } else if (AMSettings.hasParentClass(field, 'advanced')) { category = 'advanced'; } else { console.error('[HandleField] No Parent Category Found.'); return; } /* Toggles */ if (AMSettings.hasParentClass(field, 'toggle-element')) { field.checked = preferences[category][element]; field.addEventListener('change', (event) => { ipcRenderer.invoke('setStoreValue', `${category}.${element}`, event.target.checked).catch((err) => console.error(err)); }); console.warn(`[HandleField] Event listener created for ${category}.${element}`) } /* Dropdowns */ else if (field.classList.contains('form-dropdown-select')) { field.value = preferences[category][element]; field.addEventListener('change', (event) => { ipcRenderer.invoke('setStoreValue', `${category}.${element}`, event.target.value).catch((err) => console.error(err)); }); console.warn(`[HandleField] Event listener created for ${category}.${element}`) } /* LastFM Connect Button */ else if (field.id === "lfmConnect") { ipcRenderer.invoke('getStoreValue', 'tokens.lastfm').then((token) => { if (token) { field.innerHTML = `Disconnect\n

    (Authed: ${token})

    `; field.onclick = AMSettings.lastfm.LastFMDeauthorize; } }) } }, CreateMenu: (parent) => { preferences = ipcRenderer.sendSync('getStore'); AMJavaScript.getRequest("ameres://html/preferences-main.html", (content) => { document.getElementsByClassName(parent)[0].innerHTML = content; if (document.querySelector('footer')) { document.querySelector('.dt-footer').style.display = "block"; document.querySelector('.dt-footer').classList.add('app-prefs-credits'); AMJavaScript.getRequest("ameres://html/preferences-footer.html", (content) => { document.querySelector('.dt-footer').innerHTML = content; }) } AMSettings.themes.updateThemesListing(AM.themesListing); /* Adjust Preferences Menu if Acrylic is not Supported */ if (AM.acrylicSupported) { document.getElementById('transparencyEffect').innerHTML = document.getElementById('transparencyEffect').innerHTML + "\n"; document.getElementById('transparencyEffect').innerHTML = document.getElementById('transparencyEffect').innerHTML + "\n"; } else { document.getElementById('transparencyDisableBlurToggleLI').remove(); } /* Remove System Accent Toggle if its not win32/darwin */ ipcRenderer.invoke('fetchOperatingSystem').then((platform) => { if (platform !== "win32" && platform !== "darwin") { document.getElementById('useOperatingSystemAccentToggleLI').remove(); } }); /* General Settings */ AMSettings.HandleField('incognitoMode'); AMSettings.HandleField('playbackNotifications'); AMSettings.HandleField('trayTooltipSongName'); AMSettings.HandleField('startupPage'); AMSettings.HandleField('analyticsEnabled'); AMSettings.HandleField('discordRPC'); AMSettings.HandleField('discordClearActivityOnPause'); AMSettings.HandleField('lfmConnect'); AMSettings.HandleField('lastfmRemoveFeaturingArtists'); AMSettings.HandleField('lastfmNowPlaying'); AMSettings.HandleField('lastfmScrobbleDelay'); /* Visual Settings */ AMSettings.HandleField('theme'); AMSettings.HandleField('frameType'); AMSettings.HandleField('transparencyEffect'); AMSettings.HandleField('transparencyTheme'); AMSettings.HandleField('transparencyDisableBlur'); AMSettings.HandleField('transparencyMaximumRefreshRate'); AMSettings.HandleField('yton'); AMSettings.HandleField('mxmon'); AMSettings.HandleField('mxmlanguage'); AMSettings.HandleField('streamerMode'); AMSettings.HandleField('removeUpsell'); AMSettings.HandleField('removeAppleLogo'); AMSettings.HandleField('removeFooter'); AMSettings.HandleField('removeScrollbars'); AMSettings.HandleField('useOperatingSystemAccent'); AMSettings.HandleField('scaling'); /* Audio Settings */ AMSettings.HandleField('audioQuality'); AMSettings.HandleField('seamlessAudioTransitions'); AMSettings.HandleField('castingBitDepth'); AMSettings.HandleField('enableDLNA'); AMSettings.HandleField('volume'); /* Window Settings */ AMSettings.HandleField('appStartupBehavior'); AMSettings.HandleField('closeButtonMinimize'); /* Advanced Settings */ AMSettings.HandleField('forceApplicationMode'); AMSettings.HandleField('hardwareAcceleration'); AMSettings.HandleField('verboseLogging'); AMSettings.HandleField('alwaysOnTop'); AMSettings.HandleField('autoUpdaterBetaBuilds'); AMSettings.HandleField('useBetaSite'); AMSettings.HandleField('preventMediaKeyHijacking'); AMSettings.HandleField('devToolsOnStartup'); AMSettings.HandleField('allowMultipleInstances'); }) } } } } catch (e) { console.error("[JS] Error while trying to apply custom.js", e); }