Merge branch 'main' into main-ts
This commit is contained in:
commit
bc56aee137
31 changed files with 1832 additions and 734 deletions
|
@ -52,7 +52,7 @@ var CiderContextMenu = {
|
|||
}
|
||||
item.tabIndex = 0
|
||||
item.classList.add("context-menu-item")
|
||||
if(menudata.items[i]["icon"]) {
|
||||
if (menudata.items[i]["icon"]) {
|
||||
item.innerHTML += `<div class="sidebar-icon">${await app.getSvgIcon(menudata.items[i]["icon"])}</div>`
|
||||
}
|
||||
item.innerHTML += menudata.items[i].name
|
||||
|
@ -290,7 +290,18 @@ const app = new Vue({
|
|||
},
|
||||
socialBadges: {
|
||||
badgeMap: {},
|
||||
version: ""
|
||||
version: "",
|
||||
mediaItems: [],
|
||||
mediaItemDLState: 0 // 0 = not started, 1 = in progress, 2 = complete
|
||||
},
|
||||
menuPanel: {
|
||||
visible: false,
|
||||
event: null,
|
||||
content: {
|
||||
name: "",
|
||||
items: {},
|
||||
headerItems: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -315,6 +326,53 @@ const app = new Vue({
|
|||
},
|
||||
},
|
||||
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"
|
||||
}
|
||||
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 = {
|
||||
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;
|
||||
}
|
||||
},
|
||||
async getSvgIcon(url) {
|
||||
let response = await fetch(url);
|
||||
let data = await response.text();
|
||||
|
@ -353,22 +411,11 @@ const app = new Vue({
|
|||
history.forward()
|
||||
},
|
||||
getHTMLStyle() {
|
||||
switch (this.cfg.visual.window_transparency) {
|
||||
case "acrylic":
|
||||
default:
|
||||
document.querySelector("html").style.background = "";
|
||||
document.querySelector("body").style.background = "";
|
||||
document.querySelector("body").classList.remove("notransparency")
|
||||
break;
|
||||
case "disabled":
|
||||
document.querySelector("html").style.background = "#222";
|
||||
document.querySelector("body").classList.add("notransparency")
|
||||
|
||||
// document.querySelector("body").style.background = "#222";
|
||||
break;
|
||||
}
|
||||
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;
|
||||
|
@ -387,10 +434,12 @@ const app = new Vue({
|
|||
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 ) {
|
||||
} 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.albumRelationship(self.selectedMediaItems[i].id,"tracks");
|
||||
let ids = res.map(function(i) {return {id:i.id, type: i.type}})
|
||||
let res = await self.mk.api.albumRelationship(self.selectedMediaItems[i].id, "tracks");
|
||||
let ids = res.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"
|
||||
|
@ -398,10 +447,12 @@ const app = new Vue({
|
|||
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 )) {
|
||||
} 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.library.albumRelationship(self.selectedMediaItems[i].id,"tracks");
|
||||
let ids = res.map(function(i) {return {id:i.id, type: i.type}})
|
||||
let res = await self.mk.api.library.albumRelationship(self.selectedMediaItems[i].id, "tracks");
|
||||
let ids = res.map(function (i) {
|
||||
return {id: i.id, type: i.type}
|
||||
})
|
||||
pl_items = pl_items.concat(ids)
|
||||
} else {
|
||||
pl_items.push({
|
||||
|
@ -635,6 +686,11 @@ const app = new Vue({
|
|||
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") {
|
||||
|
@ -721,7 +777,7 @@ const app = new Vue({
|
|||
}
|
||||
]
|
||||
}
|
||||
CiderContextMenu.Create(event, menu)
|
||||
this.showMenuPanel(menu, event)
|
||||
},
|
||||
async editPlaylistFolder(id, name = "New Playlist") {
|
||||
let self = this
|
||||
|
@ -754,8 +810,8 @@ const app = new Vue({
|
|||
}
|
||||
}
|
||||
).then(res => {
|
||||
self.refreshPlaylists()
|
||||
})
|
||||
self.refreshPlaylists()
|
||||
})
|
||||
},
|
||||
copyToClipboard(str) {
|
||||
navigator.clipboard.writeText(str)
|
||||
|
@ -886,7 +942,9 @@ const app = new Vue({
|
|||
"fields[catalog]": "artistUrl,albumUrl",
|
||||
"fields[songs]": "artistUrl,albumUrl"
|
||||
}
|
||||
if (!transient) {this.playlists.loadingState = 0;}
|
||||
if (!transient) {
|
||||
this.playlists.loadingState = 0;
|
||||
}
|
||||
let playlistId = ''
|
||||
|
||||
try {
|
||||
|
@ -991,6 +1049,7 @@ const app = new Vue({
|
|||
return hash;
|
||||
},
|
||||
appRoute(route) {
|
||||
console.log(route)
|
||||
if (route == "" || route == "#" || route == "/") {
|
||||
return;
|
||||
}
|
||||
|
@ -1004,12 +1063,13 @@ const app = new Vue({
|
|||
let hash = route.split("/")
|
||||
let page = hash[0]
|
||||
let id = hash[1]
|
||||
console.log(`page: ${page} id: ${id}`)
|
||||
let isLibrary = hash[2] ?? false
|
||||
console.log(`page: ${page} id: ${id} isLibrary: ${isLibrary}`)
|
||||
this.routeView({
|
||||
kind: page,
|
||||
id: id,
|
||||
attributes: {
|
||||
playParams: {kind: page, id: id}
|
||||
playParams: {kind: page, id: id, isLibrary: isLibrary}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -1036,7 +1096,7 @@ const app = new Vue({
|
|||
document.querySelector("#app-content").scrollTop = 0
|
||||
} else if (kind.toString().includes("artist")) {
|
||||
app.getArtistInfo(id, isLibrary)
|
||||
window.location.hash = `${kind}/${id}`
|
||||
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
||||
document.querySelector("#app-content").scrollTop = 0
|
||||
|
||||
} else if (kind.toString().includes("record-label") || kind.toString().includes("curator")) {
|
||||
|
@ -1057,7 +1117,7 @@ const app = new Vue({
|
|||
let params = {extend: "editorialVideo"}
|
||||
app.page = (kind) + "_" + (id);
|
||||
app.getTypeFromID((kind), (id), (isLibrary), params);
|
||||
window.location.hash = `${kind}/${id}`
|
||||
window.location.hash = `${kind}/${id}${isLibrary ? "/" + isLibrary : ''}`
|
||||
document.querySelector("#app-content").scrollTop = 0
|
||||
} else {
|
||||
app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '')
|
||||
|
@ -1198,81 +1258,81 @@ const app = new Vue({
|
|||
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 = ''
|
||||
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)
|
||||
// }
|
||||
// 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)
|
||||
// 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) {}
|
||||
// if (res.next) {
|
||||
// getPlaylistTracks(res.next)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// } catch (e) {}
|
||||
|
||||
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
else {
|
||||
app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '')
|
||||
}
|
||||
})
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
else {
|
||||
app.playMediaItemById((id), (kind), (isLibrary), item.attributes.url ?? '')
|
||||
}
|
||||
})
|
||||
},
|
||||
async getTypeFromID(kind, id, isLibrary = false, params = {}, params2 = {}) {
|
||||
let a;
|
||||
|
@ -1306,13 +1366,14 @@ const app = new Vue({
|
|||
},
|
||||
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[self.library.songs.sorting]
|
||||
let bb = b.attributes[self.library.songs.sorting]
|
||||
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]
|
||||
|
@ -1323,13 +1384,13 @@ const app = new Vue({
|
|||
if (bb == null) {
|
||||
bb = ""
|
||||
}
|
||||
if (self.library.songs.sortOrder == "asc") {
|
||||
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 (self.library.songs.sortOrder == "desc") {
|
||||
} else if (prefs.sortOrder == "desc") {
|
||||
if (aa.toString().match(/^\d+$/) && bb.toString().match(/^\d+$/)) {
|
||||
return bb - aa
|
||||
} else {
|
||||
|
@ -1570,9 +1631,10 @@ const app = new Vue({
|
|||
} else {
|
||||
|
||||
if (downloaded.next != null && typeof downloaded.next === "function") {
|
||||
downloaded.next("", params, {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
}) } else {
|
||||
downloaded.next("", params, {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
})
|
||||
} else {
|
||||
console.log("Download next", downloaded.next)
|
||||
}
|
||||
}
|
||||
|
@ -1648,10 +1710,11 @@ const app = new Vue({
|
|||
processChunk(response)
|
||||
})
|
||||
} else {
|
||||
if (downloaded.next != null && typeof downloaded.next === "function") {
|
||||
downloaded.next("", params, {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
}) } else {
|
||||
if (downloaded.next != null && typeof downloaded.next === "function") {
|
||||
downloaded.next("", params, {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
})
|
||||
} else {
|
||||
console.log("Download next", downloaded.next)
|
||||
}
|
||||
}
|
||||
|
@ -1729,12 +1792,13 @@ const app = new Vue({
|
|||
})
|
||||
} else {
|
||||
if (downloaded.next != null && typeof downloaded.next === "function") {
|
||||
downloaded.next("", "artists", {includeResponseMeta: !0}).then((response) => {
|
||||
downloaded.next("", "artists", {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
}) } else {
|
||||
console.log("Download next", downloaded.next)
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
console.log("Download next", downloaded.next)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1780,7 +1844,7 @@ const app = new Vue({
|
|||
let hours = Math.floor(time / 3600)
|
||||
let mins = Math.floor(time / 60) % 60
|
||||
let secs = time % 60
|
||||
return app.showingPlaylist.relationships.tracks.data.length + " tracks, " + ((hours > 0) ? (hours + (" hour" + ((hours > 1) ? "s, " : ", "))) : "") + ((mins > 0) ? (mins + (" minute" + ((mins > 1) ? "s, " : ", "))) : "") + secs + (" second" + ((secs > 1) ? "s." : "."));
|
||||
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 ""
|
||||
|
@ -2354,76 +2418,84 @@ const app = new Vue({
|
|||
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.listing.length > childIndex && parent == "librarysongs") {
|
||||
if (app.library.songs.displayListing.length > childIndex && parent == "librarysongs") {
|
||||
console.log(item)
|
||||
if (item && ((app.library.songs.listing[childIndex].id != item.id))) {
|
||||
childIndex = app.library.songs.listing.indexOf(item)
|
||||
if (item && ((app.library.songs.displayListing[childIndex].id != item.id))) {
|
||||
childIndex = app.library.songs.displayListing.indexOf(item)
|
||||
}
|
||||
|
||||
let query = app.library.songs.listing.map(item => new MusicKit.MediaItem(item));
|
||||
try {
|
||||
app.mk.stop()
|
||||
} catch (e) {
|
||||
}
|
||||
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({[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)
|
||||
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({[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)
|
||||
app.mk.play()
|
||||
})
|
||||
} else {
|
||||
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({[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(){
|
||||
if ((app.showingPlaylist && app.showingPlaylist.id == id)) {
|
||||
let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
|
||||
if (query.length > 100) {
|
||||
let u = query.slice(100); if (app.mk.shuffleMode == 1) { shuffleArray(u) }
|
||||
app.mk.queue.append(u)}
|
||||
} else {
|
||||
app.getPlaylistFromID(id, true).then(function () {
|
||||
if (truekind == "playlists" && (id.startsWith("p.") || id.startsWith("pl.u"))) {
|
||||
app.mk.setQueue({[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 () {
|
||||
if ((app.showingPlaylist && app.showingPlaylist.id == id)) {
|
||||
let query = app.showingPlaylist.relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
|
||||
if (query.length > 100) {
|
||||
let u = query.slice(100); if (app.mk.shuffleMode == 1) { shuffleArray(u) }
|
||||
app.mk.queue.append(u)}
|
||||
})
|
||||
}
|
||||
})
|
||||
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({[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)
|
||||
app.mk.play()
|
||||
})
|
||||
} else {
|
||||
app.mk.play()
|
||||
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({[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)
|
||||
app.mk.play()
|
||||
})
|
||||
} else {
|
||||
app.mk.play()
|
||||
}
|
||||
})
|
||||
}
|
||||
})}
|
||||
})}
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
try {
|
||||
|
@ -2524,7 +2596,8 @@ const app = new Vue({
|
|||
if (type.slice(-1) != "s") {
|
||||
type += "s"
|
||||
}
|
||||
let id = item.playParams.catalogId ? item.playParams.catalogId : item.id
|
||||
type = type.replace("library-", "")
|
||||
let id = item.attributes.playParams.catalogId ?? item.id
|
||||
|
||||
let index = types.findIndex(function (type) {
|
||||
return type.type == this
|
||||
|
@ -2535,7 +2608,11 @@ const app = new Vue({
|
|||
types[index].id.push(id)
|
||||
}
|
||||
}
|
||||
return await this.mk.api.catalogResources(types, {"omit[resource]": "autos", relate: "library", fields: "inLibrary"})
|
||||
return await this.mk.api.catalogResources(types, {
|
||||
"omit[resource]": "autos",
|
||||
relate: "library",
|
||||
fields: "inLibrary"
|
||||
})
|
||||
},
|
||||
isInLibrary(playParams) {
|
||||
let self = this
|
||||
|
@ -2572,7 +2649,7 @@ const app = new Vue({
|
|||
}
|
||||
},
|
||||
getMediaItemArtwork(url, height = 64, width) {
|
||||
if(typeof url == "undefined" || url == "") {
|
||||
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"))}`;
|
||||
|
@ -2582,7 +2659,7 @@ const app = new Vue({
|
|||
}
|
||||
return newurl
|
||||
},
|
||||
_rgbToRgb(rgb = [0,0,0]) {
|
||||
_rgbToRgb(rgb = [0, 0, 0]) {
|
||||
// if rgb
|
||||
return `rgb(${rgb[0]},${rgb[1]},${rgb[2]})`
|
||||
},
|
||||
|
@ -2602,7 +2679,7 @@ const app = new Vue({
|
|||
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 =>{
|
||||
getBase64FromUrl(this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"].replace('{w}', size).replace('{h}', size)).then(img => {
|
||||
document.querySelectorAll('.bg-artwork').forEach(artwork => {
|
||||
artwork.src = img;
|
||||
})
|
||||
|
@ -2690,29 +2767,32 @@ const app = new Vue({
|
|||
|
||||
|
||||
// },
|
||||
async getCurrentArtURL(){
|
||||
try{
|
||||
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!= '' )
|
||||
{
|
||||
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 != '') {
|
||||
this.currentArtUrl = (this.mk["nowPlayingItem"]["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50);
|
||||
try{
|
||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);}
|
||||
catch (e) {}
|
||||
try {
|
||||
document.querySelector('.app-playback-controls .artwork').style.setProperty('--artwork', `url("${this.currentArtUrl}")`);
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
let data = await this.mk.api.library.song(this.mk.nowPlayingItem.id);
|
||||
if (data != null && data !== "" && data.attributes != null && data.attributes.artwork != null) {
|
||||
this.currentArtUrl = (data["attributes"]["artwork"]["url"] ?? '').replace('{w}', 50).replace('{h}', 50);
|
||||
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) {}
|
||||
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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
},
|
||||
|
@ -2737,7 +2817,7 @@ const app = new Vue({
|
|||
const data = await this.mk.api.library.song(this.mk.nowPlayingItem.id)
|
||||
|
||||
if (data != null && data !== "") {
|
||||
getBase64FromUrl((data["attributes"]["artwork"]["url"]).toString()).then(img =>{
|
||||
getBase64FromUrl((data["attributes"]["artwork"]["url"]).toString()).then(img => {
|
||||
document.querySelector('.bg-artwork').forEach(artwork => {
|
||||
artwork.src = img;
|
||||
})
|
||||
|
@ -2763,16 +2843,16 @@ const app = new Vue({
|
|||
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-")) {
|
||||
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=${id}`)
|
||||
if(response.data.data.length != 0) {
|
||||
if (response.data.data.length != 0) {
|
||||
let value = response.data.data[0].attributes.value
|
||||
return value
|
||||
}else{
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
},
|
||||
|
@ -2780,7 +2860,7 @@ const app = new Vue({
|
|||
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-")) {
|
||||
if (!type.startsWith("library-")) {
|
||||
type = "library-" + type
|
||||
}
|
||||
id = item.id
|
||||
|
@ -2804,7 +2884,7 @@ const app = new Vue({
|
|||
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-")) {
|
||||
if (!type.startsWith("library-")) {
|
||||
type = "library-" + type
|
||||
}
|
||||
id = item.id
|
||||
|
@ -2828,7 +2908,7 @@ const app = new Vue({
|
|||
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-")) {
|
||||
if (!type.startsWith("library-")) {
|
||||
type = "library-" + type
|
||||
}
|
||||
id = item.id
|
||||
|
@ -2842,16 +2922,20 @@ const app = new Vue({
|
|||
},
|
||||
volumeWheel(event) {
|
||||
if (event.deltaY < 0) {
|
||||
if(this.mk.volume < 1){
|
||||
if (this.mk.volume < 1) {
|
||||
if (this.mk.volume <= 0.9) {
|
||||
this.mk.volume += 0.1
|
||||
} else { this.mk.volume = 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}
|
||||
if (this.mk.volume > 0) {
|
||||
if (this.mk.volume >= 0.1) {
|
||||
this.mk.volume -= 0.1
|
||||
} else {
|
||||
this.mk.volume = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2921,10 +3005,53 @@ const app = new Vue({
|
|||
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()
|
||||
}
|
||||
|
@ -2935,51 +3062,15 @@ const app = new Vue({
|
|||
"name": "Add to Library...",
|
||||
"disabled": false,
|
||||
"action": function () {
|
||||
app.addToLibrary(item_id);
|
||||
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/heart.svg",
|
||||
"id": "love",
|
||||
"name": "Love",
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
app.love(app.mk.nowPlayingItem)
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/unheart.svg",
|
||||
"id": "unlove",
|
||||
"name": "Unlove",
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
app.unlove(app.mk.nowPlayingItem)
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/thumbs-down.svg",
|
||||
"id": "dislike",
|
||||
"name": "Dislike",
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
app.dislike(app.mk.nowPlayingItem)
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/x-circle.svg",
|
||||
"id": "undo_dislike",
|
||||
"name": "Undo dislike",
|
||||
"disabled": true,
|
||||
"action": function () {
|
||||
app.unlove(app.mk.nowPlayingItem)
|
||||
}
|
||||
},
|
||||
{
|
||||
"icon": "./assets/feather/radio.svg",
|
||||
"name": "Start Radio",
|
||||
"action": function () {
|
||||
app.mk.setStationQueue({song: item_id}).then(() => {
|
||||
app.mk.setStationQueue({song: app.mk.nowPlayingItem.id}).then(() => {
|
||||
app.mk.play()
|
||||
app.selectedMediaItems = []
|
||||
})
|
||||
|
@ -3004,17 +3095,23 @@ const app = new Vue({
|
|||
// }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) {
|
||||
|
||||
let rating = await app.getRating(app.mk.nowPlayingItem)
|
||||
if(rating == 0) {
|
||||
menus.normal.items.find(x => x.id == 'love').disabled = false
|
||||
menus.normal.items.find(x => x.id == 'dislike').disabled = false
|
||||
}else if(rating == 1) {
|
||||
menus.normal.items.find(x => x.id == 'unlove').disabled = false
|
||||
}else if(rating == -1) {
|
||||
menus.normal.items.find(x => x.id == 'undo_dislike').disabled = false
|
||||
}
|
||||
CiderContextMenu.Create(event, menus[useMenu])
|
||||
},
|
||||
LastFMDeauthorize() {
|
||||
ipcRenderer.invoke('setStoreValue', 'lastfm.enabled', false).catch((e) => console.error(e));
|
||||
|
@ -3061,10 +3158,14 @@ const app = new Vue({
|
|||
peak: peak
|
||||
}
|
||||
},
|
||||
fullscreen(flag){
|
||||
fullscreen(flag) {
|
||||
if (flag) {
|
||||
ipcRenderer.send('setFullScreen', true);
|
||||
app.appMode = 'fullscreen';
|
||||
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);
|
||||
|
@ -3079,6 +3180,41 @@ const app = new Vue({
|
|||
}
|
||||
})
|
||||
|
||||
Vue.component('animated-number', {
|
||||
|
||||
template: "<div style='display: inline-block;'>{{ displayNumber }}</div>",
|
||||
props: {'number': {default: 0}},
|
||||
|
||||
data() {
|
||||
return {
|
||||
displayNumber: 0,
|
||||
interval: false
|
||||
}
|
||||
},
|
||||
|
||||
ready() {
|
||||
this.displayNumber = this.number ? this.number : 0;
|
||||
},
|
||||
|
||||
watch: {
|
||||
number() {
|
||||
clearInterval(this.interval);
|
||||
|
||||
if (this.number == this.displayNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.interval = window.setInterval(() => {
|
||||
if (this.displayNumber != this.number) {
|
||||
var change = (this.number - this.displayNumber) / 10;
|
||||
change = change >= 0 ? Math.ceil(change) : Math.floor(change);
|
||||
this.displayNumber = this.displayNumber + change;
|
||||
}
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Vue.component('sidebar-library-item', {
|
||||
template: '#sidebar-library-item',
|
||||
props: {
|
||||
|
@ -3189,14 +3325,19 @@ document.addEventListener('musickitloaded', function () {
|
|||
};
|
||||
request.open("GET", "https://api.cider.sh/");
|
||||
request.send();
|
||||
|
||||
// check for widevine failure and reconfigure the instance.
|
||||
window.addEventListener("drmUnsupported", function () {
|
||||
initMusicKit()
|
||||
});
|
||||
});
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
// Use the window load event to keep the page load performant
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('sw.js?v=1');
|
||||
navigator.serviceWorker.register('sw.js?v=1');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const getBase64FromUrl = async (url) => {
|
||||
const data = await fetch(url);
|
||||
|
@ -3269,6 +3410,12 @@ function xmlToJson(xml) {
|
|||
return obj;
|
||||
};
|
||||
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
|
||||
var checkIfScrollIsStatic = setInterval(() => {
|
||||
try {
|
||||
if (position === document.getElementsByClassName('lyric-body')[0].scrollTop) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue