@@ -57,7 +57,8 @@ export default {
},
sizeMultiplier: Number,
bookCoverWidth: Number,
- bookCoverAspectRatio: Number
+ bookCoverAspectRatio: Number,
+ continueListeningShelf: Boolean
},
data() {
return {
diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue
index c7f029df..5231de62 100644
--- a/client/components/cards/LazyBookCard.vue
+++ b/client/components/cards/LazyBookCard.vue
@@ -128,7 +128,8 @@ export default {
},
orderBy: String,
filterBy: String,
- sortingIgnorePrefix: Boolean
+ sortingIgnorePrefix: Boolean,
+ continueListeningShelf: Boolean
},
data() {
return {
@@ -368,7 +369,7 @@ export default {
},
moreMenuItems() {
if (this.recentEpisode) {
- return [
+ const items = [
{
func: 'editPodcast',
text: 'Edit Podcast'
@@ -378,6 +379,7 @@ export default {
text: `Mark as ${this.itemIsFinished ? 'Not Finished' : 'Finished'}`
}
]
+ return items
}
var items = []
@@ -413,8 +415,14 @@ export default {
}
if (this.series && this.bookMount) {
items.push({
- func: 'hideSeriesFromContinueListening',
- text: 'Hide Series from Continue Series'
+ func: 'removeSeriesFromContinueListening',
+ text: 'Remove Series from Continue Series'
+ })
+ }
+ if (this.continueListeningShelf) {
+ items.push({
+ func: 'removeFromContinueListening',
+ text: 'Remove from Continue Listening'
})
}
return items
@@ -595,11 +603,29 @@ export default {
// More menu func
this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' })
},
- hideSeriesFromContinueListening() {
+ removeSeriesFromContinueListening() {
const axios = this.$axios || this.$nuxt.$axios
this.processing = true
axios
- .$post(`/api/me/series/${this.series.id}/hide`)
+ .$get(`/api/me/series/${this.series.id}/remove-from-continue-listening`)
+ .then((data) => {
+ console.log('User updated', data)
+ })
+ .catch((error) => {
+ console.error('Failed to remove series from home', error)
+ this.$toast.error('Failed to update user')
+ })
+ .finally(() => {
+ this.processing = false
+ })
+ },
+ removeFromContinueListening() {
+ if (!this.userProgress) return
+
+ const axios = this.$axios || this.$nuxt.$axios
+ this.processing = true
+ axios
+ .$get(`/api/me/progress/${this.userProgress.id}/remove-from-continue-listening`)
.then((data) => {
console.log('User updated', data)
})
diff --git a/client/components/widgets/ItemSlider.vue b/client/components/widgets/ItemSlider.vue
index 530be981..fea2d06d 100644
--- a/client/components/widgets/ItemSlider.vue
+++ b/client/components/widgets/ItemSlider.vue
@@ -13,7 +13,7 @@
@@ -34,7 +34,8 @@ export default {
bookshelfView: {
type: Number,
default: 1
- }
+ },
+ continueListeningShelf: Boolean
},
data() {
return {
diff --git a/server/controllers/MeController.js b/server/controllers/MeController.js
index ffd045d8..c2efb331 100644
--- a/server/controllers/MeController.js
+++ b/server/controllers/MeController.js
@@ -277,11 +277,11 @@ class MeController {
})
}
- // GET: api/me/series/:id/hide
- async hideSeriesFromContinueListening(req, res) {
+ // GET: api/me/series/:id/remove-from-continue-listening
+ async removeSeriesFromContinueListening(req, res) {
const series = this.db.series.find(se => se.id === req.params.id)
if (!series) {
- Logger.error(`[MeController] hideSeriesFromContinueListening: Series ${req.params.id} not found`)
+ Logger.error(`[MeController] removeSeriesFromContinueListening: Series ${req.params.id} not found`)
return res.sendStatus(404)
}
@@ -292,5 +292,15 @@ class MeController {
}
res.json(req.user.toJSONForBrowser())
}
+
+ // GET: api/me/progress/:id/remove-from-continue-listening
+ async removeItemFromContinueListening(req, res) {
+ const hasUpdated = req.user.removeProgressFromContinueListening(req.params.id)
+ if (hasUpdated) {
+ await this.db.updateEntity('user', req.user)
+ this.clientEmitter(req.user.id, 'user_updated', req.user.toJSONForBrowser())
+ }
+ res.json(req.user.toJSONForBrowser())
+ }
}
module.exports = new MeController()
\ No newline at end of file
diff --git a/server/objects/user/MediaProgress.js b/server/objects/user/MediaProgress.js
index 169a9243..70b2d678 100644
--- a/server/objects/user/MediaProgress.js
+++ b/server/objects/user/MediaProgress.js
@@ -8,6 +8,7 @@ class MediaProgress {
this.progress = null // 0 to 1
this.currentTime = null // seconds
this.isFinished = false
+ this.hideFromContinueListening = false
this.lastUpdate = null
this.startedAt = null
@@ -27,6 +28,7 @@ class MediaProgress {
progress: this.progress,
currentTime: this.currentTime,
isFinished: this.isFinished,
+ hideFromContinueListening: this.hideFromContinueListening,
lastUpdate: this.lastUpdate,
startedAt: this.startedAt,
finishedAt: this.finishedAt
@@ -41,6 +43,7 @@ class MediaProgress {
this.progress = progress.progress
this.currentTime = progress.currentTime
this.isFinished = !!progress.isFinished
+ this.hideFromContinueListening = !!progress.hideFromContinueListening
this.lastUpdate = progress.lastUpdate
this.startedAt = progress.startedAt
this.finishedAt = progress.finishedAt || null
@@ -58,6 +61,7 @@ class MediaProgress {
this.progress = Math.min(1, (progress.progress || 0))
this.currentTime = progress.currentTime || 0
this.isFinished = !!progress.isFinished || this.progress == 1
+ this.hideFromContinueListening = !!progress.hideFromContinueListening
this.lastUpdate = Date.now()
this.startedAt = Date.now()
this.finishedAt = null
@@ -102,9 +106,21 @@ class MediaProgress {
this.startedAt = Date.now()
}
if (hasUpdates) {
+ if (payload.hideFromContinueListening === undefined) {
+ // Reset this flag when the media progress is updated
+ this.hideFromContinueListening = false
+ }
+
this.lastUpdate = Date.now()
}
return hasUpdates
}
+
+ removeFromContinueListening() {
+ if (this.hideFromContinueListening) return false
+
+ this.hideFromContinueListening = true
+ return true
+ }
}
module.exports = MediaProgress
\ No newline at end of file
diff --git a/server/objects/user/User.js b/server/objects/user/User.js
index 220d6ce4..a28f6baa 100644
--- a/server/objects/user/User.js
+++ b/server/objects/user/User.js
@@ -407,5 +407,11 @@ class User {
this.seriesHideFromContinueListening.push(seriesId)
return true
}
+
+ removeProgressFromContinueListening(progressId) {
+ const progress = this.mediaProgress.find(mp => mp.id === progressId)
+ if (!progress) return false
+ return progress.removeFromContinueListening()
+ }
}
module.exports = User
\ No newline at end of file
diff --git a/server/routers/ApiRouter.js b/server/routers/ApiRouter.js
index 4853e487..c9220e5a 100644
--- a/server/routers/ApiRouter.js
+++ b/server/routers/ApiRouter.js
@@ -138,6 +138,7 @@ class ApiRouter {
//
this.router.get('/me/listening-sessions', MeController.getListeningSessions.bind(this))
this.router.get('/me/listening-stats', MeController.getListeningStats.bind(this))
+ this.router.get('/me/progress/:id/remove-from-continue-listening', MeController.removeItemFromContinueListening.bind(this))
this.router.get('/me/progress/:id/:episodeId?', MeController.getMediaProgress.bind(this))
this.router.patch('/me/progress/batch/update', MeController.batchUpdateMediaProgress.bind(this))
this.router.patch('/me/progress/:id', MeController.createUpdateMediaProgress.bind(this))
@@ -150,7 +151,7 @@ class ApiRouter {
this.router.patch('/me/settings', MeController.updateSettings.bind(this))
this.router.post('/me/sync-local-progress', MeController.syncLocalMediaProgress.bind(this))
this.router.get('/me/items-in-progress', MeController.getAllLibraryItemsInProgress.bind(this))
- this.router.post('/me/series/:id/hide', MeController.hideSeriesFromContinueListening.bind(this))
+ this.router.get('/me/series/:id/remove-from-continue-listening', MeController.removeSeriesFromContinueListening.bind(this))
//
// Backup Routes
diff --git a/server/utils/libraryHelpers.js b/server/utils/libraryHelpers.js
index 0a3ebae7..a7b8a6a4 100644
--- a/server/utils/libraryHelpers.js
+++ b/server/utils/libraryHelpers.js
@@ -531,7 +531,7 @@ module.exports = {
}
categoryMap.recentlyFinished.biggest = categoryMap.recentlyFinished.items[0].finishedAt
}
- } else if (mediaProgress.inProgress) { // Handle most recently listened
+ } else if (mediaProgress.inProgress && !mediaProgress.hideFromContinueListening) { // Handle most recently listened
if (mediaProgress.lastUpdate > categoryMap.recentlyListened.smallest) { // Item belongs on shelf
const libraryItemObj = {
...libraryItem.toJSONMinified(),