102 lines
3.0 KiB
Vue
102 lines
3.0 KiB
Vue
<template>
|
|
<div v-if="item" class="w-full flex items-center px-4 py-2" :class="wrapperClass" @mouseover="mouseover" @mouseleave="mouseleave">
|
|
<covers-preview-cover :src="coverUrl" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" />
|
|
<div class="flex-grow px-2 py-1 queue-item-row-content truncate">
|
|
<p class="text-gray-200 text-sm truncate">{{ title }}</p>
|
|
<p class="text-gray-300 text-sm">{{ subtitle }}</p>
|
|
<p v-if="caption" class="text-gray-400 text-xs">{{ caption }}</p>
|
|
</div>
|
|
<div class="w-28">
|
|
<p v-if="isOpenInPlayer" class="text-sm text-right text-gray-400">{{ $strings.ButtonPlaying }}</p>
|
|
<div v-else-if="isHovering" class="flex items-center justify-end -mx-1">
|
|
<button class="outline-none mx-1 flex items-center" @click.stop="playClick">
|
|
<span class="material-symbols fill text-2xl text-success">play_arrow</span>
|
|
</button>
|
|
<button class="outline-none mx-1 flex items-center" @click.stop="removeClick">
|
|
<span class="material-symbols text-2xl text-error">close</span>
|
|
</button>
|
|
</div>
|
|
<p v-else class="text-gray-400 text-sm text-right">{{ durationPretty }}</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
item: {
|
|
type: Object,
|
|
default: () => {}
|
|
},
|
|
index: Number
|
|
},
|
|
data() {
|
|
return {
|
|
isHovering: false
|
|
}
|
|
},
|
|
computed: {
|
|
title() {
|
|
return this.item.title || ''
|
|
},
|
|
subtitle() {
|
|
return this.item.subtitle || ''
|
|
},
|
|
caption() {
|
|
return this.item.caption
|
|
},
|
|
libraryItemId() {
|
|
return this.item.libraryItemId
|
|
},
|
|
episodeId() {
|
|
return this.item.episodeId
|
|
},
|
|
coverPath() {
|
|
return this.item.coverPath
|
|
},
|
|
coverUrl() {
|
|
if (!this.coverPath) return `${this.$config.routerBasePath}/book_placeholder.jpg`
|
|
return this.$store.getters['globals/getLibraryItemCoverSrcById'](this.libraryItemId)
|
|
},
|
|
bookCoverAspectRatio() {
|
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
|
},
|
|
duration() {
|
|
return this.item.duration
|
|
},
|
|
durationPretty() {
|
|
if (!this.duration) return 'N/A'
|
|
return this.$elapsedPretty(this.duration)
|
|
},
|
|
isOpenInPlayer() {
|
|
return this.$store.getters['getIsMediaStreaming'](this.libraryItemId, this.episodeId)
|
|
},
|
|
wrapperClass() {
|
|
if (this.isOpenInPlayer) return 'bg-yellow-400 bg-opacity-10'
|
|
if (this.index % 2 === 0) return 'bg-gray-300 bg-opacity-5 hover:bg-opacity-10'
|
|
return 'bg-bg hover:bg-gray-300 hover:bg-opacity-10'
|
|
}
|
|
},
|
|
methods: {
|
|
mouseover() {
|
|
this.isHovering = true
|
|
},
|
|
mouseleave() {
|
|
this.isHovering = false
|
|
},
|
|
playClick() {
|
|
this.$emit('play', this.item)
|
|
},
|
|
removeClick() {
|
|
this.$emit('remove', this.item)
|
|
}
|
|
},
|
|
mounted() {}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.queue-item-row-content {
|
|
max-width: calc(100% - 48px - 128px);
|
|
}
|
|
</style> |