2022-10-26 12:34:32 +00:00
|
|
|
<template>
|
2024-05-19 05:49:42 +00:00
|
|
|
<button
|
2024-04-04 22:20:42 +00:00
|
|
|
:style="{ backgroundImage: `url(${defaultCover})` }"
|
2024-05-19 05:49:42 +00:00
|
|
|
:title="title"
|
|
|
|
class="song-thumbnail w-[48px] aspect-square bg-cover relative rounded overflow-hidden active:scale-95"
|
|
|
|
@click.prevent="playOrPause"
|
2024-04-04 22:20:42 +00:00
|
|
|
>
|
2024-02-24 15:37:01 +00:00
|
|
|
<img
|
|
|
|
v-koel-hide-broken-icon
|
2024-05-19 05:49:42 +00:00
|
|
|
alt="Cover image"
|
|
|
|
:src="src"
|
|
|
|
class="w-full aspect-square object-cover"
|
2024-02-24 15:37:01 +00:00
|
|
|
loading="lazy"
|
|
|
|
>
|
2024-05-19 05:49:42 +00:00
|
|
|
<span class="absolute top-0 left-0 w-full h-full group-hover:bg-black/40 z-10" />
|
|
|
|
<span
|
|
|
|
class="absolute flex opacity-0 items-center justify-center w-[24px] aspect-square rounded-full top-1/2
|
|
|
|
left-1/2 -translate-x-1/2 -translate-y-1/2 bg-k-highlight group-hover:opacity-100 duration-500 transition z-20"
|
2024-04-04 22:20:42 +00:00
|
|
|
>
|
2024-06-02 17:15:31 +00:00
|
|
|
<Icon v-if="playable.playback_state === 'Playing'" :icon="faPause" class="text-white" />
|
2024-05-19 05:49:42 +00:00
|
|
|
<Icon v-else :icon="faPlay" class="text-white ml-0.5" />
|
|
|
|
</span>
|
|
|
|
</button>
|
2022-10-26 12:34:32 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
2022-11-29 10:18:58 +00:00
|
|
|
import { computed, toRefs } from 'vue'
|
2022-10-26 12:34:32 +00:00
|
|
|
import { faPause, faPlay } from '@fortawesome/free-solid-svg-icons'
|
2024-05-19 05:49:42 +00:00
|
|
|
import { defaultCover, getPlayableProp } from '@/utils'
|
2022-10-26 12:34:32 +00:00
|
|
|
import { playbackService } from '@/services'
|
|
|
|
|
2024-06-02 17:15:31 +00:00
|
|
|
const props = defineProps<{ playable: Playable }>()
|
|
|
|
const { playable } = toRefs(props)
|
2022-10-26 12:34:32 +00:00
|
|
|
|
2024-06-02 17:15:31 +00:00
|
|
|
const src = computed(() => getPlayableProp<string>(playable.value, 'album_cover', 'episode_image'))
|
2024-05-19 05:49:42 +00:00
|
|
|
|
2024-06-02 17:15:31 +00:00
|
|
|
const play = () => playbackService.play(playable.value)
|
2022-10-26 12:34:32 +00:00
|
|
|
|
2022-11-29 10:18:58 +00:00
|
|
|
const title = computed(() => {
|
2024-06-02 17:15:31 +00:00
|
|
|
if (playable.value.playback_state === 'Playing') {
|
2022-11-29 10:18:58 +00:00
|
|
|
return 'Pause'
|
|
|
|
}
|
|
|
|
|
2024-06-02 17:15:31 +00:00
|
|
|
if (playable.value.playback_state === 'Paused') {
|
2022-11-29 10:18:58 +00:00
|
|
|
return 'Resume'
|
|
|
|
}
|
|
|
|
|
|
|
|
return 'Play'
|
|
|
|
})
|
|
|
|
|
2024-05-19 05:49:42 +00:00
|
|
|
const playOrPause = () => {
|
2024-06-02 17:15:31 +00:00
|
|
|
if (playable.value.playback_state === 'Stopped') {
|
|
|
|
// @todo play at the right playback position for Episodes
|
2022-10-26 12:34:32 +00:00
|
|
|
play()
|
2024-06-02 17:15:31 +00:00
|
|
|
} else if (playable.value.playback_state === 'Paused') {
|
2022-10-26 12:34:32 +00:00
|
|
|
playbackService.resume()
|
|
|
|
} else {
|
|
|
|
playbackService.pause()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|