288 lines
No EOL
12 KiB
Text
288 lines
No EOL
12 KiB
Text
<script type="text/x-template" id="sidebar-playlist">
|
|
<div class="sidebar-playlist" :key="item.id">
|
|
<button class="app-sidebar-item app-sidebar-item-playlist" :key="item.id"
|
|
:class="item.type != 'library-playlist-folders' ? {'active': $root.page.includes(item.id)} : ['playlist-folder', {'folder-button-active': folderOpened}, isPlaylistSelected]"
|
|
@contextmenu="playlistContextMenu($event, item.id)"
|
|
@dragstart="startDrag($event, item)"
|
|
@dragover="dragOver"
|
|
@drop="onDrop"
|
|
:href="item.href"
|
|
@click='clickEvent()'>
|
|
<template v-if="!renaming">
|
|
<svg-icon :url="icon" name="sidebar-playlist"/> {{ item.attributes.name }}
|
|
<small class="presentNotice" v-if="hasRelatedMediaItems">(Track present)</small>
|
|
</template>
|
|
<input type="text" v-model="item.attributes.name" class="pl-rename-field" @blur="rename()" @keydown.enter="rename()" v-else>
|
|
</button>
|
|
<div class="folder-body" v-if="item.type === 'library-playlist-folders' && folderOpened">
|
|
<template v-if="children.length != 0">
|
|
<sidebar-playlist v-for="item in children" :relate-media-items="relateMediaItems" :playlist-select="playlistSelect" :item="item" :key="item.id"></sidebar-playlist>
|
|
</template>
|
|
<template v-else>
|
|
<div class="spinner"></div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<script>
|
|
Vue.component('sidebar-playlist', {
|
|
template: '#sidebar-playlist',
|
|
props: {
|
|
item: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
playlistSelect: {
|
|
type: Function,
|
|
required: false
|
|
},
|
|
relateMediaItems: {
|
|
type: Array,
|
|
required: false,
|
|
default() {
|
|
return []
|
|
}
|
|
}
|
|
},
|
|
data: function () {
|
|
return {
|
|
folderOpened: false,
|
|
children: [],
|
|
playlistRoot: "p.playlistsroot",
|
|
renaming: false,
|
|
icon: "",
|
|
hasRelatedMediaItems: false
|
|
}
|
|
},
|
|
async mounted() {
|
|
if (this.item.type !== "library-playlist-folders") {
|
|
this.icon = ("./assets/feather/list.svg")
|
|
} else {
|
|
this.icon = ("./assets/feather/folder.svg")
|
|
}
|
|
let playlistMap = this.$root.playlists.trackMapping
|
|
if (this.relateMediaItems.length != 0) {
|
|
if (playlistMap[this.relateMediaItems[0]]) {
|
|
if (playlistMap[this.relateMediaItems[0]].includes(this.item.id)) {
|
|
this.hasRelatedMediaItems = true
|
|
}
|
|
}
|
|
|
|
}
|
|
},
|
|
methods: {
|
|
clickEvent() {
|
|
if (this.item.type != "library-playlist-folders") {
|
|
if (this.playlistSelect) {
|
|
this.playlistSelect(this.item)
|
|
} else {
|
|
this.openPlaylist(this.item)
|
|
}
|
|
} else {
|
|
this.getPlaylistChildren(this.item)
|
|
}
|
|
},
|
|
rename() {
|
|
this.renaming = false
|
|
|
|
if (this.item.type === "library-playlist-folders") {
|
|
this.$root.editPlaylistFolder(this.item.id, this.item.attributes.name)
|
|
} else {
|
|
this.$root.editPlaylist(this.item.id, this.item.attributes.name)
|
|
}
|
|
},
|
|
async getChildren() {
|
|
let self = this
|
|
this.children = []
|
|
this.children = this.$root.playlists.listing.filter(child => {
|
|
if (child.parent == self.item.id) {
|
|
return child
|
|
}
|
|
})
|
|
},
|
|
async move(item, sendTo) {
|
|
let self = this
|
|
console.log(sendTo)
|
|
let type = item.type.replace("library-", "")
|
|
let typeTo = sendTo.type
|
|
this.$root.mk.api.v3.music(`/v1/me/library/${type}/${item.id}/parent`, {}, {
|
|
fetchOptions: {
|
|
method: "PUT",
|
|
body: JSON.stringify({
|
|
data: [{
|
|
id: sendTo.id,
|
|
type: typeTo
|
|
}]
|
|
})
|
|
}
|
|
})
|
|
|
|
// find the item in this.$root.playlists.listing and store it in a variable
|
|
this.$root.playlists.listing.filter(playlist => {
|
|
if (playlist.id == item.id) {
|
|
console.log(playlist)
|
|
playlist.parent = sendTo.id
|
|
|
|
}
|
|
})
|
|
if (typeof this.$root.getChildren == "function") {
|
|
this.$root.getChildren()
|
|
console.log(this.$root.children)
|
|
}
|
|
await this.getChildren()
|
|
this.$root.sortPlaylists()
|
|
// await this.$root.refreshPlaylists()
|
|
},
|
|
playlistContextMenu(event, playlist_id) {
|
|
let menu = {
|
|
items: {
|
|
"moveToParent": {
|
|
name: this.$root.getLz('action.moveToTop'),
|
|
action: () => {
|
|
let self = this
|
|
this.move(this.item, {
|
|
id: this.playlistRoot,
|
|
type: "library-playlist-folders"
|
|
})
|
|
setTimeout(() => { self.getChildren() }, 2000)
|
|
}
|
|
},
|
|
"rename": {
|
|
name: this.$root.getLz('action.rename'),
|
|
action: () => {
|
|
this.renaming = true
|
|
setTimeout(() => {
|
|
document.querySelector(".pl-rename-field").focus()
|
|
document.querySelector(".pl-rename-field").select()
|
|
}, 100)
|
|
}
|
|
},
|
|
"deleteFromPlaylist": {
|
|
name: this.$root.getLz('action.removeFromLibrary'),
|
|
action: () => {
|
|
this.$root.deletePlaylist(playlist_id)
|
|
}
|
|
},
|
|
"addToFavorites": {
|
|
name: this.$root.getLz('action.addToFavorites'),
|
|
disabled: true,
|
|
hidden: true,
|
|
action: () => {
|
|
this.addFavorite(playlist_id, "library-playlists")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.item.type === "library-playlist-folders") {
|
|
menu.items.addToFavorites.disabled = true
|
|
}
|
|
app.showMenuPanel(menu, event)
|
|
},
|
|
dragOver(evt) {
|
|
evt.preventDefault();
|
|
evt.dataTransfer.dropEffect = "move";
|
|
},
|
|
onDrop(evt) {
|
|
let data = JSON.parse(evt.dataTransfer.getData("text/plain"))
|
|
evt.preventDefault();
|
|
if (data.id == this.item.id) {
|
|
return;
|
|
}
|
|
console.log(data)
|
|
if (data) {
|
|
if (this.item.type == "library-playlists" || this.item.type == "library-playlist-folders") {
|
|
if (data.type == "library-playlists" && this.item.type == "library-playlists") {
|
|
return
|
|
}
|
|
this.move(data, this.item)
|
|
}
|
|
}
|
|
},
|
|
startDrag(evt) {
|
|
evt.dataTransfer.dropEffect = 'move'
|
|
evt.dataTransfer.effectAllowed = 'move'
|
|
evt.dataTransfer.setData('text/plain', JSON.stringify(this.item))
|
|
},
|
|
openPlaylist(item) {
|
|
this.$root.appRoute(`playlist_` + item.id);
|
|
this.$root.showingPlaylist = [];
|
|
if (item.id == 'ciderlocal') {
|
|
this.$root.showingPlaylist = {
|
|
"id": "ciderlocal",
|
|
"type": "library-playlists",
|
|
"href": "",
|
|
"attributes": {
|
|
"artwork": {
|
|
"width": null,
|
|
"height": null,
|
|
"url": "",
|
|
"hasP3": false
|
|
},
|
|
"dateAdded": "2021-02-16T03:39:47Z",
|
|
"name": "Local Songs",
|
|
"canDelete": true,
|
|
"hasCatalog": true,
|
|
"canEdit": true,
|
|
"playParams": {
|
|
"id": "ciderlocal",
|
|
"kind": "playlist",
|
|
"isLibrary": true,
|
|
},
|
|
"isPublic": true,
|
|
"description": {
|
|
"standard": ""
|
|
}
|
|
},
|
|
"relationships": {
|
|
"tracks": {
|
|
"href": "",
|
|
"data": this.$root.library.localsongs
|
|
}
|
|
}
|
|
}
|
|
this.$root.playlists.loadingState = 1;
|
|
} else {
|
|
this.$root.getPlaylistFromID(this.$root.page.substring(9), true)
|
|
}
|
|
},
|
|
getPlaylistChildren(item) {
|
|
let self = this
|
|
this.children = []
|
|
this.getChildren()
|
|
this.toggleFolder()
|
|
|
|
this.$root.mk.api.v3.music(`v1/me/library/playlist-folders/${item.id}/children`).then(data => {
|
|
let children = data.data.data;
|
|
children.forEach(child => {
|
|
if (!self.$root.playlists.listing.find(listing => listing.id == child.id)) {
|
|
child.parent = self.item.id
|
|
self.$root.playlists.listing.push(child)
|
|
}
|
|
})
|
|
|
|
self.$root.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
|
|
}
|
|
})
|
|
self.getChildren()
|
|
})
|
|
},
|
|
isPlaylistSelected(item) {
|
|
if (this.$root.showingPlaylist.id == item.id) {
|
|
return ["active"]
|
|
} else {
|
|
return []
|
|
}
|
|
},
|
|
toggleFolder() {
|
|
this.folderOpened = !this.folderOpened;
|
|
}
|
|
}
|
|
});
|
|
</script> |