2022-10-13 15:18:47 +00:00
|
|
|
<template>
|
2024-03-13 16:15:44 +00:00
|
|
|
<div
|
|
|
|
:class="{ playing: song?.playback_state === 'Playing' }"
|
|
|
|
:draggable="draggable"
|
2024-05-19 05:49:42 +00:00
|
|
|
class="song-info px-6 py-0 flex items-center content-start w-[84px] md:w-[420px] gap-5"
|
2024-03-13 16:15:44 +00:00
|
|
|
@dragstart="onDragStart"
|
|
|
|
>
|
2024-04-04 22:20:42 +00:00
|
|
|
<span class="album-thumb block h-[55%] md:h-3/4 aspect-square rounded-full bg-cover" />
|
|
|
|
<div v-if="song" class="meta overflow-hidden hidden md:block">
|
|
|
|
<h3 class="title text-ellipsis overflow-hidden whitespace-nowrap">{{ song.title }}</h3>
|
|
|
|
<a
|
2024-05-19 05:49:42 +00:00
|
|
|
:href="artistOrPodcastUri"
|
2024-04-23 21:01:27 +00:00
|
|
|
class="artist text-ellipsis overflow-hidden whitespace-nowrap block text-[0.9rem] !text-k-text-secondary hover:!text-k-accent"
|
2024-04-04 22:20:42 +00:00
|
|
|
>
|
2024-05-19 05:49:42 +00:00
|
|
|
{{ artistOrPodcastName }}
|
2024-04-04 22:20:42 +00:00
|
|
|
</a>
|
2022-10-13 15:18:47 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
|
import { computed, ref } from 'vue'
|
2024-05-19 05:49:42 +00:00
|
|
|
import { defaultCover, getPlayableProp, isSong, requireInjection } from '@/utils'
|
|
|
|
import { CurrentPlayableKey } from '@/symbols'
|
2024-03-13 16:15:44 +00:00
|
|
|
import { useDraggable } from '@/composables'
|
|
|
|
|
2024-05-19 05:49:42 +00:00
|
|
|
const { startDragging } = useDraggable('playables')
|
2022-10-13 15:18:47 +00:00
|
|
|
|
2024-05-19 05:49:42 +00:00
|
|
|
const song = requireInjection(CurrentPlayableKey, ref())
|
|
|
|
|
|
|
|
const cover = computed(() => {
|
2024-10-13 17:37:01 +00:00
|
|
|
if (!song.value) {
|
|
|
|
return defaultCover
|
|
|
|
}
|
2024-05-19 05:49:42 +00:00
|
|
|
return getPlayableProp(song.value, 'album_cover', 'episode_image')
|
|
|
|
})
|
|
|
|
|
|
|
|
const artistOrPodcastUri = computed(() => {
|
2024-10-13 17:37:01 +00:00
|
|
|
if (!song.value) {
|
|
|
|
return ''
|
|
|
|
}
|
2024-05-19 05:49:42 +00:00
|
|
|
return isSong(song.value) ? `#/artist/${song.value?.artist_id}` : `#/podcasts/${song.value.podcast_id}`
|
|
|
|
})
|
|
|
|
|
|
|
|
const artistOrPodcastName = computed(() => {
|
2024-10-13 17:37:01 +00:00
|
|
|
if (!song.value) {
|
|
|
|
return ''
|
|
|
|
}
|
2024-05-19 05:49:42 +00:00
|
|
|
return getPlayableProp(song.value, 'artist_name', 'podcast_title')
|
|
|
|
})
|
2022-10-13 15:18:47 +00:00
|
|
|
|
2024-08-30 11:39:24 +00:00
|
|
|
const coverBackgroundImage = computed(() => `url(${cover.value ?? defaultCover})`)
|
2024-03-13 16:15:44 +00:00
|
|
|
const draggable = computed(() => Boolean(song.value))
|
|
|
|
|
|
|
|
const onDragStart = (event: DragEvent) => {
|
|
|
|
if (song.value) {
|
|
|
|
startDragging(event, [song.value])
|
|
|
|
}
|
|
|
|
}
|
2022-10-13 15:18:47 +00:00
|
|
|
</script>
|
|
|
|
|
2024-04-04 20:13:35 +00:00
|
|
|
<style lang="postcss" scoped>
|
2022-10-13 15:18:47 +00:00
|
|
|
.song-info {
|
2022-12-23 16:06:27 +00:00
|
|
|
:fullscreen & {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply pl-0;
|
2022-10-13 15:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.album-thumb {
|
2024-04-04 22:20:42 +00:00
|
|
|
background-image: v-bind(coverBackgroundImage);
|
2022-12-23 15:44:34 +00:00
|
|
|
|
|
|
|
:fullscreen & {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply h-20;
|
2022-12-23 15:44:34 +00:00
|
|
|
}
|
2022-10-13 15:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.meta {
|
2022-12-23 15:44:34 +00:00
|
|
|
:fullscreen & {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply -mt-72 origin-bottom-left absolute overflow-hidden;
|
2022-12-23 15:44:34 +00:00
|
|
|
|
|
|
|
.title {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply text-5xl mb-[0.4rem] font-bold;
|
2022-12-23 15:44:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.artist {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply text-3xl w-fit;
|
2022-12-23 15:44:34 +00:00
|
|
|
}
|
|
|
|
}
|
2022-10-13 15:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
&.playing .album-thumb {
|
2024-04-04 22:20:42 +00:00
|
|
|
@apply motion-reduce:animate-none;
|
2022-10-13 15:18:47 +00:00
|
|
|
animation: spin 30s linear infinite;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes spin {
|
|
|
|
100% {
|
|
|
|
transform: rotate(360deg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|