mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-01-17 00:08:55 +01:00
Add:Show current book duration on match page as compared with book listed #1803
This commit is contained in:
parent
5ccf0df308
commit
401bd91204
@ -15,8 +15,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<p v-if="book.author" class="text-gray-300 text-xs md:text-sm">by {{ book.author }}</p>
|
<p v-if="book.author" class="text-gray-300 text-xs md:text-sm">by {{ book.author }}</p>
|
||||||
<p v-if="book.narrator" class="text-gray-400 text-xs">Narrated by {{ book.narrator }}</p>
|
<p v-if="book.narrator" class="text-gray-400 text-xs">Narrated by {{ book.narrator }}</p>
|
||||||
<p v-if="book.duration" class="text-gray-400 text-xs">Runtime: {{ $elapsedPrettyExtended(book.duration * 60) }}</p>
|
<p v-if="book.duration" class="text-gray-400 text-xs">Runtime: {{ $elapsedPrettyExtended(bookDuration, false) }} {{ bookDurationComparison }}</p>
|
||||||
<div v-if="book.series && book.series.length" class="flex py-1 -mx-1">
|
<div v-if="book.series?.length" class="flex py-1 -mx-1">
|
||||||
<div v-for="(series, index) in book.series" :key="index" class="bg-white bg-opacity-10 rounded-full px-1 py-0.5 mx-1">
|
<div v-for="(series, index) in book.series" :key="index" class="bg-white bg-opacity-10 rounded-full px-1 py-0.5 mx-1">
|
||||||
<p class="leading-3 text-xs text-gray-400">
|
<p class="leading-3 text-xs text-gray-400">
|
||||||
{{ series.series }}<span v-if="series.sequence"> #{{ series.sequence }}</span>
|
{{ series.series }}<span v-if="series.sequence"> #{{ series.sequence }}</span>
|
||||||
@ -29,9 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else class="px-4 flex-grow">
|
<div v-else class="px-4 flex-grow">
|
||||||
<h1>
|
<h1>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">{{ book.title }}<widgets-explicit-indicator :explicit="book.explicit" /></div>
|
||||||
{{ book.title }}<widgets-explicit-indicator :explicit="book.explicit" />
|
|
||||||
</div>
|
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-base text-gray-300 whitespace-nowrap truncate">by {{ book.author }}</p>
|
<p class="text-base text-gray-300 whitespace-nowrap truncate">by {{ book.author }}</p>
|
||||||
<p v-if="book.genres" class="text-xs text-gray-400 leading-5">{{ book.genres.join(', ') }}</p>
|
<p v-if="book.genres" class="text-xs text-gray-400 leading-5">{{ book.genres.join(', ') }}</p>
|
||||||
@ -56,7 +54,8 @@ export default {
|
|||||||
default: () => {}
|
default: () => {}
|
||||||
},
|
},
|
||||||
isPodcast: Boolean,
|
isPodcast: Boolean,
|
||||||
bookCoverAspectRatio: Number
|
bookCoverAspectRatio: Number,
|
||||||
|
currentBookDuration: Number
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -65,12 +64,27 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
bookCovers() {
|
bookCovers() {
|
||||||
return this.book.covers ? this.book.covers || [] : []
|
return this.book.covers || []
|
||||||
|
},
|
||||||
|
bookDuration() {
|
||||||
|
return (this.book.duration || 0) * 60
|
||||||
|
},
|
||||||
|
bookDurationComparison() {
|
||||||
|
if (!this.bookDuration || !this.currentBookDuration) return ''
|
||||||
|
let differenceInSeconds = this.currentBookDuration - this.bookDuration
|
||||||
|
// Only show seconds on difference if difference is less than an hour
|
||||||
|
if (differenceInSeconds < 0) {
|
||||||
|
differenceInSeconds = Math.abs(differenceInSeconds)
|
||||||
|
return `(${this.$elapsedPrettyExtended(differenceInSeconds, false, differenceInSeconds < 3600)} shorter)`
|
||||||
|
} else if (differenceInSeconds > 0) {
|
||||||
|
return `(${this.$elapsedPrettyExtended(differenceInSeconds, false, differenceInSeconds < 3600)} longer)`
|
||||||
|
}
|
||||||
|
return '(exact match)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectMatch() {
|
selectMatch() {
|
||||||
var book = { ...this.book }
|
const book = { ...this.book }
|
||||||
book.cover = this.selectedCover
|
book.cover = this.selectedCover
|
||||||
this.$emit('select', book)
|
this.$emit('select', book)
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-show="!processing" class="w-full max-h-full overflow-y-auto overflow-x-hidden matchListWrapper mt-4">
|
<div v-show="!processing" class="w-full max-h-full overflow-y-auto overflow-x-hidden matchListWrapper mt-4">
|
||||||
<template v-for="(res, index) in searchResults">
|
<template v-for="(res, index) in searchResults">
|
||||||
<cards-book-match-card :key="index" :book="res" :is-podcast="isPodcast" :book-cover-aspect-ratio="bookCoverAspectRatio" @select="selectMatch" />
|
<cards-book-match-card :key="index" :book="res" :current-book-duration="currentBookDuration" :is-podcast="isPodcast" :book-cover-aspect-ratio="bookCoverAspectRatio" @select="selectMatch" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedMatchOrig" class="absolute top-0 left-0 w-full bg-bg h-full px-2 py-6 md:p-8 max-h-full overflow-y-auto overflow-x-hidden">
|
<div v-if="selectedMatchOrig" class="absolute top-0 left-0 w-full bg-bg h-full px-2 py-6 md:p-8 max-h-full overflow-y-auto overflow-x-hidden">
|
||||||
@ -205,7 +205,7 @@ export default {
|
|||||||
processing: Boolean,
|
processing: Boolean,
|
||||||
libraryItem: {
|
libraryItem: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { }
|
default: () => {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -290,13 +290,17 @@ export default {
|
|||||||
return this.$strings.LabelSearchTitle
|
return this.$strings.LabelSearchTitle
|
||||||
},
|
},
|
||||||
media() {
|
media() {
|
||||||
return this.libraryItem ? this.libraryItem.media || {} : {}
|
return this.libraryItem?.media || {}
|
||||||
},
|
},
|
||||||
mediaMetadata() {
|
mediaMetadata() {
|
||||||
return this.media.metadata || {}
|
return this.media.metadata || {}
|
||||||
},
|
},
|
||||||
|
currentBookDuration() {
|
||||||
|
if (this.isPodcast) return 0
|
||||||
|
return this.media.duration || 0
|
||||||
|
},
|
||||||
mediaType() {
|
mediaType() {
|
||||||
return this.libraryItem ? this.libraryItem.mediaType : null
|
return this.libraryItem?.mediaType || null
|
||||||
},
|
},
|
||||||
isPodcast() {
|
isPodcast() {
|
||||||
return this.mediaType == 'podcast'
|
return this.mediaType == 'podcast'
|
||||||
|
@ -54,7 +54,7 @@ Vue.prototype.$secondsToTimestamp = (seconds, includeMs = false, alwaysIncludeHo
|
|||||||
return `${_hours}:${_minutes.toString().padStart(2, '0')}:${_seconds.toString().padStart(2, '0')}${msString}`
|
return `${_hours}:${_minutes.toString().padStart(2, '0')}:${_seconds.toString().padStart(2, '0')}${msString}`
|
||||||
}
|
}
|
||||||
|
|
||||||
Vue.prototype.$elapsedPrettyExtended = (seconds, useDays = true) => {
|
Vue.prototype.$elapsedPrettyExtended = (seconds, useDays = true, showSeconds = true) => {
|
||||||
if (isNaN(seconds) || seconds === null) return ''
|
if (isNaN(seconds) || seconds === null) return ''
|
||||||
seconds = Math.round(seconds)
|
seconds = Math.round(seconds)
|
||||||
|
|
||||||
@ -69,11 +69,16 @@ Vue.prototype.$elapsedPrettyExtended = (seconds, useDays = true) => {
|
|||||||
hours -= days * 24
|
hours -= days * 24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If not showing seconds then round minutes up
|
||||||
|
if (minutes && seconds && !showSeconds) {
|
||||||
|
if (seconds >= 30) minutes++
|
||||||
|
}
|
||||||
|
|
||||||
const strs = []
|
const strs = []
|
||||||
if (days) strs.push(`${days}d`)
|
if (days) strs.push(`${days}d`)
|
||||||
if (hours) strs.push(`${hours}h`)
|
if (hours) strs.push(`${hours}h`)
|
||||||
if (minutes) strs.push(`${minutes}m`)
|
if (minutes) strs.push(`${minutes}m`)
|
||||||
if (seconds) strs.push(`${seconds}s`)
|
if (seconds && showSeconds) strs.push(`${seconds}s`)
|
||||||
return strs.join(' ')
|
return strs.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user