Skip to content

Commit

Permalink
feat: allow dragging and dropping playlist folders to queue (koel#1624)
Browse files Browse the repository at this point in the history
  • Loading branch information
phanan committed Dec 7, 2022
1 parent c6c805c commit 9bb4e8c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
Expand Up @@ -3,8 +3,10 @@
class="playlist-folder"
:class="{ droppable }"
tabindex="0"
draggable="true"
@dragleave="onDragLeave"
@dragover="onDragOver"
@dragstart="onDragStart"
@drop="onDrop"
>
<a @click.prevent="toggle" @contextmenu.prevent="onContextMenu">
Expand Down Expand Up @@ -32,7 +34,7 @@ import { faFolder, faFolderOpen } from '@fortawesome/free-solid-svg-icons'
import { computed, defineAsyncComponent, ref, toRefs } from 'vue'
import { playlistFolderStore, playlistStore } from '@/stores'
import { eventBus } from '@/utils'
import { useDroppable } from '@/composables'
import { useDraggable, useDroppable } from '@/composables'
const PlaylistSidebarItem = defineAsyncComponent(() => import('./PlaylistSidebarItem.vue'))
Expand All @@ -46,9 +48,12 @@ const droppableOnHatch = ref(false)
const playlistsInFolder = computed(() => playlistStore.byFolder(folder.value))
const { acceptsDrop, resolveDroppedValue } = useDroppable(['playlist'])
const { startDragging } = useDraggable('playlist-folder')
const toggle = () => (opened.value = !opened.value)
const onDragStart = (event: DragEvent) => startDragging(event, folder.value)
const onDragOver = (event: DragEvent) => {
if (!acceptsDrop(event)) return false
Expand Down Expand Up @@ -97,7 +102,11 @@ const onDropOnHatch = async (event: DragEvent) => {
await playlistFolderStore.removePlaylistFromFolder(folder.value, playlist)
}
const onContextMenu = event => eventBus.emit('PLAYLIST_FOLDER_CONTEXT_MENU_REQUESTED', event, folder.value)
const onContextMenu = (event: MouseEvent) => eventBus.emit(
'PLAYLIST_FOLDER_CONTEXT_MENU_REQUESTED',
event,
folder.value
)
</script>

<style lang="scss" scoped>
Expand Down
Expand Up @@ -16,11 +16,13 @@
import { faListOl } from '@fortawesome/free-solid-svg-icons'
import { ref } from 'vue'
import { queueStore } from '@/stores'
import { useDroppable } from '@/composables'
import { useDroppable, useMessageToaster } from '@/composables'
import SidebarItem from './SidebarItem.vue'
import { pluralize } from '@/utils'
const { acceptsDrop, resolveDroppedSongs } = useDroppable(['songs', 'album', 'artist', 'playlist'])
const { toastWarning, toastSuccess } = useMessageToaster()
const { acceptsDrop, resolveDroppedSongs } = useDroppable(['songs', 'album', 'artist', 'playlist', 'playlist-folder'])
const droppable = ref(false)
Expand All @@ -32,7 +34,13 @@ const onQueueDrop = async (event: DragEvent) => {
event.preventDefault()
const songs = await resolveDroppedSongs(event) || []
songs.length && queueStore.queue(songs)
if (songs.length) {
queueStore.queue(songs)
toastSuccess(`Added ${ pluralize(songs, 'song') } to queue.`)
} else {
toastWarning('No applicable songs to queue.')
}
return false
}
Expand Down
21 changes: 16 additions & 5 deletions resources/assets/js/composables/useDragAndDrop.ts
@@ -1,8 +1,8 @@
import { arrayify, logger, pluralize } from '@/utils'
import { albumStore, artistStore, playlistStore, songStore } from '@/stores'
import { albumStore, artistStore, playlistFolderStore, playlistStore, songStore } from '@/stores'

type Draggable = Song | Song[] | Album | Artist | Playlist
const draggableTypes = <const>['songs', 'album', 'artist', 'playlist']
type Draggable = Song | Song[] | Album | Artist | Playlist | PlaylistFolder
const draggableTypes = <const>['songs', 'album', 'artist', 'playlist', 'playlist-folder']
type DraggableType = typeof draggableTypes[number]

const createGhostDragImage = (event: DragEvent, text: string): void => {
Expand Down Expand Up @@ -33,7 +33,7 @@ export const useDraggable = (type: DraggableType) => {
return
}

let text
let text: string
let data: any

switch (type) {
Expand Down Expand Up @@ -62,6 +62,12 @@ export const useDraggable = (type: DraggableType) => {
data = dragged.id
break

case 'playlist-folder':
dragged = <PlaylistFolder>dragged
text = dragged.name
data = dragged.id
break

default:
return
}
Expand Down Expand Up @@ -125,8 +131,13 @@ export const useDroppable = (acceptedTypes: DraggableType[]) => {
const artist = await artistStore.resolve(<number>data)
return artist ? await songStore.fetchForArtist(artist) : <Song[]>[]
case 'playlist':
const playlist = await playlistStore.byId(<number>data)
const playlist = playlistStore.byId(<number>data)
return playlist ? await songStore.fetchForPlaylist(playlist) : <Song[]>[]
case 'playlist-folder':
const folder = playlistFolderStore.byId(<string>data)
return folder ? await songStore.fetchForPlaylistFolder(folder) : <Song[]>[]
default:
throw new Error(`Unknown drag type: ${type}`)
}
} catch (error) {
logger.error(error, event)
Expand Down

0 comments on commit 9bb4e8c

Please sign in to comment.