Add favorite property for items and associated filters.

This commit is contained in:
Rapha149 2026-03-16 19:46:45 +01:00
parent 6d3773a0b8
commit a5999fb9df
14 changed files with 308 additions and 11 deletions

View file

@ -65,6 +65,14 @@
<div cy-id="ebookFormat" v-if="ebookFormat" class="absolute" :style="{ bottom: 0.375 + 'em', left: 0.375 + 'em' }">
<span class="text-white/80" :style="{ fontSize: 0.8 + 'em' }">{{ ebookFormat }}</span>
</div>
<!-- Unfavorite star icon -->
<div v-if="!isFavorite && !isSelectionMode"
class="absolute text-gray-300 hover:text-yellow-400 left-0 z-10 cursor-pointer hover:scale-110 transform duration-150"
:style="{ padding: 0.375 + 'em', bottom: ebookFormat ? '1.25em' : '0px' }"
@click.stop.prevent="toggleFavorite">
<span class="material-symbols" aria-hidden="true" :style="{ fontSize: 1.5 + 'em' }">star</span>
</div>
</div>
<!-- Processing/loading spinner overlay -->
@ -93,6 +101,14 @@
<span class="material-symbols" aria-hidden="true" :style="{ fontSize: 1.5 + 'em' }">public</span>
</div>
<!-- Favorite star icon -->
<div v-if="isFavorite && !isSelectionMode"
class="absolute text-yellow-400 left-0 z-10 cursor-pointer hover:scale-110 transform duration-150"
:style="{ padding: 0.375 + 'em', bottom: ebookFormat ? '1.25em' : '0px' }"
@click.stop.prevent="toggleFavorite">
<span class="material-symbols fill" aria-hidden="true" :style="{ fontSize: 1.5 + 'em' }">star</span>
</div>
<!-- Series sequence -->
<div cy-id="seriesSequence" v-if="seriesSequence && !isHovering && !isSelectionMode" class="absolute rounded-lg bg-black/90 box-shadow-md z-10" :style="{ top: 0.375 + 'em', right: 0.375 + 'em', padding: `${0.1}em ${0.25}em` }">
<p :style="{ fontSize: 0.8 + 'em' }">#{{ seriesSequence }}</p>
@ -653,6 +669,9 @@ export default {
mediaItemShare() {
return this._libraryItem.mediaItemShare || null
},
isFavorite() {
return this.store.getters['user/getIsLibraryItemFavorite'](this.libraryItemId)
},
showSubtitles() {
return !this.isPodcast && this.store.getters['user/getUserSetting']('showSubtitles')
}
@ -757,6 +776,22 @@ export default {
toast.error(updatePayload.isFinished ? this.$strings.ToastItemMarkedAsFinishedFailed : this.$strings.ToastItemMarkedAsNotFinishedFailed)
})
},
toggleFavorite() {
const axios = this.$axios || this.$nuxt.$axios
const endpoint = `/api/me/item/${this.libraryItemId}/favorite`
if (this.isFavorite) {
axios.$delete(endpoint).catch(error => {
console.error('Failed to remove favorite', error)
this.$toast.error('Failed to remove from favorites')
})
} else {
axios.$post(endpoint).catch(error => {
console.error('Failed to add favorite', error)
this.$toast.error('Failed to add to favorites')
})
}
},
editPodcast() {
this.$emit('editPodcast', this.libraryItem)
},

View file

@ -158,6 +158,11 @@ export default {
text: this.$strings.LabelAll,
value: 'all'
},
{
text: this.$strings.LabelFavorite,
value: 'favorite',
sublist: false
},
{
text: this.$strings.LabelGenre,
textPlural: this.$strings.LabelGenres,
@ -266,6 +271,11 @@ export default {
text: this.$strings.LabelAll,
value: 'all'
},
{
text: this.$strings.LabelFavorite,
value: 'favorite',
sublist: false
},
{
text: this.$strings.LabelGenre,
textPlural: this.$strings.LabelGenres,