Merge branch 'advplyr:master' into audible-confidence-score

This commit is contained in:
mikiher 2025-06-26 18:09:13 +03:00 committed by GitHub
commit 9c44fc0d01
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 187 additions and 65 deletions

View file

@ -94,6 +94,9 @@ export default {
userIsAdminOrUp() {
return this.$store.getters['user/getIsAdminOrUp']
},
userCanAccessExplicitContent() {
return this.$store.getters['user/getUserCanAccessExplicitContent']
},
libraryMediaType() {
return this.$store.getters['libraries/getCurrentLibraryMediaType']
},
@ -239,6 +242,15 @@ export default {
sublist: false
}
]
if (this.userCanAccessExplicitContent) {
items.push({
text: this.$strings.LabelExplicit,
value: 'explicit',
sublist: false
})
}
if (this.userIsAdminOrUp) {
items.push({
text: this.$strings.LabelShareOpen,
@ -249,7 +261,7 @@ export default {
return items
},
podcastItems() {
return [
const items = [
{
text: this.$strings.LabelAll,
value: 'all'
@ -283,6 +295,16 @@ export default {
sublist: false
}
]
if (this.userCanAccessExplicitContent) {
items.push({
text: this.$strings.LabelExplicit,
value: 'explicit',
sublist: false
})
}
return items
},
selectItems() {
if (this.isSeries) return this.seriesItems

View file

@ -35,7 +35,14 @@
<widgets-podcast-type-indicator :type="episode.episodeType" />
</div>
<p v-if="episode.subtitle" class="mb-1 text-sm text-gray-300 line-clamp-2">{{ episode.subtitle }}</p>
<p class="text-xs text-gray-300">Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}</p>
<div class="flex items-center space-x-2">
<!-- published -->
<p class="text-xs text-gray-300 w-40">Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}</p>
<!-- duration -->
<p v-if="episode.durationSeconds && !isNaN(episode.durationSeconds)" class="text-xs text-gray-300 min-w-28">{{ $strings.LabelDuration }}: {{ $elapsedPretty(episode.durationSeconds) }}</p>
<!-- size -->
<p v-if="episode.enclosure?.length && !isNaN(episode.enclosure.length) && Number(episode.enclosure.length) > 0" class="text-xs text-gray-300">{{ $strings.LabelSize }}: {{ $bytesPretty(Number(episode.enclosure.length)) }}</p>
</div>
</div>
</div>
</div>

View file

@ -16,7 +16,7 @@
</div>
</div>
<p dir="auto" class="text-lg font-semibold mb-6">{{ title }}</p>
<div v-if="description" dir="auto" class="default-style less-spacing" v-html="description" />
<div v-if="description" dir="auto" class="default-style less-spacing" @click="handleDescriptionClick" v-html="description" />
<p v-else class="mb-2">{{ $strings.MessageNoDescription }}</p>
<div class="w-full h-px bg-white/5 my-4" />
@ -34,6 +34,12 @@
{{ audioFileSize }}
</p>
</div>
<div class="grow">
<p class="font-semibold text-xs mb-1">{{ $strings.LabelDuration }}</p>
<p class="mb-2 text-xs">
{{ audioFileDuration }}
</p>
</div>
</div>
</div>
</modals-modal>
@ -68,7 +74,7 @@ export default {
return this.episode.title || 'No Episode Title'
},
description() {
return this.episode.description || ''
return this.parseDescription(this.episode.description || '')
},
media() {
return this.libraryItem?.media || {}
@ -90,11 +96,49 @@ export default {
return this.$bytesPretty(size)
},
audioFileDuration() {
const duration = this.episode.duration || 0
return this.$elapsedPretty(duration)
},
bookCoverAspectRatio() {
return this.$store.getters['libraries/getBookCoverAspectRatio']
}
},
methods: {},
methods: {
handleDescriptionClick(e) {
if (e.target.matches('span.time-marker')) {
const time = parseInt(e.target.dataset.time)
if (!isNaN(time)) {
this.$eventBus.$emit('play-item', {
episodeId: this.episodeId,
libraryItemId: this.libraryItem.id,
startTime: time
})
}
e.preventDefault()
}
},
parseDescription(description) {
const timeMarkerLinkRegex = /<a href="#([^"]*?\b\d{1,2}:\d{1,2}(?::\d{1,2})?)">(.*?)<\/a>/g
const timeMarkerRegex = /\b\d{1,2}:\d{1,2}(?::\d{1,2})?\b/g
function convertToSeconds(time) {
const timeParts = time.split(':').map(Number)
return timeParts.reduce((acc, part, index) => acc * 60 + part, 0)
}
return description
.replace(timeMarkerLinkRegex, (match, href, displayTime) => {
const time = displayTime.match(timeMarkerRegex)[0]
const seekTimeInSeconds = convertToSeconds(time)
return `<span class="time-marker cursor-pointer text-blue-400 hover:text-blue-300" data-time="${seekTimeInSeconds}">${displayTime}</span>`
})
.replace(timeMarkerRegex, (match) => {
const seekTimeInSeconds = convertToSeconds(match)
return `<span class="time-marker cursor-pointer text-blue-400 hover:text-blue-300" data-time="${seekTimeInSeconds}">${match}</span>`
})
}
},
mounted() {}
}
</script>