mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
b0edac4234
This patch is a minor extension to the update progress and batch update progress API and allows you to specify `finishedAt` and `startedAt` when updating a progress. If not specified, both values are still automatically set to the current time. If just `finishedAt` is specified, `startedAt` is set to the same value. Example API request: ``` ❯ curl -i -X PATCH \ 'http://127.0.0.1:3333/api/me/progress/li_ywupqxw5d22adcadpa' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJyb290IiwidXNlcm5hbWUiOiJyb290IiwiaWF0IjoxNjY4OTYxNjAxfQ._NbilCoFy_hfoqy7uvbV4E_0X6qgLYapQ_MoRptP0oI' \ -H 'Content-Type: application/json' \ --data-raw '{"isFinished":true, "finishedAt": 1668556852000, "startedAt": 1668056852000}' ```
126 lines
3.7 KiB
JavaScript
126 lines
3.7 KiB
JavaScript
class MediaProgress {
|
|
constructor(progress) {
|
|
this.id = null
|
|
this.libraryItemId = null
|
|
this.episodeId = null // For podcasts
|
|
|
|
this.duration = null
|
|
this.progress = null // 0 to 1
|
|
this.currentTime = null // seconds
|
|
this.isFinished = false
|
|
this.hideFromContinueListening = false
|
|
|
|
this.lastUpdate = null
|
|
this.startedAt = null
|
|
this.finishedAt = null
|
|
|
|
if (progress) {
|
|
this.construct(progress)
|
|
}
|
|
}
|
|
|
|
toJSON() {
|
|
return {
|
|
id: this.id,
|
|
libraryItemId: this.libraryItemId,
|
|
episodeId: this.episodeId,
|
|
duration: this.duration,
|
|
progress: this.progress,
|
|
currentTime: this.currentTime,
|
|
isFinished: this.isFinished,
|
|
hideFromContinueListening: this.hideFromContinueListening,
|
|
lastUpdate: this.lastUpdate,
|
|
startedAt: this.startedAt,
|
|
finishedAt: this.finishedAt
|
|
}
|
|
}
|
|
|
|
construct(progress) {
|
|
this.id = progress.id
|
|
this.libraryItemId = progress.libraryItemId
|
|
this.episodeId = progress.episodeId
|
|
this.duration = progress.duration || 0
|
|
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
|
|
}
|
|
|
|
get inProgress() {
|
|
return !this.isFinished && this.progress > 0
|
|
}
|
|
|
|
setData(libraryItemId, progress, episodeId = null) {
|
|
this.id = episodeId ? `${libraryItemId}-${episodeId}` : libraryItemId
|
|
this.libraryItemId = libraryItemId
|
|
this.episodeId = episodeId
|
|
this.duration = progress.duration || 0
|
|
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.finishedAt = null
|
|
if (this.isFinished) {
|
|
this.finishedAt = progress.finishedAt || Date.now()
|
|
this.progress = 1
|
|
}
|
|
this.startedAt = this.finishedAt || Date.now()
|
|
}
|
|
|
|
update(payload) {
|
|
var hasUpdates = false
|
|
for (const key in payload) {
|
|
if (this[key] !== undefined && payload[key] !== this[key]) {
|
|
if (key === 'isFinished') {
|
|
if (!payload[key]) { // Updating to Not Finished - Reset progress and current time
|
|
this.finishedAt = null
|
|
this.progress = 0
|
|
this.currentTime = 0
|
|
} else { // Updating to Finished
|
|
if (!this.finishedAt) this.finishedAt = Date.now()
|
|
this.progress = 1
|
|
}
|
|
}
|
|
|
|
this[key] = payload[key]
|
|
hasUpdates = true
|
|
}
|
|
}
|
|
|
|
var timeRemaining = this.duration - this.currentTime
|
|
// If time remaining is less than 5 seconds then mark as finished
|
|
if ((this.progress >= 1 || (this.duration && !isNaN(timeRemaining) && timeRemaining < 5))) {
|
|
this.isFinished = true
|
|
this.finishedAt = payload.finishedAt || Date.now()
|
|
this.progress = 1
|
|
} else if (this.progress < 1 && this.isFinished) {
|
|
this.isFinished = false
|
|
this.finishedAt = null
|
|
}
|
|
|
|
if (!this.startedAt) {
|
|
this.startedAt = this.finishedAt || 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 |