Add: route for syncing local progress from app

This commit is contained in:
advplyr 2021-11-19 20:08:03 -06:00
parent 43dc85ad81
commit 66911a4b70
6 changed files with 67 additions and 10 deletions

View File

@ -164,10 +164,6 @@ export default {
audioPlayed() {
if (!this.$refs.audio) return
console.log('Audio Played', this.$refs.audio.currentTime, 'Total Duration', this.$refs.audio.duration)
// setTimeout(() => {
// console.log('Audio Played FOLLOW UP', this.$refs.audio.currentTime, 'Total Duration', this.$refs.audio.duration)
// this.startListenTimeInterval()
// }, 500)
this.startListenTimeInterval()
this.isPaused = this.$refs.audio.paused
},

View File

@ -1,6 +1,6 @@
{
"name": "audiobookshelf-client",
"version": "1.6.22",
"version": "1.6.23",
"description": "Audiobook manager and player",
"main": "index.js",
"scripts": {

View File

@ -1,6 +1,6 @@
{
"name": "audiobookshelf",
"version": "1.6.22",
"version": "1.6.23",
"description": "Self-hosted audiobook server for managing and playing audiobooks",
"main": "index.js",
"scripts": {

View File

@ -114,6 +114,8 @@ class ApiController {
this.router.get('/listeningSessions', this.getCurrentUserListeningSessions.bind(this))
this.router.get('/listeningStats', this.getCurrentUserListeningStats.bind(this))
this.router.post('/syncUserAudiobookData', this.syncUserAudiobookData.bind(this))
}
async find(req, res) {
@ -606,6 +608,12 @@ class ApiController {
}
req.user.resetAudiobookProgress(audiobook)
await this.db.updateEntity('user', req.user)
var userAudiobookData = req.user.audiobooks[audiobook.id]
if (userAudiobookData) {
this.clientEmitter(req.user.id, 'current_user_audiobook_update', { id: audiobook.id, data: userAudiobookData })
}
this.clientEmitter(req.user.id, 'user_updated', req.user.toJSONForBrowser())
res.sendStatus(200)
}
@ -1162,11 +1170,40 @@ class ApiController {
}
async getCurrentUserListeningStats(req, res) {
if (!req.user) {
return res.sendStatus(500)
}
var listeningStats = await this.getUserListeningStatsHelpers(req.user.id)
res.json(listeningStats)
}
async syncUserAudiobookData(req, res) {
if (!req.body.data) {
return res.status(403).send('Invalid local user audiobook data')
}
var hasUpdates = false
// Local user audiobook data use the latest update
req.body.data.forEach((uab) => {
if (!uab || !uab.audiobookId) {
Logger.error('[ApiController] Invalid user audiobook data', uab)
return
}
var audiobook = this.db.audiobooks.find(ab => ab.id === uab.audiobookId)
if (!audiobook) {
Logger.info('[ApiController] syncUserAudiobookData local audiobook data audiobook no longer exists', uab.audiobookId)
return
}
if (req.user.syncLocalUserAudiobookData(uab, audiobook)) {
this.clientEmitter(req.user.id, 'current_user_audiobook_update', { id: uab.audiobookId, data: uab })
hasUpdates = true
}
})
if (hasUpdates) {
await this.db.updateEntity('user', req.user)
}
var allUserAudiobookData = Object.values(req.user.audiobooksToJSON())
res.json(allUserAudiobookData)
}
}
module.exports = ApiController

View File

@ -328,5 +328,30 @@ class User {
this.audiobooks[audiobookId].deleteBookmark(time)
return this.audiobooks[audiobookId]
}
syncLocalUserAudiobookData(localUserAudiobookData, audiobook) {
if (!localUserAudiobookData || !localUserAudiobookData.audiobookId) {
Logger.error(`[User] Invalid local user audiobook data`, localUserAudiobookData)
return false
}
if (!this.audiobooks[localUserAudiobookData.audiobookId]) {
this.audiobooks[localUserAudiobookData.audiobookId] = new UserAudiobookData(localUserAudiobookData)
return true
}
var userAbD = this.audiobooks[localUserAudiobookData.audiobookId]
if (userAbD.lastUpdate >= localUserAudiobookData.lastUpdate) {
// Server audiobook data is more recent
return false
}
// Local Data More recent
var wasUpdated = this.audiobooks[localUserAudiobookData.audiobookId].update(localUserAudiobookData)
if (wasUpdated) {
Logger.debug(`[User] syncLocalUserAudiobookData local data was more recent for "${audiobook.title}"`)
}
return wasUpdated
}
}
module.exports = User

View File

@ -5,7 +5,6 @@ class UserAudiobookData {
constructor(progress) {
this.audiobookId = null
this.id = null
this.totalDuration = null // seconds
this.progress = null // 0 to 1
this.currentTime = null // seconds