server/core/lib/rate.ts
import { VIDEO_RATE_TYPES } from '@server/initializers/constants.js'
import { sequelizeTypescript } from '@server/initializers/database.js'
import { AccountVideoRateModel } from '@server/models/account/account-video-rate.js'
import { AccountModel } from '@server/models/account/account.js'
import { getLocalRateUrl, sendVideoRateChange } from './activitypub/video-rates.js'
import { MAccountId, MAccountUrl, MVideoFullLight } from '@server/types/models/index.js'
import { UserVideoRateType } from '@peertube/peertube-models'
export async function userRateVideo (options: {
rateType: UserVideoRateType
account: MAccountUrl & MAccountId
video: MVideoFullLight
}) {
const { account, rateType, video } = options
await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t }
const accountInstance = await AccountModel.load(account.id, t)
const previousRate = await AccountVideoRateModel.load(accountInstance.id, video.id, t)
// Same rate, nothing do to
if (rateType === 'none' && !previousRate || previousRate?.type === rateType) return
let likesToIncrement = 0
let dislikesToIncrement = 0
if (rateType === VIDEO_RATE_TYPES.LIKE) likesToIncrement++
else if (rateType === VIDEO_RATE_TYPES.DISLIKE) dislikesToIncrement++
// There was a previous rate, update it
if (previousRate) {
// We will remove the previous rate, so we will need to update the video count attribute
if (previousRate.type === 'like') likesToIncrement--
else if (previousRate.type === 'dislike') dislikesToIncrement--
if (rateType === 'none') { // Destroy previous rate
await previousRate.destroy(sequelizeOptions)
} else { // Update previous rate
previousRate.type = rateType
previousRate.url = getLocalRateUrl(rateType, account.Actor, video)
await previousRate.save(sequelizeOptions)
}
} else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
const query = {
accountId: accountInstance.id,
videoId: video.id,
type: rateType,
url: getLocalRateUrl(rateType, account.Actor, video)
}
await AccountVideoRateModel.create(query, sequelizeOptions)
}
const incrementQuery = {
likes: likesToIncrement,
dislikes: dislikesToIncrement
}
await video.increment(incrementQuery, sequelizeOptions)
await sendVideoRateChange(accountInstance, video, likesToIncrement, dislikesToIncrement, t)
})
}