diff --git a/client/components/app/BookShelfToolbar.vue b/client/components/app/BookShelfToolbar.vue index b7ecff624..57054dce7 100644 --- a/client/components/app/BookShelfToolbar.vue +++ b/client/components/app/BookShelfToolbar.vue @@ -134,6 +134,13 @@ export default { } ] + if (this.userCanUpdate && this.isBookLibrary) { + items.push({ + text: this.$strings.ButtonAddPlaceholder, + action: 'add-placeholder' + }) + } + if (this.userIsAdminOrUp || this.selectedSeries.rssFeed) { items.push({ text: this.$strings.LabelOpenRSSFeed, @@ -427,6 +434,12 @@ export default { seriesContextMenuAction({ action }) { if (action === 'open-rss-feed') { this.showOpenSeriesRSSFeed() + } else if (action === 'add-placeholder') { + if (this.processingSeries) { + console.warn('Already processing series') + return + } + this.createSeriesPlaceholder() } else if (action === 're-add-to-continue-listening') { if (this.processingSeries) { console.warn('Already processing series') @@ -566,6 +579,25 @@ export default { } this.$store.commit('globals/setConfirmPrompt', payload) }, + async createSeriesPlaceholder() { + if (!this.seriesId) return + this.processingSeries = true + const payload = { + title: this.$strings.LabelPlaceholderDefaultTitle + } + try { + const libraryItem = await this.$axios.$post(`/api/libraries/${this.currentLibraryId}/series/${this.seriesId}/placeholders`, payload) + this.$toast.success(this.$strings.ToastPlaceholderCreated) + this.$store.commit('setBookshelfBookIds', []) + this.$store.commit('showEditModal', libraryItem) + this.$eventBus.$emit('series-bookshelf-refresh', { seriesId: this.seriesId }) + } catch (error) { + console.error('Failed to create placeholder', error) + this.$toast.error(this.$strings.ToastPlaceholderCreateFailed) + } finally { + this.processingSeries = false + } + }, updateOrder() { this.saveSettings() }, diff --git a/client/components/app/LazyBookshelf.vue b/client/components/app/LazyBookshelf.vue index 4c72d0d78..3baf90c03 100644 --- a/client/components/app/LazyBookshelf.vue +++ b/client/components/app/LazyBookshelf.vue @@ -566,8 +566,19 @@ export default { this.entityComponentRefs[indexOf].setEntity(libraryItem) } } + if (this.entityName === 'series-books' && this.seriesId) { + const seriesIds = libraryItem.media?.metadata?.series?.map((se) => se.id) || [] + if (!seriesIds.includes(this.seriesId)) { + this.resetEntities(this.currScrollTop) + } + } } }, + seriesBookshelfRefresh({ seriesId } = {}) { + if (this.entityName !== 'series-books') return + if (seriesId && this.seriesId && seriesId !== this.seriesId) return + this.resetEntities(this.currScrollTop) + }, routeToBookshelfIfLastIssueRemoved() { if (this.totalEntities === 0) { const currentRouteQuery = this.$route.query @@ -791,6 +802,7 @@ export default { this.$eventBus.$on('bookshelf_clear_selection', this.clearSelectedEntities) this.$eventBus.$on('user-settings', this.settingsUpdated) + this.$eventBus.$on('series-bookshelf-refresh', this.seriesBookshelfRefresh) if (this.$root.socket) { this.$root.socket.on('item_updated', this.libraryItemUpdated) @@ -822,6 +834,7 @@ export default { this.$eventBus.$off('bookshelf_clear_selection', this.clearSelectedEntities) this.$eventBus.$off('user-settings', this.settingsUpdated) + this.$eventBus.$off('series-bookshelf-refresh', this.seriesBookshelfRefresh) if (this.$root.socket) { this.$root.socket.off('item_updated', this.libraryItemUpdated) diff --git a/client/components/cards/ItemUploadCard.vue b/client/components/cards/ItemUploadCard.vue index adbf3adbe..7767e402e 100644 --- a/client/components/cards/ItemUploadCard.vue +++ b/client/components/cards/ItemUploadCard.vue @@ -40,7 +40,10 @@
-
+
+ +
+