Add:Create playlist from a collection #1226

This commit is contained in:
advplyr 2022-12-17 17:31:19 -06:00
parent 9b1f7f566f
commit 5165f11460
6 changed files with 143 additions and 12 deletions

View file

@ -0,0 +1,55 @@
<template>
<div class="relative h-9 w-9" v-click-outside="clickOutsideObj">
<button type="button" :disabled="disabled" class="relative h-full w-full flex items-center justify-center shadow-sm pl-3 pr-3 text-left focus:outline-none cursor-pointer text-gray-100 hover:text-gray-200 rounded-full hover:bg-white/5" aria-haspopup="listbox" aria-expanded="true" @click.stop.prevent="clickShowMenu">
<span class="material-icons">more_vert</span>
</button>
<transition name="menu">
<div v-show="showMenu" class="absolute right-0 mt-1 z-10 bg-bg border border-black-200 shadow-lg max-h-56 w-48 rounded-md py-1 overflow-auto focus:outline-none sm:text-sm">
<template v-for="(item, index) in items">
<div :key="index" class="flex items-center px-2 py-1.5 hover:bg-white hover:bg-opacity-5 text-white text-xs cursor-pointer" @click.stop="clickAction(item.action)">
<p>{{ item.text }}</p>
</div>
</template>
</div>
</transition>
</div>
</template>
<script>
export default {
props: {
disabled: Boolean,
items: {
type: Array,
default: () => []
}
},
data() {
return {
clickOutsideObj: {
handler: this.clickedOutside,
events: ['mousedown'],
isActive: true
},
showMenu: false
}
},
computed: {},
methods: {
clickShowMenu() {
if (this.disabled) return
this.showMenu = !this.showMenu
},
clickedOutside() {
this.showMenu = false
},
clickAction(action) {
if (this.disabled) return
this.showMenu = false
this.$emit('action', action)
}
},
mounted() {}
}
</script>

View file

@ -19,9 +19,11 @@
{{ streaming ? $strings.ButtonPlaying : $strings.ButtonPlay }}
</ui-btn>
<ui-icon-btn v-if="userCanUpdate" icon="edit" class="mx-0.5" @click="editClick" />
<button type="button" class="h-9 w-9 flex items-center justify-center shadow-sm pl-3 pr-3 text-left focus:outline-none cursor-pointer text-gray-100 hover:text-gray-200 rounded-full hover:bg-white/5 mx-px" @click.stop.prevent="editClick">
<span class="material-icons text-xl">edit</span>
</button>
<ui-icon-btn v-if="userCanDelete" icon="delete" class="mx-0.5" @click="removeClick" />
<ui-context-menu-dropdown :items="contextMenuItems" class="mx-px" @action="contextMenuAction" />
</div>
<div class="my-8 max-w-2xl">
@ -32,7 +34,7 @@
</div>
</div>
</div>
<div v-show="processingRemove" class="absolute top-0 left-0 w-full h-full z-10 bg-black bg-opacity-40 flex items-center justify-center">
<div v-show="processing" class="absolute top-0 left-0 w-full h-full z-10 bg-black bg-opacity-40 flex items-center justify-center">
<ui-loading-indicator />
</div>
</div>
@ -64,7 +66,7 @@ export default {
},
data() {
return {
processingRemove: false
processing: false
}
},
computed: {
@ -102,15 +104,55 @@ export default {
},
userCanDelete() {
return this.$store.getters['user/getUserCanDelete']
},
contextMenuItems() {
const items = [
{
text: 'Create playlist from collection',
action: 'create-playlist'
}
]
if (this.userCanDelete) {
items.push({
text: 'Delete collection',
action: 'delete'
})
}
return items
}
},
methods: {
contextMenuAction(action) {
if (action === 'delete') {
this.removeClick()
} else if (action === 'create-playlist') {
this.createPlaylistFromCollection()
}
},
createPlaylistFromCollection() {
this.processing = true
this.$axios
.$post(`/api/playlists/collection/${this.collectionId}`)
.then((playlist) => {
if (playlist) {
this.$toast.success('Playlist created')
this.$router.push(`/playlist/${playlist.id}`)
}
})
.catch((error) => {
const errMsg = error.response ? error.response.data || '' : ''
this.$toast.error(errMsg || 'Failed to create playlist')
})
.finally(() => {
this.processing = false
})
},
editClick() {
this.$store.commit('globals/setEditCollection', this.collection)
},
removeClick() {
if (confirm(this.$getString('MessageConfirmRemoveCollection', [this.collectionName]))) {
this.processingRemove = true
this.processing = true
this.$axios
.$delete(`/api/collections/${this.collection.id}`)
.then(() => {
@ -121,7 +163,7 @@ export default {
this.$toast.error(this.$strings.ToastCollectionRemoveFailed)
})
.finally(() => {
this.processingRemove = false
this.processing = false
})
}
},