diff --git a/src/renderer/.jsbeautifyrc b/src/renderer/.jsbeautifyrc new file mode 100644 index 00000000..bde13199 --- /dev/null +++ b/src/renderer/.jsbeautifyrc @@ -0,0 +1,5 @@ +{ + "js": { + "beautify.ignore": "src/renderer/index.js" + } +} \ No newline at end of file diff --git a/src/renderer/index.js b/src/renderer/index.js index c4d1fef4..61e69fa1 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -123,3465 +123,3358 @@ const store = new Vuex.Store({ }) const app = new Vue({ - el: "#app", - store: store, - data: { - appMode: "player", - ipcRenderer: ipcRenderer, - cfg: ipcRenderer.sendSync("getStore"), - isDev: ipcRenderer.sendSync("is-dev"), - drawertest: false, - platform: "", - mk: {}, - quickPlayQuery: "", - search: { - term: "", - hints: [], - showHints: false, - results: {}, - resultsSocial: {}, - limit: 10 + el: "#app", + store: store, + data: { + appMode: "player", + ipcRenderer: ipcRenderer, + cfg: ipcRenderer.sendSync("getStore"), + isDev: ipcRenderer.sendSync("is-dev"), + drawertest: false, + platform: "", + mk: {}, + quickPlayQuery: "", + search: { + term: "", + hints: [], + showHints: false, + results: {}, + resultsSocial: {}, + limit: 10 + }, + fullscreenLyrics: false, + playerLCD: { + playbackDuration: 0, + desiredDuration: 0, + userInteraction: false + }, + drawer: { + open: false, + panel: "" + }, + browsepage: [], + listennow: [], + madeforyou: [], + radio: { + personal: [] + }, + webview: { + url: "", + title: "", + loading: false + }, + showingPlaylist: [], + appleCurator: [], + artistPage: { + data: {}, + }, + library: { + downloadNotification: { + show: false, + message: "", + total: 0, + progress: 0 + }, + songs: { + sortingOptions: { + "albumName": "Album", + "artistName": "Artist", + "name": "Name", + "genre": "Genre", + "releaseDate": "Release Date", + "durationInMillis": "Duration" }, - fullscreenLyrics: false, - playerLCD: { - playbackDuration: 0, - desiredDuration: 0, - userInteraction: false + sorting: "name", + sortOrder: "asc", + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + albums: { + sortingOptions: { + "artistName": "Artist", + "name": "Name", + "genre": "Genre", + "releaseDate": "Release Date" }, - drawer: { - open: false, - panel: "" + viewAs: 'covers', + sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page + sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + artists: { + sortingOptions: { + "artistName": "Artist", + "name": "Name", + "genre": "Genre", + "releaseDate": "Release Date" }, - browsepage: [], - listennow: [], - madeforyou: [], - radio: { - personal: [] - }, - webview: { - url: "", - title: "", - loading: false - }, - showingPlaylist: [], - appleCurator: [], - artistPage: { - data: {}, - }, - library: { - downloadNotification: { - show: false, - message: "", - total: 0, - progress: 0 - }, - songs: { - sortingOptions: { - "albumName": "Album", - "artistName": "Artist", - "name": "Name", - "genre": "Genre", - "releaseDate": "Release Date", - "durationInMillis": "Duration" - }, - sorting: "name", - sortOrder: "asc", - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - albums: { - sortingOptions: { - "artistName": "Artist", - "name": "Name", - "genre": "Genre", - "releaseDate": "Release Date" - }, - viewAs: 'covers', - sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page - sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - artists: { - sortingOptions: { - "artistName": "Artist", - "name": "Name", - "genre": "Genre", - "releaseDate": "Release Date" - }, - viewAs: 'covers', - sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page - sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page - listing: [], - meta: { total: 0, progress: 0 }, - search: "", - displayListing: [], - downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library - }, - }, - playlists: { - listing: [], - details: {}, - loadingState: 0, // 0 loading, 1 loaded, 2 error - id: "" - }, - mxmtoken: "", - mkIsReady: false, - playerReady: false, - animateBackground: false, - currentArtUrl: '', - lyricon: false, - currentTrackID: '', - currentTrackIDBG: '', - lyrics: [], - currentLyricsLine: 0, - lyriccurrenttime: 0, - richlyrics: [], - lyricsMediaItem: {}, - lyricsDebug: { - current: 0, - start: 0, - end: 0 - }, - tmpVar: [], - notification: false, - chrome: { - hideUserInfo: ipcRenderer.sendSync("is-dev"), - artworkReady: false, - userinfo: { - "id": "", - "attributes": { - "name": "Cider User", - "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } - } - }, - menuOpened: false, - maximized: false, - drawerOpened: false, - drawerState: "queue", - topChromeVisible: true, - progresshover: false, - windowControlPosition: "right" - }, - collectionList: { - response: {}, - title: "", - type: "" - }, - prevButtonBackIndicator: false, - currentSongInfo: {}, - page: "", - pageHistory: [], - songstest: false, - hangtimer: null, - selectedMediaItems: [], - routes: ["browse", "listen_now", "radio"], - musicBaseUrl: "https://api.music.apple.com/", - modals: { - addToPlaylist: false, - spatialProperties: false - }, - socialBadges: { - badgeMap: {}, - version: "", - mediaItems: [], - mediaItemDLState: 0 // 0 = not started, 1 = in progress, 2 = complete - }, - menuPanel: { - visible: false, - event: null, - content: { - name: "", - items: {}, - headerItems: {} - } + viewAs: 'covers', + sorting: ["dateAdded", "name"], // [0] = recentlyadded page, [1] = albums page + sortOrder: ["desc", "asc"], // [0] = recentlyadded page, [1] = albums page + listing: [], + meta: { total: 0, progress: 0 }, + search: "", + displayListing: [], + downloadState: 0 // 0 = not started, 1 = in progress, 2 = complete, 3 = empty library + }, + }, + playlists: { + listing: [], + details: {}, + loadingState: 0, // 0 loading, 1 loaded, 2 error + id: "" + }, + mxmtoken: "", + mkIsReady: false, + playerReady: false, + animateBackground: false, + currentArtUrl: '', + lyricon: false, + currentTrackID: '', + currentTrackIDBG: '', + lyrics: [], + currentLyricsLine: 0, + lyriccurrenttime: 0, + richlyrics: [], + lyricsMediaItem: {}, + lyricsDebug: { + current: 0, + start: 0, + end: 0 + }, + tmpVar: [], + notification: false, + chrome: { + hideUserInfo: ipcRenderer.sendSync("is-dev"), + artworkReady: false, + userinfo: { + "id": "", + "attributes": { + "name": "Cider User", + "handle": "CiderUser", + "artwork": { "url": "./assets/logocut.png" } } }, - watch: { - cfg: { - handler: function(val, oldVal) { - console.log(`cfg changed from ${oldVal} to ${val}`); - ipcRenderer.send("setStore", val); - }, - deep: true - }, - page: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, - showingPlaylist: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, - artistPage: () => { - document.getElementById("app-content").scrollTo(0, 0); - app.resetState() - }, + menuOpened: false, + maximized: false, + drawerOpened: false, + drawerState: "queue", + topChromeVisible: true, + progresshover: false, + windowControlPosition: "right" + }, + collectionList: { + response: {}, + title: "", + type: "" + }, + prevButtonBackIndicator: false, + currentSongInfo: {}, + page: "", + pageHistory: [], + songstest: false, + hangtimer: null, + selectedMediaItems: [], + routes: ["browse", "listen_now", "radio"], + musicBaseUrl: "https://api.music.apple.com/", + modals: { + addToPlaylist: false, + spatialProperties: false + }, + socialBadges: { + badgeMap: {}, + version: "", + mediaItems: [], + mediaItemDLState: 0 // 0 = not started, 1 = in progress, 2 = complete + }, + menuPanel: { + visible: false, + event: null, + content: { + name: "", + items: {}, + headerItems: {} + } + } + }, + watch: { + cfg: { + handler: function(val, oldVal) { + console.log(`cfg changed from ${oldVal} to ${val}`); + ipcRenderer.send("setStore", val); }, - methods: { - async showSocialListeningTo() { - let contentIds = Object.keys(app.socialBadges.badgeMap) - app.showCollection({ data: this.socialBadges.mediaItems }, "Friends Listening To", "albums") - if (this.socialBadges.mediaItemDLState == 1 || this.socialBadges.mediaItemDLState == 2) { - return + deep: true + }, + page: () => { + document.getElementById("app-content").scrollTo(0, 0); + app.resetState() + }, + showingPlaylist: () => { + document.getElementById("app-content").scrollTo(0, 0); + app.resetState() + }, + artistPage: () => { + document.getElementById("app-content").scrollTo(0, 0); + app.resetState() + }, + }, + methods: { + async showSocialListeningTo() { + let contentIds = Object.keys(app.socialBadges.badgeMap) + app.showCollection({ data: this.socialBadges.mediaItems }, "Friends Listening To", "albums") + if (this.socialBadges.mediaItemDLState == 1 || this.socialBadges.mediaItemDLState == 2) { + return + } + this.socialBadges.mediaItemDLState = 2 + await asyncForEach(contentIds, async(item) => { + try { + let type = "albums" + if (item.includes("pl.")) { + type = "playlists" } - this.socialBadges.mediaItemDLState = 2 - await asyncForEach(contentIds, async(item) => { - try { - let type = "albums" - if (item.includes("pl.")) { - type = "playlists" - } - if (item.includes("ra.")) { - type = "stations" - } - let found = await app.mk.api.v3.music(`/v1/catalog/us/${type}/${item}`) - this.socialBadges.mediaItems.push(found.data.data[0]) - } catch (e) { + if (item.includes("ra.")) { + type = "stations" + } + let found = await app.mk.api.v3.music(`/v1/catalog/us/${type}/${item}`) + this.socialBadges.mediaItems.push(found.data.data[0]) + } catch (e) { - } - }) - }, - async openAppleMusicURL(url) { - let properties = MusicKit.formattedMediaURL(url) - let item = { + } + }) + }, + async openAppleMusicURL(url) { + let properties = MusicKit.formattedMediaURL(url) + let item = { + id: properties.contentId, + attributes: { + playParams: { id: properties.contentId, - attributes: { - playParams: { - id: properties.contentId, - kind: properties.kind, - } - }, - type: properties.kind, - kind: properties.kind - } - app.routeView(item) - }, - async showMenuPanel(data, event) { - app.menuPanel.visible = true; - app.menuPanel.content.name = data.name ? ? ""; - app.menuPanel.content.items = data.items ? ? {}; - app.menuPanel.content.headerItems = data.headerItems ? ? {}; - if (event) { - app.menuPanel.event = event; + kind: properties.kind, } }, - async getSvgIcon(url) { - let response = await fetch(url); - let data = await response.text(); - return data; - }, - getSocialBadges(cb = () => {}) { - let self = this - try { - app.mk.api.v3.music("/v1/social/badging-map").then(data => { - self.socialBadges.badgeMap = data.data.results.badgingMap - cb(data.data.results.badgingMap) + type: properties.kind, + kind: properties.kind + } + app.routeView(item) + }, + async showMenuPanel(data, event) { + app.menuPanel.visible = true; + app.menuPanel.content.name = data.name ?? ""; + app.menuPanel.content.items = data.items ?? {}; + app.menuPanel.content.headerItems = data.headerItems ?? {}; + if (event) { + app.menuPanel.event = event; + } + }, + async getSvgIcon(url) { + let response = await fetch(url); + let data = await response.text(); + return data; + }, + getSocialBadges(cb = () => {}) { + let self = this + try { + app.mk.api.v3.music("/v1/social/badging-map").then(data => { + self.socialBadges.badgeMap = data.data.results.badgingMap + cb(data.data.results.badgingMap) + }) + } catch (ex) { + this.socialBadges.badgeMap = {} + } + }, + addFavorite(id, type) { + this.cfg.home.favoriteItems.push({ + id: id, + type: type + }); + }, + modularUITest(val = false) { + this.fullscreenLyrics = val; + if (val) { + document.querySelector("#app-main").classList.add("modular-fs") + } else { + document.querySelector("#app-main").classList.remove("modular-fs") + } + }, + navigateBack() { + history.back() + }, + navigateForward() { + history.forward() + }, + getHTMLStyle() { + document.querySelector("html").style.background = "#222"; + document.querySelector("body").classList.add("notransparency") + }, + resetState() { + this.menuPanel.visible = false; + app.selectedMediaItems = []; + for (let key in app.modals) { + app.modals[key] = false; + } + }, + promptAddToPlaylist() { + app.modals.addToPlaylist = true; + }, + async addSelectedToPlaylist(playlist_id) { + let self = this + let pl_items = [] + for (let i = 0; i < self.selectedMediaItems.length; i++) { + if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { + self.selectedMediaItems[i].kind = "songs" + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind + }) + } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { + self.selectedMediaItems[i].kind = "albums" + let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function(i) { + return { id: i.id, type: i.type } + }) + pl_items = pl_items.concat(ids) + } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { + self.selectedMediaItems[i].kind = "library-songs" + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind + }) + } else if ((self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums") || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { + self.selectedMediaItems[i].kind = "library-albums" + let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); + let ids = res.data.data.map(function(i) { + return { id: i.id, type: i.type } + }) + pl_items = pl_items.concat(ids) + } else { + pl_items.push({ + id: self.selectedMediaItems[i].id, + type: self.selectedMediaItems[i].kind + }) + } + + } + this.modals.addToPlaylist = false + await app.mk.api.v3.music( + `/v1/me/library/playlists/${playlist_id}/tracks`, {}, { + fetchOptions: { + method: "POST", + body: JSON.stringify({ + data: pl_items }) - } catch (ex) { - this.socialBadges.badgeMap = {} } - }, - addFavorite(id, type) { - this.cfg.home.favoriteItems.push({ - id: id, - type: type - }); - }, - modularUITest(val = false) { - this.fullscreenLyrics = val; - if (val) { - document.querySelector("#app-main").classList.add("modular-fs") - } else { - document.querySelector("#app-main").classList.remove("modular-fs") - } - }, - navigateBack() { - history.back() - }, - navigateForward() { - history.forward() - }, - getHTMLStyle() { - document.querySelector("html").style.background = "#222"; - document.querySelector("body").classList.add("notransparency") - }, - resetState() { - this.menuPanel.visible = false; - app.selectedMediaItems = []; - for (let key in app.modals) { - app.modals[key] = false; - } - }, - promptAddToPlaylist() { - app.modals.addToPlaylist = true; - }, - async addSelectedToPlaylist(playlist_id) { - let self = this - let pl_items = [] - for (let i = 0; i < self.selectedMediaItems.length; i++) { - if (self.selectedMediaItems[i].kind == "song" || self.selectedMediaItems[i].kind == "songs") { - self.selectedMediaItems[i].kind = "songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "album" || self.selectedMediaItems[i].kind == "albums") && self.selectedMediaItems[i].isLibrary != true) { - self.selectedMediaItems[i].kind = "albums" - let res = await self.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } - }) - pl_items = pl_items.concat(ids) - } else if (self.selectedMediaItems[i].kind == "library-song" || self.selectedMediaItems[i].kind == "library-songs") { - self.selectedMediaItems[i].kind = "library-songs" - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } else if ((self.selectedMediaItems[i].kind == "library-album" || self.selectedMediaItems[i].kind == "library-albums") || (self.selectedMediaItems[i].kind == "album" && self.selectedMediaItems[i].isLibrary == true)) { - self.selectedMediaItems[i].kind = "library-albums" - let res = await self.mk.api.v3.music(`/v1/me/library/albums/${self.selectedMediaItems[i].id}/tracks`); - let ids = res.data.data.map(function(i) { - return { id: i.id, type: i.type } - }) - pl_items = pl_items.concat(ids) - } else { - pl_items.push({ - id: self.selectedMediaItems[i].id, - type: self.selectedMediaItems[i].kind - }) - } + } + ).then(() => { + if (this.page == 'playlist_' + this.showingPlaylist.id) { + this.getPlaylistFromID(this.showingPlaylist.id) + } + }) + }, + async init() { + let self = this + clearTimeout(this.hangtimer) + this.mk = MusicKit.getInstance() + this.mk.authorize().then(() => { + self.mkIsReady = true + //document.location.reload() + }) + this.$forceUpdate() + if (this.isDev) { + this.mk.privateEnabled = true + } + if (this.cfg.visual.hw_acceleration == "disabled") { + document.body.classList.add("no-gpu") + } + this.mk._services.timing.mode = 0 + this.platform = ipcRenderer.sendSync('cider-platform'); + try { + // Set profile name + this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0] + } catch (err) {} + + // API Fallback + if (!this.chrome.userinfo) { + this.chrome.userinfo = { + "id": "", + "attributes": { + "name": "Cider User", + "handle": "CiderUser", + "artwork": { "url": "./assets/logocut.png" } } - this.modals.addToPlaylist = false - await app.mk.api.v3.music( - `/v1/me/library/playlists/${playlist_id}/tracks`, {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - data: pl_items - }) - } - } - ).then(() => { - if (this.page == 'playlist_' + this.showingPlaylist.id) { - this.getPlaylistFromID(this.showingPlaylist.id) - } + } + } + MusicKitInterop.init() + // Set the volume + this.mk.volume = this.cfg.audio.volume + // ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => { + // self.mk.volume = value + // }) + + // load cached library + if (localStorage.getItem("librarySongs") != null) { + this.library.songs.listing = JSON.parse(localStorage.getItem("librarySongs")) + this.library.songs.displayListing = this.library.songs.listing + } + if (localStorage.getItem("libraryAlbums") != null) { + this.library.albums.listing = JSON.parse(localStorage.getItem("libraryAlbums")) + this.library.albums.displayListing = this.library.albums.listing + } + + window.onbeforeunload = function(e) { + window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)) + window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)) + window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue.items)) + }; + + // Load saved quality + switch (app.cfg.audio.quality) { + case "extreme": + app.mk.bitrate = app.cfg.audio.quality = 990 + break; + case "high": + app.mk.bitrate = app.cfg.audio.quality = 256 + break; + case "low": + app.mk.bitrate = app.cfg.audio.quality = 64 + break; + default: + app.mk.bitrate = app.cfg.audio.quality + } + + + // load last played track + try { + let lastItem = window.localStorage.getItem("currentTrack") + let time = window.localStorage.getItem("currentTime") + let queue = window.localStorage.getItem("currentQueue") + if (lastItem != null) { + lastItem = JSON.parse(lastItem) + let kind = lastItem.attributes.playParams.kind; + let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; + app.mk.setQueue({ + [truekind]: [lastItem.attributes.playParams.id] }) - }, - async init() { - let self = this - clearTimeout(this.hangtimer) - this.mk = MusicKit.getInstance() - this.mk.authorize().then(() => { - self.mkIsReady = true - //document.location.reload() - }) - this.$forceUpdate() - if (this.isDev) { - this.mk.privateEnabled = true - } - if (this.cfg.visual.hw_acceleration == "disabled") { - document.body.classList.add("no-gpu") - } - this.mk._services.timing.mode = 0 - this.platform = ipcRenderer.sendSync('cider-platform'); - - try { - // Set profile name - this.chrome.userinfo = (await app.mk.api.v3.music(`/v1/me/social-profile`)).data.data[0] - } catch (err) {} - - // API Fallback - if (!this.chrome.userinfo) { - this.chrome.userinfo = { - "id": "", - "attributes": { - "name": "Cider User", - "handle": "CiderUser", - "artwork": { "url": "./assets/logocut.png" } - } - } - } - MusicKitInterop.init() - // Set the volume - this.mk.volume = this.cfg.audio.volume - // ipcRenderer.invoke('getStoreValue', 'audio.volume').then((value) => { - // self.mk.volume = value - // }) - - // load cached library - if (localStorage.getItem("librarySongs") != null) { - this.library.songs.listing = JSON.parse(localStorage.getItem("librarySongs")) - this.library.songs.displayListing = this.library.songs.listing - } - if (localStorage.getItem("libraryAlbums") != null) { - this.library.albums.listing = JSON.parse(localStorage.getItem("libraryAlbums")) - this.library.albums.displayListing = this.library.albums.listing - } - - window.onbeforeunload = function(e) { - window.localStorage.setItem("currentTrack", JSON.stringify(app.mk.nowPlayingItem)) - window.localStorage.setItem("currentTime", JSON.stringify(app.mk.currentPlaybackTime)) - window.localStorage.setItem("currentQueue", JSON.stringify(app.mk.queue.items)) - }; - - // Load saved quality - switch (app.cfg.audio.quality) { - case "extreme": - app.mk.bitrate = app.cfg.audio.quality = 990 - break; - case "high": - app.mk.bitrate = app.cfg.audio.quality = 256 - break; - case "low": - app.mk.bitrate = app.cfg.audio.quality = 64 - break; - default: - app.mk.bitrate = app.cfg.audio.quality - } - - - // load last played track - try { - let lastItem = window.localStorage.getItem("currentTrack") - let time = window.localStorage.getItem("currentTime") - let queue = window.localStorage.getItem("currentQueue") - if (lastItem != null) { - lastItem = JSON.parse(lastItem) - let kind = lastItem.attributes.playParams.kind; - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - app.mk.setQueue({ - [truekind]: [lastItem.attributes.playParams.id] - }) - app.mk.mute() - setTimeout(() => { - app.mk.play().then(() => { - app.mk.pause().then(() => { - if (time != null) { - app.mk.seekToTime(time) - } - app.mk.unmute() - if (queue != null) { - queue = JSON.parse(queue) - if (queue && queue.length > 0) { - let ids = queue.map(e => (e.playParams ? e.playParams.id : (e.attributes.playParams ? e.attributes.playParams.id : ''))) - let i = 0; - if (ids.length > 0) { - for (id of ids) { - if (!(i == 0 && ids[0] == lastItem.attributes.playParams.id)) { - try { - app.mk.playLater({ songs: [id] }) - } catch (err) {} - } - i++; - } - } - } - } - - }) - - }) - }, 1500) - - } - - } catch (e) { - console.log(e) - } - - MusicKit.getInstance().videoContainerElement = document.getElementById("apple-music-video-player") - - ipcRenderer.on('SoundCheckTag', (event, tag) => { - let replaygain = self.parseSCTagToRG(tag) - try { - CiderAudio.audioNodes.gainNode.gain.value = (Math.min(Math.pow(10, (replaygain.gain / 20)), (1 / replaygain.peak))) - } catch (e) { - - } - }) - - this.mk.addEventListener(MusicKit.Events.playbackTimeDidChange, (a) => { - self.lyriccurrenttime = self.mk.currentPlaybackTime - this.currentSongInfo = a - self.playerLCD.playbackDuration = (self.mk.currentPlaybackTime) - }) - - this.mk.addEventListener(MusicKit.Events.nowPlayingItemDidChange, (a) => { - if (self.$refs.queue) { - self.$refs.queue.updateQueue(); - } - this.currentSongInfo = a - - - if (app.cfg.audio.normalization) { - // get unencrypted audio previews to get SoundCheck's normalization tag - try { - let previewURL = null - try { - previewURL = app.mk.nowPlayingItem.previewURL - } catch (e) {} - if (!previewURL) { - app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/songs/${app.mk.nowPlayingItem._songId ?? app.mk.nowPlayingItem.relationships.catalog.data[0].id}`).then((response) => { - previewURL = response.data.data[0].attributes.previews[0].url - if (previewURL) - ipcRenderer.send('getPreviewURL', previewURL) - }) - } else { - if (previewURL) - ipcRenderer.send('getPreviewURL', previewURL) - } - - } catch (e) {} - } - - try { - a = a.item.attributes; - } catch (_) {} << - << << < HEAD - let type = (self.mk.nowPlayingItem != null) ? self.mk.nowPlayingItem["type"] || '' : ''; === - === = - let type = (self.mk.nowPlayingItem != null) ? self.mk.nowPlayingItem["type"] ? ? '' : ''; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - - if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie")) { - document.getElementById("apple-music-video-container").style.display = "block"; - // app.chrome.topChromeVisible = false - } else { - document.getElementById("apple-music-video-container").style.display = "none"; - // app.chrome.topChromeVisible = true - } - self.chrome.artworkReady = false - self.lyrics = [] - self.richlyrics = [] - app.getCurrentArtURL(); - // app.getNowPlayingArtwork(42); - app.getNowPlayingArtworkBG(32); - app.loadLyrics(); - - // Playback Notifications - if ((app.platform === "darwin" || app.platform === "linux") && !document.hasFocus() && a.artistName && a.artwork && a.name) { - if (this.notification) { - this.notification.close() - } - this.notification = new Notification(a.name, { - body: a.artistName, - icon: a.artwork.url.replace('/{w}x{h}bb', '/512x512bb').replace('/2000x2000bb', '/35x35bb'), - silent: true, - }); - } - - }) - - - this.mk.addEventListener(MusicKit.Events.playbackVolumeDidChange, (_a) => { - this.cfg.audio.volume = this.mk.volume - }) - - this.refreshPlaylists() - document.body.removeAttribute("loading") - if (window.location.hash != "") { - this.appRoute(window.location.hash) - } else { - this.page = "home" - } - + app.mk.mute() setTimeout(() => { - this.getSocialBadges() - this.getBrowsePage(); - this.$forceUpdate() - }, 500) - }, - getAppClasses() { - if (this.cfg.advanced.experiments.includes('compactui')) { - return { compact: true } - } - }, - invokeDrawer(panel) { - if (this.drawer.panel == panel && this.drawer.open) { - if (panel == "lyrics") { - this.lyricon = false - } - this.drawer.panel = "" - this.drawer.open = false - } else { - if (panel == "lyrics") { - this.lyricon = true - } else { - this.lyricon = false - } - this.drawer.open = true - this.drawer.panel = panel - } - }, - select_removeMediaItem(id) { - this.selectedMediaItems.filter(item => item.guid == id).forEach(item => { - this.selectedMediaItems.splice(this.selectedMediaItems.indexOf(item), 1) - }) - }, - select_hasMediaItem(id) { - let found = this.selectedMediaItems.find(item => item.guid == id) - if (found) { - return true - } else { - return false - } - }, - select_selectMediaItem(id, kind, index, guid, library) { - if (!this.select_hasMediaItem(guid)) { - this.selectedMediaItems.push({ - id: id, - kind: kind, - index: index, - guid: guid, - isLibrary: library - }) - } - }, - getPlaylistFolderChildren(id) { - return this.playlists.listing.filter(playlist => { - if (playlist.parent == id) { - return playlist - } - }) - }, - async refreshPlaylists() { - let self = this - this.apiCall('https://api.music.apple.com/v1/me/library/playlist-folders/p.playlistsroot/children/', res => { - self.playlists.listing = res.data - self.playlists.listing.forEach(playlist => { - playlist.parent = "p.playlistsroot" - }) - self.sortPlaylists() - }) - }, - sortPlaylists() { - this.playlists.listing.sort((a, b) => { - if (a.type === "library-playlist-folders" && b.type !== "library-playlist-folders") { - return -1 - } else if (a.type !== "library-playlist-folders" && b.type === "library-playlist-folders") { - return 1 - } else { - return 0 - } - }) - }, - playlistHeaderContextMenu(event) { - let menu = { - items: [{ - name: "New Playlist", - action: () => { - this.newPlaylist() + app.mk.play().then(() => { + app.mk.pause().then(() => { + if (time != null) { + app.mk.seekToTime(time) } - }, - { - name: "New Playlist Folder", - action: () => { - this.newPlaylistFolder() - } - } - ] - } - this.showMenuPanel(menu, event) - }, - async editPlaylistFolder(id, name = "New Playlist") { - let self = this - this.mk.api.v3.music( - `/v1/me/library/playlist-folders/${id}`, {}, { - fetchOptions: { - method: "PATCH", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then(res => { - self.refreshPlaylists() - }) - }, - async editPlaylist(id, name = "New Playlist") { - let self = this - this.mk.api.v3.music( - `/v1/me/library/playlists/${id}`, {}, { - fetchOptions: { - method: "PATCH", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then(res => { - self.refreshPlaylists() - }) - }, - copyToClipboard(str) { - navigator.clipboard.writeText(str) - }, - newPlaylist(name = "New Playlist", tracks = []) { - let self = this - let request = { - name: name - } - if (tracks.length > 0) { - request.tracks = tracks - } - app.mk.api.v3.music(`/v1/me/library/playlists`, {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - "attributes": { "name": name }, - "relationships": { - "tracks": { "data": tracks }, - } - }) - } - }).then(res => { - res = res.data.data[0] - console.log(res) - self.appRoute(`playlist_` + res.id); - self.showingPlaylist = []; - self.getPlaylistFromID(app.page.substring(9)) - self.playlists.listing.push({ - id: res.id, - attributes: { - name: name - }, - parent: "p.playlistsroot" - }) - self.sortPlaylists() - setTimeout(() => { - app.refreshPlaylists() - }, 8000) - }) - }, - deletePlaylist(id) { - let self = this - if (confirm(`Are you sure you want to delete this playlist?`)) { - app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, {}, { - fetchOptions: { - method: "DELETE" - } - }).then(res => { - // remove this playlist from playlists.listing if it exists - let found = self.playlists.listing.find(item => item.id == id) - if (found) { - self.playlists.listing.splice(self.playlists.listing.indexOf(found), 1) - } - }) - } - }, - async showCollection(response, title, type) { - let self = this - this.collectionList.response = response - this.collectionList.title = title - this.collectionList.type = type - app.appRoute("collection-list") - }, - async showArtistView(artist, title, view) { - let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists/${artist}/view/${view}`)).data - console.log(response) - await this.showCollection(response, title, "artists") - }, - async showRecordLabelView(label, title, view) { - let response = (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/record-labels/${label}/view/${view}`)).data - await this.showCollection(response, title, "record-labels") - }, - async showSearchView(term, group, title) { - let response = await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${term}`, { - platform: "web", - groups: group, - types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", - limit: 25, - relate: { - editorialItems: ["contents"] - }, - include: { - albums: ["artists"], - songs: ["artists"], - "music-videos": ["artists"] - }, - extend: "artistUrl", - fields: { - artists: "url,name,artwork,hero", - albums: "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url" - }, - with: "serverBubbles,lyricHighlights", - art: { - "url": "cf" - }, - omit: { - resource: ["autos"] - }, - groups: group - }) - console.log('searchres', response) - let responseFormat = { - data: response.data.results[group].data, - next: response.data.results[group].data, - groups: group - } - await this.showCollection(responseFormat, title, "search") - }, - async getPlaylistContinuous(response, transient = false) { - response = response.data.data[0] - let self = this - let playlistId = response.id - if (!transient) this.playlists.loadingState = 0 - this.showingPlaylist = response - if (!response.relationships.tracks.next) { - this.playlists.loadingState = 1 - return - } - - function getPlaylistTracks(next) { - app.apiCall(app.musicBaseUrl + next, res => { - if (self.showingPlaylist.id != playlistId) { - return - } - self.showingPlaylist.relationships.tracks.data = self.showingPlaylist.relationships.tracks.data.concat(res.data) - if (res.next) { - getPlaylistTracks(res.next) - } else { - self.playlists.loadingState = 1 - } - }) - } - - getPlaylistTracks(response.relationships.tracks.next) - - }, - async getPlaylistFromID(id, transient = false) { - let self = this - const params = { - include: "tracks", - platform: "web", - "include[library-playlists]": "catalog,tracks", - "fields[playlists]": "curatorName,playlistType,name,artwork,url,playParams", - "include[library-songs]": "catalog,artists,albums,playParams,name,artwork,url", - "fields[catalog]": "artistUrl,albumUrl,url", - "fields[songs]": "artistUrl,albumUrl,playParams,name,artwork,url,artistName,albumName,durationInMillis" - } - if (!transient) { - this.playlists.loadingState = 0; - } - app.mk.api.v3.music(`/v1/me/library/playlists/${id}`, params).then(res => { - self.getPlaylistContinuous(res, transient) - }).catch((e) => { - console.log(e); - try { - app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`, params).then(res => { - self.getPlaylistContinuous(res, transient) - }) - } catch (err) { - console.log(err) - } - }) - - }, - async getArtistFromID(id) { - const artistData = await this.mkapi("artists", false, id, { - "views": "featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see", - "extend": "artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero", - "extend[playlists]": "trackCount", - "include[songs]": "albums", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount", - "limit[artists:top-songs]": 20, - "art[url]": "f" - }, { includeResponseMeta: !0 }) - console.log(artistData.data.data[0]) - this.artistPage.data = artistData.data.data[0] - this.page = "artist-page" - }, - progressBarStyle() { - let val = this.playerLCD.playbackDuration - if (this.playerLCD.desiredDuration > 0) { - val = this.playerLCD.desiredDuration - } - let min = 0 - let max = this.mk.currentPlaybackDuration - let value = (val - min) / (max - min) * 100 - return { - 'background': ('linear-gradient(to right, var(--keyColor) 0%, var(--keyColor) ' + value + '%, #333 ' + value + '%, #333 100%)') - } - }, - async getRecursive(response) { - // if response has a .next() property run it and keep running until .next is null or undefined - // and then return the response concatenated with the results of the next() call - function executeRequest() { - if (response.next) { - return response.next().then(executeRequest) - } else { - return response - } - } - - return executeRequest() - }, - async getRecursive2(response, sendTo) { - let returnData = { - "data": [], - "meta": {} - } - if (response.next) { - console.log("has next") - returnData.data.concat(response.data) - returnData.meta = response.meta - return await this.getRecursive(await response.next()) - } else { - console.log("no next") - returnData.data.concat(response.data) - return returnData - } - }, - async getSearchHints() { - if (this.search.term == "") { - this.search.hints = [] - return - } - let hints = await (await app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search/hints?term=${this.search.term}`)).data.results - this.search.hints = hints ? hints.terms : [] - }, - getSongProgress() { - if (this.playerLCD.userInteraction) { - return this.playerLCD.desiredDuration - } else { - return this.playerLCD.playbackDuration - } - }, - convertToMins(time) { - let mins = Math.floor(time / 60) - let seconds = (Math.floor(time % 60) / 100).toFixed(2) - return `${mins}:${seconds.replace("0.", "")}` - }, - hashCode(str) { - let hash = 0, - i, chr; - if (str.length === 0) return hash; - for (i = 0; i < str.length; i++) { - chr = str.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer - } - return hash; - }, - appRoute(route) { - console.log(route) - if (route == "" || route == "#" || route == "/") { - return; - } - route = route.replace(/#/g, "") - // if the route contains does not include a / then route to the page directly - if (route.indexOf("/") == -1) { - this.page = route - window.location.hash = this.page - return - } - let hash = route.split("/") - let page = hash[0] - let id = hash[1] << - << << < HEAD - let isLibrary = hash[2] || false === - === = - let isLibrary = hash[2] ? ? false >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - console.log(`page: ${page} id: ${id} isLibrary: ${isLibrary}`) - this.routeView({ - kind: page, - id: id, - attributes: { - playParams: { kind: page, id: id, isLibrary: isLibrary } - } - }) - }, - routeView(item) { << - << << < HEAD - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind || (item.type || '')) : (item.type || '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id || (item.id || '')) : (item.id || ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary || false) : false; === - === = - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ? ? (item.type ? ? '')) : (item.type ? ? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ? ? (item.id ? ? '')) : (item.id ? ? ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ? ? false) : false; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - console.log(kind, id, isLibrary) - - if (true) { - if (kind.includes("playlist") || kind.includes("album")) { - app.showingPlaylist = []; - } - if (kind.toString().includes("apple-curator")) { - kind = "appleCurator" - app.getTypeFromID("appleCurator", (id), false, { - platform: "web", - include: "grouping,playlists", - extend: "editorialArtwork", - "art[url]": "f" - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (kind.toString().includes("artist")) { - app.getArtistInfo(id, isLibrary) - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - - } else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) { - if (kind.toString().includes("record-label")) { - kind = "recordLabel" - } else { - kind = "curator" - } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), { - extend: "editorialVideo", - include: 'grouping,playlists', - views: 'top-releases,latest-releases,top-artists' - }); - window.location.hash = `${kind}/${id}` - document.querySelector("#app-content").scrollTop = 0 - } else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) { - let params = { extend: "editorialVideo" } - app.page = (kind) + "_" + (id); - app.getTypeFromID((kind), (id), (isLibrary), params); - window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}` - document.querySelector("#app-content").scrollTop = 0 - } else { << - << << < HEAD - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url || '') === - === = - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ? ? '') >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - } - - } - - }, - prevButton() { - if (!app.prevButtonBackIndicator && app.mk.nowPlayingItem && app.mk.currentPlaybackTime > 2) { - app.prevButtonBackIndicator = true; - app.mk.seekToTime(0); - } else { - app.prevButtonBackIndicator = false; - app.mk.skipToPreviousItem() - } - }, - async getNowPlayingItemDetailed(target) { - let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, (app.mk.nowPlayingItem.songId == -1), (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], { "include[songs]": "albums,artists" }); - app.searchAndNavigate(u.data.data[0], target) - }, - async searchAndNavigate(item, target) { - let self = this - app.tmpVar = item; - switch (target) { - case "artist": - let artistId = ''; - try { - if (item.relationships.artists && item.relationships.artists.data.length > 0 && !item.relationships.artists.data[0].type.includes("library")) { - if (item.relationships.artists.data[0].type === "artist" || item.relationships.artists.data[0].type === "artists") { - artistId = item.relationships.artists.data[0].id - } - } - if (artistId == '') { - const url = (item.relationships.catalog.data[0].attributes.artistUrl); - artistId = (url).substring(url.lastIndexOf('/') + 1) - if (artistId.includes('viewCollaboration')) { - artistId = artistId.substring(artistId.lastIndexOf('ids=') + 4, artistId.lastIndexOf('-')) - } - } - } catch (_) {} - - if (artistId == "") { - let artistQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.artistName}`, { - limit: 1, - types: 'artists' - })).data.results; - try { - if (artistQuery.artists.data.length > 0) { - artistId = artistQuery.artists.data[0].id; - console.log(artistId) - } - } catch (e) {} - } - console.log(artistId); - if (artistId != "") - self.appRoute(`artist/${artistId}`) - break; - case "album": - let albumId = ''; - try { - if (item.relationships.albums && item.relationships.albums.data.length > 0 && !item.relationships.albums.data[0].type.includes("library")) { - if (item.relationships.albums.data[0].type === "album" || item.relationships.albums.data[0].type === "albums") { - albumId = item.relationships.albums.data[0].id - } - } - if (albumId == '') { - const url = (item.relationships.catalog.data[0].attributes.url); - albumId = (url).substring(url.lastIndexOf('/') + 1) - if (albumId.includes("?i=")) { - albumId = albumId.substring(0, albumId.indexOf("?i=")) - } - } - } catch (_) {} - - if (albumId == "") { - try { - let albumQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.albumName + " " + (item.attributes.artistName ?? "")}`, { - limit: 1, - types: 'albums' - })).data.results; - if (albumQuery.albums.data.length > 0) { - albumId = albumQuery.albums.data[0].id; - console.log(albumId) - } - } catch (e) {} - } - if (albumId != "") { - self.appRoute(`album/${albumId}`) - } - break; - case "recordLabel": - let labelId = ''; - try { - labelId = item.relationships['record-labels'].data[0].id - } catch (_) {} - - if (labelId == "") { - try { - let labelQuery = (await app.mk.api.v3.music(`v1/catalog/${app.mk.storefrontId}/search?term=${item.attributes.recordLabel}`, { - limit: 1, - types: 'record-labels' - })).data.results; - if (labelQuery["record-labels"].data.length > 0) { - labelId = labelQuery["record-labels"].data[0].id; - console.log(labelId) - } - } catch (e) {} - } - if (labelId != "") { - app.showingPlaylist = [] - await app.getTypeFromID("recordLabel", labelId, false, { views: 'top-releases,latest-releases,top-artists' }); - app.page = "recordLabel_" + labelId; - } - - break; - } - }, - exitMV() { - MusicKit.getInstance().stop() - document.getElementById("apple-music-video-container").style.display = "none"; - }, - getArtistInfo(id, isLibrary) { - this.getArtistFromID(id) - //this.getTypeFromID("artist",id,isLibrary,query) - }, - playMediaItem(item) { << - << << < HEAD - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind || (item.type || '')) : (item.type || '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id || (item.id || '')) : (item.id || ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary || false) : false; === - === = - let kind = (item.attributes.playParams ? (item.attributes.playParams.kind ? ? (item.type ? ? '')) : (item.type ? ? '')); - let id = (item.attributes.playParams ? (item.attributes.playParams.id ? ? (item.id ? ? '')) : (item.id ? ? ''));; - let isLibrary = item.attributes.playParams ? (item.attributes.playParams.isLibrary ? ? false) : false; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(kind, id, isLibrary) - app.mk.stop().then(() => { - if (kind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { - app.mk.play() - }) - } - // else if (kind.includes("playlist") && (id.startsWith("p.") || id.startsWith("pl."))){ - // /* Randomize array in-place using Durstenfeld shuffle algorithm */ - // function shuffleArray(array) { - // for (var i = array.length - 1; i > 0; i--) { - // var j = Math.floor(Math.random() * (i + 1)); - // var temp = array[i]; - // array[i] = array[j]; - // array[j] = temp; - // } - // } - // app.mk.clearQueue().then(function () { { - // app.mk.setQueue({[truekind]: [item.attributes.playParams.id ?? item.id]}).then(function () { - // app.mk.play().then(function (){ - // app.mk.clearQueue().then(function (){ - // var playlistId = id - // const params = { - // include: "tracks", - // platform: "web", - // "include[library-playlists]": "catalog,tracks", - // "fields[playlists]": "curatorName,playlistType,name,artwork,url", - // "include[library-songs]": "catalog,artists,albums", - // "fields[catalog]": "artistUrl,albumUrl", - // "fields[songs]": "artistUrl,albumUrl" - // } - // var playlistId = '' - - // try { - // function getPlaylist(id, params, isLibrary){ - // if (isLibrary){ - // return app.mk.api.library.playlist(id, params) - // } else { return app.mk.api.playlist(id, params)} - // } - // getPlaylist(id, params, isLibrary).then(res => { - // let query = res.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) - // if (!res.relationships.tracks.next) { - // return - // } else { - // getPlaylistTracks(res.relationships.tracks.next) - // } - - // function getPlaylistTracks(next) { - // app.apiCall(app.musicBaseUrl + next, res => { - // if (res.id != playlistId) { - // return - // } - // let query = res.data.map(item => new MusicKit.MediaItem(item)) - // if (app.mk.shuffleMode == 1){shuffleArray(query); console.log('shf')} - // app.mk.queue.append(query) - - // if (res.next) { - // getPlaylistTracks(res.next) - // } - // }) - // } - // }) - // } catch (e) {} - - - // }) - // }) - // }) - // } - // }) - // } - else { << - << << < HEAD - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url || '') === - === = - app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ? ? '') >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - } - }) - }, - async getTypeFromID(kind, id, isLibrary = false, params = {}, params2 = {}) { - let a; - if (kind == "album" | kind == "albums") { - params["include"] = "tracks,artists,record-labels"; - } - try { - a = await this.mkapi(kind.toString(), isLibrary, id.toString(), params, params2); - } catch (e) { - console.log(e); - try { - a = await this.mkapi(kind.toString(), !isLibrary, id.toString(), params, params2); - } catch (err) { - console.log(err); - a = [] - } finally { - if (kind == "appleCurator") { - app.appleCurator = a.data.data[0] - } else { - this.getPlaylistContinuous(a) - } - } - } finally { - if (kind == "appleCurator") { - app.appleCurator = a.data.data[0] - } else { - this.getPlaylistContinuous(a) - } - }; - }, - searchLibrarySongs() { - let self = this - let prefs = this.cfg.libraryPrefs.songs - - function sortSongs() { - // sort this.library.songs.displayListing by song.attributes[self.library.songs.sorting] in descending or ascending order based on alphabetical order and numeric order - // check if song.attributes[self.library.songs.sorting] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.songs.displayListing.sort((a, b) => { - let aa = a.attributes[prefs.sort] - let bb = b.attributes[prefs.sort] - if (self.library.songs.sorting == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (prefs.sortOrder == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (prefs.sortOrder == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.songs.search == "") { - this.library.songs.displayListing = this.library.songs.listing - sortSongs() - } else { - this.library.songs.displayListing = this.library.songs.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.songs.search.toLowerCase() - let artistName = "" - let albumName = "" - if (item.attributes.artistName != null) { - artistName = item.attributes.artistName.toLowerCase() - } - if (item.attributes.albumName != null) { - albumName = item.attributes.albumName.toLowerCase() - } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - artistName = artistName.replace(/[^a-z0-9 ]/gi, "") - albumName = albumName.replace(/[^a-z0-9 ]/gi, "") - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortSongs() - } - }, - // make a copy of searchLibrarySongs except use Albums instead of Songs - searchLibraryAlbums(index) { - let self = this - - function sortAlbums() { - // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order - // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.albums.displayListing.sort((a, b) => { - let aa = a.attributes[self.library.albums.sorting[index]] - let bb = b.attributes[self.library.albums.sorting[index]] - if (self.library.albums.sorting[index] == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (self.library.albums.sortOrder[index] == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (self.library.albums.sortOrder[index] == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.albums.search == "") { - this.library.albums.displayListing = this.library.albums.listing - sortAlbums() - } else { - this.library.albums.displayListing = this.library.albums.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.albums.search.toLowerCase() - let artistName = "" - let albumName = "" - if (item.attributes.artistName != null) { - artistName = item.attributes.artistName.toLowerCase() - } - if (item.attributes.albumName != null) { - albumName = item.attributes.albumName.toLowerCase() - } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - artistName = artistName.replace(/[^a-z0-9 ]/gi, "") - albumName = albumName.replace(/[^a-z0-9 ]/gi, "") - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortAlbums() - } - }, - // make a copy of searchLibrarySongs except use Albums instead of Songs - searchLibraryArtists(index) { - let self = this - - function sortArtists() { - // sort this.library.albums.displayListing by album.attributes[self.library.albums.sorting[index]] in descending or ascending order based on alphabetical order and numeric order - // check if album.attributes[self.library.albums.sorting[index]] is a number and if so, sort by number if not, sort by alphabetical order ignoring case - self.library.artists.displayListing.sort((a, b) => { - let aa = a.attributes[self.library.artists.sorting[index]] - let bb = b.attributes[self.library.artists.sorting[index]] - if (self.library.artists.sorting[index] == "genre") { - aa = a.attributes.genreNames[0] - bb = b.attributes.genreNames[0] - } - if (aa == null) { - aa = "" - } - if (bb == null) { - bb = "" - } - if (self.library.artists.sortOrder[index] == "asc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return aa - bb - } else { - return aa.toString().toLowerCase().localeCompare(bb.toString().toLowerCase()) - } - } else if (self.library.artists.sortOrder[index] == "desc") { - if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) { - return bb - aa - } else { - return bb.toString().toLowerCase().localeCompare(aa.toString().toLowerCase()) - } - } - }) - } - - if (this.library.artists.search == "") { - this.library.artists.displayListing = this.library.artists.listing - sortArtists() - } else { - this.library.artists.displayListing = this.library.artists.listing.filter(item => { - let itemName = item.attributes.name.toLowerCase() - let searchTerm = this.library.artists.search.toLowerCase() - let artistName = "" - let albumName = "" - // if (item.attributes.artistName != null) { - // artistName = item.attributes.artistName.toLowerCase() - // } - // if (item.attributes.albumName != null) { - // albumName = item.attributes.albumName.toLowerCase() - // } - - // remove any non-alphanumeric characters and spaces from search term and item name - searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "") - itemName = itemName.replace(/[^a-z0-9 ]/gi, "") - - - if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) { - return item - } - }) - sortArtists() - } - }, - getSidebarItemClass(page) { - if (this.page == page) { - return ["active"] - } else { - return [] - } - }, - async mkapi(method, library = false, term, params = {}, params2 = {}, attempts = 0) { - if (method.includes(`recordLabel`)) { method = `record-labels` } - if (method.includes(`appleCurator`)) { method = `apple-curators` } - if (attempts > 3) { - return - } - let truemethod = (!method.endsWith("s")) ? (method + "s") : method; - try { - if (library) { - return await this.mk.api.v3.music(`v1/me/library/${truemethod}/${term.toString()}`, params, params2) - } else { - return await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/${truemethod}/${term.toString()}`, params, params2) - } - } catch (e) { - console.log(e) - return await this.mkapi(method, library, term, params, params2, attempts + 1) - } - }, - getLibraryGenres() { - let genres = [] - genres = [] - this.library.songs.listing.forEach((item) => { - item.attributes.genreNames.forEach((genre) => { - if (!genres.includes(genre)) { - genres.push(genre) - } - }) - }) - return genres - }, - async getLibrarySongsFull(force = false) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.songs.downloadState == 2) && !force) { - return - } - if (this.library.songs.downloadState == 1) { - return - } - if (localStorage.getItem("librarySongs") != null) { - this.library.songs.listing = JSON.parse(localStorage.getItem("librarySongs")) - this.searchLibrarySongs() - } - if (this.songstest) { - return - } - this.library.songs.downloadState = 1 - this.library.downloadNotification.show = true - this.library.downloadNotification.message = "Updating library songs..." - - function downloadChunk() { - const params = { - "include[library-songs]": "catalog,artists,albums", - "fields[artists]": "name,url,id", - "fields[albums]": "name,url,id", - platform: "web", - "fields[catalog]": "artistUrl,albumUrl", - "fields[songs]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - self.library.songs.downloadState = 1 - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/songs/`, params).then((response) => { - processChunk(response.data) - }) - } else { - - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }) - } else { - console.log("Download next", downloaded.next) - } - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.downloadNotification.show = true - self.library.downloadNotification.message = "Updating library songs..." - self.library.downloadNotification.total = downloaded.meta.total - self.library.downloadNotification.progress = library.length - - if (downloaded.meta.total == 0) { - self.library.songs.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.songs.listing = library - self.library.songs.downloadState = 2 - self.library.downloadNotification.show = false - self.searchLibrarySongs() - localStorage.setItem("librarySongs", JSON.stringify(library)) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length} songs so far`) - downloadChunk() - } else { - self.library.songs.listing = library - self.library.songs.downloadState = 2 - self.library.downloadNotification.show = false - self.searchLibrarySongs() - localStorage.setItem("librarySongs", JSON.stringify(library)) - console.log(library) - } - } - - downloadChunk() - }, - // copy the getLibrarySongsFull function except change Songs to Albums - async getLibraryAlbumsFull(force = false, index) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.albums.downloadState == 2 || this.library.albums.downloadState == 1) && !force) { - return - } - if (localStorage.getItem("libraryAlbums") != null) { - this.library.albums.listing = JSON.parse(localStorage.getItem("libraryAlbums")) - this.searchLibraryAlbums(index) - } - if (this.songstest) { - return - } - this.library.albums.downloadState = 1 - this.library.downloadNotification.show = true - this.library.downloadNotification.message = "Updating library albums..." - - function downloadChunk() { - self.library.albums.downloadState = 1 - const params = { - "include[library-albums]": "catalog,artists,albums", - "fields[artists]": "name,url,id", - "fields[albums]": "name,url,id", - platform: "web", - "fields[catalog]": "artistUrl,albumUrl", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/albums/`, params).then((response) => { - processChunk(response.data) - }) - } else { - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }) - } else { - console.log("Download next", downloaded.next) - } - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.downloadNotification.show = true - self.library.downloadNotification.message = "Updating library albums..." - self.library.downloadNotification.total = downloaded.meta.total - self.library.downloadNotification.progress = library.length - if (downloaded.meta.total == 0) { - self.library.albums.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.albums.listing = library - self.library.albums.downloadState = 2 - self.library.downloadNotification.show = false - localStorage.setItem("libraryAlbums", JSON.stringify(library)) - self.searchLibraryAlbums(index) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length - } albums so far`) - downloadChunk() - } else { - self.library.albums.listing = library - self.library.albums.downloadState = 2 - self.library.downloadNotification.show = false - localStorage.setItem("libraryAlbums", JSON.stringify(library)) - self.searchLibraryAlbums(index) - console.log(library) - } - } - - downloadChunk() - }, - // copy the getLibrarySongsFull function except change Songs to Albums - async getLibraryArtistsFull(force = false, index) { - let self = this - let library = [] - let downloaded = null; - if ((this.library.artists.downloadState == 2 || this.library.artists.downloadState == 1) && !force) { - return - } - if (localStorage.getItem("libraryArtists") != null) { - this.library.artists.listing = JSON.parse(localStorage.getItem("libraryArtists")) - this.searchLibraryArtists(index) - } - if (this.songstest) { - return - } - this.library.artists.downloadState = 1 - this.library.downloadNotification.show = true - this.library.downloadNotification.message = "Updating library artists..." - - function downloadChunk() { - self.library.artists.downloadState = 1 - const params = { - include: "catalog", - // "include[library-artists]": "catalog,artists,albums", - // "fields[artists]": "name,url,id", - // "fields[albums]": "name,url,id", - platform: "web", - // "fields[catalog]": "artistUrl,albumUrl", - // "fields[artists]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - limit: 100, - } - if (downloaded == null) { - app.mk.api.v3.music(`/v1/me/library/artists/`, params).then((response) => { - processChunk(response.data) - }) - - } else { - if (downloaded.next != null) { - app.mk.api.v3.music(downloaded.next, params).then((response) => { - processChunk(response.data) - }) - } else { - console.log("Download next", downloaded.next) - } - - } - } - - function processChunk(response) { - downloaded = response - library = library.concat(downloaded.data) - self.library.downloadNotification.show = true - self.library.downloadNotification.message = "Updating library artists..." - self.library.downloadNotification.total = downloaded.meta.total - self.library.downloadNotification.progress = library.length - if (downloaded.meta.total == 0) { - self.library.albums.downloadState = 3 - return - } - if (typeof downloaded.next == "undefined") { - console.log("downloaded.next is undefined") - self.library.artists.listing = library - self.library.artists.downloadState = 2 - self.library.artists.show = false - localStorage.setItem("libraryArtists", JSON.stringify(library)) - self.searchLibraryArtists(index) - } - if (downloaded.meta.total > library.length || typeof downloaded.meta.next != "undefined") { - console.log(`downloading next chunk - ${library.length - } artists so far`) - downloadChunk() - } else { - self.library.artists.listing = library - self.library.artists.downloadState = 2 - self.library.downloadNotification.show = false - localStorage.setItem("libraryArtists", JSON.stringify(library)) - self.searchLibraryArtists(index) - console.log(library) - } - } - - downloadChunk() - }, - getTotalTime() { - try { - if (app.showingPlaylist.relationships.tracks.data.length > 0) { - let time = Math.round([].concat(...app.showingPlaylist.relationships.tracks.data).reduce((a, { attributes: { durationInMillis } }) => a + durationInMillis, 0) / 1000); - let hours = Math.floor(time / 3600) - let mins = Math.floor(time / 60) % 60 - let secs = time % 60 - return app.showingPlaylist.relationships.tracks.data.length + " track" + (app.showingPlaylist.relationships.tracks.data.length > 1 ? "s" : "") + ", " + ((hours > 0) ? (hours + (" hour" + ((hours > 1) ? "s, " : ", "))) : "") + ((mins > 0) ? (mins + (" minute" + ((mins > 1) ? "s, " : ", "))) : "") + secs + (" second" + ((secs > 1) ? "s." : ".")); - } else return "" - } catch (err) { - return "" - } - }, - async getLibrarySongs() { - let response = await this.mkapi("songs", true, "", { limit: 100 }, { includeResponseMeta: !0 }) - this.library.songs.listing = response.data.data - this.library.songs.meta = response.data.meta - }, - async getLibraryAlbums() { - let response = await this.mkapi("albums", true, "", { limit: 100 }, { includeResponseMeta: !0 }) - this.library.albums.listing = response.data.data - this.library.albums.meta = response.data.meta - }, - async getListenNow(attempt = 0) { - if (attempt > 3) { - return - } - try { - this.listennow = (await this.mk.api.v3.music(`v1/me/recommendations?timezone=${encodeURIComponent(this.formatTimezoneOffset())}`, { - name: "listen-now", - with: "friendsMix,library,social", - "art[social-profiles:url]": "c", - "art[url]": "c,f", - "omit[resource]": "autos", - "relate[editorial-items]": "contents", - extend: ["editorialCard", "editorialVideo"], - "extend[albums]": ["artistUrl"], - "extend[library-albums]": ["artistUrl", "editorialVideo"], - "extend[playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], - "extend[library-playlists]": ["artistNames", "editorialArtwork", "editorialVideo"], - "extend[social-profiles]": "topGenreNames", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - "fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"], - "fields[artists]": ["name", "url"], - "extend[stations]": ["airDate", "supportsAirTimeUpdates"], - "meta[stations]": "inflectionPoints", - types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-upsells", - platform: "web" - }, { - includeResponseMeta: !0, - reload: !0 - })).data; - console.log(this.listennow) - } catch (e) { - console.log(e) - this.getListenNow(attempt + 1) - } - }, - async getBrowsePage(attempt = 0) { - if (attempt > 3) { - return - } - try { - let browse = await app.mk.api.v3.music(`/v1/editorial/${app.mk.storefrontId}/groupings`, { - platform: "web", - name: "music", - "omit[resource:artists]": "relationships", - "include[albums]": "artists", - "include[songs]": "artists", - "include[music-videos]": "artists", - extend: "editorialArtwork,artistUrl", - "fields[artists]": "name,url,artwork,editorialArtwork,genreNames,editorialNotes", - "art[url]": "f" - }); - this.browsepage = browse.data.data[0]; - console.log(this.browsepage) - } catch (e) { - console.log(e) - this.getBrowsePage(attempt + 1) - } - }, - async getRadioStations(attempt = 0) { - if (attempt > 3) { - return - } - try { - this.radio.personal = (await app.mk.api.v3.music(`/v1/me/recent/radio-stations`, { - "platform": "web", - "art[url]": "f" - })).data.data; - } catch (e) { - console.log(e) - this.getRadioStations(attempt + 1) - } - }, - async getMadeForYou(attempt = 0) { - if (attempt > 3) { - return - } - try { - mfu = await app.mk.api.v3.music("/v1/me/library/playlists?platform=web&extend=editorialVideo&fields%5Bplaylists%5D=lastModifiedDate&filter%5Bfeatured%5D=made-for-you&include%5Blibrary-playlists%5D=catalog&fields%5Blibrary-playlists%5D=artwork%2Cname%2CplayParams%2CdateAdded") - this.madeforyou = mfu.data - } catch (e) { - console.log(e) - this.getMadeForYou(attempt + 1) - } - }, - newPlaylistFolder(name = "New Folder") { - let self = this - this.mk.api.v3.music( - "/v1/me/library/playlist-folders/", {}, { - fetchOptions: { - method: "POST", - body: JSON.stringify({ - attributes: { name: name } - }) - } - } - ).then((res) => { - let playlist = (res.data.data[0]) - self.playlists.listing.push({ - id: playlist.id, - attributes: { - name: playlist.attributes.name - }, - type: "library-playlist-folders", - parent: "p.playlistsroot" - }) - self.sortPlaylists() - setTimeout(() => { - app.refreshPlaylists() - }, 13000) - }) - }, - unauthorize() { - this.mk.unauthorize() - }, - showSearch() { - this.page = "search" - }, - loadLyrics() { << - << << < HEAD - const musicType = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["type"] || '' : ''; === - === = - const musicType = (MusicKit.getInstance().nowPlayingItem != null) ? MusicKit.getInstance().nowPlayingItem["type"] ? ? '' : ''; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - console.log("mt", musicType) - if (musicType === "musicVideo") { - this.loadYTLyrics(); - } else { - if (app.cfg.lyrics.enable_mxm) { - this.loadMXM(); - } else { - this.loadAMLyrics(); - } - } - }, - loadAMLyrics() { << - << << < HEAD - const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] || -1 : -1; === - === = - const songID = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem["_songId"] ? ? -1 : -1; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - // this.getMXM( trackName, artistName, 'en', duration); - if (songID != -1) { - MusicKit.getInstance().api.lyric(songID) - .then((response) => { - this.lyricsMediaItem = response.attributes["ttml"] - this.parseTTML() - }) - } - }, - addToLibrary(id) { - let self = this - this.mk.addToLibrary(id).then((data) => { - self.getLibrarySongsFull(true) - }) - }, - removeFromLibrary(kind, id) { - let self = this - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - app.mk.api.v3.music(`v1/me/library/${truekind}/${id.toString()}`, {}, { - fetchOptions: { - method: "DELETE" - } - }).then((data) => { - self.getLibrarySongsFull(true) - }) - }, - async loadYTLyrics() { << - << << < HEAD - const track = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title || '' : ''; - const artist = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName || '' : ''; - const time = (this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] || -1000) / 1000) || -1) : -1; === - === = - const track = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ? ? '' : ''; - const artist = (this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ? ? '' : ''; - const time = (this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ? ? -1000) / 1000) ? ? -1) : -1; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - ipcRenderer.invoke('getYTLyrics', track, artist).then((result) => { - if (result.length > 0) { - let ytid = result[0]['id']['videoId']; - if (app.cfg.lyrics.enable_yt) { << - << << < HEAD - loadYT(ytid, app.cfg.lyrics.mxm_language || "en") === - === = - loadYT(ytid, app.cfg.lyrics.mxm_language ? ? "en") >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - } else { - app.loadMXM() - } - } else { - app.loadMXM() - } - - function loadYT(id, lang) { - let req = new XMLHttpRequest(); - let url = `https://www.youtube.com/watch?&v=${id}`; - req.open('GET', url, true); - req.onerror = function(e) { - this.loadMXM(); - } - req.onload = function() { - // console.log(this.responseText); - res = this.responseText; - let captionurl1 = res.substring(res.indexOf(`{"playerCaptionsRenderer":{"baseUrl":"`) + (`{"playerCaptionsRenderer":{"baseUrl":"`).length); - let captionurl = captionurl1.substring(0, captionurl1.indexOf(`"`)); - if (captionurl.includes("timedtext")) { - let json = JSON.parse(`{"url": "${captionurl}"}`); - let newurl = json.url + `&lang=${lang}&format=ttml` - - let req2 = new XMLHttpRequest(); - - req2.open('GET', newurl, true); - req2.onerror = function(e) { - app.loadMXM(); - } - req2.onload = function() { - try { - const ttmlLyrics = this.responseText; - if (ttmlLyrics) { - this.lyricsMediaItem = ttmlLyrics - this.parseTTML() - } - } catch (e) { - app.loadMXM(); - } - - } - req2.send(); - } else { - - app.loadMXM(); - - } - } - req.send(); - } - - }) - - }, - loadMXM() { - let attempt = 0; << - << << < HEAD - const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title || '' : ''); - const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName || '' : ''); - const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] || -1000) / 1000) || -1) : -1); - const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId || '' : ''); === - === = - const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ? ? '' : ''); - const artist = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.artistName ? ? '' : ''); - const time = encodeURIComponent((this.mk.nowPlayingItem != null) ? (Math.round((this.mk.nowPlayingItem.attributes["durationInMillis"] ? ? -1000) / 1000) ? ? -1) : -1); - const id = encodeURIComponent((this.mk.nowPlayingItem != null) ? app.mk.nowPlayingItem._songId ? ? '' : ''); >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - let lrcfile = ""; - let richsync = []; - const lang = app.cfg.lyrics.mxm_language // translation language - function revisedRandId() { - return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); - } - - /* get token */ - function getToken(mode, track, artist, songid, lang, time, id) { - if (attempt > 2) { - app.loadAMLyrics(); - } else { - attempt = attempt + 1; - let url = "https://apic-desktop.musixmatch.com/ws/1.1/token.get?app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req = new XMLHttpRequest(); - req.overrideMimeType("application/json"); - req.open('GET', url, true); - req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { - let jsonResponse = JSON.parse(this.responseText); - let status2 = jsonResponse["message"]["header"]["status_code"]; - if (status2 == 200) { << - << << < HEAD - let token = jsonResponse["message"]["body"]["user_token"] || ''; === - === = - let token = jsonResponse["message"]["body"]["user_token"] ? ? ''; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - if (token != "" && token != "UpgradeOnlyUpgradeOnlyUpgradeOnlyUpgradeOnly") { - console.log('200 token', mode); - // token good - app.mxmtoken = token; - - if (mode == 1) { - getMXMSubs(track, artist, app.mxmtoken, lang, time, id); - } else { - getMXMTrans(songid, lang, app.mxmtoken); - } - } else { - console.log('fake 200 token'); - getToken(mode, track, artist, songid, lang, time) - } - } else { - console.log('token 4xx'); - getToken(mode, track, artist, songid, lang, time) - } - - }; - req.onerror = function() { - console.log('error'); - app.loadAMLyrics(); - }; - req.send(); - } - } - - function getMXMSubs(track, artist, token, lang, time, id) { - let usertoken = encodeURIComponent(token); - let richsyncQuery = (app.cfg.lyrics.mxm_karaoke) ? "&optional_calls=track.richsync" : "" - let timecustom = (!time || (time && time < 0)) ? '' : `&f_subtitle_length=${time}&q_duration=${time}&f_subtitle_length_max_deviation=40`; - let itunesid = (id && id != "") ? `&track_itunes_id=${id}` : ''; - let url = "https://apic-desktop.musixmatch.com/ws/1.1/macro.subtitles.get?format=json&namespace=lyrics_richsynched" + richsyncQuery + "&subtitle_format=lrc&q_artist=" + artist + "&q_track=" + track + itunesid + "&usertoken=" + usertoken + timecustom + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req = new XMLHttpRequest(); - req.overrideMimeType("application/json"); - req.open('GET', url, true); - req.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req.onload = function() { - let jsonResponse = JSON.parse(this.responseText); - console.log(jsonResponse); - let status1 = jsonResponse["message"]["header"]["status_code"]; - - if (status1 == 200) { - let id = ''; - try { - if (jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["header"]["status_code"] == 200 && jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["header"]["status_code"] == 200) { << - << << < HEAD - id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] || ''; === - === = - id = jsonResponse["message"]["body"]["macro_calls"]["matcher.track.get"]["message"]["body"]["track"]["track_id"] ? ? ''; >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - lrcfile = jsonResponse["message"]["body"]["macro_calls"]["track.subtitles.get"]["message"]["body"]["subtitle_list"][0]["subtitle"]["subtitle_body"]; - - try { - lrcrich = jsonResponse["message"]["body"]["macro_calls"]["track.richsync.get"]["message"]["body"]["richsync"]["richsync_body"]; - richsync = JSON.parse(lrcrich); - app.richlyrics = richsync; - } catch (_) {} - } - - if (lrcfile == "") { - app.loadAMLyrics() - } else { - if (richsync == [] || richsync.length == 0) { - console.log("ok"); - // process lrcfile to json here - app.lyricsMediaItem = lrcfile - let u = app.lyricsMediaItem.split(/[\r\n]/); - let preLrc = [] - for (var i = u.length - 1; i >= 0; i--) { - let xline = (/(\[[0-9.:\[\]]*\])+(.*)/).exec(u[i]) << - << << < HEAD - let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) || 99999) : 99999 - preLrc.push({ - startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) || 0, - === - === = - let end = (preLrc.length > 0) ? ((preLrc[preLrc.length - 1].startTime) ? ? 99999) : 99999 - preLrc.push({ - startTime: app.toMS(xline[1].substring(1, xline[1].length - 2)) ? ? 0, - >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - endTime: end, - line: xline[2], - translation: '' - }) - } - if (preLrc.length > 0) - preLrc.push({ - startTime: 0, - endTime: preLrc[preLrc.length - 1].startTime, - line: "lrcInstrumental", - translation: '' - }); app.lyrics = preLrc.reverse(); - } - else { - preLrc = richsync.map(function(item) { - return { - startTime: item.ts, - endTime: item.te, - line: item.x, - translation: '' - } - }) - if (preLrc.length > 0) - preLrc.unshift({ - startTime: 0, - endTime: preLrc[0].startTime, - line: "lrcInstrumental", - translation: '' - }); - app.lyrics = preLrc; - } - if (lrcfile != null && lrcfile != '' && lang != "disabled") { - // load translation - getMXMTrans(id, lang, token); - } else { - app.loadAMLyrics() - } - } - } catch (e) { - console.log(e); - app.loadAMLyrics() - } - } else { //4xx rejected - getToken(1, track, artist, '', lang, time); - } - } - req.send(); - } - - function getMXMTrans(id, lang, token) { - if (lang != "disabled" && id != '') { - let usertoken = encodeURIComponent(token); - let url2 = "https://apic-desktop.musixmatch.com/ws/1.1/crowd.track.translations.get?translation_fields_set=minimal&selected_language=" + lang + "&track_id=" + id + "&comment_format=text&part=user&format=json&usertoken=" + usertoken + "&app_id=web-desktop-app-v1.0&t=" + revisedRandId(); - let req2 = new XMLHttpRequest(); - req2.overrideMimeType("application/json"); - req2.open('GET', url2, true); - req2.setRequestHeader("authority", "apic-desktop.musixmatch.com"); - req2.onload = function() { - let jsonResponse2 = JSON.parse(this.responseText); - console.log(jsonResponse2); - let status2 = jsonResponse2["message"]["header"]["status_code"]; - if (status2 == 200) { - try { - let preTrans = [] - let u = app.lyrics; - let translation_list = jsonResponse2["message"]["body"]["translations_list"]; - if (translation_list.length > 0) { - for (var i = 0; i < u.length - 1; i++) { - preTrans[i] = "" - for (var trans_line of translation_list) { - if (u[i].line == " " + trans_line["translation"]["matched_line"] || u[i].line == trans_line["translation"]["matched_line"]) { - u[i].translation = trans_line["translation"]["description"]; - break; - } - } - } - app.lyrics = u; - } - } catch (e) { - /// not found trans -> ignore - } - } else { //4xx rejected - getToken(2, '', '', id, lang, ''); - } - } - req2.send(); - } - - } - - if (track != "" & track != "No Title Found") { - if (app.mxmtoken != null && app.mxmtoken != '') { - getMXMSubs(track, artist, app.mxmtoken, lang, time, id) - } else { - getToken(1, track, artist, '', lang, time); - } - } - }, - toMS(str) { - let rawTime = str.match(/(\d+:)?(\d+:)?(\d+)(\.\d+)?/); - let hours = (rawTime[2] != null) ? (rawTime[1].replace(":", "")) : 0; - let minutes = (rawTime[2] != null) ? (hours * 60 + rawTime[2].replace(":", "") * 1) : ((rawTime[1] != null) ? rawTime[1].replace(":", "") : 0); - let seconds = (rawTime[3] != null) ? (rawTime[3]) : 0; - let milliseconds = (rawTime[4] != null) ? (rawTime[4].replace(".", "")) : 0 - return parseFloat(`${minutes * 60 + seconds * 1}.${milliseconds * 1}`); - }, - parseTTML() { - this.lyrics = []; - let preLrc = []; - let xml = this.stringToXml(this.lyricsMediaItem); - let lyricsLines = xml.getElementsByTagName('p'); - let synced = true; - let endTimes = []; - if (xml.getElementsByTagName('tt')[0].getAttribute("itunes:timing") === "None") { - synced = false; - } - endTimes.push(0); - if (synced) { - for (element of lyricsLines) { - start = this.toMS(element.getAttribute('begin')) - end = this.toMS(element.getAttribute('end')) - if (start - endTimes[endTimes.length - 1] > 5 && endTimes[endTimes.length - 1] != 0) { - preLrc.push({ - startTime: endTimes[endTimes.length - 1], - endTime: start, - line: "lrcInstrumental" - }); - } - preLrc.push({ startTime: start, endTime: end, line: element.textContent }); - endTimes.push(end); - } - // first line dot - if (preLrc.length > 0) - preLrc.unshift({ startTime: 0, endTime: preLrc[0].startTime, line: "lrcInstrumental" }); - } else { - for (element of lyricsLines) { - preLrc.push({ startTime: 9999999, endTime: 9999999, line: element.textContent }); - } - } - this.lyrics = preLrc; - - }, - parseLyrics() { - let xml = this.stringToXml(this.lyricsMediaItem) - let json = xmlToJson(xml); - this.lyrics = json - }, - stringToXml(st) { - // string to xml - let xml = (new DOMParser()).parseFromString(st, "text/xml"); - return xml; - - }, - getCurrentTime() { - return parseFloat(this.hmsToSecondsOnly(this.parseTime(this.mk.nowPlayingItem.attributes.durationInMillis - app.mk.currentPlaybackTimeRemaining * 1000))); - }, - seekTo(time) { - this.mk.seekToTime(time); - }, - parseTime(value) { - let minutes = Math.floor(value / 60000); - let seconds = ((value % 60000) / 1000).toFixed(0); - return minutes + ":" + (seconds < 10 ? '0' : '') + seconds; - }, - parseTimeDecimal(value) { - let minutes = Math.floor(value / 60000); - let seconds = ((value % 60000) / 1000).toFixed(0); - return minutes + "." + (seconds < 10 ? '0' : '') + seconds; - }, - hmsToSecondsOnly(str) { - let p = str.split(':'), - s = 0, - m = 1; - - while (p.length > 0) { - s += m * parseInt(p.pop(), 10); - m *= 60; - } - - return s; - }, - getLyricBGStyle(start, end) { - let currentTime = this.getCurrentTime(); - // let duration = this.mk.nowPlayingItem.attributes.durationInMillis - let start2 = this.hmsToSecondsOnly(start) - let end2 = this.hmsToSecondsOnly(end) - // let currentProgress = ((100 * (currentTime)) / (end2)) - // check if currenttime is between start and end - this.player.lyricsDebug.start = start2 - this.player.lyricsDebug.end = end2 - this.player.lyricsDebug.current = currentTime - if (currentTime >= start2 && currentTime <= end2) { - return { - "--bgSpeed": `${(end2 - start2)}s` - } - } else { - return {} - } - }, - playMediaItemById(id, kind, isLibrary, raurl = "") { - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(id, truekind, isLibrary) - try { - if (truekind.includes("artist")) { - app.mk.setStationQueue({ artist: 'a-' + id }).then(() => { - app.mk.play() - }) - } else if (truekind == "radioStations") { - this.mk.setStationQueue({ url: raurl }).then(function(queue) { - MusicKit.getInstance().play() - }); - } else { - this.mk.setQueue({ - [truekind]: [id] - }).then(function(queue) { - MusicKit.getInstance().play() - }) - } - } catch (err) { - console.log(err) - this.playMediaItemById(id, kind, isLibrary, raurl) - } - }, - queueParentandplayChild(parent, childIndex, item) { - - /* Randomize array in-place using Durstenfeld shuffle algorithm */ - function shuffleArray(array) { - for (var i = array.length - 1; i > 0; i--) { - var j = Math.floor(Math.random() * (i + 1)); - var temp = array[i]; - array[i] = array[j]; - array[j] = temp; - } - } - - let kind = parent.substring(0, parent.indexOf(":")) - let id = parent.substring(parent.indexOf(":") + 1, parent.length) - let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind; - console.log(truekind, id) - - try { - if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") { - console.log(item) - if (item && ((app.library.songs.displayListing[childIndex].id != item.id))) { - childIndex = app.library.songs.displayListing.indexOf(item) - } - - let query = app.library.songs.displayListing.map(item => new MusicKit.MediaItem(item)); - - - app.mk.stop().then(() => { - this.mk.clearQueue().then(function(_) { - if (app.mk.shuffleMode == 1) { - shuffleArray(query) - } - app.mk.queue.append(query) - if (childIndex != -1) { - app.mk.changeToMediaAtIndex(childIndex) - } else if (item) { - app.mk.playNext({ << - << << < HEAD[item.attributes.playParams.kind || item.type]: item.attributes.playParams.id || item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) || 1) === - === = [item.attributes.playParams.kind ? ? item.type]: item.attributes.playParams.id ? ? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ? ? 1) >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - app.mk.play() - }) - } else { - app.mk.play() - } - }) - }) - } else { - app.mk.stop().then(() => { - if (truekind == "playlists" && (id.startsWith("p.") || id.startsWith("pl.u"))) { - app.mk.setQueue({ << - << << < HEAD[item.attributes.playParams.kind || item.type]: item.attributes.playParams.id || item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) || 1).then(function() { === - === = [item.attributes.playParams.kind ? ? item.type]: item.attributes.playParams.id ? ? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ? ? 1).then(function() { >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - if ((app.showingPlaylist && app.showingPlaylist.id == id)) { - let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - let u = query; - if (app.mk.shuffleMode == 1) { - shuffleArray(u) - } - app.mk.queue.append(u) - } else { - app.getPlaylistFromID(id, true).then(function() { - let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item)); - let u = query; - if (app.mk.shuffleMode == 1) { - shuffleArray(u) - } - app.mk.queue.append(u) - }) - } - }) - - }) - } else { - this.mk.setQueue({ - [truekind]: [id] - }).then(function(queue) { - if (item && ((queue._itemIDs[childIndex] != item.id))) { - childIndex = queue._itemIDs.indexOf(item.id) - } - if (childIndex != -1) { - app.mk.changeToMediaAtIndex(childIndex) - } else if (item) { - app.mk.playNext({ << - << << < HEAD[item.attributes.playParams.kind || item.type]: item.attributes.playParams.id || item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) || 1) === - === = [item.attributes.playParams.kind ? ? item.type]: item.attributes.playParams.id ? ? item.id - }).then(function() { - app.mk.changeToMediaAtIndex(app.mk.queue._itemIDs.indexOf(item.id) ? ? 1) >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - app.mk.play() - }) - } else { - app.mk.play() - } - }) - } - }) - } - } - catch (err) { - console.log(err) - try { - app.mk.stop() - } catch (e) {} << - << << < HEAD - this.playMediaItemById(item.attributes.playParams.id || item.id, item.attributes.playParams.kind || item.type, item.attributes.playParams.isLibrary || false, item.attributes.url) === - === = - this.playMediaItemById(item.attributes.playParams.id ? ? item.id, item.attributes.playParams.kind ? ? item.type, item.attributes.playParams.isLibrary ? ? false, item.attributes.url) >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - } - - }, - friendlyTypes(type) { - // use switch statement to return friendly name for media types "songs,artists,albums,playlists,music-videos,stations,apple-curators,curators" - switch (type) { - case "song": - return "Songs" - break; - case "artist": - return "Artists" - break; - case "album": - return "Albums" - break; - case "playlist": - return "Playlists" - break; - case "music_video": - return "Music Videos" - break; - case "station": - return "Stations" - break; - case "apple-curator": - return "Apple Curators" - break; - case "radio_show": - return "Radio Shows" - break; - case "record_label": - return "Record Labels" - break; - case "radio_episode": - return "Episodes" - break; - case "video_extra": - return "Video Extras" - break; - case "curator": - return "Curators" - break; - case "top": - return "Top" - break; - default: - return type - break; - } - }, - async searchQuery(term = this.search.term) { - let self = this - if (term == "") { - return - } - //this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${this.search.term}` - this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/search?term=${this.search.term}`, { - types: "activities,albums,apple-curators,artists,curators,editorial-items,music-movies,music-videos,playlists,songs,stations,tv-episodes,uploaded-videos,record-labels", - "relate[editorial-items]": "contents", - "include[editorial-items]": "contents", - "include[albums]": "artists", - "include[artists]": "artists", - "include[songs]": "artists,albums", - "include[music-videos]": "artists", - "extend": "artistUrl", - "fields[artists]": "url,name,artwork,hero", - "fields[albums]": "artistName,artistUrl,artwork,contentRating,editorialArtwork,name,playParams,releaseDate,url", - "with": "serverBubbles,lyricHighlights", - "art[url]": "c,f", - "omit[resource]": "autos", - "platform": "web", - limit: 25 - }).then(function(results) { - results.data.results["meta"] = results.data.meta - self.search.results = results.data.results - }) - - await app.mk.api.v3.music(`v1/social/${app.mk.storefrontId}/search?term=${app.search.term}`, { - types: ["playlists", "social-profiles"], - limit: 25, - with: ["serverBubbles", "lyricSnippet"], - "art[url]": "f", - "art[social-profiles:url]": "c" - }, { includeResponseMeta: !0 }).then(function(results) { - results.data.results["meta"] = results.data.meta - self.search.resultsSocial = results.data.results - }) - }, - async inLibrary(items = []) { - let types = [] - - for (let item of items) { - let type = item.type - if (type.slice(-1) != "s") { - type += "s" - } - type = type.replace("library-", "") << - << << < HEAD - let id = item.attributes.playParams.catalogId || item.id === - === = - let id = item.attributes.playParams.catalogId ? ? item.id >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - - let index = types.findIndex(function(type) { - return type.type == this - }, type) - if (index == -1) { - types.push({ type: type, id: [id] }) - } else { - types[index].id.push(id) - } - } - types2 = types.map(function(item) { - return { - [`ids[${item.type}]`]: [item.id] - } - }) - types2 = types2.reduce(function(result, item) { - var key = Object.keys(item)[0]; //first property: a, b, c - result[key] = item[key]; - return result; - }, {}); - return (await this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}`, {... { - "omit[resource]": "autos", - relate: "library", - fields: "inLibrary" - }, - ...types2 - })).data.data - }, - isInLibrary(playParams) { - let self = this - let id = "" - // ugly code to check if current playback item is in library - if (typeof playParams == "undefined") { - return true - } - if (playParams["isLibrary"]) { - return true - } else if (playParams["catalogId"]) { - id = playParams["catalogId"] - } else if (playParams["id"]) { - id = playParams["id"] - } - let found = this.library.songs.listing.filter((item) => { - if (item["attributes"]) { - if (item["attributes"]["playParams"] && (item["attributes"]["playParams"]["catalogId"] == id)) { - return item; - } - } - }) - if (found.length != 0) { - return true - } else { - return false - } - }, - mkReady() { - if (this.mk["nowPlayingItem"]) { - return true - } else { - return false - } - }, - getMediaItemArtwork(url, height = 64, width) { - if (typeof url == "undefined" || url == "") { - return "https://beta.music.apple.com/assets/product/MissingArtworkMusic.svg" - } - let newurl = `${url.replace('{w}', width ?? height).replace('{h}', height).replace('{f}', "webp").replace('{c}', ((width === 900) ? "sr" : "cc"))}`; - - if (newurl.includes("900x516")) { - newurl = newurl.replace("900x516cc", "900x516sr").replace("900x516bb", "900x516sr"); - } - return newurl - }, - _rgbToRgb(rgb = [0, 0, 0]) { - // if rgb - return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})` - }, - getNowPlayingArtworkBG(size = 600) { - let self = this - if (typeof this.mk.nowPlayingItem === "undefined") return; - let bginterval = setInterval(() => { - if (!this.mkReady()) { - return "" - } - - try { - if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackID && document.querySelector('.bg-artwork')) { - if (document.querySelector('.bg-artwork')) { - clearInterval(bginterval); - } - this.currentTrackID = this.mk.nowPlayingItem["id"]; - document.querySelector('.bg-artwork').src = ""; - if (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"]) { - getBase64FromUrl(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).then(img => { - document.querySelectorAll('.bg-artwork').forEach(artwork => { - artwork.src = img; - }) - self.$store.commit("setLCDArtwork", img) - }) - - // Vibrant.from(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).getPalette().then(palette=>{ - // let angle = "140deg" - // let gradient = "" - // let colors = Object.values(palette).filter(color=>color!=null) - // if(colors.length > 0){ - // let stops = [] - // colors.forEach(color=>{ - // stops.push(`${self._rgbToRgb(color._rgb)} 0%`) - // }) - // stops.push(`${self._rgbToRgb(colors[0]._rgb)} 100%`) - // gradient = `linear-gradient(${angle}, ${stops.join(", ")}` - // } - // - // document.querySelector("#app").style.setProperty("--bgColor", gradient) - // }).setQuantizer(Vibrant.Quantizer.WebWorker) - - try { - clearInterval(bginterval); - } catch (err) {} - } else { - this.setLibraryArtBG() - } - } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { - try { - clearInterval(bginterval); - } catch (err) {} - } - } catch (e) { - if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.bg-artwork')) { - this.setLibraryArtBG() - try { - clearInterval(bginterval); - } catch (err) {} - } - } - }, 200) - }, - - // getNowPlayingArtwork(size = 600) { - // if (typeof this.mk.nowPlayingItem === "undefined") return; - // let interval = setInterval(() => { - - // try { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] != this.currentTrackIDBG && document.querySelector('.app-playback-controls .artwork')) { - // this.currentTrackIDBG = this.mk.nowPlayingItem["id"]; - // if (document.querySelector('.app-playback-controls .artwork') != null) { - // clearInterval(interval); - // } - // if (app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url!= '' ) { - // document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${decodeURI((this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"])).replace('{w}', size).replace('{h}', size)}")`); - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } else { - // this.setLibraryArt() - // } - // } else if (this.mk.nowPlayingItem["id"] == this.currentTrackID) { - // try { - // clearInterval(interval); - // } catch (err) { - // } - // } - // } catch (e) { - // if (this.mk.nowPlayingItem && this.mk.nowPlayingItem["id"] && document.querySelector('.app-playback-controls .artwork')) { - // this.setLibraryArt() - // try { - // clearInterval(interval); - // } catch (err) { - // } - - // } - - // } - // }, 200) - - - // }, - async getCurrentArtURL() { - try { - this.currentArtUrl = ''; - if (app.mk.nowPlayingItem != null && app.mk.nowPlayingItem.attributes != null && app.mk.nowPlayingItem.attributes.artwork != null && app.mk.nowPlayingItem.attributes.artwork.url != null && app.mk.nowPlayingItem.attributes.artwork.url != '') { << - << << < HEAD - this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] || '').replace('{w}', 50).replace('{h}', 50); === - === = - this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ? ? '').replace('{w}', 50).replace('{h}', 50); >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 + app.mk.unmute() + if (queue != null) { + queue = JSON.parse(queue) + if (queue && queue.length > 0) { + let ids = queue.map(e => (e.playParams ? e.playParams.id : (e.attributes.playParams ? e.attributes.playParams.id : ''))) + let i = 0; + if (ids.length > 0) { + for (id of ids) { + if (!(i == 0 && ids[0] == lastItem.attributes.playParams.id)) { try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } else { - let data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) { << - << << < HEAD - this.currentArtUrl = (data["attributes"]["artwork"]["url"] || '').replace('{w}', 50).replace('{h}', 50); === - === = - this.currentArtUrl = (data["attributes"]["artwork"]["url"] ? ? '').replace('{w}', 50).replace('{h}', 50); >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } else { - this.currentArtUrl = ''; - try { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`); - } catch (e) {} - } + app.mk.playLater({ songs: [id] }) + } catch (err) {} } - } catch (e) { - + i++; } - }, - async setLibraryArt() { - if (typeof this.mk.nowPlayingItem === "undefined") return; - try { - const data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - - if (data != null && data !== "") { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', 'url("' + (data["attributes"]["artwork"]["url"]).toString() + '")'); - } else { - document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("")`); - } - } catch (e) {} - }, - async setLibraryArtBG() { - if (typeof this.mk.nowPlayingItem === "undefined") return; - try { - const data = await this.mk.api.v3.music(`/v1/me/library/songs/${this.mk.nowPlayingItem.id}`); - data = data.data.data[0]; - - if (data != null && data !== "") { - getBase64FromUrl((data["attributes"]["artwork"]["url"]).toString()).then(img => { - document.querySelector('.bg-artwork').forEach(artwork => { - artwork.src = img; - }) - self.$store.commit("setLCDArtwork", img) - }) - } - } catch (e) {} - - }, - quickPlay(query) { - let self = this - MusicKit.getInstance().api.search(query, { limit: 2, types: 'songs' }).then(function(data) { - MusicKit.getInstance().setQueue({ song: data["songs"]['data'][0]["id"] }).then(function(queue) { - MusicKit.getInstance().play() - setTimeout(() => { - self.$forceUpdate() - }, 1000) - }) - }) - }, - async getRating(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - let response = await this.mk.api.v3.music(`/v1/me/ratings/${type}?platform=web&ids=${type.includes('library') ? item.id : id}}`) - if (response.data.data.length != 0) { - let value = response.data.data[0].attributes.value - return value - } else { - return 0 - } - }, - love(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "PUT", - body: JSON.stringify({ - "type": "rating", - "attributes": { - "value": 1 - } - }) - } - }) - }, - dislike(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "PUT", - body: JSON.stringify({ - "type": "rating", - "attributes": { - "value": -1 - } - }) - } - }) - }, - unlove(item) { - let type = item.type.slice(-1) === "s" ? item.type : item.type + "s" - let id = item.attributes.playParams.catalogId ? item.attributes.playParams.catalogId : item.id - if (item.id.startsWith("i.")) { - if (!type.startsWith("library-")) { - type = "library-" + type - } - id = item.id - } - this.mk.api.v3.music(`/v1/me/ratings/${type}/${id}`, {}, { - fetchOptions: { - method: "DELETE", - } - }) - }, - volumeWheel(event) { - if (event.deltaY < 0) { - if (this.mk.volume < 1) { - if (this.mk.volume <= 0.9) { - this.mk.volume += 0.1 - } else { - this.mk.volume = 1 - } - } - } else if (event.deltaY > 0) { - if (this.mk.volume > 0) { - if (this.mk.volume >= 0.1) { - this.mk.volume -= 0.1 - } else { - this.mk.volume = 0 - } - } - } - }, - async apiCall(url, callback) { - const xmlHttp = new XMLHttpRequest(); - - xmlHttp.onreadystatechange = (e) => { - if (xmlHttp.readyState !== 4) { - return; - } - - if (xmlHttp.status === 200) { - // console.log('SUCCESS', xmlHttp.responseText); - callback(JSON.parse(xmlHttp.responseText)); - } else { - console.warn('request_error'); - } - }; - - xmlHttp.open("GET", url); - xmlHttp.setRequestHeader("Authorization", "Bearer " + MusicKit.getInstance().developerToken); - xmlHttp.setRequestHeader("Music-User-Token", "" + MusicKit.getInstance().musicUserToken); - xmlHttp.setRequestHeader("Accept", "application/json"); - xmlHttp.setRequestHeader("Content-Type", "application/json"); - xmlHttp.responseType = "text"; - xmlHttp.send(); - }, - fetchPlaylist(id, callback) { - // id can be found in playlist.attributes.playParams.globalId - // this.mk.api. - this.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/playlists/${id}`).then(res => { - callback(res.data.data[0]) - }) - - // tracks are found in relationship.data - }, - windowFocus(val) { - if (val) { - document.querySelectorAll(".animated-artwork-video").forEach(el => { - el.play() - }) - this.animateBackground = true - } else { - document.querySelectorAll(".animated-artwork-video").forEach(el => { - el.pause() - }) - this.animateBackground = false - } - }, - async nowPlayingContextMenu(event) { - // function revisedRandId() { - // return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(2, 10); - // } - let self = this - let data_type = this.mk.nowPlayingItem.playParams.kind << - << << < HEAD - let item_id = this.mk.nowPlayingItem.attributes.playParams.id || this.mk.nowPlayingItem.id - let isLibrary = this.mk.nowPlayingItem.attributes.playParams.isLibrary || false === - === = - let item_id = this.mk.nowPlayingItem.attributes.playParams.id ? ? this.mk.nowPlayingItem.id - let isLibrary = this.mk.nowPlayingItem.attributes.playParams.isLibrary ? ? false >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - let params = { "fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library", "t": "1" } - // let res = await app.mkapi(data_type, isLibrary , item_id, params); - // if (res && res.relationships && res.relationships.library && res.relationships.library.data && res.relationships.library.data.length > 0) { - // item_id = res.relationships.library.data[0].id - // } - app.selectedMediaItems = [] - app.select_selectMediaItem(item_id, data_type, 0, '12344', isLibrary) - let useMenu = "normal" - let menus = { - multiple: { - items: [] - }, - normal: { - headerItems: [{ - "icon": "./assets/feather/heart.svg", - "id": "love", - "name": "Love", - "hidden": false, - "disabled": true, - "action": function() { - app.love(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/heart.svg", - "id": "unlove", - "active": true, - "name": "Unlove", - "hidden": true, - "action": function() { - app.unlove(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/thumbs-down.svg", - "id": "dislike", - "name": "Dislike", - "hidden": false, - "disabled": true, - "action": function() { - app.dislike(app.mk.nowPlayingItem) - } - }, - { - "icon": "./assets/feather/thumbs-down.svg", - "id": "undo_dislike", - "name": "Undo dislike", - "active": true, - "hidden": true, - "action": function() { - app.unlove(app.mk.nowPlayingItem) - } - }, - ], - items: [{ - "icon": "./assets/feather/list.svg", - "name": "Add to Playlist...", - "hidden": true, - "action": function() { - app.promptAddToPlaylist() - } - }, - { - "icon": "./assets/feather/plus.svg", - "id": "addToLibrary", - "name": "Add to Library...", - "disabled": false, - "action": function() { - app.addToLibrary(app.mk.nowPlayingItem.id); - // if (!isLibrary) {app.addToLibrary(item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = true} else { app.removeFromLibrary(data_type,item_id); this.mk.nowPlayingItem.attributes.playParams["isLibrary"] = false}; - } - }, - { - "icon": "./assets/feather/radio.svg", - "name": "Start Radio", - "action": function() { - app.mk.setStationQueue({ song: app.mk.nowPlayingItem.id }).then(() => { - app.mk.play() - app.selectedMediaItems = [] - }) - } - }, - ] - } - } - if (this.contextExt) { - // if this.context-ext.normal is true append all options to the 'normal' menu which is a kvp of arrays - if (this.contextExt.normal) { - menus.normal.items = menus.normal.items.concat(this.contextExt.normal) - } - } - - // isLibrary = await app.inLibrary([this.mk.nowPlayingItem]) - // console.warn(isLibrary) - // if(isLibrary.length != 0) { - // if (isLibrary[0].attributes.inLibrary) { - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } - // }else{ - // menus.normal.items.find(x => x.id == "addToLibrary").disabled = true - // } - this.showMenuPanel(menus[useMenu], event) - - try { - let rating = await app.getRating(app.mk.nowPlayingItem) - if (rating == 0) { - menus.normal.headerItems.find(x => x.id == 'love').disabled = false - menus.normal.headerItems.find(x => x.id == 'dislike').disabled = false - } else if (rating == 1) { - menus.normal.headerItems.find(x => x.id == 'unlove').hidden = false - menus.normal.headerItems.find(x => x.id == 'love').hidden = true - } else if (rating == -1) { - menus.normal.headerItems.find(x => x.id == 'undo_dislike').hidden = false - menus.normal.headerItems.find(x => x.id == 'dislike').hidden = true - } - } catch (err) { - - } - }, - LastFMDeauthorize() { - ipcRenderer.invoke('setStoreValue', 'lastfm.enabled', false).catch((e) => console.error(e)); - ipcRenderer.invoke('setStoreValue', 'lastfm.auth_token', '').catch((e) => console.error(e)); - app.cfg.lastfm.auth_token = ""; - app.cfg.lastfm.enabled = false; - const element = document.getElementById('lfmConnect'); - element.innerHTML = 'Connect'; - element.onclick = app.LastFMAuthenticate; - }, - LastFMAuthenticate() { - console.log("[LastFM] Received LastFM authentication callback") - const element = document.getElementById('lfmConnect'); - window.open('https://www.last.fm/api/auth?api_key=f9986d12aab5a0fe66193c559435ede3&cb=cider://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) { - app.cfg.lastfm.auth_token = lfmAuthKey; - app.cfg.lastfm.enabled = true; - element.innerHTML = `Disconnect\n
(Authed: ${lfmAuthKey})
`; - element.onclick = app.LastFMDeauthorize; - }); - }, - parseSCTagToRG: function(tag) { - let soundcheck = tag.split(" ") - let numbers = [] - for (item of soundcheck) { - numbers.push(parseInt(item, 16)) - - } - numbers.shift() << - << << < HEAD - let gain = Math.log10((Math.max(numbers[0], numbers[1]) || 1000) / 1000.0) * -10 === - === = - let gain = Math.log10((Math.max(numbers[0], numbers[1]) ? ? 1000) / 1000.0) * -10 >>> - >>> > c7f180daf8cf1b2cdc35e1afde3b6c3ae98b7916 - let peak = Math.max(numbers[6], numbers[7]) / 32768.0 - return { - gain: gain, - peak: peak - } - }, - fullscreen(flag) { - if (flag) { - ipcRenderer.send('setFullScreen', true); - if (app.mk.nowPlayingItem.type && app.mk.nowPlayingItem.type.toLowerCase().includes("video")) { - document.querySelector('video#apple-music-video-player').requestFullscreen() - } else { - app.appMode = 'fullscreen'; - } - document.addEventListener('keydown', event => { - if (event.key === 'Escape' && app.appMode === 'fullscreen') { - this.fullscreen(false); - } - }); - } else { - ipcRenderer.send('setFullScreen', false); - app.appMode = 'player'; - } - }, - formatTimezoneOffset: (e = new Date) => { - let leadingZeros = (e, s = 2) => { - let n = "" + e; - for (; n.length < s;) - n = "0" + n; - return n - } - - const s = e.getTimezoneOffset(), - n = Math.floor(Math.abs(s) / 60), - d = Math.round(Math.abs(s) % 60); - let h = "+"; - return 0 !== s && (h = s > 0 ? "-" : "+"), - `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}` - }, - + } + } } + }) - Vue.component('animated-number', { + }) + }, 1500) - template: "(Authed: ${lfmAuthKey})
`; + element.onclick = app.LastFMDeauthorize; + }); + }, + parseSCTagToRG: function(tag) { + let soundcheck = tag.split(" ") + let numbers = [] + for (item of soundcheck) { + numbers.push(parseInt(item, 16)) + + } + numbers.shift() + let gain = Math.log10((Math.max(numbers[0], numbers[1]) ?? 1000) / 1000.0) * -10 + let peak = Math.max(numbers[6], numbers[7]) / 32768.0 + return { + gain: gain, + peak: peak + } + }, + fullscreen(flag) { + if (flag) { + ipcRenderer.send('setFullScreen', true); + if (app.mk.nowPlayingItem.type && app.mk.nowPlayingItem.type.toLowerCase().includes("video")) { + document.querySelector('video#apple-music-video-player').requestFullscreen() + } else { + app.appMode = 'fullscreen'; + } + document.addEventListener('keydown', event => { + if (event.key === 'Escape' && app.appMode === 'fullscreen') { + this.fullscreen(false); + } + }); + } else { + ipcRenderer.send('setFullScreen', false); + app.appMode = 'player'; + } + }, + formatTimezoneOffset: (e = new Date) => { + let leadingZeros = (e, s = 2) => { + let n = "" + e; + for (; n.length < s;) + n = "0" + n; + return n + } + + const s = e.getTimezoneOffset(), + n = Math.floor(Math.abs(s) / 60), + d = Math.round(Math.abs(s) % 60); + let h = "+"; + return 0 !== s && (h = s > 0 ? "-" : "+"), + `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}` + }, + + } +}) + +Vue.component('animated-number', { + + template: "