koel/resources/assets/js/components/song/SongContextMenu.vue

106 lines
3.8 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2022-04-24 08:29:14 +00:00
<ContextMenuBase extra-class="song-menu" ref="base" data-testid="song-context-menu">
2022-04-15 17:00:08 +00:00
<template v-if="onlyOneSongSelected">
2022-04-15 14:24:30 +00:00
<li class="playback" @click.stop.prevent="doPlayback">
<span v-if="firstSongPlaying">Pause</span>
<span v-else>Play</span>
</li>
2022-06-10 10:47:46 +00:00
<li class="go-to-album" @click="viewAlbumDetails(songs[0].album_id)">Go to Album</li>
<li class="go-to-artist" @click="viewArtistDetails(songs[0].artist_id)">Go to Artist</li>
2022-04-15 14:24:30 +00:00
</template>
<li class="has-sub">
Add To
<ul class="menu submenu menu-add-to">
<template v-if="queue.length">
<li v-if="currentSong" class="after-current" @click="queueSongsAfterCurrent">After Current Song</li>
<li class="bottom-queue" @click="queueSongsToBottom">Bottom of Queue</li>
<li class="top-queue" @click="queueSongsToTop">Top of Queue</li>
</template>
<li v-else @click="queueSongsToBottom">Queue</li>
2022-04-15 14:24:30 +00:00
<li class="separator"></li>
<li class="favorite" @click="addSongsToFavorite">Favorites</li>
<li class="separator" v-if="normalPlaylists.length"></li>
<li
class="playlist"
v-for="p in normalPlaylists"
:key="p.id"
@click="addSongsToExistingPlaylist(p)"
>{{ p.name }}
</li>
</ul>
</li>
<li class="open-edit-form" v-if="isAdmin" @click="openEditForm">Edit</li>
<li class="download" v-if="allowDownload" @click="download">Download</li>
2022-04-15 14:24:30 +00:00
<li
class="copy-url"
v-if="copyable && onlyOneSongSelected"
@click="copyUrl"
>
Copy Shareable URL
</li>
2022-04-24 08:29:14 +00:00
</ContextMenuBase>
2022-04-15 14:24:30 +00:00
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
import { computed, Ref, toRef } from 'vue'
import { alerts, copyText, eventBus, isClipboardSupported as copyable } from '@/utils'
import { commonStore, playlistStore, queueStore, songStore, userStore } from '@/stores'
2022-04-24 08:50:45 +00:00
import { downloadService, playbackService } from '@/services'
2022-04-15 14:24:30 +00:00
import router from '@/router'
import { useAuthorization, useContextMenu, useSongMenuMethods } from '@/composables'
2022-04-15 17:00:08 +00:00
2022-06-10 10:47:46 +00:00
const { context, base, ContextMenuBase, open, close, trigger } = useContextMenu()
2022-04-15 17:00:08 +00:00
2022-04-20 10:20:09 +00:00
const songs = toRef(context, 'songs') as Ref<Song[]>
2022-04-15 17:00:08 +00:00
const {
queueSongsAfterCurrent,
queueSongsToBottom,
queueSongsToTop,
addSongsToFavorite,
addSongsToExistingPlaylist
2022-04-20 10:20:09 +00:00
} = useSongMenuMethods(songs, close)
2022-04-15 17:00:08 +00:00
const playlists = toRef(playlistStore.state, 'playlists')
2022-06-10 10:47:46 +00:00
const allowDownload = toRef(commonStore.state, 'allow_download')
const user = toRef(userStore.state, 'current')
const queue = toRef(queueStore.state, 'songs')
const currentSong = toRef(queueStore.state, 'current')
2022-04-15 17:00:08 +00:00
const onlyOneSongSelected = computed(() => songs.value.length === 1)
2022-06-10 10:47:46 +00:00
const firstSongPlaying = computed(() => songs.value.length ? songs.value[0].playback_state === 'Playing' : false)
const normalPlaylists = computed(() => playlists.value.filter(playlist => !playlist.is_smart))
const { isAdmin } = useAuthorization()
2022-04-15 17:00:08 +00:00
2022-06-10 10:47:46 +00:00
const doPlayback = () => trigger(() => {
2022-04-15 17:00:08 +00:00
if (!songs.value.length) return
2022-06-10 10:47:46 +00:00
switch (songs.value[0].playback_state) {
2022-04-15 17:00:08 +00:00
case 'Playing':
2022-04-24 08:50:45 +00:00
playbackService.pause()
2022-04-15 17:00:08 +00:00
break
case 'Paused':
2022-04-24 08:50:45 +00:00
playbackService.resume()
2022-04-15 17:00:08 +00:00
break
default:
queueStore.queueIfNotQueued(songs.value[0])
2022-04-24 08:50:45 +00:00
playbackService.play(songs.value[0])
2022-04-15 17:00:08 +00:00
break
2022-04-15 14:24:30 +00:00
}
2022-06-10 10:47:46 +00:00
})
2022-04-15 17:00:08 +00:00
2022-06-10 10:47:46 +00:00
const openEditForm = () => trigger(() => songs.value.length && eventBus.emit('MODAL_SHOW_EDIT_SONG_FORM', songs.value))
const viewAlbumDetails = (albumId: number) => trigger(() => router.go(`album/${albumId}`))
const viewArtistDetails = (artistId: number) => trigger(() => router.go(`artist/${artistId}`))
const download = () => trigger(() => downloadService.fromSongs(songs.value))
2022-04-15 17:00:08 +00:00
2022-06-10 10:47:46 +00:00
const copyUrl = () => trigger(() => {
2022-04-15 17:00:08 +00:00
copyText(songStore.getShareableUrl(songs.value[0]))
alerts.success('URL copied to clipboard.')
2022-06-10 10:47:46 +00:00
})
2022-04-15 17:00:08 +00:00
2022-06-10 10:47:46 +00:00
defineExpose({ open })
2022-04-15 14:24:30 +00:00
</script>