mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-09 05:19:37 +00:00
Update user audiobook progress model, add mark as read/not read, download individual tracks
This commit is contained in:
parent
4f094df0b2
commit
11d7330c5d
21 changed files with 496 additions and 100 deletions
91
server/objects/AudiobookProgress.js
Normal file
91
server/objects/AudiobookProgress.js
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
class AudiobookProgress {
|
||||
constructor(progress) {
|
||||
this.audiobookId = null
|
||||
this.totalDuration = null // seconds
|
||||
this.progress = null // 0 to 1
|
||||
this.currentTime = null // seconds
|
||||
this.isRead = false
|
||||
this.lastUpdate = null
|
||||
this.startedAt = null
|
||||
this.finishedAt = null
|
||||
|
||||
if (progress) {
|
||||
this.construct(progress)
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
audiobookId: this.audiobookId,
|
||||
totalDuration: this.totalDuration,
|
||||
progress: this.progress,
|
||||
currentTime: this.currentTime,
|
||||
isRead: this.isRead,
|
||||
lastUpdate: this.lastUpdate,
|
||||
startedAt: this.startedAt,
|
||||
finishedAt: this.finishedAt
|
||||
}
|
||||
}
|
||||
|
||||
construct(progress) {
|
||||
this.audiobookId = progress.audiobookId
|
||||
this.totalDuration = progress.totalDuration
|
||||
this.progress = progress.progress
|
||||
this.currentTime = progress.currentTime
|
||||
this.isRead = !!progress.isRead
|
||||
this.lastUpdate = progress.lastUpdate
|
||||
this.startedAt = progress.startedAt
|
||||
this.finishedAt = progress.finishedAt || null
|
||||
}
|
||||
|
||||
updateFromStream(stream) {
|
||||
this.audiobookId = stream.audiobookId
|
||||
this.totalDuration = stream.totalDuration
|
||||
this.progress = stream.clientProgress
|
||||
this.currentTime = stream.clientCurrentTime
|
||||
this.lastUpdate = Date.now()
|
||||
|
||||
if (!this.startedAt) {
|
||||
this.startedAt = Date.now()
|
||||
}
|
||||
|
||||
// If has < 10 seconds remaining mark as read
|
||||
var timeRemaining = this.totalDuration - this.currentTime
|
||||
if (timeRemaining < 10) {
|
||||
if (!this.isRead) {
|
||||
this.isRead = true
|
||||
this.progress = 1
|
||||
this.finishedAt = Date.now()
|
||||
}
|
||||
} else {
|
||||
this.isRead = false
|
||||
this.finishedAt = null
|
||||
}
|
||||
}
|
||||
|
||||
update(payload) {
|
||||
var hasUpdates = false
|
||||
for (const key in payload) {
|
||||
if (payload[key] !== this[key]) {
|
||||
if (key === 'isRead') {
|
||||
if (!payload[key]) { // Updating to Not Read - Reset progress and current time
|
||||
this.finishedAt = null
|
||||
this.progress = 0
|
||||
this.currentTime = 0
|
||||
} else { // Updating to Read
|
||||
if (!this.finishedAt) this.finishedAt = Date.now()
|
||||
this.progress = 1
|
||||
}
|
||||
}
|
||||
|
||||
this[key] = payload[key]
|
||||
hasUpdates = true
|
||||
}
|
||||
}
|
||||
if (!this.startedAt) {
|
||||
this.startedAt = Date.now()
|
||||
}
|
||||
return hasUpdates
|
||||
}
|
||||
}
|
||||
module.exports = AudiobookProgress
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
const AudiobookProgress = require('./AudiobookProgress')
|
||||
|
||||
class User {
|
||||
constructor(user) {
|
||||
this.id = null
|
||||
|
|
@ -26,6 +28,17 @@ class User {
|
|||
}
|
||||
}
|
||||
|
||||
audiobooksToJSON() {
|
||||
if (!this.audiobooks) return null
|
||||
var _map = {}
|
||||
for (const key in this.audiobooks) {
|
||||
if (this.audiobooks[key]) {
|
||||
_map[key] = this.audiobooks[key].toJSON()
|
||||
}
|
||||
}
|
||||
return _map
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
id: this.id,
|
||||
|
|
@ -34,7 +47,7 @@ class User {
|
|||
type: this.type,
|
||||
stream: this.stream,
|
||||
token: this.token,
|
||||
audiobooks: this.audiobooks,
|
||||
audiobooks: this.audiobooksToJSON(),
|
||||
isActive: this.isActive,
|
||||
createdAt: this.createdAt,
|
||||
settings: this.settings
|
||||
|
|
@ -48,7 +61,7 @@ class User {
|
|||
type: this.type,
|
||||
stream: this.stream,
|
||||
token: this.token,
|
||||
audiobooks: this.audiobooks,
|
||||
audiobooks: this.audiobooksToJSON(),
|
||||
isActive: this.isActive,
|
||||
createdAt: this.createdAt,
|
||||
settings: this.settings
|
||||
|
|
@ -62,7 +75,14 @@ class User {
|
|||
this.type = user.type
|
||||
this.stream = user.stream || null
|
||||
this.token = user.token
|
||||
this.audiobooks = user.audiobooks || null
|
||||
if (user.audiobooks) {
|
||||
this.audiobooks = {}
|
||||
for (const key in user.audiobooks) {
|
||||
if (user.audiobooks[key]) {
|
||||
this.audiobooks[key] = new AudiobookProgress(user.audiobooks[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
this.isActive = (user.isActive === undefined || user.id === 'root') ? true : !!user.isActive
|
||||
this.createdAt = user.createdAt || Date.now()
|
||||
this.settings = user.settings || this.getDefaultUserSettings()
|
||||
|
|
@ -84,18 +104,21 @@ class User {
|
|||
return hasUpdates
|
||||
}
|
||||
|
||||
updateAudiobookProgress(stream) {
|
||||
updateAudiobookProgressFromStream(stream) {
|
||||
if (!this.audiobooks) this.audiobooks = {}
|
||||
if (!this.audiobooks[stream.audiobookId]) {
|
||||
this.audiobooks[stream.audiobookId] = {
|
||||
audiobookId: stream.audiobookId,
|
||||
totalDuration: stream.totalDuration,
|
||||
startedAt: Date.now()
|
||||
}
|
||||
this.audiobooks[stream.audiobookId] = new AudiobookProgress()
|
||||
}
|
||||
this.audiobooks[stream.audiobookId].lastUpdate = Date.now()
|
||||
this.audiobooks[stream.audiobookId].progress = stream.clientProgress
|
||||
this.audiobooks[stream.audiobookId].currentTime = stream.clientCurrentTime
|
||||
this.audiobooks[stream.audiobookId].updateFromStream(stream)
|
||||
}
|
||||
|
||||
updateAudiobookProgress(audiobookId, updatePayload) {
|
||||
if (!this.audiobooks) this.audiobooks = {}
|
||||
if (!this.audiobooks[audiobookId]) {
|
||||
this.audiobooks[audiobookId] = new AudiobookProgress()
|
||||
this.audiobooks[audiobookId].audiobookId = audiobookId
|
||||
}
|
||||
return this.audiobooks[audiobookId].update(updatePayload)
|
||||
}
|
||||
|
||||
// Returns Boolean If update was made
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue