Update API media progress endpoints to use new user model. Merge book & episode endpoints

This commit is contained in:
advplyr 2024-08-11 11:53:30 -05:00
parent 68ef3a07a7
commit 9cd92c7b7f
8 changed files with 295 additions and 109 deletions

View file

@ -3,6 +3,8 @@ const sequelize = require('sequelize')
const Logger = require('../Logger')
const oldUser = require('../objects/user/User')
const SocketAuthority = require('../SocketAuthority')
const { isNullOrNaN } = require('../utils')
const { DataTypes, Model } = sequelize
class User extends Model {
@ -577,6 +579,116 @@ class User extends Model {
})
return mediaProgress?.getOldMediaProgress() || null
}
/**
* TODO: Uses old model and should account for the different between ebook/audiobook progress
*
* @typedef ProgressUpdatePayload
* @property {string} libraryItemId
* @property {string} [episodeId]
* @property {number} [duration]
* @property {number} [progress]
* @property {number} [currentTime]
* @property {boolean} [isFinished]
* @property {boolean} [hideFromContinueListening]
* @property {string} [ebookLocation]
* @property {number} [ebookProgress]
* @property {string} [finishedAt]
* @property {number} [lastUpdate]
*
* @param {ProgressUpdatePayload} progressPayload
* @returns {Promise<{ mediaProgress: import('./MediaProgress'), error: [string], statusCode: [number] }>}
*/
async createUpdateMediaProgressFromPayload(progressPayload) {
/** @type {import('./MediaProgress')|null} */
let mediaProgress = null
let mediaItemId = null
if (progressPayload.episodeId) {
const podcastEpisode = await this.sequelize.models.podcastEpisode.findByPk(progressPayload.episodeId, {
attributes: ['id', 'podcastId'],
include: [
{
model: this.sequelize.models.mediaProgress,
where: { userId: this.id },
required: false
},
{
model: this.sequelize.models.podcast,
attributes: ['id', 'title'],
include: {
model: this.sequelize.models.libraryItem,
attributes: ['id']
}
}
]
})
if (!podcastEpisode) {
Logger.error(`[User] createUpdateMediaProgress: episode ${progressPayload.episodeId} not found`)
return {
error: 'Episode not found',
statusCode: 404
}
}
mediaItemId = podcastEpisode.id
mediaProgress = podcastEpisode.mediaProgresses?.[0]
} else {
const libraryItem = await this.sequelize.models.libraryItem.findByPk(progressPayload.libraryItemId, {
attributes: ['id', 'mediaId', 'mediaType'],
include: {
model: this.sequelize.models.book,
attributes: ['id', 'title'],
required: false,
include: {
model: this.sequelize.models.mediaProgress,
where: { userId: this.id },
required: false
}
}
})
if (!libraryItem) {
Logger.error(`[User] createUpdateMediaProgress: library item ${progressPayload.libraryItemId} not found`)
return {
error: 'Library item not found',
statusCode: 404
}
}
mediaItemId = libraryItem.media.id
mediaProgress = libraryItem.media.mediaProgresses?.[0]
}
if (mediaProgress) {
mediaProgress = await mediaProgress.applyProgressUpdate(progressPayload)
this.mediaProgresses = this.mediaProgresses.map((mp) => (mp.id === mediaProgress.id ? mediaProgress : mp))
} else {
const newMediaProgressPayload = {
userId: this.id,
mediaItemId,
mediaItemType: progressPayload.episodeId ? 'podcastEpisode' : 'book',
duration: isNullOrNaN(progressPayload.duration) ? 0 : Number(progressPayload.duration),
currentTime: isNullOrNaN(progressPayload.currentTime) ? 0 : Number(progressPayload.currentTime),
isFinished: !!progressPayload.isFinished,
hideFromContinueListening: !!progressPayload.hideFromContinueListening,
ebookLocation: progressPayload.ebookLocation || null,
ebookProgress: isNullOrNaN(progressPayload.ebookProgress) ? 0 : Number(progressPayload.ebookProgress),
finishedAt: progressPayload.finishedAt || null,
extraData: {
libraryItemId: progressPayload.libraryItemId,
progress: isNullOrNaN(progressPayload.progress) ? 0 : Number(progressPayload.progress)
}
}
if (newMediaProgressPayload.isFinished) {
newMediaProgressPayload.finishedAt = new Date()
newMediaProgressPayload.extraData.progress = 1
} else {
newMediaProgressPayload.finishedAt = null
}
mediaProgress = await this.sequelize.models.mediaProgress.create(newMediaProgressPayload)
this.mediaProgresses.push(mediaProgress)
}
return {
mediaProgress
}
}
}
module.exports = User