]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/app/shared/shared-video-comment/video-comment.service.ts
Fix loading bar for HTTP requests
[github/Chocobozzz/PeerTube.git] / client / src / app / shared / shared-video-comment / video-comment.service.ts
CommitLineData
93991770
C
1import { SortMeta } from 'primeng/api'
2import { from, Observable } from 'rxjs'
3import { catchError, concatMap, map, toArray } from 'rxjs/operators'
4635f59d
C
4import { HttpClient, HttpParams } from '@angular/common/http'
5import { Injectable } from '@angular/core'
0f8d00e3 6import { ComponentPaginationLight, RestExtractor, RestPagination, RestService } from '@app/core'
67ed6552 7import { objectLineFeedToHtml } from '@app/helpers'
4635f59d 8import {
67ed6552
C
9 FeedFormat,
10 ResultList,
3d9eaae3 11 VideoComment as VideoCommentServerModel,
0f8d00e3 12 VideoCommentAdmin,
3d9eaae3 13 VideoCommentCreate,
be27ef3b 14 VideoCommentThreadTree as VideoCommentThreadTreeServerModel
67ed6552 15} from '@shared/models'
cfde28ba 16import { environment } from '../../../environments/environment'
67ed6552 17import { VideoCommentThreadTree } from './video-comment-thread-tree.model'
4635f59d
C
18import { VideoComment } from './video-comment.model'
19
20@Injectable()
21export class VideoCommentService {
f1273314
C
22 static BASE_FEEDS_URL = environment.apiUrl + '/feeds/video-comments.'
23
4635f59d
C
24 private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
25
26 constructor (
27 private authHttp: HttpClient,
28 private restExtractor: RestExtractor,
29 private restService: RestService
30 ) {}
31
32 addCommentThread (videoId: number | string, comment: VideoCommentCreate) {
33 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
1506307f 34 const normalizedComment = objectLineFeedToHtml(comment, 'text')
4635f59d 35
c199c427 36 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
db400f44 37 .pipe(
c199c427 38 map(data => this.extractVideoComment(data.comment)),
e4f0e92e 39 catchError(err => this.restExtractor.handleError(err))
db400f44 40 )
4635f59d
C
41 }
42
43 addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) {
44 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId
1506307f 45 const normalizedComment = objectLineFeedToHtml(comment, 'text')
4635f59d 46
c199c427 47 return this.authHttp.post<{ comment: VideoCommentServerModel }>(url, normalizedComment)
db400f44 48 .pipe(
c199c427 49 map(data => this.extractVideoComment(data.comment)),
e4f0e92e 50 catchError(err => this.restExtractor.handleError(err))
db400f44 51 )
4635f59d
C
52 }
53
0f8d00e3
C
54 getAdminVideoComments (options: {
55 pagination: RestPagination,
56 sort: SortMeta,
57 search?: string
58 }): Observable<ResultList<VideoCommentAdmin>> {
59 const { pagination, sort, search } = options
f1273314 60 const url = VideoCommentService.BASE_VIDEO_URL + 'comments'
0f8d00e3
C
61
62 let params = new HttpParams()
63 params = this.restService.addRestGetParams(params, pagination, sort)
64
65 if (search) {
66 params = this.buildParamsFromSearch(search, params)
67 }
68
69 return this.authHttp.get<ResultList<VideoCommentAdmin>>(url, { params })
70 .pipe(
71 catchError(res => this.restExtractor.handleError(res))
72 )
73 }
74
93cae479 75 getVideoCommentThreads (parameters: {
4635f59d 76 videoId: number | string,
440d39c5 77 componentPagination: ComponentPaginationLight,
67ed6552 78 sort: string
e8f902c0 79 }): Observable<ResultList<VideoComment>> {
93cae479
C
80 const { videoId, componentPagination, sort } = parameters
81
4635f59d
C
82 const pagination = this.restService.componentPaginationToRestPagination(componentPagination)
83
84 let params = new HttpParams()
85 params = this.restService.addRestGetParams(params, pagination, sort)
86
87 const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads'
e8f902c0 88 return this.authHttp.get<ResultList<VideoComment>>(url, { params })
db400f44 89 .pipe(
e8f902c0 90 map(result => this.extractVideoComments(result)),
e4f0e92e 91 catchError(err => this.restExtractor.handleError(err))
db400f44 92 )
4635f59d
C
93 }
94
93cae479
C
95 getVideoThreadComments (parameters: {
96 videoId: number | string,
97 threadId: number
98 }): Observable<VideoCommentThreadTree> {
99 const { videoId, threadId } = parameters
4635f59d
C
100 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}`
101
102 return this.authHttp
be27ef3b 103 .get<VideoCommentThreadTreeServerModel>(url)
db400f44 104 .pipe(
be27ef3b 105 map(tree => this.extractVideoCommentTree(tree)),
e4f0e92e 106 catchError(err => this.restExtractor.handleError(err))
db400f44 107 )
4635f59d
C
108 }
109
4cb6d457
C
110 deleteVideoComment (videoId: number | string, commentId: number) {
111 const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comments/${commentId}`
112
113 return this.authHttp
db400f44
C
114 .delete(url)
115 .pipe(
116 map(this.restExtractor.extractDataBool),
e4f0e92e 117 catchError(err => this.restExtractor.handleError(err))
db400f44 118 )
4cb6d457
C
119 }
120
93991770
C
121 deleteVideoComments (comments: { videoId: number | string, commentId: number }[]) {
122 return from(comments)
123 .pipe(
124 concatMap(c => this.deleteVideoComment(c.videoId, c.commentId)),
125 toArray()
126 )
127 }
128
53877968
C
129 getVideoCommentsFeeds (videoUUID?: string) {
130 const feeds = [
131 {
132 format: FeedFormat.RSS,
133 label: 'rss 2.0',
134 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.RSS.toLowerCase()
135 },
136 {
137 format: FeedFormat.ATOM,
138 label: 'atom 1.0',
139 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.ATOM.toLowerCase()
140 },
141 {
142 format: FeedFormat.JSON,
143 label: 'json 1.0',
144 url: VideoCommentService.BASE_FEEDS_URL + FeedFormat.JSON.toLowerCase()
145 }
146 ]
147
148 if (videoUUID !== undefined) {
149 for (const feed of feeds) {
150 feed.url += '?videoId=' + videoUUID
151 }
152 }
153
154 return feeds
155 }
156
4635f59d
C
157 private extractVideoComment (videoComment: VideoCommentServerModel) {
158 return new VideoComment(videoComment)
159 }
160
161 private extractVideoComments (result: ResultList<VideoCommentServerModel>) {
162 const videoCommentsJson = result.data
163 const totalComments = result.total
db400f44 164 const comments: VideoComment[] = []
4635f59d
C
165
166 for (const videoCommentJson of videoCommentsJson) {
167 comments.push(new VideoComment(videoCommentJson))
168 }
169
e8f902c0 170 return { data: comments, total: totalComments }
4635f59d
C
171 }
172
be27ef3b
C
173 private extractVideoCommentTree (tree: VideoCommentThreadTreeServerModel) {
174 if (!tree) return tree as VideoCommentThreadTree
4635f59d
C
175
176 tree.comment = new VideoComment(tree.comment)
177 tree.children.forEach(c => this.extractVideoCommentTree(c))
178
be27ef3b 179 return tree as VideoCommentThreadTree
4635f59d 180 }
0f8d00e3
C
181
182 private buildParamsFromSearch (search: string, params: HttpParams) {
183 const filters = this.restService.parseQueryStringFilter(search, {
f1273314 184 isLocal: {
0f8d00e3
C
185 prefix: 'local:',
186 isBoolean: true,
187 handler: v => {
188 if (v === 'true') return v
189 if (v === 'false') return v
190
191 return undefined
192 }
193 },
194
195 searchAccount: { prefix: 'account:' },
196 searchVideo: { prefix: 'video:' }
197 })
198
199 return this.restService.addObjectParams(params, filters)
200 }
4635f59d 201}