1 import { catchError, map } from 'rxjs/operators'
2 import { HttpClient, HttpParams } from '@angular/common/http'
3 import { Injectable } from '@angular/core'
4 import { objectLineFeedToHtml } from '@app/shared/misc/utils'
5 import { Observable } from 'rxjs'
6 import { FeedFormat, ResultList } from '../../../../../../shared/models'
8 VideoComment as VideoCommentServerModel,
10 VideoCommentThreadTree as VideoCommentThreadTreeServerModel
11 } from '../../../../../../shared/models/videos/video-comment.model'
12 import { environment } from '../../../../environments/environment'
13 import { RestExtractor, RestService } from '../../../shared/rest'
14 import { ComponentPaginationLight } from '../../../shared/rest/component-pagination.model'
15 import { CommentSortField } from '../../../shared/video/sort-field.type'
16 import { VideoComment } from './video-comment.model'
17 import { VideoCommentThreadTree } from '@app/videos/+video-watch/comment/video-comment-thread-tree.model'
20 export class VideoCommentService {
21 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
22 private static BASE_FEEDS_URL = environment.apiUrl + '/feeds/video-comments.'
25 private authHttp: HttpClient,
26 private restExtractor: RestExtractor,
27 private restService: RestService
30 addCommentThread (videoId: number | string, comment: VideoCommentCreate) {
31 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
32 const normalizedComment = objectLineFeedToHtml(comment, 'text')
34 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
36 map(data => this.extractVideoComment(data.comment)),
37 catchError(err => this.restExtractor.handleError(err))
41 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) {
42 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId
43 const normalizedComment = objectLineFeedToHtml(comment, 'text')
45 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
47 map(data => this.extractVideoComment(data.comment)),
48 catchError(err => this.restExtractor.handleError(err))
52 getVideoCommentThreads (parameters: {
53 videoId: number | string,
54 componentPagination: ComponentPaginationLight,
55 sort: CommentSortField
56 }): Observable<ResultList<VideoComment>> {
57 const { videoId, componentPagination, sort } = parameters
59 const pagination = this.restService.componentPaginationToRestPagination(componentPagination)
61 let params = new HttpParams()
62 params = this.restService.addRestGetParams(params, pagination, sort)
64 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
65 return this.authHttp.get<ResultList<VideoComment>>(url, { params })
67 map(result => this.extractVideoComments(result)),
68 catchError(err => this.restExtractor.handleError(err))
72 getVideoThreadComments (parameters: {
73 videoId: number | string,
75 }): Observable<VideoCommentThreadTree> {
76 const { videoId, threadId } = parameters
77 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}`
80 .get<VideoCommentThreadTreeServerModel>(url)
82 map(tree => this.extractVideoCommentTree(tree)),
83 catchError(err => this.restExtractor.handleError(err))
87 deleteVideoComment (videoId: number | string, commentId: number) {
88 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comments/${commentId}`
93 map(this.restExtractor.extractDataBool),
94 catchError(err => this.restExtractor.handleError(err))
98 getVideoCommentsFeeds (videoUUID?: string) {
101 format: FeedFormat.RSS,
103 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.RSS.toLowerCase()
106 format: FeedFormat.ATOM,
108 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.ATOM.toLowerCase()
111 format: FeedFormat.JSON,
113 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.JSON.toLowerCase()
117 if (videoUUID !== undefined) {
118 for (const feed of feeds) {
119 feed.url += '?videoId=' + videoUUID
126 private extractVideoComment (videoComment: VideoCommentServerModel) {
127 return new VideoComment(videoComment)
130 private extractVideoComments (result: ResultList<VideoCommentServerModel>) {
131 const videoCommentsJson = result.data
132 const totalComments = result.total
133 const comments: VideoComment[] = []
135 for (const videoCommentJson of videoCommentsJson) {
136 comments.push(new VideoComment(videoCommentJson))
139 return { data: comments, total: totalComments }
142 private extractVideoCommentTree (tree: VideoCommentThreadTreeServerModel) {
143 if (!tree) return tree as VideoCommentThreadTree
145 tree.comment = new VideoComment(tree.comment)
146 tree.children.forEach(c => this.extractVideoCommentTree(c))
148 return tree as VideoCommentThreadTree