mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-28 17:49:06 +01:00
Add:Hide series from home page option #919
This commit is contained in:
parent
8c32fed911
commit
9ee6eaade9
@ -244,6 +244,24 @@ export default {
|
|||||||
this.libraryItemUpdated(li)
|
this.libraryItemUpdated(li)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
seriesUpdated(series) {
|
||||||
|
if (series.hideFromHome) {
|
||||||
|
this.shelves.forEach((shelf) => {
|
||||||
|
if (shelf.type == 'book' && shelf.id == 'continue-series') {
|
||||||
|
// Filter out series books from continue series shelf
|
||||||
|
shelf.entities = shelf.entities.filter((ent) => {
|
||||||
|
if (ent.media.metadata.series && ent.media.metadata.series.id == series.id) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
} else if (shelf.type == 'series') {
|
||||||
|
// Filter out series from series shelf
|
||||||
|
shelf.entities = shelf.entities.filter((ent) => {
|
||||||
|
return ent.id != series.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
authorUpdated(author) {
|
authorUpdated(author) {
|
||||||
this.shelves.forEach((shelf) => {
|
this.shelves.forEach((shelf) => {
|
||||||
if (shelf.type == 'authors') {
|
if (shelf.type == 'authors') {
|
||||||
@ -270,6 +288,7 @@ export default {
|
|||||||
this.$store.commit('user/addSettingsListener', { id: 'bookshelf', meth: this.settingsUpdated })
|
this.$store.commit('user/addSettingsListener', { id: 'bookshelf', meth: this.settingsUpdated })
|
||||||
|
|
||||||
if (this.$root.socket) {
|
if (this.$root.socket) {
|
||||||
|
this.$root.socket.on('series_updated', this.seriesUpdated)
|
||||||
this.$root.socket.on('author_updated', this.authorUpdated)
|
this.$root.socket.on('author_updated', this.authorUpdated)
|
||||||
this.$root.socket.on('author_removed', this.authorRemoved)
|
this.$root.socket.on('author_removed', this.authorRemoved)
|
||||||
this.$root.socket.on('item_updated', this.libraryItemUpdated)
|
this.$root.socket.on('item_updated', this.libraryItemUpdated)
|
||||||
@ -285,6 +304,7 @@ export default {
|
|||||||
this.$store.commit('user/removeSettingsListener', 'bookshelf')
|
this.$store.commit('user/removeSettingsListener', 'bookshelf')
|
||||||
|
|
||||||
if (this.$root.socket) {
|
if (this.$root.socket) {
|
||||||
|
this.$root.socket.off('series_updated', this.seriesUpdated)
|
||||||
this.$root.socket.off('author_updated', this.authorUpdated)
|
this.$root.socket.off('author_updated', this.authorUpdated)
|
||||||
this.$root.socket.off('author_removed', this.authorRemoved)
|
this.$root.socket.off('author_removed', this.authorRemoved)
|
||||||
this.$root.socket.off('item_updated', this.libraryItemUpdated)
|
this.$root.socket.off('item_updated', this.libraryItemUpdated)
|
||||||
|
@ -21,13 +21,14 @@
|
|||||||
<template v-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome">
|
<template v-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome">
|
||||||
<p v-if="!selectedSeries" class="font-book hidden md:block">{{ numShowing }} {{ entityName }}</p>
|
<p v-if="!selectedSeries" class="font-book hidden md:block">{{ numShowing }} {{ entityName }}</p>
|
||||||
<div v-else class="items-center hidden md:flex w-full">
|
<div v-else class="items-center hidden md:flex w-full">
|
||||||
<p class="pl-4 font-book text-lg">
|
<p class="pl-2 font-book text-lg">
|
||||||
{{ seriesName }}
|
{{ seriesName }}
|
||||||
</p>
|
</p>
|
||||||
<div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3">
|
<div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3">
|
||||||
<span class="font-mono">{{ numShowing }}</span>
|
<span class="font-mono">{{ numShowing }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
|
<ui-btn v-if="seriesHideFromHome" :loading="processingSeriesHideFromHome" color="primary" small class="mr-2" @click="showSeriesOnHome">Show on Home</ui-btn>
|
||||||
<ui-btn color="primary" small :loading="processingSeries" class="flex items-center" @click="markSeriesFinished">
|
<ui-btn color="primary" small :loading="processingSeries" class="flex items-center" @click="markSeriesFinished">
|
||||||
<div class="h-5 w-5">
|
<div class="h-5 w-5">
|
||||||
<svg v-if="isSeriesFinished" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)">
|
<svg v-if="isSeriesFinished" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)">
|
||||||
@ -37,8 +38,8 @@
|
|||||||
<path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-7 19.6l-7-4.66V3h14v12.93l-7 4.67zm-2.01-7.42l-2.58-2.59L6 12l4 4 8-8-1.42-1.42z" />
|
<path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-7 19.6l-7-4.66V3h14v12.93l-7 4.67zm-2.01-7.42l-2.58-2.59L6 12l4 4 8-8-1.42-1.42z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span class="pl-2"> Mark Series {{ isSeriesFinished ? 'Not Finished' : 'Finished' }}</span></ui-btn
|
<span class="pl-2"> Mark Series {{ isSeriesFinished ? 'Not Finished' : 'Finished' }}</span>
|
||||||
>
|
</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-grow hidden sm:inline-block" />
|
<div class="flex-grow hidden sm:inline-block" />
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ export default {
|
|||||||
authors: {
|
authors: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -94,7 +95,8 @@ export default {
|
|||||||
keywordTimeout: null,
|
keywordTimeout: null,
|
||||||
processingSeries: false,
|
processingSeries: false,
|
||||||
processingIssues: false,
|
processingIssues: false,
|
||||||
processingAuthors: false
|
processingAuthors: false,
|
||||||
|
processingSeriesHideFromHome: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -150,6 +152,9 @@ export default {
|
|||||||
seriesName() {
|
seriesName() {
|
||||||
return this.selectedSeries ? this.selectedSeries.name : null
|
return this.selectedSeries ? this.selectedSeries.name : null
|
||||||
},
|
},
|
||||||
|
seriesHideFromHome() {
|
||||||
|
return this.selectedSeries ? this.selectedSeries.hideFromHome : null
|
||||||
|
},
|
||||||
seriesProgress() {
|
seriesProgress() {
|
||||||
return this.selectedSeries ? this.selectedSeries.progress : null
|
return this.selectedSeries ? this.selectedSeries.progress : null
|
||||||
},
|
},
|
||||||
@ -171,6 +176,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async showSeriesOnHome() {
|
||||||
|
this.processingSeriesHideFromHome = true
|
||||||
|
const seriesId = this.selectedSeries.id
|
||||||
|
this.$axios
|
||||||
|
.$patch(`/api/series/${seriesId}`, { hideFromHome: false })
|
||||||
|
.then((data) => {
|
||||||
|
console.log('Updated series', data)
|
||||||
|
this.$toast.success('Series updated successfully')
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to update series', error)
|
||||||
|
this.$toast.error('Failed to update series')
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.processingSeriesHideFromHome = false
|
||||||
|
})
|
||||||
|
},
|
||||||
async matchAllAuthors() {
|
async matchAllAuthors() {
|
||||||
this.processingAuthors = true
|
this.processingAuthors = true
|
||||||
|
|
||||||
|
@ -411,6 +411,12 @@ export default {
|
|||||||
text: 'Re-Scan'
|
text: 'Re-Scan'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
if (this.userIsAdminOrUp && this.series && this.bookMount) {
|
||||||
|
items.push({
|
||||||
|
func: 'hideSeriesFromHome',
|
||||||
|
text: 'Hide Series from Home'
|
||||||
|
})
|
||||||
|
}
|
||||||
return items
|
return items
|
||||||
},
|
},
|
||||||
_socket() {
|
_socket() {
|
||||||
@ -572,11 +578,12 @@ export default {
|
|||||||
} else if (result === 'REMOVED') {
|
} else if (result === 'REMOVED') {
|
||||||
this.$toast.error(`Re-Scan complete item was removed`)
|
this.$toast.error(`Re-Scan complete item was removed`)
|
||||||
}
|
}
|
||||||
this.processing = false
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Failed to scan library item', error)
|
console.error('Failed to scan library item', error)
|
||||||
this.$toast.error('Failed to scan library item')
|
this.$toast.error('Failed to scan library item')
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
this.processing = false
|
this.processing = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -588,6 +595,22 @@ export default {
|
|||||||
// More menu func
|
// More menu func
|
||||||
this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' })
|
this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' })
|
||||||
},
|
},
|
||||||
|
hideSeriesFromHome() {
|
||||||
|
const axios = this.$axios || this.$nuxt.$axios
|
||||||
|
this.processing = true
|
||||||
|
axios
|
||||||
|
.$patch(`/api/series/${this.series.id}`, { hideFromHome: true })
|
||||||
|
.then((data) => {
|
||||||
|
console.log('Series updated', data)
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to hide series from home', error)
|
||||||
|
this.$toast.error('Failed to update series')
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.processing = false
|
||||||
|
})
|
||||||
|
},
|
||||||
openCollections() {
|
openCollections() {
|
||||||
this.store.commit('setSelectedLibraryItem', this.libraryItem)
|
this.store.commit('setSelectedLibraryItem', this.libraryItem)
|
||||||
this.store.commit('globals/setShowUserCollectionsModal', true)
|
this.store.commit('globals/setShowUserCollectionsModal', true)
|
||||||
|
@ -40,7 +40,20 @@ export default {
|
|||||||
return this.$store.state.streamLibraryItem
|
return this.$store.state.streamLibraryItem
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {},
|
methods: {
|
||||||
beforeDestroy() {}
|
seriesUpdated(series) {
|
||||||
|
this.series = series
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$root.socket) {
|
||||||
|
this.$root.socket.on('series_updated', this.seriesUpdated)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.$root.socket) {
|
||||||
|
this.$root.socket.off('series_updated', this.seriesUpdated)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -34,6 +34,15 @@ class SeriesController {
|
|||||||
res.json(series)
|
res.json(series)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update(req, res) {
|
||||||
|
const hasUpdated = req.series.update(req.body)
|
||||||
|
if (hasUpdated) {
|
||||||
|
await this.db.updateEntity('series', req.series)
|
||||||
|
this.emitter('series_updated', req.series)
|
||||||
|
}
|
||||||
|
res.json(req.series)
|
||||||
|
}
|
||||||
|
|
||||||
middleware(req, res, next) {
|
middleware(req, res, next) {
|
||||||
var series = this.db.series.find(se => se.id === req.params.id)
|
var series = this.db.series.find(se => se.id === req.params.id)
|
||||||
if (!series) return res.sendStatus(404)
|
if (!series) return res.sendStatus(404)
|
||||||
|
@ -5,6 +5,7 @@ class Series {
|
|||||||
this.id = null
|
this.id = null
|
||||||
this.name = null
|
this.name = null
|
||||||
this.description = null
|
this.description = null
|
||||||
|
this.hideFromHome = false
|
||||||
this.addedAt = null
|
this.addedAt = null
|
||||||
this.updatedAt = null
|
this.updatedAt = null
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ class Series {
|
|||||||
this.id = series.id
|
this.id = series.id
|
||||||
this.name = series.name
|
this.name = series.name
|
||||||
this.description = series.description || null
|
this.description = series.description || null
|
||||||
|
this.hideFromHome = !!series.hideFromHome
|
||||||
this.addedAt = series.addedAt
|
this.addedAt = series.addedAt
|
||||||
this.updatedAt = series.updatedAt
|
this.updatedAt = series.updatedAt
|
||||||
}
|
}
|
||||||
@ -26,6 +28,7 @@ class Series {
|
|||||||
id: this.id,
|
id: this.id,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
description: this.description,
|
||||||
|
hideFromHome: this.hideFromHome,
|
||||||
addedAt: this.addedAt,
|
addedAt: this.addedAt,
|
||||||
updatedAt: this.updatedAt
|
updatedAt: this.updatedAt
|
||||||
}
|
}
|
||||||
@ -43,10 +46,24 @@ class Series {
|
|||||||
this.id = getId('ser')
|
this.id = getId('ser')
|
||||||
this.name = data.name
|
this.name = data.name
|
||||||
this.description = data.description || null
|
this.description = data.description || null
|
||||||
|
this.hideFromHome = !!data.hideFromHome
|
||||||
this.addedAt = Date.now()
|
this.addedAt = Date.now()
|
||||||
this.updatedAt = Date.now()
|
this.updatedAt = Date.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(series) {
|
||||||
|
if (!series) return false
|
||||||
|
const keysToUpdate = ['name', 'description', 'hideFromHome']
|
||||||
|
var hasUpdated = false
|
||||||
|
for (const key of keysToUpdate) {
|
||||||
|
if (series[key] !== undefined && series[key] !== this[key]) {
|
||||||
|
this[key] = series[key]
|
||||||
|
hasUpdated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasUpdated
|
||||||
|
}
|
||||||
|
|
||||||
checkNameEquals(name) {
|
checkNameEquals(name) {
|
||||||
if (!name || !this.name) return false
|
if (!name || !this.name) return false
|
||||||
return this.name.toLowerCase() == name.toLowerCase().trim()
|
return this.name.toLowerCase() == name.toLowerCase().trim()
|
||||||
|
@ -178,6 +178,7 @@ class ApiRouter {
|
|||||||
//
|
//
|
||||||
this.router.get('/series/search', SeriesController.search.bind(this))
|
this.router.get('/series/search', SeriesController.search.bind(this))
|
||||||
this.router.get('/series/:id', SeriesController.middleware.bind(this), SeriesController.findOne.bind(this))
|
this.router.get('/series/:id', SeriesController.middleware.bind(this), SeriesController.findOne.bind(this))
|
||||||
|
this.router.patch('/series/:id', SeriesController.middleware.bind(this), SeriesController.update.bind(this))
|
||||||
|
|
||||||
//
|
//
|
||||||
// Playback Session Routes
|
// Playback Session Routes
|
||||||
|
@ -417,7 +417,7 @@ module.exports = {
|
|||||||
|
|
||||||
if (!seriesMap[librarySeries.id]) {
|
if (!seriesMap[librarySeries.id]) {
|
||||||
const seriesObj = allSeries.find(se => se.id === librarySeries.id)
|
const seriesObj = allSeries.find(se => se.id === librarySeries.id)
|
||||||
if (seriesObj) {
|
if (seriesObj && !seriesObj.hideFromHome) {
|
||||||
var series = {
|
var series = {
|
||||||
...seriesObj.toJSON(),
|
...seriesObj.toJSON(),
|
||||||
books: [libraryItemJson],
|
books: [libraryItemJson],
|
||||||
|
Loading…
Reference in New Issue
Block a user