diff options
author | Chocobozzz <me@florianbigard.com> | 2017-12-27 16:11:53 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2017-12-27 16:11:53 +0100 |
commit | 4635f59d7c3fea4b97029f10886c62fdf38b2084 (patch) | |
tree | d97357a00042bbfb33c4177ee24c01171d28dfce /client/src/app/videos/+video-watch/comment | |
parent | ea44f375f5d3da06ca0aebfe871b9f924a26ec29 (diff) | |
download | PeerTube-4635f59d7c3fea4b97029f10886c62fdf38b2084.tar.gz PeerTube-4635f59d7c3fea4b97029f10886c62fdf38b2084.tar.zst PeerTube-4635f59d7c3fea4b97029f10886c62fdf38b2084.zip |
Add video comment components
Diffstat (limited to 'client/src/app/videos/+video-watch/comment')
11 files changed, 508 insertions, 0 deletions
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.html b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html new file mode 100644 index 000000000..792053614 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.html | |||
@@ -0,0 +1,15 @@ | |||
1 | <form novalidate [formGroup]="form" (ngSubmit)="formValidated()"> | ||
2 | <div class="form-group"> | ||
3 | <textarea placeholder="Add comment..." formControlName="text" [ngClass]="{ 'input-error': formErrors['text'] }"> | ||
4 | </textarea> | ||
5 | <div *ngIf="formErrors.text" class="form-error"> | ||
6 | {{ formErrors.text }} | ||
7 | </div> | ||
8 | </div> | ||
9 | |||
10 | <div class="submit-comment"> | ||
11 | <button *ngIf="isAddButtonDisplayed()" [ngClass]="{ disabled: !form.valid }"> | ||
12 | Post comment | ||
13 | </button> | ||
14 | </div> | ||
15 | </form> | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss b/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss new file mode 100644 index 000000000..9661062e8 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.scss | |||
@@ -0,0 +1,20 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .form-group { | ||
5 | margin-bottom: 10px; | ||
6 | } | ||
7 | |||
8 | textarea { | ||
9 | @include peertube-textarea(100%, 150px); | ||
10 | } | ||
11 | |||
12 | .submit-comment { | ||
13 | display: flex; | ||
14 | justify-content: end; | ||
15 | |||
16 | button { | ||
17 | @include peertube-button; | ||
18 | @include orange-button | ||
19 | } | ||
20 | } | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts new file mode 100644 index 000000000..5ad83fc47 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment-add.component.ts | |||
@@ -0,0 +1,84 @@ | |||
1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' | ||
2 | import { FormBuilder, FormGroup } from '@angular/forms' | ||
3 | import { NotificationsService } from 'angular2-notifications' | ||
4 | import { Observable } from 'rxjs/Observable' | ||
5 | import { VideoCommentCreate } from '../../../../../../shared/models/videos/video-comment.model' | ||
6 | import { FormReactive } from '../../../shared' | ||
7 | import { VIDEO_COMMENT_TEXT } from '../../../shared/forms/form-validators/video-comment' | ||
8 | import { Video } from '../../../shared/video/video.model' | ||
9 | import { VideoComment } from './video-comment.model' | ||
10 | import { VideoCommentService } from './video-comment.service' | ||
11 | |||
12 | @Component({ | ||
13 | selector: 'my-video-comment-add', | ||
14 | templateUrl: './video-comment-add.component.html', | ||
15 | styleUrls: ['./video-comment-add.component.scss'] | ||
16 | }) | ||
17 | export class VideoCommentAddComponent extends FormReactive implements OnInit { | ||
18 | @Input() video: Video | ||
19 | @Input() parentComment: VideoComment | ||
20 | |||
21 | @Output() commentCreated = new EventEmitter<VideoCommentCreate>() | ||
22 | |||
23 | form: FormGroup | ||
24 | formErrors = { | ||
25 | 'text': '' | ||
26 | } | ||
27 | validationMessages = { | ||
28 | 'text': VIDEO_COMMENT_TEXT.MESSAGES | ||
29 | } | ||
30 | |||
31 | constructor ( | ||
32 | private formBuilder: FormBuilder, | ||
33 | private notificationsService: NotificationsService, | ||
34 | private videoCommentService: VideoCommentService | ||
35 | ) { | ||
36 | super() | ||
37 | } | ||
38 | |||
39 | buildForm () { | ||
40 | this.form = this.formBuilder.group({ | ||
41 | text: [ '', VIDEO_COMMENT_TEXT.VALIDATORS ] | ||
42 | }) | ||
43 | |||
44 | this.form.valueChanges.subscribe(data => this.onValueChanged(data)) | ||
45 | } | ||
46 | |||
47 | ngOnInit () { | ||
48 | this.buildForm() | ||
49 | } | ||
50 | |||
51 | formValidated () { | ||
52 | const commentCreate: VideoCommentCreate = this.form.value | ||
53 | let obs: Observable<any> | ||
54 | |||
55 | if (this.parentComment) { | ||
56 | obs = this.addCommentReply(commentCreate) | ||
57 | } else { | ||
58 | obs = this.addCommentThread(commentCreate) | ||
59 | } | ||
60 | |||
61 | obs.subscribe( | ||
62 | comment => { | ||
63 | this.commentCreated.emit(comment) | ||
64 | this.form.reset() | ||
65 | }, | ||
66 | |||
67 | err => this.notificationsService.error('Error', err.text) | ||
68 | ) | ||
69 | } | ||
70 | |||
71 | isAddButtonDisplayed () { | ||
72 | return this.form.value['text'] | ||
73 | } | ||
74 | |||
75 | private addCommentReply (commentCreate: VideoCommentCreate) { | ||
76 | return this.videoCommentService | ||
77 | .addCommentReply(this.video.id, this.parentComment.id, commentCreate) | ||
78 | } | ||
79 | |||
80 | private addCommentThread (commentCreate: VideoCommentCreate) { | ||
81 | return this.videoCommentService | ||
82 | .addCommentThread(this.video.id, commentCreate) | ||
83 | } | ||
84 | } | ||
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 new file mode 100644 index 000000000..9608a1033 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.html | |||
@@ -0,0 +1,29 @@ | |||
1 | <div class="comment"> | ||
2 | <div class="comment-account-date"> | ||
3 | <div class="comment-account">{{ comment.by }}</div> | ||
4 | <div class="comment-date">{{ comment.createdAt | myFromNow }}</div> | ||
5 | </div> | ||
6 | <div>{{ comment.text }}</div> | ||
7 | |||
8 | <div class="comment-actions"> | ||
9 | <div *ngIf="isUserLoggedIn()" (click)="onWantToReply()" class="comment-action-reply">Reply</div> | ||
10 | </div> | ||
11 | |||
12 | <my-video-comment-add | ||
13 | *ngIf="isUserLoggedIn() && inReplyToCommentId === comment.id" [video]="video" [parentComment]="comment" | ||
14 | (commentCreated)="onCommentReplyCreated($event)" | ||
15 | ></my-video-comment-add> | ||
16 | |||
17 | <div *ngIf="commentTree" class="children"> | ||
18 | <div *ngFor="let commentChild of commentTree.children"> | ||
19 | <my-video-comment | ||
20 | [comment]="commentChild.comment" | ||
21 | [video]="video" | ||
22 | [inReplyToCommentId]="inReplyToCommentId" | ||
23 | [commentTree]="commentChild" | ||
24 | (wantedToReply)="onWantedToReply($event)" | ||
25 | (resetReply)="onResetReply()" | ||
26 | ></my-video-comment> | ||
27 | </div> | ||
28 | </div> | ||
29 | </div> | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.component.scss b/client/src/app/videos/+video-watch/comment/video-comment.component.scss new file mode 100644 index 000000000..7e1a32f48 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.scss | |||
@@ -0,0 +1,38 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .comment { | ||
5 | font-size: 15px; | ||
6 | margin-top: 30px; | ||
7 | |||
8 | .comment-account-date { | ||
9 | display: flex; | ||
10 | margin-bottom: 4px; | ||
11 | |||
12 | .comment-account { | ||
13 | font-weight: $font-bold; | ||
14 | } | ||
15 | |||
16 | .comment-date { | ||
17 | color: #585858; | ||
18 | margin-left: 10px; | ||
19 | } | ||
20 | } | ||
21 | |||
22 | .comment-actions { | ||
23 | margin: 10px 0; | ||
24 | |||
25 | .comment-action-reply { | ||
26 | color: #585858; | ||
27 | cursor: pointer; | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | .children { | ||
33 | margin-left: 20px; | ||
34 | |||
35 | .comment { | ||
36 | margin-top: 15px; | ||
37 | } | ||
38 | } | ||
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 new file mode 100644 index 000000000..b8e2acd52 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment.component.ts | |||
@@ -0,0 +1,67 @@ | |||
1 | import { Component, EventEmitter, Input, Output } from '@angular/core' | ||
2 | import { NotificationsService } from 'angular2-notifications' | ||
3 | import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' | ||
4 | import { AuthService } from '../../../core/auth' | ||
5 | import { User } from '../../../shared/users' | ||
6 | import { Video } from '../../../shared/video/video.model' | ||
7 | import { VideoComment } from './video-comment.model' | ||
8 | import { VideoCommentService } from './video-comment.service' | ||
9 | |||
10 | @Component({ | ||
11 | selector: 'my-video-comment', | ||
12 | templateUrl: './video-comment.component.html', | ||
13 | styleUrls: ['./video-comment.component.scss'] | ||
14 | }) | ||
15 | export class VideoCommentComponent { | ||
16 | @Input() video: Video | ||
17 | @Input() comment: VideoComment | ||
18 | @Input() commentTree: VideoCommentThreadTree | ||
19 | @Input() inReplyToCommentId: number | ||
20 | |||
21 | @Output() wantedToReply = new EventEmitter<VideoComment>() | ||
22 | @Output() resetReply = new EventEmitter() | ||
23 | |||
24 | constructor (private authService: AuthService, | ||
25 | private notificationsService: NotificationsService, | ||
26 | private videoCommentService: VideoCommentService) { | ||
27 | } | ||
28 | |||
29 | onCommentReplyCreated (comment: VideoComment) { | ||
30 | this.videoCommentService.addCommentReply(this.video.id, this.comment.id, comment) | ||
31 | .subscribe( | ||
32 | createdComment => { | ||
33 | if (!this.commentTree) { | ||
34 | this.commentTree = { | ||
35 | comment: this.comment, | ||
36 | children: [] | ||
37 | } | ||
38 | } | ||
39 | |||
40 | this.commentTree.children.push({ | ||
41 | comment: createdComment, | ||
42 | children: [] | ||
43 | }) | ||
44 | this.resetReply.emit() | ||
45 | }, | ||
46 | |||
47 | err => this.notificationsService.error('Error', err.message) | ||
48 | ) | ||
49 | } | ||
50 | |||
51 | onWantToReply () { | ||
52 | this.wantedToReply.emit(this.comment) | ||
53 | } | ||
54 | |||
55 | isUserLoggedIn () { | ||
56 | return this.authService.isLoggedIn() | ||
57 | } | ||
58 | |||
59 | // Event from child comment | ||
60 | onWantedToReply (comment: VideoComment) { | ||
61 | this.wantedToReply.emit(comment) | ||
62 | } | ||
63 | |||
64 | onResetReply () { | ||
65 | this.resetReply.emit() | ||
66 | } | ||
67 | } | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.model.ts b/client/src/app/videos/+video-watch/comment/video-comment.model.ts new file mode 100644 index 000000000..df7d5244c --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment.model.ts | |||
@@ -0,0 +1,38 @@ | |||
1 | import { VideoComment as VideoCommentServerModel } from '../../../../../../shared/models/videos/video-comment.model' | ||
2 | |||
3 | export class VideoComment implements VideoCommentServerModel { | ||
4 | id: number | ||
5 | url: string | ||
6 | text: string | ||
7 | threadId: number | ||
8 | inReplyToCommentId: number | ||
9 | videoId: number | ||
10 | createdAt: Date | string | ||
11 | updatedAt: Date | string | ||
12 | account: { | ||
13 | name: string | ||
14 | host: string | ||
15 | } | ||
16 | totalReplies: number | ||
17 | |||
18 | by: string | ||
19 | |||
20 | private static createByString (account: string, serverHost: string) { | ||
21 | return account + '@' + serverHost | ||
22 | } | ||
23 | |||
24 | constructor (hash: VideoCommentServerModel) { | ||
25 | this.id = hash.id | ||
26 | this.url = hash.url | ||
27 | this.text = hash.text | ||
28 | this.threadId = hash.threadId | ||
29 | this.inReplyToCommentId = hash.inReplyToCommentId | ||
30 | this.videoId = hash.videoId | ||
31 | this.createdAt = new Date(hash.createdAt.toString()) | ||
32 | this.updatedAt = new Date(hash.updatedAt.toString()) | ||
33 | this.account = hash.account | ||
34 | this.totalReplies = hash.totalReplies | ||
35 | |||
36 | this.by = VideoComment.createByString(this.account.name, this.account.host) | ||
37 | } | ||
38 | } | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comment.service.ts b/client/src/app/videos/+video-watch/comment/video-comment.service.ts new file mode 100644 index 000000000..2fe6cc3e9 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comment.service.ts | |||
@@ -0,0 +1,93 @@ | |||
1 | import { HttpClient, HttpParams } from '@angular/common/http' | ||
2 | import { Injectable } from '@angular/core' | ||
3 | import 'rxjs/add/operator/catch' | ||
4 | import 'rxjs/add/operator/map' | ||
5 | import { Observable } from 'rxjs/Observable' | ||
6 | import { ResultList } from '../../../../../../shared/models' | ||
7 | import { | ||
8 | VideoComment as VideoCommentServerModel, VideoCommentCreate, | ||
9 | VideoCommentThreadTree | ||
10 | } from '../../../../../../shared/models/videos/video-comment.model' | ||
11 | import { environment } from '../../../../environments/environment' | ||
12 | import { RestExtractor, RestService } from '../../../shared/rest' | ||
13 | import { ComponentPagination } from '../../../shared/rest/component-pagination.model' | ||
14 | import { SortField } from '../../../shared/video/sort-field.type' | ||
15 | import { VideoComment } from './video-comment.model' | ||
16 | |||
17 | @Injectable() | ||
18 | export class VideoCommentService { | ||
19 | private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/' | ||
20 | |||
21 | constructor ( | ||
22 | private authHttp: HttpClient, | ||
23 | private restExtractor: RestExtractor, | ||
24 | private restService: RestService | ||
25 | ) {} | ||
26 | |||
27 | addCommentThread (videoId: number | string, comment: VideoCommentCreate) { | ||
28 | const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' | ||
29 | |||
30 | return this.authHttp.post(url, comment) | ||
31 | .map(data => this.extractVideoComment(data['comment'])) | ||
32 | .catch(this.restExtractor.handleError) | ||
33 | } | ||
34 | |||
35 | addCommentReply (videoId: number | string, inReplyToCommentId: number, comment: VideoCommentCreate) { | ||
36 | const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comments/' + inReplyToCommentId | ||
37 | |||
38 | return this.authHttp.post(url, comment) | ||
39 | .map(data => this.extractVideoComment(data['comment'])) | ||
40 | .catch(this.restExtractor.handleError) | ||
41 | } | ||
42 | |||
43 | getVideoCommentThreads ( | ||
44 | videoId: number | string, | ||
45 | componentPagination: ComponentPagination, | ||
46 | sort: SortField | ||
47 | ): Observable<{ comments: VideoComment[], totalComments: number}> { | ||
48 | const pagination = this.restService.componentPaginationToRestPagination(componentPagination) | ||
49 | |||
50 | let params = new HttpParams() | ||
51 | params = this.restService.addRestGetParams(params, pagination, sort) | ||
52 | |||
53 | const url = VideoCommentService.BASE_VIDEO_URL + videoId + '/comment-threads' | ||
54 | return this.authHttp | ||
55 | .get(url, { params }) | ||
56 | .map(this.extractVideoComments) | ||
57 | .catch((res) => this.restExtractor.handleError(res)) | ||
58 | } | ||
59 | |||
60 | getVideoThreadComments (videoId: number | string, threadId: number): Observable<VideoCommentThreadTree> { | ||
61 | const url = `${VideoCommentService.BASE_VIDEO_URL + videoId}/comment-threads/${threadId}` | ||
62 | |||
63 | return this.authHttp | ||
64 | .get(url) | ||
65 | .map(tree => this.extractVideoCommentTree(tree as VideoCommentThreadTree)) | ||
66 | .catch((res) => this.restExtractor.handleError(res)) | ||
67 | } | ||
68 | |||
69 | private extractVideoComment (videoComment: VideoCommentServerModel) { | ||
70 | return new VideoComment(videoComment) | ||
71 | } | ||
72 | |||
73 | private extractVideoComments (result: ResultList<VideoCommentServerModel>) { | ||
74 | const videoCommentsJson = result.data | ||
75 | const totalComments = result.total | ||
76 | const comments = [] | ||
77 | |||
78 | for (const videoCommentJson of videoCommentsJson) { | ||
79 | comments.push(new VideoComment(videoCommentJson)) | ||
80 | } | ||
81 | |||
82 | return { comments, totalComments } | ||
83 | } | ||
84 | |||
85 | private extractVideoCommentTree (tree: VideoCommentThreadTree) { | ||
86 | if (!tree) return tree | ||
87 | |||
88 | tree.comment = new VideoComment(tree.comment) | ||
89 | tree.children.forEach(c => this.extractVideoCommentTree(c)) | ||
90 | |||
91 | return tree | ||
92 | } | ||
93 | } | ||
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 new file mode 100644 index 000000000..9d7581269 --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.html | |||
@@ -0,0 +1,31 @@ | |||
1 | <div> | ||
2 | <div class="title-page title-page-single"> | ||
3 | Comments | ||
4 | </div> | ||
5 | |||
6 | <my-video-comment-add | ||
7 | *ngIf="isUserLoggedIn()" | ||
8 | [video]="video" | ||
9 | (commentCreated)="onCommentThreadCreated($event)" | ||
10 | ></my-video-comment-add> | ||
11 | |||
12 | <div class="comment-threads"> | ||
13 | <div *ngFor="let comment of comments"> | ||
14 | <my-video-comment | ||
15 | [comment]="comment" | ||
16 | [video]="video" | ||
17 | [inReplyToCommentId]="inReplyToCommentId" | ||
18 | [commentTree]="threadComments[comment.id]" | ||
19 | (wantedToReply)="onWantedToReply($event)" | ||
20 | (resetReply)="onResetReply()" | ||
21 | ></my-video-comment> | ||
22 | |||
23 | <div *ngIf="comment.totalReplies !== 0 && !threadComments[comment.id]" (click)="viewReplies(comment)" class="view-replies"> | ||
24 | View all {{ comment.totalReplies }} replies | ||
25 | |||
26 | <span *ngIf="!threadLoading[comment.id]" class="glyphicon glyphicon-menu-down"></span> | ||
27 | <my-loader class="comment-thread-loading" [loading]="threadLoading[comment.id]"></my-loader> | ||
28 | </div> | ||
29 | </div> | ||
30 | </div> | ||
31 | </div> | ||
diff --git a/client/src/app/videos/+video-watch/comment/video-comments.component.scss b/client/src/app/videos/+video-watch/comment/video-comments.component.scss new file mode 100644 index 000000000..2f6e4663b --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.scss | |||
@@ -0,0 +1,14 @@ | |||
1 | @import '_variables'; | ||
2 | @import '_mixins'; | ||
3 | |||
4 | .view-replies { | ||
5 | font-weight: $font-semibold; | ||
6 | font-size: 15px; | ||
7 | cursor: pointer; | ||
8 | } | ||
9 | |||
10 | .glyphicon, .comment-thread-loading { | ||
11 | margin-left: 5px; | ||
12 | display: inline-block; | ||
13 | font-size: 13px; | ||
14 | } | ||
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 new file mode 100644 index 000000000..32e0f2fbd --- /dev/null +++ b/client/src/app/videos/+video-watch/comment/video-comments.component.ts | |||
@@ -0,0 +1,79 @@ | |||
1 | import { Component, Input, OnInit } from '@angular/core' | ||
2 | import { NotificationsService } from 'angular2-notifications' | ||
3 | import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/video-comment.model' | ||
4 | import { AuthService } from '../../../core/auth' | ||
5 | import { ComponentPagination } from '../../../shared/rest/component-pagination.model' | ||
6 | import { User } from '../../../shared/users' | ||
7 | import { SortField } from '../../../shared/video/sort-field.type' | ||
8 | import { Video } from '../../../shared/video/video.model' | ||
9 | import { VideoComment } from './video-comment.model' | ||
10 | import { VideoCommentService } from './video-comment.service' | ||
11 | |||
12 | @Component({ | ||
13 | selector: 'my-video-comments', | ||
14 | templateUrl: './video-comments.component.html', | ||
15 | styleUrls: ['./video-comments.component.scss'] | ||
16 | }) | ||
17 | export class VideoCommentsComponent implements OnInit { | ||
18 | @Input() video: Video | ||
19 | @Input() user: User | ||
20 | |||
21 | comments: VideoComment[] = [] | ||
22 | sort: SortField = '-createdAt' | ||
23 | componentPagination: ComponentPagination = { | ||
24 | currentPage: 1, | ||
25 | itemsPerPage: 25, | ||
26 | totalItems: null | ||
27 | } | ||
28 | inReplyToCommentId: number | ||
29 | threadComments: { [ id: number ]: VideoCommentThreadTree } = {} | ||
30 | threadLoading: { [ id: number ]: boolean } = {} | ||
31 | |||
32 | constructor ( | ||
33 | private authService: AuthService, | ||
34 | private notificationsService: NotificationsService, | ||
35 | private videoCommentService: VideoCommentService | ||
36 | ) {} | ||
37 | |||
38 | ngOnInit () { | ||
39 | this.videoCommentService.getVideoCommentThreads(this.video.id, this.componentPagination, this.sort) | ||
40 | .subscribe( | ||
41 | res => { | ||
42 | this.comments = res.comments | ||
43 | this.componentPagination.totalItems = res.totalComments | ||
44 | }, | ||
45 | |||
46 | err => this.notificationsService.error('Error', err.message) | ||
47 | ) | ||
48 | } | ||
49 | |||
50 | viewReplies (comment: VideoComment) { | ||
51 | this.threadLoading[comment.id] = true | ||
52 | |||
53 | this.videoCommentService.getVideoThreadComments(this.video.id, comment.id) | ||
54 | .subscribe( | ||
55 | res => { | ||
56 | this.threadComments[comment.id] = res | ||
57 | this.threadLoading[comment.id] = false | ||
58 | }, | ||
59 | |||
60 | err => this.notificationsService.error('Error', err.message) | ||
61 | ) | ||
62 | } | ||
63 | |||
64 | onCommentThreadCreated (comment: VideoComment) { | ||
65 | this.comments.unshift(comment) | ||
66 | } | ||
67 | |||
68 | onWantedToReply (comment: VideoComment) { | ||
69 | this.inReplyToCommentId = comment.id | ||
70 | } | ||
71 | |||
72 | onResetReply () { | ||
73 | this.inReplyToCommentId = undefined | ||
74 | } | ||
75 | |||
76 | isUserLoggedIn () { | ||
77 | return this.authService.isLoggedIn() | ||
78 | } | ||
79 | } | ||