import { cloneDeep } from 'lodash' ; import * as Sequelize from 'sequelize' ; import express from 'express' ; import { logger } from '@server/helpers/logger' ; import { sequelizeTypescript } from '@server/initializers/database' ; import { ResultList } from '../../shared/models' ; import { VideoCommentThreadTree } from '../../shared/models/videos/comment/video-comment.model' ; import { VideoCommentModel } from '../models/video/video-comment' ; import { MAccountDefault , MComment , MCommentOwnerVideo , MCommentOwnerVideoReply , MVideoFullLight } from '../types/models' ; import { sendCreateVideoComment , sendDeleteVideoComment } from './activitypub/send' ; import { getLocalVideoCommentActivityPubUrl } from './activitypub/url' ; import { Hooks } from './plugins/hooks' ; async function removeComment ( videoCommentInstance , req , res ) { const videoCommentInstanceBefore = cloneDeep ( videoCommentInstance ) ; await sequelizeTypescript . transaction ( async ( t ) => { if ( videoCommentInstance . isOwned ( ) || videoCommentInstance . Video . isOwned ( ) ) { await sendDeleteVideoComment ( videoCommentInstance , t ) ; } videoCommentInstance . markAsDeleted ( ) ; await videoCommentInstance . save ( { transaction : t } ) ; } ) ; logger . info ( 'Video comment %d deleted.' , videoCommentInstance . id ) ; Hooks . runAction ( 'action:api.video-comment.deleted' , { comment : videoCommentInstanceBefore , req , res } ) ; } async function createVideoComment ( obj , t ) { let originCommentId = null ; let inReplyToCommentId = null ; if ( obj . inReplyToComment && obj . inReplyToComment !== null ) { originCommentId = obj . inReplyToComment . originCommentId || obj . inReplyToComment . id ; inReplyToCommentId = obj . inReplyToComment . id ; } const comment = await VideoCommentModel . create ( { text : obj . text , originCommentId , inReplyToCommentId , videoId : obj . video . id , accountId : obj . account . id , url : new Date ( ) . toISOString ( ) } , { transaction : t , validate : false } ) ; comment . url = getLocalVideoCommentActivityPubUrl ( obj . video , comment ) ; const savedComment = await comment . save ( { transaction : t } ) ; savedComment . InReplyToVideoComment = obj . inReplyToComment ; savedComment . Video = obj . video ; savedComment . Account = obj . account ; await sendCreateVideoComment ( savedComment , t ) ; return savedComment ; } function buildFormattedCommentTree ( resultList ) { const comments = resultList . data ; const comment = comments . shift ( ) ; const thread = { comment : comment . toFormattedJSON ( ) , children : [ ] } ; const idx = { [ comment . id ] : thread } ; while ( comments . length !== 0 ) { const childComment = comments . shift ( ) ; const childCommentThread = { comment : childComment . toFormattedJSON ( ) , children : [ ] } ; const parentCommentThread = idx [ childComment . inReplyToCommentId ] ; if ( ! parentCommentThread ) continue ; parentCommentThread . children . push ( childCommentThread ) ; idx [ childComment . id ] = childCommentThread ; } return thread ; } export { removeComment , createVideoComment , buildFormattedCommentTree } ;