diff options
author | Chocobozzz <me@florianbigard.com> | 2021-02-19 09:50:13 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-02-19 10:06:52 +0100 |
commit | 9d6b9d10ef8cbef39e89bc709285abffb0d8caa1 (patch) | |
tree | 3425b22556e00d1b15de15c72b2802cfc9374473 /client/src/app | |
parent | fae6e4da8f516a9d6c3bad9bf6f35811ccacbad8 (diff) | |
download | PeerTube-9d6b9d10ef8cbef39e89bc709285abffb0d8caa1.tar.gz PeerTube-9d6b9d10ef8cbef39e89bc709285abffb0d8caa1.tar.zst PeerTube-9d6b9d10ef8cbef39e89bc709285abffb0d8caa1.zip |
Fix video comments display with deleted comments
Diffstat (limited to 'client/src/app')
6 files changed, 37 insertions, 18 deletions
diff --git a/client/src/app/+videos/+video-watch/comment/video-comment.component.html b/client/src/app/+videos/+video-watch/comment/video-comment.component.html index 8847753a5..ba41b6f48 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comment.component.html +++ b/client/src/app/+videos/+video-watch/comment/video-comment.component.html | |||
@@ -1,4 +1,4 @@ | |||
1 | <div *ngIf="isNotDeletedOrDeletedWithReplies()" class="root-comment"> | 1 | <div *ngIf="isCommentDisplayed()" class="root-comment"> |
2 | <div class="left"> | 2 | <div class="left"> |
3 | <a *ngIf="!comment.isDeleted" [href]="comment.account.url" target="_blank" rel="noopener noreferrer"> | 3 | <a *ngIf="!comment.isDeleted" [href]="comment.account.url" target="_blank" rel="noopener noreferrer"> |
4 | <img | 4 | <img |
diff --git a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts index 0958b25c0..5c5d72b22 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comment.component.ts +++ b/client/src/app/+videos/+video-watch/comment/video-comment.component.ts | |||
@@ -62,6 +62,7 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
62 | if (!this.commentTree) { | 62 | if (!this.commentTree) { |
63 | this.commentTree = { | 63 | this.commentTree = { |
64 | comment: this.comment, | 64 | comment: this.comment, |
65 | hasDisplayedChildren: false, | ||
65 | children: [] | 66 | children: [] |
66 | } | 67 | } |
67 | 68 | ||
@@ -70,6 +71,7 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
70 | 71 | ||
71 | this.commentTree.children.unshift({ | 72 | this.commentTree.children.unshift({ |
72 | comment: createdComment, | 73 | comment: createdComment, |
74 | hasDisplayedChildren: false, | ||
73 | children: [] | 75 | children: [] |
74 | }) | 76 | }) |
75 | 77 | ||
@@ -133,8 +135,11 @@ export class VideoCommentComponent implements OnInit, OnChanges { | |||
133 | ($event.target as HTMLImageElement).src = Account.GET_DEFAULT_AVATAR_URL() | 135 | ($event.target as HTMLImageElement).src = Account.GET_DEFAULT_AVATAR_URL() |
134 | } | 136 | } |
135 | 137 | ||
136 | isNotDeletedOrDeletedWithReplies () { | 138 | isCommentDisplayed () { |
137 | return !this.comment.isDeleted || this.comment.isDeleted && this.comment.totalReplies !== 0 | 139 | // Not deleted |
140 | return !this.comment.isDeleted || | ||
141 | this.comment.totalReplies !== 0 || // Or root comment thread has replies | ||
142 | (this.commentTree?.hasDisplayedChildren) // Or this is a reply that have other replies | ||
138 | } | 143 | } |
139 | 144 | ||
140 | private getUserIfNeeded (account: Account) { | 145 | private getUserIfNeeded (account: Account) { |
diff --git a/client/src/app/+videos/+video-watch/comment/video-comments.component.html b/client/src/app/+videos/+video-watch/comment/video-comments.component.html index f9ebfcc1f..4a6426d30 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comments.component.html +++ b/client/src/app/+videos/+video-watch/comment/video-comments.component.html | |||
@@ -1,10 +1,10 @@ | |||
1 | <div> | 1 | <div> |
2 | <div class="title-block"> | 2 | <div class="title-block"> |
3 | <h2 class="title-page title-page-single"> | 3 | <h2 class="title-page title-page-single"> |
4 | <ng-container *ngIf="componentPagination.totalItems > 0; then hasComments; else noComments"></ng-container> | 4 | <ng-container *ngIf="totalNotDeletedComments > 0; then hasComments; else noComments"></ng-container> |
5 | <ng-template #hasComments> | 5 | <ng-template #hasComments> |
6 | <ng-container i18n *ngIf="componentPagination.totalItems === 1; else manyComments">1 Comment</ng-container> | 6 | <ng-container i18n *ngIf="totalNotDeletedComments === 1; else manyComments">1 Comment</ng-container> |
7 | <ng-template i18n #manyComments>{{ componentPagination.totalItems }} Comments</ng-template> | 7 | <ng-template i18n #manyComments>{{ totalNotDeletedComments }} Comments</ng-template> |
8 | </ng-template> | 8 | </ng-template> |
9 | <ng-template i18n #noComments>Comments</ng-template> | 9 | <ng-template i18n #noComments>Comments</ng-template> |
10 | </h2> | 10 | </h2> |
@@ -30,7 +30,7 @@ | |||
30 | [textValue]="commentThreadRedraftValue" | 30 | [textValue]="commentThreadRedraftValue" |
31 | ></my-video-comment-add> | 31 | ></my-video-comment-add> |
32 | 32 | ||
33 | <div *ngIf="componentPagination.totalItems === 0 && comments.length === 0" i18n>No comments.</div> | 33 | <div *ngIf="totalNotDeletedComments === 0 && comments.length === 0" i18n>No comments.</div> |
34 | 34 | ||
35 | <div | 35 | <div |
36 | class="comment-threads" | 36 | class="comment-threads" |
diff --git a/client/src/app/+videos/+video-watch/comment/video-comments.component.ts b/client/src/app/+videos/+video-watch/comment/video-comments.component.ts index f83a73ccd..d36dd9e34 100644 --- a/client/src/app/+videos/+video-watch/comment/video-comments.component.ts +++ b/client/src/app/+videos/+video-watch/comment/video-comments.component.ts | |||
@@ -21,15 +21,20 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
21 | 21 | ||
22 | comments: VideoComment[] = [] | 22 | comments: VideoComment[] = [] |
23 | highlightedThread: VideoComment | 23 | highlightedThread: VideoComment |
24 | |||
24 | sort = '-createdAt' | 25 | sort = '-createdAt' |
26 | |||
25 | componentPagination: ComponentPagination = { | 27 | componentPagination: ComponentPagination = { |
26 | currentPage: 1, | 28 | currentPage: 1, |
27 | itemsPerPage: 10, | 29 | itemsPerPage: 10, |
28 | totalItems: null | 30 | totalItems: null |
29 | } | 31 | } |
32 | totalNotDeletedComments: number | ||
33 | |||
30 | inReplyToCommentId: number | 34 | inReplyToCommentId: number |
31 | commentReplyRedraftValue: string | 35 | commentReplyRedraftValue: string |
32 | commentThreadRedraftValue: string | 36 | commentThreadRedraftValue: string |
37 | |||
33 | threadComments: { [ id: number ]: VideoCommentThreadTree } = {} | 38 | threadComments: { [ id: number ]: VideoCommentThreadTree } = {} |
34 | threadLoading: { [ id: number ]: boolean } = {} | 39 | threadLoading: { [ id: number ]: boolean } = {} |
35 | 40 | ||
@@ -122,8 +127,8 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
122 | obs.subscribe( | 127 | obs.subscribe( |
123 | res => { | 128 | res => { |
124 | this.comments = this.comments.concat(res.data) | 129 | this.comments = this.comments.concat(res.data) |
125 | // Client does not display removed comments | 130 | this.componentPagination.totalItems = res.total |
126 | this.componentPagination.totalItems = res.total - this.comments.filter(c => c.isDeleted).length | 131 | this.totalNotDeletedComments = res.totalNotDeletedComments |
127 | 132 | ||
128 | this.onDataSubject.next(res.data) | 133 | this.onDataSubject.next(res.data) |
129 | this.hooks.runAction('action:video-watch.video-threads.loaded', 'video-watch', { data: this.componentPagination }) | 134 | this.hooks.runAction('action:video-watch.video-threads.loaded', 'video-watch', { data: this.componentPagination }) |
@@ -241,6 +246,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy { | |||
241 | this.inReplyToCommentId = undefined | 246 | this.inReplyToCommentId = undefined |
242 | this.componentPagination.currentPage = 1 | 247 | this.componentPagination.currentPage = 1 |
243 | this.componentPagination.totalItems = null | 248 | this.componentPagination.totalItems = null |
249 | this.totalNotDeletedComments = null | ||
244 | 250 | ||
245 | this.syndicationItems = this.videoCommentService.getVideoCommentsFeeds(this.video.uuid) | 251 | this.syndicationItems = this.videoCommentService.getVideoCommentsFeeds(this.video.uuid) |
246 | this.loadMoreThreads() | 252 | this.loadMoreThreads() |
diff --git a/client/src/app/shared/shared-video-comment/video-comment-thread-tree.model.ts b/client/src/app/shared/shared-video-comment/video-comment-thread-tree.model.ts index 7c2aaeadd..9956c88a6 100644 --- a/client/src/app/shared/shared-video-comment/video-comment-thread-tree.model.ts +++ b/client/src/app/shared/shared-video-comment/video-comment-thread-tree.model.ts | |||
@@ -3,5 +3,6 @@ import { VideoComment } from './video-comment.model' | |||
3 | 3 | ||
4 | export class VideoCommentThreadTree implements VideoCommentThreadTreeServerModel { | 4 | export class VideoCommentThreadTree implements VideoCommentThreadTreeServerModel { |
5 | comment: VideoComment | 5 | comment: VideoComment |
6 | hasDisplayedChildren: boolean | ||
6 | children: VideoCommentThreadTree[] | 7 | children: VideoCommentThreadTree[] |
7 | } | 8 | } |
diff --git a/client/src/app/shared/shared-video-comment/video-comment.service.ts b/client/src/app/shared/shared-video-comment/video-comment.service.ts index c107a33ab..0f09778df 100644 --- a/client/src/app/shared/shared-video-comment/video-comment.service.ts +++ b/client/src/app/shared/shared-video-comment/video-comment.service.ts | |||
@@ -8,6 +8,7 @@ import { objectLineFeedToHtml } from '@app/helpers' | |||
8 | import { | 8 | import { |
9 | FeedFormat, | 9 | FeedFormat, |
10 | ResultList, | 10 | ResultList, |
11 | ThreadsResultList, | ||
11 | VideoComment as VideoCommentServerModel, | 12 | VideoComment as VideoCommentServerModel, |
12 | VideoCommentAdmin, | 13 | VideoCommentAdmin, |
13 | VideoCommentCreate, | 14 | VideoCommentCreate, |
@@ -76,7 +77,7 @@ export class VideoCommentService { | |||
76 | videoId: number | string, | 77 | videoId: number | string, |
77 | componentPagination: ComponentPaginationLight, | 78 | componentPagination: ComponentPaginationLight, |
78 | sort: string | 79 | sort: string |
79 | }): Observable<ResultList<VideoComment>> { | 80 | }): Observable<ThreadsResultList<VideoComment>> { |
80 | const { videoId, componentPagination, sort } = parameters | 81 | const { videoId, componentPagination, sort } = parameters |
81 | 82 | ||
82 | const pagination = this.restService.componentPaginationToRestPagination(componentPagination) | 83 | const pagination = this.restService.componentPaginationToRestPagination(componentPagination) |
@@ -85,7 +86,7 @@ export class VideoCommentService { | |||
85 | params = this.restService.addRestGetParams(params, pagination, sort) | 86 | params = this.restService.addRestGetParams(params, pagination, sort) |
86 | 87 | ||
87 | const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' | 88 | const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' |
88 | return this.authHttp.get<ResultList<VideoComment>>(url, { params }) | 89 | return this.authHttp.get<ThreadsResultList<VideoComment>>(url, { params }) |
89 | .pipe( | 90 | .pipe( |
90 | map(result => this.extractVideoComments(result)), | 91 | map(result => this.extractVideoComments(result)), |
91 | catchError(err => this.restExtractor.handleError(err)) | 92 | catchError(err => this.restExtractor.handleError(err)) |
@@ -158,7 +159,7 @@ export class VideoCommentService { | |||
158 | return new VideoComment(videoComment) | 159 | return new VideoComment(videoComment) |
159 | } | 160 | } |
160 | 161 | ||
161 | private extractVideoComments (result: ResultList<VideoCommentServerModel>) { | 162 | private extractVideoComments (result: ThreadsResultList<VideoCommentServerModel>) { |
162 | const videoCommentsJson = result.data | 163 | const videoCommentsJson = result.data |
163 | const totalComments = result.total | 164 | const totalComments = result.total |
164 | const comments: VideoComment[] = [] | 165 | const comments: VideoComment[] = [] |
@@ -167,16 +168,22 @@ export class VideoCommentService { | |||
167 | comments.push(new VideoComment(videoCommentJson)) | 168 | comments.push(new VideoComment(videoCommentJson)) |
168 | } | 169 | } |
169 | 170 | ||
170 | return { data: comments, total: totalComments } | 171 | return { data: comments, total: totalComments, totalNotDeletedComments: result.totalNotDeletedComments } |
171 | } | 172 | } |
172 | 173 | ||
173 | private extractVideoCommentTree (tree: VideoCommentThreadTreeServerModel) { | 174 | private extractVideoCommentTree (serverTree: VideoCommentThreadTreeServerModel): VideoCommentThreadTree { |
174 | if (!tree) return tree as VideoCommentThreadTree | 175 | if (!serverTree) return null |
175 | 176 | ||
176 | tree.comment = new VideoComment(tree.comment) | 177 | const tree = { |
177 | tree.children.forEach(c => this.extractVideoCommentTree(c)) | 178 | comment: new VideoComment(serverTree.comment), |
179 | children: serverTree.children.map(c => this.extractVideoCommentTree(c)) | ||
180 | } | ||
181 | |||
182 | const hasDisplayedChildren = tree.children.length === 0 | ||
183 | ? !tree.comment.isDeleted | ||
184 | : tree.children.some(c => c.hasDisplayedChildren) | ||
178 | 185 | ||
179 | return tree as VideoCommentThreadTree | 186 | return Object.assign(tree, { hasDisplayedChildren }) |
180 | } | 187 | } |
181 | 188 | ||
182 | private buildParamsFromSearch (search: string, params: HttpParams) { | 189 | private buildParamsFromSearch (search: string, params: HttpParams) { |