aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-11-17 11:18:49 +0100
committerChocobozzz <me@florianbigard.com>2021-11-17 11:18:49 +0100
commit3cfa817672657df18260ece5b354efa0f3b6e317 (patch)
tree318a7113fac4fcf1e6d0f7888cda1939aeefc500 /client/src/app/shared
parent4bdff96d77c03e5cce6052188f69a65bf6ea5781 (diff)
downloadPeerTube-3cfa817672657df18260ece5b354efa0f3b6e317.tar.gz
PeerTube-3cfa817672657df18260ece5b354efa0f3b6e317.tar.zst
PeerTube-3cfa817672657df18260ece5b354efa0f3b6e317.zip
Add ability to bulk block videos
Diffstat (limited to 'client/src/app/shared')
-rw-r--r--client/src/app/shared/shared-abuse-list/abuse-list-table.component.html4
-rw-r--r--client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts2
-rw-r--r--client/src/app/shared/shared-moderation/video-block.component.html24
-rw-r--r--client/src/app/shared/shared-moderation/video-block.component.ts51
-rw-r--r--client/src/app/shared/shared-moderation/video-block.service.ts24
-rw-r--r--client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.html2
-rw-r--r--client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts2
7 files changed, 74 insertions, 35 deletions
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
index d0eef7d4b..0d75a21d7 100644
--- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
+++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html
@@ -77,10 +77,6 @@
77 77
78 <td *ngIf="abuse.video.deleted" class="c-hand" [pRowToggler]="abuse"> 78 <td *ngIf="abuse.video.deleted" class="c-hand" [pRowToggler]="abuse">
79 <div class="table-video" i18n-title title="Video was deleted"> 79 <div class="table-video" i18n-title title="Video was deleted">
80 <div class="table-video-image">
81 <span i18n>Deleted</span>
82 </div>
83
84 <div class="table-video-text"> 80 <div class="table-video-text">
85 <div> 81 <div>
86 {{ abuse.video.name }} 82 {{ abuse.video.name }}
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
index b902726fa..08cf297cc 100644
--- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
+++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts
@@ -338,7 +338,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit {
338 label: $localize`Block video`, 338 label: $localize`Block video`,
339 isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted, 339 isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted,
340 handler: abuse => { 340 handler: abuse => {
341 this.videoBlocklistService.blockVideo(abuse.video.id, undefined, abuse.video.channel.isLocal) 341 this.videoBlocklistService.blockVideo([ { videoId: abuse.video.id, unfederate: abuse.video.channel.isLocal } ])
342 .subscribe({ 342 .subscribe({
343 next: () => { 343 next: () => {
344 this.notifier.success($localize`Video blocked.`) 344 this.notifier.success($localize`Video blocked.`)
diff --git a/client/src/app/shared/shared-moderation/video-block.component.html b/client/src/app/shared/shared-moderation/video-block.component.html
index 5e9e8493c..e5793f2ca 100644
--- a/client/src/app/shared/shared-moderation/video-block.component.html
+++ b/client/src/app/shared/shared-moderation/video-block.component.html
@@ -1,7 +1,14 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title" *ngIf="!video.isLive">Block video "{{ video.name }}"</h4> 3 <ng-container *ngIf="isMultiple()">
4 <h4 i18n class="modal-title" *ngIf="video.isLive">Block live "{{ video.name }}"</h4> 4 <h4 i18n class="modal-title">Block {{ videos.length }} videos</h4>
5 </ng-container>
6
7 <ng-container *ngIf="!isMultiple()">
8 <h4 i18n class="modal-title" *ngIf="!getSingleVideo().isLive">Block video "{{ getSingleVideo().name }}"</h4>
9 <h4 i18n class="modal-title" *ngIf="getSingleVideo().isLive">Block live "{{ getSingleVideo().name }}"</h4>
10 </ng-container>
11
5 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon> 12 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
6 </div> 13 </div>
7 14
@@ -18,19 +25,20 @@
18 </div> 25 </div>
19 </div> 26 </div>
20 27
21 <div class="form-group" *ngIf="video.isLocal"> 28 <div class="form-group" *ngIf="hasLocal()">
22 <my-peertube-checkbox 29 <my-peertube-checkbox
23 inputName="unfederate" formControlName="unfederate" 30 inputName="unfederate" formControlName="unfederate"
24 i18n-labelText labelText="Unfederate the video" 31 i18n-labelText labelText="Unfederate"
25 > 32 >
26 <ng-container ngProjectAs="description"> 33 <ng-container ngProjectAs="description">
27 <span i18n>This will ask remote instances to delete it</span> 34 <span *ngIf="isMultiple()" i18n>This will ask remote instances to delete local videos</span>
35 <span *ngIf="!isMultiple()" i18n>This will ask remote instances to delete this video</span>
28 </ng-container> 36 </ng-container>
29 </my-peertube-checkbox> 37 </my-peertube-checkbox>
30 </div> 38 </div>
31 39
32 <strong class="live-info" *ngIf="video.isLive" i18n> 40 <strong class="live-info" *ngIf="hasLive()" i18n>
33 Blocking this live will automatically terminate the live stream. 41 Blocking a live will automatically terminate the live stream.
34 </strong> 42 </strong>
35 43
36 <div class="form-group inputs"> 44 <div class="form-group inputs">
@@ -39,7 +47,7 @@
39 (click)="hide()" (key.enter)="hide()" 47 (click)="hide()" (key.enter)="hide()"
40 > 48 >
41 49
42 <input type="submit" i18n-value value="Submit" class="peertube-button orange-button" [disabled]="!form.valid" /> 50 <input type="submit" i18n-value value="Block" class="peertube-button orange-button" [disabled]="!form.valid" />
43 </div> 51 </div>
44 </form> 52 </form>
45 53
diff --git a/client/src/app/shared/shared-moderation/video-block.component.ts b/client/src/app/shared/shared-moderation/video-block.component.ts
index a6180dd14..400913f02 100644
--- a/client/src/app/shared/shared-moderation/video-block.component.ts
+++ b/client/src/app/shared/shared-moderation/video-block.component.ts
@@ -1,4 +1,4 @@
1import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'
2import { Notifier } from '@app/core' 2import { Notifier } from '@app/core'
3import { FormReactive, FormValidatorService } from '@app/shared/shared-forms' 3import { FormReactive, FormValidatorService } from '@app/shared/shared-forms'
4import { Video } from '@app/shared/shared-main' 4import { Video } from '@app/shared/shared-main'
@@ -13,12 +13,12 @@ import { VideoBlockService } from './video-block.service'
13 styleUrls: [ './video-block.component.scss' ] 13 styleUrls: [ './video-block.component.scss' ]
14}) 14})
15export class VideoBlockComponent extends FormReactive implements OnInit { 15export class VideoBlockComponent extends FormReactive implements OnInit {
16 @Input() video: Video = null
17
18 @ViewChild('modal', { static: true }) modal: NgbModal 16 @ViewChild('modal', { static: true }) modal: NgbModal
19 17
20 @Output() videoBlocked = new EventEmitter() 18 @Output() videoBlocked = new EventEmitter()
21 19
20 videos: Video[]
21
22 error: string = null 22 error: string = null
23 23
24 private openedModal: NgbModalRef 24 private openedModal: NgbModalRef
@@ -41,7 +41,25 @@ export class VideoBlockComponent extends FormReactive implements OnInit {
41 }, defaultValues) 41 }, defaultValues)
42 } 42 }
43 43
44 show () { 44 isMultiple () {
45 return this.videos.length > 1
46 }
47
48 getSingleVideo () {
49 return this.videos[0]
50 }
51
52 hasLive () {
53 return this.videos.some(v => v.isLive)
54 }
55
56 hasLocal () {
57 return this.videos.some(v => v.isLocal)
58 }
59
60 show (videos: Video[]) {
61 this.videos = videos
62
45 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false }) 63 this.openedModal = this.modalService.open(this.modal, { centered: true, keyboard: false })
46 } 64 }
47 65
@@ -51,17 +69,30 @@ export class VideoBlockComponent extends FormReactive implements OnInit {
51 } 69 }
52 70
53 block () { 71 block () {
54 const reason = this.form.value['reason'] || undefined 72 const options = this.videos.map(v => ({
55 const unfederate = this.video.isLocal ? this.form.value['unfederate'] : undefined 73 videoId: v.id,
74 reason: this.form.value['reason'] || undefined,
75 unfederate: v.isLocal
76 ? this.form.value['unfederate']
77 : undefined
78 }))
56 79
57 this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate) 80 this.videoBlocklistService.blockVideo(options)
58 .subscribe({ 81 .subscribe({
59 next: () => { 82 next: () => {
60 this.notifier.success($localize`Video blocked.`) 83 const message = this.isMultiple
84 ? $localize`Blocked ${this.videos.length} videos.`
85 : $localize`Blocked ${this.getSingleVideo().name}`
86
87 this.notifier.success(message)
61 this.hide() 88 this.hide()
62 89
63 this.video.blacklisted = true 90 for (const o of options) {
64 this.video.blacklistedReason = reason 91 const video = this.videos.find(v => v.id === o.videoId)
92
93 video.blacklisted = true
94 video.blacklistedReason = o.reason
95 }
65 96
66 this.videoBlocked.emit() 97 this.videoBlocked.emit()
67 }, 98 },
diff --git a/client/src/app/shared/shared-moderation/video-block.service.ts b/client/src/app/shared/shared-moderation/video-block.service.ts
index c22ceefcc..5dfb0d7d4 100644
--- a/client/src/app/shared/shared-moderation/video-block.service.ts
+++ b/client/src/app/shared/shared-moderation/video-block.service.ts
@@ -63,16 +63,20 @@ export class VideoBlockService {
63 ) 63 )
64 } 64 }
65 65
66 blockVideo (videoId: number, reason: string, unfederate: boolean) { 66 blockVideo (options: {
67 const body = { 67 videoId: number
68 unfederate, 68 reason?: string
69 reason 69 unfederate: boolean
70 } 70 }[]) {
71 return observableFrom(options)
72 .pipe(
73 concatMap(({ videoId, unfederate, reason }) => {
74 const body = { unfederate, reason }
71 75
72 return this.authHttp.post(VideoBlockService.BASE_VIDEOS_URL + videoId + '/blacklist', body) 76 return this.authHttp.post(VideoBlockService.BASE_VIDEOS_URL + videoId + '/blacklist', body)
73 .pipe( 77 }),
74 map(this.restExtractor.extractDataBool), 78 toArray(),
75 catchError(res => this.restExtractor.handleError(res)) 79 catchError(res => this.restExtractor.handleError(res))
76 ) 80 )
77 } 81 }
78} 82}
diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.html b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.html
index 7a6394202..3fea2a8a4 100644
--- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.html
+++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.html
@@ -20,6 +20,6 @@
20 20
21 <my-video-download #videoDownloadModal></my-video-download> 21 <my-video-download #videoDownloadModal></my-video-download>
22 <my-video-report #videoReportModal [video]="video"></my-video-report> 22 <my-video-report #videoReportModal [video]="video"></my-video-report>
23 <my-video-block #videoBlockModal [video]="video" (videoBlocked)="onVideoBlocked()"></my-video-block> 23 <my-video-block #videoBlockModal (videoBlocked)="onVideoBlocked()"></my-video-block>
24 <my-live-stream-information #liveStreamInformationModal *ngIf="displayOptions.liveInfo"></my-live-stream-information> 24 <my-live-stream-information #liveStreamInformationModal *ngIf="displayOptions.liveInfo"></my-live-stream-information>
25</ng-container> 25</ng-container>
diff --git a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
index 790ae2a5e..eff56b40e 100644
--- a/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/shared-video-miniature/video-actions-dropdown.component.ts
@@ -128,7 +128,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
128 showBlockModal () { 128 showBlockModal () {
129 this.modalOpened.emit() 129 this.modalOpened.emit()
130 130
131 this.videoBlockModal.show() 131 this.videoBlockModal.show([ this.video ])
132 } 132 }
133 133
134 showLiveInfoModal (video: Video) { 134 showLiveInfoModal (video: Video) {