video-comment.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { cloneDeep } from 'lodash'
  2. import * as Sequelize from 'sequelize'
  3. import { logger } from '@server/helpers/logger'
  4. import { sequelizeTypescript } from '@server/initializers/database'
  5. import { ResultList } from '../../shared/models'
  6. import { VideoCommentThreadTree } from '../../shared/models/videos/video-comment.model'
  7. import { VideoCommentModel } from '../models/video/video-comment'
  8. import { MAccountDefault, MComment, MCommentOwnerVideo, MCommentOwnerVideoReply, MVideoFullLight } from '../types/models'
  9. import { sendCreateVideoComment, sendDeleteVideoComment } from './activitypub/send'
  10. import { getLocalVideoCommentActivityPubUrl } from './activitypub/url'
  11. import { Hooks } from './plugins/hooks'
  12. async function removeComment (videoCommentInstance: MCommentOwnerVideo) {
  13. const videoCommentInstanceBefore = cloneDeep(videoCommentInstance)
  14. await sequelizeTypescript.transaction(async t => {
  15. if (videoCommentInstance.isOwned() || videoCommentInstance.Video.isOwned()) {
  16. await sendDeleteVideoComment(videoCommentInstance, t)
  17. }
  18. markCommentAsDeleted(videoCommentInstance)
  19. await videoCommentInstance.save()
  20. })
  21. logger.info('Video comment %d deleted.', videoCommentInstance.id)
  22. Hooks.runAction('action:api.video-comment.deleted', { comment: videoCommentInstanceBefore })
  23. }
  24. async function createVideoComment (obj: {
  25. text: string
  26. inReplyToComment: MComment | null
  27. video: MVideoFullLight
  28. account: MAccountDefault
  29. }, t: Sequelize.Transaction) {
  30. let originCommentId: number | null = null
  31. let inReplyToCommentId: number | null = null
  32. if (obj.inReplyToComment && obj.inReplyToComment !== null) {
  33. originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id
  34. inReplyToCommentId = obj.inReplyToComment.id
  35. }
  36. const comment = await VideoCommentModel.create({
  37. text: obj.text,
  38. originCommentId,
  39. inReplyToCommentId,
  40. videoId: obj.video.id,
  41. accountId: obj.account.id,
  42. url: new Date().toISOString()
  43. }, { transaction: t, validate: false })
  44. comment.url = getLocalVideoCommentActivityPubUrl(obj.video, comment)
  45. const savedComment: MCommentOwnerVideoReply = await comment.save({ transaction: t })
  46. savedComment.InReplyToVideoComment = obj.inReplyToComment
  47. savedComment.Video = obj.video
  48. savedComment.Account = obj.account
  49. await sendCreateVideoComment(savedComment, t)
  50. return savedComment
  51. }
  52. function buildFormattedCommentTree (resultList: ResultList<VideoCommentModel>): VideoCommentThreadTree {
  53. // Comments are sorted by id ASC
  54. const comments = resultList.data
  55. const comment = comments.shift()
  56. const thread: VideoCommentThreadTree = {
  57. comment: comment.toFormattedJSON(),
  58. children: []
  59. }
  60. const idx = {
  61. [comment.id]: thread
  62. }
  63. while (comments.length !== 0) {
  64. const childComment = comments.shift()
  65. const childCommentThread: VideoCommentThreadTree = {
  66. comment: childComment.toFormattedJSON(),
  67. children: []
  68. }
  69. const parentCommentThread = idx[childComment.inReplyToCommentId]
  70. // Maybe the parent comment was blocked by the admin/user
  71. if (!parentCommentThread) continue
  72. parentCommentThread.children.push(childCommentThread)
  73. idx[childComment.id] = childCommentThread
  74. }
  75. return thread
  76. }
  77. function markCommentAsDeleted (comment: MComment): void {
  78. comment.text = ''
  79. comment.deletedAt = new Date()
  80. comment.accountId = null
  81. }
  82. // ---------------------------------------------------------------------------
  83. export {
  84. removeComment,
  85. createVideoComment,
  86. buildFormattedCommentTree,
  87. markCommentAsDeleted
  88. }