aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app')
-rw-r--r--client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html2
-rw-r--r--client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html39
-rw-r--r--client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.scss6
-rw-r--r--client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts18
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts1
-rw-r--r--client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts19
-rw-r--r--client/src/app/shared/shared.module.ts5
-rw-r--r--client/src/app/shared/video-blacklist/video-blacklist.service.ts6
-rw-r--r--client/src/app/shared/video/video-details.model.ts2
-rw-r--r--client/src/app/videos/+video-watch/modal/video-blacklist.component.html31
-rw-r--r--client/src/app/videos/+video-watch/modal/video-blacklist.component.scss6
-rw-r--r--client/src/app/videos/+video-watch/modal/video-blacklist.component.ts66
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html11
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.scss4
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts27
-rw-r--r--client/src/app/videos/+video-watch/video-watch.module.ts2
16 files changed, 197 insertions, 48 deletions
diff --git a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
index 08501d872..aa0e18c70 100644
--- a/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
+++ b/client/src/app/+admin/video-abuses/video-abuse-list/video-abuse-list.component.html
@@ -9,7 +9,7 @@
9 <ng-template pTemplate="header"> 9 <ng-template pTemplate="header">
10 <tr> 10 <tr>
11 <th style="width: 40px"></th> 11 <th style="width: 40px"></th>
12 <th i18n style="width: 80px;">State</th> 12 <th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th>
13 <th i18n>Reason</th> 13 <th i18n>Reason</th>
14 <th i18n>Reporter</th> 14 <th i18n>Reporter</th>
15 <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> 15 <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
index 04f0e3b5c..78989dc58 100644
--- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
+++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.html
@@ -4,30 +4,43 @@
4 4
5<p-table 5<p-table
6 [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage" 6 [value]="blacklist" [lazy]="true" [paginator]="true" [totalRecords]="totalRecords" [rows]="rowsPerPage"
7 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" 7 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
8> 8>
9 <ng-template pTemplate="header"> 9 <ng-template pTemplate="header">
10 <tr> 10 <tr>
11 <th i18n pSortableColumn="name">Name <p-sortIcon field="name"></p-sortIcon></th> 11 <th style="width: 40px"></th>
12 <th i18n>Description</th> 12 <th i18n pSortableColumn="name">Video name <p-sortIcon field="name"></p-sortIcon></th>
13 <th i18n pSortableColumn="views">Views <p-sortIcon field="views"></p-sortIcon></th>
14 <th i18n>NSFW</th> 13 <th i18n>NSFW</th>
15 <th i18n>UUID</th> 14 <th i18n>UUID</th>
16 <th i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> 15 <th i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
17 <th></th> 16 <th style="width: 50px;"></th>
18 </tr> 17 </tr>
19 </ng-template> 18 </ng-template>
20 19
21 <ng-template pTemplate="body" let-videoBlacklist> 20 <ng-template pTemplate="body" let-videoBlacklist let-expanded="expanded">
22 <tr> 21 <tr>
23 <td>{{ videoBlacklist.name }}</td> 22 <td>
24 <td>{{ videoBlacklist.description }}</td> 23 <span *ngIf="videoBlacklist.reason" class="expander" [pRowToggler]="videoBlacklist">
25 <td>{{ videoBlacklist.views }}</td> 24 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
26 <td>{{ videoBlacklist.nsfw }}</td> 25 </span>
27 <td>{{ videoBlacklist.uuid }}</td> 26 </td>
27
28 <td>{{ videoBlacklist.video.name }}</td>
29 <td>{{ videoBlacklist.video.nsfw }}</td>
30 <td>{{ videoBlacklist.video.uuid }}</td>
28 <td>{{ videoBlacklist.createdAt }}</td> 31 <td>{{ videoBlacklist.createdAt }}</td>
32
29 <td class="action-cell"> 33 <td class="action-cell">
30 <my-delete-button i18n-label label="Unblacklist" (click)="removeVideoFromBlacklist(videoBlacklist)"></my-delete-button> 34 <my-action-dropdown i18n-label label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"></my-action-dropdown>
35 </td>
36 </tr>
37 </ng-template>
38
39 <ng-template pTemplate="rowexpansion" let-videoBlacklist>
40 <tr class="blacklist-reason">
41 <td colspan="6">
42 <span i18n class="blacklist-reason-label">Blacklist reason:</span>
43 {{ videoBlacklist.reason }}
31 </td> 44 </td>
32 </tr> 45 </tr>
33 </ng-template> 46 </ng-template>
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.scss b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.scss
new file mode 100644
index 000000000..5265536ca
--- /dev/null
+++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.scss
@@ -0,0 +1,6 @@
1@import '_variables';
2@import '_mixins';
3
4.blacklist-reason-label {
5 font-weight: $font-semibold;
6} \ No newline at end of file
diff --git a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
index 143ec8406..00b0ac57e 100644
--- a/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
+++ b/client/src/app/+admin/video-blacklist/video-blacklist-list/video-blacklist-list.component.ts
@@ -5,11 +5,12 @@ import { ConfirmService } from '../../../core'
5import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared' 5import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared'
6import { BlacklistedVideo } from '../../../../../../shared' 6import { BlacklistedVideo } from '../../../../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '@app/shared/buttons/action-dropdown.component'
8 9
9@Component({ 10@Component({
10 selector: 'my-video-blacklist-list', 11 selector: 'my-video-blacklist-list',
11 templateUrl: './video-blacklist-list.component.html', 12 templateUrl: './video-blacklist-list.component.html',
12 styleUrls: [] 13 styleUrls: [ './video-blacklist-list.component.scss' ]
13}) 14})
14export class VideoBlacklistListComponent extends RestTable implements OnInit { 15export class VideoBlacklistListComponent extends RestTable implements OnInit {
15 blacklist: BlacklistedVideo[] = [] 16 blacklist: BlacklistedVideo[] = []
@@ -18,6 +19,8 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
18 sort: SortMeta = { field: 'createdAt', order: 1 } 19 sort: SortMeta = { field: 'createdAt', order: 1 }
19 pagination: RestPagination = { count: this.rowsPerPage, start: 0 } 20 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
20 21
22 videoBlacklistActions: DropdownAction<BlacklistedVideo>[] = []
23
21 constructor ( 24 constructor (
22 private notificationsService: NotificationsService, 25 private notificationsService: NotificationsService,
23 private confirmService: ConfirmService, 26 private confirmService: ConfirmService,
@@ -25,6 +28,13 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
25 private i18n: I18n 28 private i18n: I18n
26 ) { 29 ) {
27 super() 30 super()
31
32 this.videoBlacklistActions = [
33 {
34 label: this.i18n('Unblacklist'),
35 handler: videoBlacklist => this.removeVideoFromBlacklist(videoBlacklist)
36 }
37 ]
28 } 38 }
29 39
30 ngOnInit () { 40 ngOnInit () {
@@ -33,17 +43,17 @@ export class VideoBlacklistListComponent extends RestTable implements OnInit {
33 43
34 async removeVideoFromBlacklist (entry: BlacklistedVideo) { 44 async removeVideoFromBlacklist (entry: BlacklistedVideo) {
35 const confirmMessage = this.i18n( 45 const confirmMessage = this.i18n(
36 'Do you really want to remove this video from the blacklist ? It will be available again in the videos list.' 46 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
37 ) 47 )
38 48
39 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist')) 49 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist'))
40 if (res === false) return 50 if (res === false) return
41 51
42 this.videoBlacklistService.removeVideoFromBlacklist(entry.videoId).subscribe( 52 this.videoBlacklistService.removeVideoFromBlacklist(entry.video.id).subscribe(
43 () => { 53 () => {
44 this.notificationsService.success( 54 this.notificationsService.success(
45 this.i18n('Success'), 55 this.i18n('Success'),
46 this.i18n('Video {{name}} removed from the blacklist.', { name: entry.name }) 56 this.i18n('Video {{name}} removed from the blacklist.', { name: entry.video.name })
47 ) 57 )
48 this.loadData() 58 this.loadData()
49 }, 59 },
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index 60d735ef7..9bc7615ca 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -5,6 +5,7 @@ export * from './login-validators.service'
5export * from './reset-password-validators.service' 5export * from './reset-password-validators.service'
6export * from './user-validators.service' 6export * from './user-validators.service'
7export * from './video-abuse-validators.service' 7export * from './video-abuse-validators.service'
8export * from './video-blacklist-validators.service'
8export * from './video-channel-validators.service' 9export * from './video-channel-validators.service'
9export * from './video-comment-validators.service' 10export * from './video-comment-validators.service'
10export * from './video-validators.service' 11export * from './video-validators.service'
diff --git a/client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts b/client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts
new file mode 100644
index 000000000..07d1f264a
--- /dev/null
+++ b/client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts
@@ -0,0 +1,19 @@
1import { I18n } from '@ngx-translate/i18n-polyfill'
2import { Validators } from '@angular/forms'
3import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared'
5
6@Injectable()
7export class VideoBlacklistValidatorsService {
8 readonly VIDEO_BLACKLIST_REASON: BuildFormValidator
9
10 constructor (private i18n: I18n) {
11 this.VIDEO_BLACKLIST_REASON = {
12 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ],
13 MESSAGES: {
14 'minlength': this.i18n('Blacklist reason must be at least 2 characters long.'),
15 'maxlength': this.i18n('Blacklist reason cannot be more than 300 characters long.')
16 }
17 }
18 }
19}
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index ea7f2c887..722415a06 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -36,7 +36,7 @@ import {
36 ReactiveFileComponent, 36 ReactiveFileComponent,
37 ResetPasswordValidatorsService, 37 ResetPasswordValidatorsService,
38 UserValidatorsService, 38 UserValidatorsService,
39 VideoAbuseValidatorsService, 39 VideoAbuseValidatorsService, VideoBlacklistValidatorsService,
40 VideoChannelValidatorsService, 40 VideoChannelValidatorsService,
41 VideoCommentValidatorsService, 41 VideoCommentValidatorsService,
42 VideoValidatorsService 42 VideoValidatorsService
@@ -133,6 +133,7 @@ import { NgbDropdownModule, NgbModalModule, NgbPopoverModule, NgbTabsetModule, N
133 MarkdownService, 133 MarkdownService,
134 VideoChannelService, 134 VideoChannelService,
135 VideoCaptionService, 135 VideoCaptionService,
136 VideoImportService,
136 137
137 FormValidatorService, 138 FormValidatorService,
138 CustomConfigValidatorsService, 139 CustomConfigValidatorsService,
@@ -144,7 +145,7 @@ import { NgbDropdownModule, NgbModalModule, NgbPopoverModule, NgbTabsetModule, N
144 VideoCommentValidatorsService, 145 VideoCommentValidatorsService,
145 VideoValidatorsService, 146 VideoValidatorsService,
146 VideoCaptionsValidatorsService, 147 VideoCaptionsValidatorsService,
147 VideoImportService, 148 VideoBlacklistValidatorsService,
148 149
149 I18nPrimengCalendarService, 150 I18nPrimengCalendarService,
150 ScreenService, 151 ScreenService,
diff --git a/client/src/app/shared/video-blacklist/video-blacklist.service.ts b/client/src/app/shared/video-blacklist/video-blacklist.service.ts
index 040d82c9a..a014260b1 100644
--- a/client/src/app/shared/video-blacklist/video-blacklist.service.ts
+++ b/client/src/app/shared/video-blacklist/video-blacklist.service.ts
@@ -36,8 +36,10 @@ export class VideoBlacklistService {
36 ) 36 )
37 } 37 }
38 38
39 blacklistVideo (videoId: number) { 39 blacklistVideo (videoId: number, reason?: string) {
40 return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', {}) 40 const body = reason ? { reason } : {}
41
42 return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', body)
41 .pipe( 43 .pipe(
42 map(this.restExtractor.extractDataBool), 44 map(this.restExtractor.extractDataBool),
43 catchError(res => this.restExtractor.handleError(res)) 45 catchError(res => this.restExtractor.handleError(res))
diff --git a/client/src/app/shared/video/video-details.model.ts b/client/src/app/shared/video/video-details.model.ts
index e500ad6fc..bdcc0bbba 100644
--- a/client/src/app/shared/video/video-details.model.ts
+++ b/client/src/app/shared/video/video-details.model.ts
@@ -44,7 +44,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
44 } 44 }
45 45
46 isBlackistableBy (user: AuthUser) { 46 isBlackistableBy (user: AuthUser) {
47 return user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true && this.isLocal === false 47 return user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true
48 } 48 }
49 49
50 isUpdatableBy (user: AuthUser) { 50 isUpdatableBy (user: AuthUser) {
diff --git a/client/src/app/videos/+video-watch/modal/video-blacklist.component.html b/client/src/app/videos/+video-watch/modal/video-blacklist.component.html
new file mode 100644
index 000000000..c436501b4
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-blacklist.component.html
@@ -0,0 +1,31 @@
1<ng-template #modal>
2 <div class="modal-header">
3 <h4 i18n class="modal-title">Blacklist video</h4>
4 <span class="close" aria-label="Close" role="button" (click)="hide()"></span>
5 </div>
6
7 <div class="modal-body">
8
9 <form novalidate [formGroup]="form" (ngSubmit)="blacklist()">
10 <div class="form-group">
11 <textarea i18n-placeholder placeholder="Reason..." formControlName="reason" [ngClass]="{ 'input-error': formErrors['reason'] }">
12 </textarea>
13 <div *ngIf="formErrors.reason" class="form-error">
14 {{ formErrors.reason }}
15 </div>
16 </div>
17
18 <div class="form-group inputs">
19 <span i18n class="action-button action-button-cancel" (click)="hide()">
20 Cancel
21 </span>
22
23 <input
24 type="submit" i18n-value value="Submit" class="action-button-submit"
25 [disabled]="!form.valid"
26 >
27 </div>
28 </form>
29
30 </div>
31</ng-template>
diff --git a/client/src/app/videos/+video-watch/modal/video-blacklist.component.scss b/client/src/app/videos/+video-watch/modal/video-blacklist.component.scss
new file mode 100644
index 000000000..afcdb9a16
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-blacklist.component.scss
@@ -0,0 +1,6 @@
1@import 'variables';
2@import 'mixins';
3
4textarea {
5 @include peertube-textarea(100%, 100px);
6}
diff --git a/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts b/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts
new file mode 100644
index 000000000..2c123ebed
--- /dev/null
+++ b/client/src/app/videos/+video-watch/modal/video-blacklist.component.ts
@@ -0,0 +1,66 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { NotificationsService } from 'angular2-notifications'
3import { FormReactive, VideoBlacklistService, VideoBlacklistValidatorsService } from '../../../shared/index'
4import { VideoDetails } from '../../../shared/video/video-details.model'
5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
8import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
9import { RedirectService } from '@app/core'
10
11@Component({
12 selector: 'my-video-blacklist',
13 templateUrl: './video-blacklist.component.html',
14 styleUrls: [ './video-blacklist.component.scss' ]
15})
16export class VideoBlacklistComponent extends FormReactive implements OnInit {
17 @Input() video: VideoDetails = null
18
19 @ViewChild('modal') modal: NgbModal
20
21 error: string = null
22
23 private openedModal: NgbModalRef
24
25 constructor (
26 protected formValidatorService: FormValidatorService,
27 private modalService: NgbModal,
28 private videoBlacklistValidatorsService: VideoBlacklistValidatorsService,
29 private videoBlacklistService: VideoBlacklistService,
30 private notificationsService: NotificationsService,
31 private redirectService: RedirectService,
32 private i18n: I18n
33 ) {
34 super()
35 }
36
37 ngOnInit () {
38 this.buildForm({
39 reason: this.videoBlacklistValidatorsService.VIDEO_BLACKLIST_REASON
40 })
41 }
42
43 show () {
44 this.openedModal = this.modalService.open(this.modal, { keyboard: false })
45 }
46
47 hide () {
48 this.openedModal.close()
49 this.openedModal = null
50 }
51
52 blacklist () {
53 const reason = this.form.value[ 'reason' ] || undefined
54
55 this.videoBlacklistService.blacklistVideo(this.video.id, reason)
56 .subscribe(
57 () => {
58 this.notificationsService.success(this.i18n('Success'), this.i18n('Video blacklisted.'))
59 this.hide()
60 this.redirectService.redirectToHomepage()
61 },
62
63 err => this.notificationsService.error(this.i18n('Error'), err.message)
64 )
65 }
66}
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html
index dd0d628bd..f82f1c554 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -90,16 +90,16 @@
90 <span class="icon icon-alert"></span> <ng-container i18n>Report</ng-container> 90 <span class="icon icon-alert"></span> <ng-container i18n>Report</ng-container>
91 </a> 91 </a>
92 92
93 <a *ngIf="isVideoBlacklistable()" class="dropdown-item" i18n-title title="Blacklist this video" href="#" (click)="blacklistVideo($event)">
94 <span class="icon icon-blacklist"></span> <ng-container i18n>Blacklist</ng-container>
95 </a>
96
97 <a *ngIf="isVideoUpdatable()" class="dropdown-item" i18n-title title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]"> 93 <a *ngIf="isVideoUpdatable()" class="dropdown-item" i18n-title title="Update this video" href="#" [routerLink]="[ '/videos/update', video.uuid ]">
98 <span class="icon icon-edit"></span> <ng-container i18n>Update</ng-container> 94 <span class="icon icon-edit"></span> <ng-container i18n>Update</ng-container>
99 </a> 95 </a>
100 96
97 <a *ngIf="isVideoBlacklistable()" class="dropdown-item" i18n-title title="Blacklist this video" href="#" (click)="showBlacklistModal($event)">
98 <span class="icon icon-blacklist"></span> <ng-container i18n>Blacklist</ng-container>
99 </a>
100
101 <a *ngIf="isVideoRemovable()" class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)"> 101 <a *ngIf="isVideoRemovable()" class="dropdown-item" i18n-title title="Delete this video" href="#" (click)="removeVideo($event)">
102 <span class="icon icon-blacklist"></span> <ng-container i18n>Delete</ng-container> 102 <span class="icon icon-delete"></span> <ng-container i18n>Delete</ng-container>
103 </a> 103 </a>
104 </div> 104 </div>
105 </div> 105 </div>
@@ -205,4 +205,5 @@
205 <my-video-share #videoShareModal [video]="video"></my-video-share> 205 <my-video-share #videoShareModal [video]="video"></my-video-share>
206 <my-video-download #videoDownloadModal [video]="video"></my-video-download> 206 <my-video-download #videoDownloadModal [video]="video"></my-video-download>
207 <my-video-report #videoReportModal [video]="video"></my-video-report> 207 <my-video-report #videoReportModal [video]="video"></my-video-report>
208 <my-video-blacklist #videoBlacklistModal [video]="video"></my-video-blacklist>
208</ng-template> 209</ng-template>
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss
index 7d269b31f..e63ab7bbd 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -258,6 +258,10 @@
258 &.icon-blacklist { 258 &.icon-blacklist {
259 background-image: url('../../../assets/images/video/blacklist.svg'); 259 background-image: url('../../../assets/images/video/blacklist.svg');
260 } 260 }
261
262 &.icon-delete {
263 background-image: url('../../../assets/images/global/delete-black.svg');
264 }
261 } 265 }
262 } 266 }
263 } 267 }
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts
index 04bcc6cd1..878655d4a 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -21,6 +21,7 @@ import { MarkdownService } from '../shared'
21import { VideoDownloadComponent } from './modal/video-download.component' 21import { VideoDownloadComponent } from './modal/video-download.component'
22import { VideoReportComponent } from './modal/video-report.component' 22import { VideoReportComponent } from './modal/video-report.component'
23import { VideoShareComponent } from './modal/video-share.component' 23import { VideoShareComponent } from './modal/video-share.component'
24import { VideoBlacklistComponent } from './modal/video-blacklist.component'
24import { addContextMenu, getVideojsOptions, loadLocale } from '../../../assets/player/peertube-player' 25import { addContextMenu, getVideojsOptions, loadLocale } from '../../../assets/player/peertube-player'
25import { ServerService } from '@app/core' 26import { ServerService } from '@app/core'
26import { I18n } from '@ngx-translate/i18n-polyfill' 27import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -41,6 +42,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
41 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent 42 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent
42 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent 43 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
43 @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent 44 @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent
45 @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent
44 46
45 otherVideosDisplayed: Video[] = [] 47 otherVideosDisplayed: Video[] = []
46 48
@@ -156,26 +158,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
156 } 158 }
157 } 159 }
158 160
159 async blacklistVideo (event: Event) {
160 event.preventDefault()
161
162 const res = await this.confirmService.confirm(this.i18n('Do you really want to blacklist this video?'), this.i18n('Blacklist'))
163 if (res === false) return
164
165 this.videoBlacklistService.blacklistVideo(this.video.id)
166 .subscribe(
167 () => {
168 this.notificationsService.success(
169 this.i18n('Success'),
170 this.i18n('Video {{videoName}} had been blacklisted.', { videoName: this.video.name })
171 )
172 this.redirectService.redirectToHomepage()
173 },
174
175 error => this.notificationsService.error(this.i18n('Error'), error.message)
176 )
177 }
178
179 showMoreDescription () { 161 showMoreDescription () {
180 if (this.completeVideoDescription === undefined) { 162 if (this.completeVideoDescription === undefined) {
181 return this.loadCompleteDescription() 163 return this.loadCompleteDescription()
@@ -230,6 +212,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
230 this.videoDownloadModal.show() 212 this.videoDownloadModal.show()
231 } 213 }
232 214
215 showBlacklistModal (event: Event) {
216 event.preventDefault()
217 this.videoBlacklistModal.show()
218 }
219
233 isUserLoggedIn () { 220 isUserLoggedIn () {
234 return this.authService.isLoggedIn() 221 return this.authService.isLoggedIn()
235 } 222 }
diff --git a/client/src/app/videos/+video-watch/video-watch.module.ts b/client/src/app/videos/+video-watch/video-watch.module.ts
index 09d5133e4..7730919fe 100644
--- a/client/src/app/videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/videos/+video-watch/video-watch.module.ts
@@ -15,6 +15,7 @@ import { VideoWatchRoutingModule } from './video-watch-routing.module'
15import { VideoWatchComponent } from './video-watch.component' 15import { VideoWatchComponent } from './video-watch.component'
16import { NgxQRCodeModule } from 'ngx-qrcode2' 16import { NgxQRCodeModule } from 'ngx-qrcode2'
17import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap' 17import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
18import { VideoBlacklistComponent } from '@app/videos/+video-watch/modal/video-blacklist.component'
18 19
19@NgModule({ 20@NgModule({
20 imports: [ 21 imports: [
@@ -31,6 +32,7 @@ import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'
31 VideoDownloadComponent, 32 VideoDownloadComponent,
32 VideoShareComponent, 33 VideoShareComponent,
33 VideoReportComponent, 34 VideoReportComponent,
35 VideoBlacklistComponent,
34 VideoSupportComponent, 36 VideoSupportComponent,
35 VideoCommentsComponent, 37 VideoCommentsComponent,
36 VideoCommentAddComponent, 38 VideoCommentAddComponent,