+
west
- {{ selectedSeries }}
+ {{ seriesName }}
{{ numShowing }}
+
+
+
+ Mark Series {{ isSeriesFinished ? 'Not Finished' : 'Finished' }}
@@ -56,7 +68,10 @@ export default {
props: {
page: String,
isHome: Boolean,
- selectedSeries: String,
+ selectedSeries: {
+ type: Object,
+ default: () => null
+ },
searchQuery: String,
viewMode: String
},
@@ -66,7 +81,8 @@ export default {
hasInit: false,
totalEntities: 0,
keywordFilter: null,
- keywordTimeout: null
+ keywordTimeout: null,
+ processingSeries: false
}
},
computed: {
@@ -103,9 +119,45 @@ export default {
},
showLibrary() {
return this.libraryBookshelfPage && this.paramId === '' && !this.showingIssues
+ },
+ seriesName() {
+ return this.selectedSeries ? this.selectedSeries.name : null
+ },
+ seriesProgress() {
+ return this.selectedSeries ? this.selectedSeries.progress : null
+ },
+ seriesLibraryItemIds() {
+ if (!this.seriesProgress) return []
+ return this.seriesProgress.libraryItemIds || []
+ },
+ isSeriesFinished() {
+ return this.seriesProgress && !!this.seriesProgress.isFinished
}
},
methods: {
+ markSeriesFinished() {
+ var newIsFinished = !this.isSeriesFinished
+ this.processingSeries = true
+ var updateProgressPayloads = this.seriesLibraryItemIds.map((lid) => {
+ return {
+ id: lid,
+ isFinished: newIsFinished
+ }
+ })
+ console.log('Progress payloads', updateProgressPayloads)
+ this.$axios
+ .patch(`/api/me/progress/batch/update`, updateProgressPayloads)
+ .then(() => {
+ this.$toast.success('Series update success')
+ this.selectedSeries.progress.isFinished = newIsFinished
+ this.processingSeries = false
+ })
+ .catch((error) => {
+ this.$toast.error('Series update failed')
+ console.error('Failed to batch update read/not read', error)
+ this.processingSeries = false
+ })
+ },
searchBackArrow() {
this.$router.replace(`/library/${this.currentLibraryId}/bookshelf`)
},
diff --git a/client/pages/library/_library/series/_id.vue b/client/pages/library/_library/series/_id.vue
index 754b332e..7396fd87 100644
--- a/client/pages/library/_library/series/_id.vue
+++ b/client/pages/library/_library/series/_id.vue
@@ -24,7 +24,7 @@ export default {
return redirect(`/library/${libraryId}`)
}
- var series = await app.$axios.$get(`/api/series/${params.id}`).catch((error) => {
+ var series = await app.$axios.$get(`/api/series/${params.id}?include=progress`).catch((error) => {
console.error('Failed', error)
return false
})
@@ -33,7 +33,7 @@ export default {
}
return {
- series: series.name,
+ series,
seriesId: params.id
}
},
diff --git a/server/controllers/SeriesController.js b/server/controllers/SeriesController.js
index 799075fa..fcd2e0a1 100644
--- a/server/controllers/SeriesController.js
+++ b/server/controllers/SeriesController.js
@@ -4,7 +4,25 @@ class SeriesController {
constructor() { }
async findOne(req, res) {
- return res.json(req.series)
+ var include = (req.query.include || '').split(',')
+
+ var seriesJson = req.series.toJSON()
+
+ // Add progress map with isFinished flag
+ if (include.includes('progress')) {
+ var libraryItemsInSeries = this.db.libraryItems.filter(li => li.mediaType === 'book' && li.media.metadata.hasSeries(seriesJson.id))
+ var libraryItemsFinished = libraryItemsInSeries.filter(li => {
+ var mediaProgress = req.user.getMediaProgress(li.id)
+ return mediaProgress && mediaProgress.isFinished
+ })
+ seriesJson.progress = {
+ libraryItemIds: libraryItemsInSeries.map(li => li.id),
+ libraryItemIdsFinished: libraryItemsFinished.map(li => li.id),
+ isFinished: libraryItemsFinished.length === libraryItemsInSeries.length
+ }
+ }
+
+ return res.json(seriesJson)
}
async search(req, res) {