aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-06-02 20:50:42 +0200
committerRigel Kent <sendmemail@rigelk.eu>2020-06-10 21:12:05 +0200
commit5baee5fca418487e72ddcd6419d31bca8659b668 (patch)
tree6604cc16d42152f4929d888565d2d435e2480d47
parentd840487fed32b4604b02030c0d7464afa925904f (diff)
downloadPeerTube-5baee5fca418487e72ddcd6419d31bca8659b668.tar.gz
PeerTube-5baee5fca418487e72ddcd6419d31bca8659b668.tar.zst
PeerTube-5baee5fca418487e72ddcd6419d31bca8659b668.zip
rename blacklist to block/blocklist, merge block and auto-block views
- also replace whitelist with allowlist - add advanced filters for video-block-list view - move icons in video-block-list and video-abuse-list to left side for visibility - add robot icon to depict automated nature of a block in video-block-list resolves #2790
-rw-r--r--client/src/app/+admin/admin.component.ts6
-rw-r--r--client/src/app/+admin/admin.module.ts6
-rw-r--r--client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html10
-rw-r--r--client/src/app/+admin/moderation/index.ts3
-rw-r--r--client/src/app/+admin/moderation/moderation.component.html6
-rw-r--r--client/src/app/+admin/moderation/moderation.component.ts8
-rw-r--r--client/src/app/+admin/moderation/moderation.routes.ts48
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html2
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html6
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts17
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/index.ts1
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html20
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss14
-rw-r--r--client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts86
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/index.ts1
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html100
-rw-r--r--client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts113
-rw-r--r--client/src/app/+admin/moderation/video-block-list/index.ts1
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.html113
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss18
-rw-r--r--client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts196
-rw-r--r--client/src/app/+admin/users/user-edit/user-edit.ts2
-rw-r--r--client/src/app/+admin/users/user-edit/user-update.component.ts2
-rw-r--r--client/src/app/+my-account/my-account-history/my-account-history.component.html2
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts6
-rw-r--r--client/src/app/menu/menu.component.ts4
-rw-r--r--client/src/app/search/search.component.html2
-rw-r--r--client/src/app/shared/forms/form-validators/index.ts2
-rw-r--r--client/src/app/shared/forms/form-validators/video-block-validators.service.ts (renamed from client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts)10
-rw-r--r--client/src/app/shared/images/global-icon.component.ts3
-rw-r--r--client/src/app/shared/index.ts2
-rw-r--r--client/src/app/shared/shared.module.ts14
-rw-r--r--client/src/app/shared/users/user-notification.model.ts6
-rw-r--r--client/src/app/shared/users/user-notifications.component.html12
-rw-r--r--client/src/app/shared/video-blacklist/index.ts1
-rw-r--r--client/src/app/shared/video-blacklist/video-blacklist.service.ts89
-rw-r--r--client/src/app/shared/video-block/index.ts1
-rw-r--r--client/src/app/shared/video-block/video-block.service.ts77
-rw-r--r--client/src/app/shared/video/abstract-video-list.html2
-rw-r--r--client/src/app/shared/video/modals/video-block.component.html (renamed from client/src/app/shared/video/modals/video-blacklist.component.html)4
-rw-r--r--client/src/app/shared/video/modals/video-block.component.scss (renamed from client/src/app/shared/video/modals/video-blacklist.component.scss)0
-rw-r--r--client/src/app/shared/video/modals/video-block.component.ts (renamed from client/src/app/shared/video/modals/video-blacklist.component.ts)31
-rw-r--r--client/src/app/shared/video/video-actions-dropdown.component.html2
-rw-r--r--client/src/app/shared/video/video-actions-dropdown.component.ts54
-rw-r--r--client/src/app/shared/video/video-miniature.component.html8
-rw-r--r--client/src/app/shared/video/video-miniature.component.scss8
-rw-r--r--client/src/app/shared/video/video-miniature.component.ts12
-rw-r--r--client/src/app/shared/video/video.model.ts12
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.html4
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.scss2
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts4
-rw-r--r--client/src/app/videos/recommendations/recommended-videos.component.html2
-rw-r--r--client/src/assets/images/global/robot.svg11
-rw-r--r--server/controllers/api/videos/blacklist.ts8
-rw-r--r--server/helpers/custom-validators/video-blacklist.ts4
-rw-r--r--server/initializers/migrations/0350-video-blacklist-type.ts4
-rw-r--r--server/lib/notifier.ts8
-rw-r--r--server/lib/video-blacklist.ts10
-rw-r--r--server/models/account/user.ts4
-rw-r--r--server/models/video/video-blacklist.ts8
-rw-r--r--server/tests/api/check-params/users.ts2
-rw-r--r--server/tests/api/check-params/video-blacklist.ts4
-rw-r--r--server/tests/api/users/users.ts4
-rw-r--r--server/tests/api/videos/video-blacklist.ts20
-rw-r--r--shared/extra-utils/users/user-notifications.ts6
-rw-r--r--shared/extra-utils/videos/video-blacklist.ts4
-rw-r--r--shared/models/users/user-flag.model.ts2
-rw-r--r--shared/models/users/user-notification.model.ts6
-rw-r--r--shared/models/users/user-right.enum.ts2
-rw-r--r--shared/models/users/user-role.ts2
-rw-r--r--shared/models/videos/blacklist/video-blacklist.model.ts6
71 files changed, 627 insertions, 643 deletions
diff --git a/client/src/app/+admin/admin.component.ts b/client/src/app/+admin/admin.component.ts
index 9662522dc..4cf3da0e8 100644
--- a/client/src/app/+admin/admin.component.ts
+++ b/client/src/app/+admin/admin.component.ts
@@ -18,7 +18,7 @@ export class AdminComponent implements OnInit {
18 ngOnInit () { 18 ngOnInit () {
19 if (this.hasUsersRight()) this.items.push({ label: this.i18n('Users'), routerLink: '/admin/users' }) 19 if (this.hasUsersRight()) this.items.push({ label: this.i18n('Users'), routerLink: '/admin/users' })
20 if (this.hasServerFollowRight()) this.items.push({ label: this.i18n('Follows & redundancies'), routerLink: '/admin/follows' }) 20 if (this.hasServerFollowRight()) this.items.push({ label: this.i18n('Follows & redundancies'), routerLink: '/admin/follows' })
21 if (this.hasVideoAbusesRight() || this.hasVideoBlacklistRight()) this.items.push({ label: this.i18n('Moderation'), routerLink: '/admin/moderation' }) 21 if (this.hasVideoAbusesRight() || this.hasVideoBlocklistRight()) this.items.push({ label: this.i18n('Moderation'), routerLink: '/admin/moderation' })
22 if (this.hasConfigRight()) this.items.push({ label: this.i18n('Configuration'), routerLink: '/admin/config' }) 22 if (this.hasConfigRight()) this.items.push({ label: this.i18n('Configuration'), routerLink: '/admin/config' })
23 if (this.hasPluginsRight()) this.items.push({ label: this.i18n('Plugins/Themes'), routerLink: '/admin/plugins' }) 23 if (this.hasPluginsRight()) this.items.push({ label: this.i18n('Plugins/Themes'), routerLink: '/admin/plugins' })
24 if (this.hasJobsRight() || this.hasLogsRight() || this.hasDebugRight()) this.items.push({ label: this.i18n('System'), routerLink: '/admin/system' }) 24 if (this.hasJobsRight() || this.hasLogsRight() || this.hasDebugRight()) this.items.push({ label: this.i18n('System'), routerLink: '/admin/system' })
@@ -36,8 +36,8 @@ export class AdminComponent implements OnInit {
36 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES) 36 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES)
37 } 37 }
38 38
39 hasVideoBlacklistRight () { 39 hasVideoBlocklistRight () {
40 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) 40 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLOCKS)
41 } 41 }
42 42
43 hasConfigRight () { 43 hasConfigRight () {
diff --git a/client/src/app/+admin/admin.module.ts b/client/src/app/+admin/admin.module.ts
index d04313c0a..eb073f709 100644
--- a/client/src/app/+admin/admin.module.ts
+++ b/client/src/app/+admin/admin.module.ts
@@ -11,8 +11,7 @@ import { UserCreateComponent, UserListComponent, UserPasswordComponent, UsersCom
11import { 11import {
12 ModerationCommentModalComponent, 12 ModerationCommentModalComponent,
13 VideoAbuseListComponent, 13 VideoAbuseListComponent,
14 VideoAutoBlacklistListComponent, 14 VideoBlockListComponent
15 VideoBlacklistListComponent
16} from './moderation' 15} from './moderation'
17import { ModerationComponent } from '@app/+admin/moderation/moderation.component' 16import { ModerationComponent } from '@app/+admin/moderation/moderation.component'
18import { RedundancyCheckboxComponent } from '@app/+admin/follows/shared/redundancy-checkbox.component' 17import { RedundancyCheckboxComponent } from '@app/+admin/follows/shared/redundancy-checkbox.component'
@@ -59,10 +58,9 @@ import { VideoAbuseDetailsComponent } from './moderation/video-abuse-list/video-
59 UserListComponent, 58 UserListComponent,
60 59
61 ModerationComponent, 60 ModerationComponent,
62 VideoBlacklistListComponent, 61 VideoBlockListComponent,
63 VideoAbuseListComponent, 62 VideoAbuseListComponent,
64 VideoAbuseDetailsComponent, 63 VideoAbuseDetailsComponent,
65 VideoAutoBlacklistListComponent,
66 ModerationCommentModalComponent, 64 ModerationCommentModalComponent,
67 InstanceServerBlocklistComponent, 65 InstanceServerBlocklistComponent,
68 InstanceAccountBlocklistComponent, 66 InstanceAccountBlocklistComponent,
diff --git a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
index 981b6685f..52c759fb7 100644
--- a/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
+++ b/client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
@@ -430,7 +430,7 @@
430 <div class="form-group"> 430 <div class="form-group">
431 <my-peertube-checkbox 431 <my-peertube-checkbox
432 inputName="autoBlacklistVideosOfUsersEnabled" formControlName="enabled" 432 inputName="autoBlacklistVideosOfUsersEnabled" formControlName="enabled"
433 i18n-labelText labelText="Blacklist new videos automatically" 433 i18n-labelText labelText="Block new videos automatically"
434 > 434 >
435 <ng-container ngProjectAs="description"> 435 <ng-container ngProjectAs="description">
436 <span i18n>Unless a user is marked as trusted, their videos will stay private until a moderator reviews them.</span> 436 <span i18n>Unless a user is marked as trusted, their videos will stay private until a moderator reviews them.</span>
@@ -671,16 +671,16 @@
671 <div class="form-group"> 671 <div class="form-group">
672 <my-peertube-checkbox inputName="servicesTwitterWhitelisted" formControlName="whitelisted"> 672 <my-peertube-checkbox inputName="servicesTwitterWhitelisted" formControlName="whitelisted">
673 <ng-template ptTemplate="label"> 673 <ng-template ptTemplate="label">
674 <ng-container i18n>Instance whitelisted by Twitter</ng-container> 674 <ng-container i18n>Instance allowed by Twitter</ng-container>
675 </ng-template> 675 </ng-template>
676 676
677 <ng-template ptTemplate="help"> 677 <ng-template ptTemplate="help">
678 <ng-container i18n> 678 <ng-container i18n>
679 If your instance is whitelisted by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br /> 679 If your instance is explicitly allowed by Twitter, a video player will be embedded in the Twitter feed on PeerTube video share.<br />
680 If the instance is not whitelisted, we use an image link card that will redirect on your PeerTube instance.<br /><br /> 680 If the instance is not, we use an image link card that will redirect on your PeerTube instance.<br /><br />
681 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on 681 Check this checkbox, save the configuration and test with a video URL of your instance (https://example.com/videos/watch/blabla) on
682 <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a> 682 <a target='_blank' rel='noopener noreferrer' href='https://cards-dev.twitter.com/validator'>https://cards-dev.twitter.com/validator</a>
683 to see if you instance is whitelisted. 683 to see if you instance is allowed.
684 </ng-container> 684 </ng-container>
685 </ng-template> 685 </ng-template>
686 </my-peertube-checkbox> 686 </my-peertube-checkbox>
diff --git a/client/src/app/+admin/moderation/index.ts b/client/src/app/+admin/moderation/index.ts
index 3c683a28c..e99244b74 100644
--- a/client/src/app/+admin/moderation/index.ts
+++ b/client/src/app/+admin/moderation/index.ts
@@ -1,5 +1,4 @@
1export * from './video-abuse-list' 1export * from './video-abuse-list'
2export * from './video-auto-blacklist-list' 2export * from './video-block-list'
3export * from './video-blacklist-list'
4export * from './moderation.component' 3export * from './moderation.component'
5export * from './moderation.routes' 4export * from './moderation.routes'
diff --git a/client/src/app/+admin/moderation/moderation.component.html b/client/src/app/+admin/moderation/moderation.component.html
index b70027957..09f149c0e 100644
--- a/client/src/app/+admin/moderation/moderation.component.html
+++ b/client/src/app/+admin/moderation/moderation.component.html
@@ -2,11 +2,9 @@
2 <div i18n class="form-sub-title">Moderation</div> 2 <div i18n class="form-sub-title">Moderation</div>
3 3
4 <div class="admin-sub-nav"> 4 <div class="admin-sub-nav">
5 <a *ngIf="hasVideoAbusesRight()" i18n routerLink="video-abuses/list" routerLinkActive="active">Video abuses</a> 5 <a *ngIf="hasVideoAbusesRight()" i18n routerLink="video-abuses/list" routerLinkActive="active">Video reports</a>
6 6
7 <a *ngIf="hasVideoBlacklistRight()" i18n routerLink="video-blacklist/list" routerLinkActive="active">{{ autoBlacklistVideosEnabled ? 'Manually blacklisted videos' : 'Blacklisted videos' }}</a> 7 <a *ngIf="hasVideoBlocklistRight()" i18n routerLink="video-blocks/list" routerLinkActive="active">Video blocks</a>
8
9 <a *ngIf="autoBlacklistVideosEnabled && hasVideoBlacklistRight()" i18n routerLink="video-auto-blacklist/list" routerLinkActive="active">Auto-blacklisted videos</a>
10 8
11 <a *ngIf="hasAccountsBlocklistRight()" i18n routerLink="blocklist/accounts" routerLinkActive="active">Muted accounts</a> 9 <a *ngIf="hasAccountsBlocklistRight()" i18n routerLink="blocklist/accounts" routerLinkActive="active">Muted accounts</a>
12 10
diff --git a/client/src/app/+admin/moderation/moderation.component.ts b/client/src/app/+admin/moderation/moderation.component.ts
index 7744deb06..d48305eed 100644
--- a/client/src/app/+admin/moderation/moderation.component.ts
+++ b/client/src/app/+admin/moderation/moderation.component.ts
@@ -7,7 +7,7 @@ import { AuthService, ServerService } from '@app/core'
7 styleUrls: [ './moderation.component.scss' ] 7 styleUrls: [ './moderation.component.scss' ]
8}) 8})
9export class ModerationComponent implements OnInit { 9export class ModerationComponent implements OnInit {
10 autoBlacklistVideosEnabled = false 10 autoBlockVideosEnabled = false
11 11
12 constructor ( 12 constructor (
13 private auth: AuthService, 13 private auth: AuthService,
@@ -16,7 +16,7 @@ export class ModerationComponent implements OnInit {
16 16
17 ngOnInit (): void { 17 ngOnInit (): void {
18 this.serverService.getConfig() 18 this.serverService.getConfig()
19 .subscribe(config => this.autoBlacklistVideosEnabled = config.autoBlacklist.videos.ofUsers.enabled) 19 .subscribe(config => this.autoBlockVideosEnabled = config.autoBlacklist.videos.ofUsers.enabled)
20 20
21 } 21 }
22 22
@@ -24,8 +24,8 @@ export class ModerationComponent implements OnInit {
24 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES) 24 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_ABUSES)
25 } 25 }
26 26
27 hasVideoBlacklistRight () { 27 hasVideoBlocklistRight () {
28 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) 28 return this.auth.getUser().hasRight(UserRight.MANAGE_VIDEO_BLOCKS)
29 } 29 }
30 30
31 hasAccountsBlocklistRight () { 31 hasAccountsBlocklistRight () {
diff --git a/client/src/app/+admin/moderation/moderation.routes.ts b/client/src/app/+admin/moderation/moderation.routes.ts
index a024f2bee..aeb555c4a 100644
--- a/client/src/app/+admin/moderation/moderation.routes.ts
+++ b/client/src/app/+admin/moderation/moderation.routes.ts
@@ -2,8 +2,7 @@ import { Routes } from '@angular/router'
2import { UserRight } from '../../../../../shared' 2import { UserRight } from '../../../../../shared'
3import { UserRightGuard } from '@app/core' 3import { UserRightGuard } from '@app/core'
4import { VideoAbuseListComponent } from '@app/+admin/moderation/video-abuse-list' 4import { VideoAbuseListComponent } from '@app/+admin/moderation/video-abuse-list'
5import { VideoBlacklistListComponent } from '@app/+admin/moderation/video-blacklist-list' 5import { VideoBlockListComponent } from '@app/+admin/moderation/video-block-list'
6import { VideoAutoBlacklistListComponent } from '@app/+admin/moderation/video-auto-blacklist-list'
7import { ModerationComponent } from '@app/+admin/moderation/moderation.component' 6import { ModerationComponent } from '@app/+admin/moderation/moderation.component'
8import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from '@app/+admin/moderation/instance-blocklist' 7import { InstanceAccountBlocklistComponent, InstanceServerBlocklistComponent } from '@app/+admin/moderation/instance-blocklist'
9 8
@@ -23,45 +22,44 @@ export const ModerationRoutes: Routes = [
23 pathMatch: 'full' 22 pathMatch: 'full'
24 }, 23 },
25 { 24 {
26 path: 'video-blacklist',
27 redirectTo: 'video-blacklist/list',
28 pathMatch: 'full'
29 },
30 {
31 path: 'video-auto-blacklist',
32 redirectTo: 'video-auto-blacklist/list',
33 pathMatch: 'full'
34 },
35 {
36 path: 'video-abuses/list', 25 path: 'video-abuses/list',
37 component: VideoAbuseListComponent, 26 component: VideoAbuseListComponent,
38 canActivate: [ UserRightGuard ], 27 canActivate: [ UserRightGuard ],
39 data: { 28 data: {
40 userRight: UserRight.MANAGE_VIDEO_ABUSES, 29 userRight: UserRight.MANAGE_VIDEO_ABUSES,
41 meta: { 30 meta: {
42 title: 'Video abuses list' 31 title: 'Video reports'
43 } 32 }
44 } 33 }
45 }, 34 },
46 { 35 {
36 path: 'video-blacklist',
37 redirectTo: 'video-blocks/list',
38 pathMatch: 'full'
39 },
40 {
41 path: 'video-auto-blacklist',
42 redirectTo: 'video-blocks/list',
43 pathMatch: 'full'
44 },
45 {
47 path: 'video-auto-blacklist/list', 46 path: 'video-auto-blacklist/list',
48 component: VideoAutoBlacklistListComponent, 47 redirectTo: 'video-blocks/list',
49 canActivate: [ UserRightGuard ], 48 pathMatch: 'full'
50 data: { 49 },
51 userRight: UserRight.MANAGE_VIDEO_BLACKLIST, 50 {
52 meta: { 51 path: 'video-blacklist',
53 title: 'Auto-blacklisted videos' 52 redirectTo: 'video-blocks/list',
54 } 53 pathMatch: 'full'
55 }
56 }, 54 },
57 { 55 {
58 path: 'video-blacklist/list', 56 path: 'video-blocks/list',
59 component: VideoBlacklistListComponent, 57 component: VideoBlockListComponent,
60 canActivate: [ UserRightGuard ], 58 canActivate: [ UserRightGuard ],
61 data: { 59 data: {
62 userRight: UserRight.MANAGE_VIDEO_BLACKLIST, 60 userRight: UserRight.MANAGE_VIDEO_BLOCKS,
63 meta: { 61 meta: {
64 title: 'Blacklisted videos' 62 title: 'Videos blocked'
65 } 63 }
66 } 64 }
67 }, 65 },
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html
index 2abcc0669..453a282d1 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html
@@ -69,7 +69,7 @@
69 <div class="screenratio"> 69 <div class="screenratio">
70 <div *ngIf="videoAbuse.video.deleted || videoAbuse.video.blacklisted"> 70 <div *ngIf="videoAbuse.video.deleted || videoAbuse.video.blacklisted">
71 <span i18n *ngIf="videoAbuse.video.deleted">The video was deleted</span> 71 <span i18n *ngIf="videoAbuse.video.deleted">The video was deleted</span>
72 <span i18n *ngIf="!videoAbuse.video.deleted">The video was blacklisted</span> 72 <span i18n *ngIf="!videoAbuse.video.deleted">The video was blocked</span>
73 </div> 73 </div>
74 <div *ngIf="!videoAbuse.video.deleted && !videoAbuse.video.blacklisted" [innerHTML]="videoAbuse.embedHtml"></div> 74 <div *ngIf="!videoAbuse.video.deleted && !videoAbuse.video.blacklisted" [innerHTML]="videoAbuse.embedHtml"></div>
75 </div> 75 </div>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
index d30475794..df15999ec 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.html
@@ -19,7 +19,7 @@
19 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:pending' }" class="dropdown-item" i18n>Unsolved reports</a> 19 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:pending' }" class="dropdown-item" i18n>Unsolved reports</a>
20 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:accepted' }" class="dropdown-item" i18n>Accepted reports</a> 20 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:accepted' }" class="dropdown-item" i18n>Accepted reports</a>
21 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:rejected' }" class="dropdown-item" i18n>Refused reports</a> 21 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'state:rejected' }" class="dropdown-item" i18n>Refused reports</a>
22 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:blacklisted' }" class="dropdown-item" i18n>Reports with blacklisted videos</a> 22 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:blacklisted' }" class="dropdown-item" i18n>Reports with blocked videos</a>
23 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:deleted' }" class="dropdown-item" i18n>Reports with deleted videos</a> 23 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'videoIs:deleted' }" class="dropdown-item" i18n>Reports with deleted videos</a>
24 </div> 24 </div>
25 </div> 25 </div>
@@ -84,9 +84,9 @@
84 </div> 84 </div>
85 <div class="video-table-video-text"> 85 <div class="video-table-video-text">
86 <div> 86 <div>
87 {{ videoAbuse.video.name }}
88 <span *ngIf="!videoAbuse.video.blacklisted" class="glyphicon glyphicon-new-window"></span> 87 <span *ngIf="!videoAbuse.video.blacklisted" class="glyphicon glyphicon-new-window"></span>
89 <span *ngIf="videoAbuse.video.blacklisted" i18n-title title="Video was blacklisted" class="glyphicon glyphicon-ban-circle"></span> 88 <span *ngIf="videoAbuse.video.blacklisted" i18n-title title="The video was blocked" class="glyphicon glyphicon-ban-circle"></span>
89 {{ videoAbuse.video.name }}
90 </div> 90 </div>
91 <div class="text-muted" i18n>by {{ videoAbuse.video.channel?.displayName }} on {{ videoAbuse.video.channel?.host }} </div> 91 <div class="text-muted" i18n>by {{ videoAbuse.video.channel?.displayName }} on {{ videoAbuse.video.channel?.host }} </div>
92 </div> 92 </div>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
index 39f619cc3..ca37bccf3 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts
@@ -3,7 +3,7 @@ import { Account } from '@app/shared/account/account.model'
3import { Notifier } from '@app/core' 3import { Notifier } from '@app/core'
4import { SortMeta } from 'primeng/api' 4import { SortMeta } from 'primeng/api'
5import { VideoAbuse, VideoAbuseState } from '../../../../../../shared' 5import { VideoAbuse, VideoAbuseState } from '../../../../../../shared'
6import { RestPagination, RestTable, VideoAbuseService, VideoBlacklistService } from '../../../shared' 6import { RestPagination, RestTable, VideoAbuseService, VideoBlockService } from '../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill' 7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component' 8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9import { ConfirmService } from '../../../core/index' 9import { ConfirmService } from '../../../core/index'
@@ -53,7 +53,7 @@ export class VideoAbuseListComponent extends RestTable implements OnInit, AfterV
53 private videoAbuseService: VideoAbuseService, 53 private videoAbuseService: VideoAbuseService,
54 private blocklistService: BlocklistService, 54 private blocklistService: BlocklistService,
55 private videoService: VideoService, 55 private videoService: VideoService,
56 private videoBlacklistService: VideoBlacklistService, 56 private videoBlocklistService: VideoBlockService,
57 private confirmService: ConfirmService, 57 private confirmService: ConfirmService,
58 private i18n: I18n, 58 private i18n: I18n,
59 private markdownRenderer: MarkdownService, 59 private markdownRenderer: MarkdownService,
@@ -101,13 +101,13 @@ export class VideoAbuseListComponent extends RestTable implements OnInit, AfterV
101 isDisplayed: videoAbuse => !videoAbuse.video.deleted 101 isDisplayed: videoAbuse => !videoAbuse.video.deleted
102 }, 102 },
103 { 103 {
104 label: this.i18n('Blacklist video'), 104 label: this.i18n('Block video'),
105 isDisplayed: videoAbuse => !videoAbuse.video.deleted && !videoAbuse.video.blacklisted, 105 isDisplayed: videoAbuse => !videoAbuse.video.deleted && !videoAbuse.video.blacklisted,
106 handler: videoAbuse => { 106 handler: videoAbuse => {
107 this.videoBlacklistService.blacklistVideo(videoAbuse.video.id, undefined, true) 107 this.videoBlocklistService.blockVideo(videoAbuse.video.id, undefined, true)
108 .subscribe( 108 .subscribe(
109 () => { 109 () => {
110 this.notifier.success(this.i18n('Video blacklisted.')) 110 this.notifier.success(this.i18n('Video blocklisted.'))
111 111
112 this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED) 112 this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED)
113 }, 113 },
@@ -117,13 +117,13 @@ export class VideoAbuseListComponent extends RestTable implements OnInit, AfterV
117 } 117 }
118 }, 118 },
119 { 119 {
120 label: this.i18n('Unblacklist video'), 120 label: this.i18n('Unblock video'),
121 isDisplayed: videoAbuse => !videoAbuse.video.deleted && videoAbuse.video.blacklisted, 121 isDisplayed: videoAbuse => !videoAbuse.video.deleted && videoAbuse.video.blacklisted,
122 handler: videoAbuse => { 122 handler: videoAbuse => {
123 this.videoBlacklistService.removeVideoFromBlacklist(videoAbuse.video.id) 123 this.videoBlocklistService.unblockVideo(videoAbuse.video.id)
124 .subscribe( 124 .subscribe(
125 () => { 125 () => {
126 this.notifier.success(this.i18n('Video unblacklisted.')) 126 this.notifier.success(this.i18n('Video unblocklisted.'))
127 127
128 this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED) 128 this.updateVideoAbuseState(videoAbuse, VideoAbuseState.ACCEPTED)
129 }, 129 },
@@ -292,7 +292,6 @@ export class VideoAbuseListComponent extends RestTable implements OnInit, AfterV
292 292
293 err => this.notifier.error(err.message) 293 err => this.notifier.error(err.message)
294 ) 294 )
295
296 } 295 }
297 296
298 protected loadData () { 297 protected loadData () {
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/index.ts b/client/src/app/+admin/moderation/video-auto-blacklist-list/index.ts
deleted file mode 100644
index e3522f68c..000000000
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './video-auto-blacklist-list.component'
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html
deleted file mode 100644
index e2193b630..000000000
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.html
+++ /dev/null
@@ -1,20 +0,0 @@
1<my-videos-selection
2 [pagination]="pagination"
3 [(selection)]="selection"
4 [(videosModel)]="videos"
5 [miniatureDisplayOptions]="miniatureDisplayOptions"
6 [titlePage]="titlePage"
7 [getVideosObservableFunction]="getVideosObservableFunction"
8>
9 <ng-template ptTemplate="globalButtons">
10 <span class="action-button action-button-unblacklist-selection" (click)="removeSelectedVideosFromBlacklist()">
11 <my-global-icon iconName="tick"></my-global-icon>
12 <ng-container i18n>Unblacklist</ng-container>
13 </span>
14 </ng-template>
15
16 <ng-template ptTemplate="rowButtons" let-video>
17 <my-button i18n-label label="Unblacklist" icon="tick" (click)="removeVideoFromBlacklist(video)"></my-button>
18 </ng-template>
19
20</my-videos-selection>
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss
deleted file mode 100644
index 85ebc6041..000000000
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.scss
+++ /dev/null
@@ -1,14 +0,0 @@
1@import '_variables';
2@import '_mixins';
3
4.action-button-unblacklist-selection {
5 display: inline-block;
6
7 @include peertube-button;
8 @include orange-button;
9 @include button-with-icon(21px);
10
11 my-global-icon {
12 @include apply-svg-color(#fff);
13 }
14}
diff --git a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts
deleted file mode 100644
index fb2962b47..000000000
--- a/client/src/app/+admin/moderation/video-auto-blacklist-list/video-auto-blacklist-list.component.ts
+++ /dev/null
@@ -1,86 +0,0 @@
1import { Component } from '@angular/core'
2import { I18n } from '@ngx-translate/i18n-polyfill'
3import { ActivatedRoute, Router } from '@angular/router'
4import { ComponentPagination } from '@app/shared/rest/component-pagination.model'
5import { AuthService, Notifier, ServerService } from '@app/core'
6import { VideoBlacklistService } from '@app/shared'
7import { immutableAssign } from '@app/shared/misc/utils'
8import { ScreenService } from '@app/shared/misc/screen.service'
9import { MiniatureDisplayOptions } from '@app/shared/video/video-miniature.component'
10import { SelectionType } from '@app/shared/video/videos-selection.component'
11import { Video } from '@app/shared/video/video.model'
12
13@Component({
14 selector: 'my-video-auto-blacklist-list',
15 templateUrl: './video-auto-blacklist-list.component.html',
16 styleUrls: [ './video-auto-blacklist-list.component.scss' ]
17})
18export class VideoAutoBlacklistListComponent {
19 titlePage: string
20 selection: SelectionType = {}
21 miniatureDisplayOptions: MiniatureDisplayOptions = {
22 date: true,
23 views: false,
24 by: true,
25 privacyLabel: false,
26 privacyText: true,
27 state: false,
28 blacklistInfo: false,
29 nsfw: true
30 }
31 pagination: ComponentPagination = {
32 currentPage: 1,
33 itemsPerPage: 5,
34 totalItems: null
35 }
36 videos: Video[] = []
37 getVideosObservableFunction = this.getVideosObservable.bind(this)
38
39 constructor (
40 protected router: Router,
41 protected route: ActivatedRoute,
42 protected notifier: Notifier,
43 protected authService: AuthService,
44 protected screenService: ScreenService,
45 protected serverService: ServerService,
46 private i18n: I18n,
47 private videoBlacklistService: VideoBlacklistService
48 ) {
49 this.titlePage = this.i18n('Auto-blacklisted videos')
50 }
51
52 getVideosObservable (page: number) {
53 const newPagination = immutableAssign(this.pagination, { currentPage: page })
54
55 return this.videoBlacklistService.getAutoBlacklistedAsVideoList(newPagination)
56 }
57
58 removeVideoFromBlacklist (entry: Video) {
59 this.videoBlacklistService.removeVideoFromBlacklist(entry.id).subscribe(
60 () => {
61 this.notifier.success(this.i18n('Video {{name}} removed from blacklist.', { name: entry.name }))
62
63 this.videos = this.videos.filter(v => v.id !== entry.id)
64 },
65
66 error => this.notifier.error(error.message)
67 )
68 }
69
70 removeSelectedVideosFromBlacklist () {
71 const toReleaseVideosIds = Object.keys(this.selection)
72 .filter(k => this.selection[ k ] === true)
73 .map(k => parseInt(k, 10))
74
75 this.videoBlacklistService.removeVideoFromBlacklist(toReleaseVideosIds).subscribe(
76 () => {
77 this.notifier.success(this.i18n('{{num}} videos removed from blacklist.', { num: toReleaseVideosIds.length }))
78
79 this.selection = {}
80 this.videos = this.videos.filter(v => toReleaseVideosIds.includes(v.id) === false)
81 },
82
83 error => this.notifier.error(error.message)
84 )
85 }
86}
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/index.ts b/client/src/app/+admin/moderation/video-blacklist-list/index.ts
deleted file mode 100644
index 4daf64187..000000000
--- a/client/src/app/+admin/moderation/video-blacklist-list/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './video-blacklist-list.component'
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
deleted file mode 100644
index cfa04514f..000000000
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.html
+++ /dev/null
@@ -1,100 +0,0 @@
1<p-table
2 [value]="blacklist" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
4 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
5 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blacklisted videos"
6 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
7>
8 <ng-template pTemplate="caption">
9 <div class="caption">
10 <div class="ml-auto has-feedback has-clear">
11 <input
12 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
13 (keyup)="onSearch($event)"
14 >
15 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetSearch()"></a>
16 <span class="sr-only" i18n>Clear filters</span>
17 </div>
18 </div>
19 </ng-template>
20
21 <ng-template pTemplate="header">
22 <tr>
23 <th style="width: 40px"></th>
24 <th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th>
25 <th style="width: 100px;" i18n>Sensitive</th>
26 <th style="width: 120px;" i18n>Unfederated</th>
27 <th style="width: 150px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
28 <th style="width: 150px;"></th>
29 </tr>
30 </ng-template>
31
32 <ng-template pTemplate="body" let-videoBlacklist let-expanded="expanded">
33 <tr>
34 <td *ngIf="!videoBlacklist.reason"></td>
35 <td *ngIf="videoBlacklist.reason" class="expand-cell c-hand" [pRowToggler]="videoBlacklist" i18n-ngbTooltip ngbTooltip="More information" placement="top-left" container="body">
36 <span class="expander">
37 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
38 </span>
39 </td>
40
41 <td>
42 <a [href]="getVideoUrl(videoBlacklist)" class="video-table-video-link" i18n-title title="Open video in a new tab" target="_blank" rel="noopener noreferrer">
43 <div class="video-table-video">
44 <div class="video-table-video-image">
45 <img [src]="videoBlacklist.video.thumbnailPath">
46 </div>
47 <div class="video-table-video-text">
48 <div>
49 {{ videoBlacklist.video.name }}
50 <span i18n-title title="Video was blacklisted" class="glyphicon glyphicon-ban-circle"></span>
51 </div>
52 <div class="text-muted">by {{ videoBlacklist.video.channel?.displayName }} on {{ videoBlacklist.video.channel?.host }} </div>
53 </div>
54 </div>
55 </a>
56 </td>
57
58 <ng-container *ngIf="videoBlacklist.reason">
59 <td class="c-hand" [pRowToggler]="videoBlacklist">{{ booleanToText(videoBlacklist.video.nsfw) }}</td>
60 <td class="c-hand" [pRowToggler]="videoBlacklist">{{ booleanToText(videoBlacklist.unfederated) }}</td>
61 <td class="c-hand" [pRowToggler]="videoBlacklist">{{ videoBlacklist.createdAt | date: 'short' }}</td>
62 </ng-container>
63 <ng-container *ngIf="!videoBlacklist.reason">
64 <td>{{ booleanToText(videoBlacklist.video.nsfw) }}</td>
65 <td>{{ booleanToText(videoBlacklist.unfederated) }}</td>
66 <td>{{ videoBlacklist.createdAt | date: 'short' }}</td>
67 </ng-container>
68
69 <td class="action-cell">
70 <my-action-dropdown
71 [ngClass]="{ 'show': expanded }" placement="bottom-right" container="body"
72 i18n-label label="Actions" [actions]="videoBlacklistActions" [entry]="videoBlacklist"
73 ></my-action-dropdown>
74 </td>
75 </tr>
76 </ng-template>
77
78 <ng-template pTemplate="rowexpansion" let-videoBlacklist>
79 <tr>
80 <td class="expand-cell" colspan="6">
81 <div class="d-flex moderation-expanded">
82 <span class="col-2 moderation-expanded-label" i18n>Blacklist reason:</span>
83 <span class="col-9 moderation-expanded-text" [innerHTML]="videoBlacklist.reasonHtml"></span>
84 </div>
85 </td>
86 </tr>
87 </ng-template>
88
89 <ng-template pTemplate="emptymessage">
90 <tr>
91 <td colspan="6">
92 <div class="empty-table-message">
93 <ng-container *ngIf="search" i18n>No blacklisted video found matching current filters.</ng-container>
94 <ng-container *ngIf="!search" i18n>No blacklisted video found.</ng-container>
95 </div>
96 </td>
97 </tr>
98 </ng-template>
99</p-table>
100
diff --git a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts b/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
deleted file mode 100644
index 63ecdeb9f..000000000
--- a/client/src/app/+admin/moderation/video-blacklist-list/video-blacklist-list.component.ts
+++ /dev/null
@@ -1,113 +0,0 @@
1import { Component, OnInit } from '@angular/core'
2import { SortMeta } from 'primeng/api'
3import { Notifier, ServerService } from '@app/core'
4import { ConfirmService } from '../../../core'
5import { RestPagination, RestTable, VideoBlacklistService } from '../../../shared'
6import { VideoBlacklist, VideoBlacklistType } from '../../../../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9import { Video } from '../../../shared/video/video.model'
10import { MarkdownService } from '@app/shared/renderer'
11
12@Component({
13 selector: 'my-video-blacklist-list',
14 templateUrl: './video-blacklist-list.component.html',
15 styleUrls: [ '../moderation.component.scss' ]
16})
17export class VideoBlacklistListComponent extends RestTable implements OnInit {
18 blacklist: (VideoBlacklist & { reasonHtml?: string })[] = []
19 totalRecords = 0
20 sort: SortMeta = { field: 'createdAt', order: -1 }
21 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
22 listBlacklistTypeFilter: VideoBlacklistType = undefined
23
24 videoBlacklistActions: DropdownAction<VideoBlacklist>[] = []
25
26 constructor (
27 private notifier: Notifier,
28 private serverService: ServerService,
29 private confirmService: ConfirmService,
30 private videoBlacklistService: VideoBlacklistService,
31 private markdownRenderer: MarkdownService,
32 private i18n: I18n
33 ) {
34 super()
35 }
36
37 ngOnInit () {
38 this.serverService.getConfig()
39 .subscribe(config => {
40 // don't filter if auto-blacklist is not enabled as this will be the only list
41 if (config.autoBlacklist.videos.ofUsers.enabled) {
42 this.listBlacklistTypeFilter = VideoBlacklistType.MANUAL
43 }
44 })
45
46 this.initialize()
47
48 this.videoBlacklistActions = [
49 {
50 label: this.i18n('Unblacklist'),
51 handler: videoBlacklist => this.removeVideoFromBlacklist(videoBlacklist)
52 }
53 ]
54 }
55
56 getIdentifier () {
57 return 'VideoBlacklistListComponent'
58 }
59
60 getVideoUrl (videoBlacklist: VideoBlacklist) {
61 return Video.buildClientUrl(videoBlacklist.video.uuid)
62 }
63
64 booleanToText (value: boolean) {
65 if (value === true) return this.i18n('yes')
66
67 return this.i18n('no')
68 }
69
70 toHtml (text: string) {
71 return this.markdownRenderer.textMarkdownToHTML(text)
72 }
73
74 async removeVideoFromBlacklist (entry: VideoBlacklist) {
75 const confirmMessage = this.i18n(
76 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.'
77 )
78
79 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist'))
80 if (res === false) return
81
82 this.videoBlacklistService.removeVideoFromBlacklist(entry.video.id).subscribe(
83 () => {
84 this.notifier.success(this.i18n('Video {{name}} removed from the blacklist.', { name: entry.video.name }))
85 this.loadData()
86 },
87
88 err => this.notifier.error(err.message)
89 )
90 }
91
92 protected loadData () {
93 this.videoBlacklistService.listBlacklist({
94 pagination: this.pagination,
95 sort: this.sort,
96 search: this.search,
97 type: this.listBlacklistTypeFilter
98 })
99 .subscribe(
100 async resultList => {
101 this.totalRecords = resultList.total
102
103 this.blacklist = resultList.data
104
105 for (const element of this.blacklist) {
106 Object.assign(element, { reasonHtml: await this.toHtml(element.reason) })
107 }
108 },
109
110 err => this.notifier.error(err.message)
111 )
112 }
113}
diff --git a/client/src/app/+admin/moderation/video-block-list/index.ts b/client/src/app/+admin/moderation/video-block-list/index.ts
new file mode 100644
index 000000000..ec4de8f62
--- /dev/null
+++ b/client/src/app/+admin/moderation/video-block-list/index.ts
@@ -0,0 +1 @@
export * from './video-block-list.component'
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html
new file mode 100644
index 000000000..f3ec37314
--- /dev/null
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.html
@@ -0,0 +1,113 @@
1<p-table
2 [value]="blocklist" [lazy]="true" [paginator]="totalRecords > 0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
3 [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
4 [showCurrentPageReport]="true" i18n-currentPageReportTemplate
5 currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} blocked videos"
6 (onPage)="onPage($event)" [expandedRowKeys]="expandedRows"
7>
8 <ng-template pTemplate="caption">
9 <div class="caption">
10 <div class="ml-auto">
11 <div class="input-group has-feedback has-clear">
12 <div class="input-group-prepend c-hand" ngbDropdown placement="bottom-left auto" container="body">
13 <div class="input-group-text" ngbDropdownToggle>
14 <span class="caret" aria-haspopup="menu" role="button"></span>
15 </div>
16
17 <div role="menu" ngbDropdownMenu>
18 <h6 class="dropdown-header" i18n>Advanced block filters</h6>
19 <a [routerLink]="[ '/admin/moderation/video-blocks/list' ]" [queryParams]="{ 'search': 'type:auto' }" class="dropdown-item" i18n>Automatic blocks</a>
20 <a [routerLink]="[ '/admin/moderation/video-blocks/list' ]" [queryParams]="{ 'search': 'type:manual' }" class="dropdown-item" i18n>Manual blocks</a>
21 </div>
22 </div>
23 <input
24 type="text" name="table-filter" id="table-filter" i18n-placeholder placeholder="Filter..."
25 (keyup)="onBlockSearch($event)"
26 >
27 <a class="glyphicon glyphicon-remove-sign form-control-feedback form-control-clear" (click)="resetTableFilter()"></a>
28 <span class="sr-only" i18n>Clear filters</span>
29 </div>
30 </div>
31 </div>
32 </ng-template>
33
34 <ng-template pTemplate="header">
35 <tr>
36 <th style="width: 40px"></th>
37 <th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th>
38 <th style="width: 100px;" i18n>Sensitive</th>
39 <th style="width: 120px;" i18n>Unfederated</th>
40 <th style="width: 150px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
41 <th style="width: 150px;"></th>
42 </tr>
43 </ng-template>
44
45 <ng-template pTemplate="body" let-videoBlock let-expanded="expanded">
46 <tr>
47 <td *ngIf="!videoBlock.reason"></td>
48 <td *ngIf="videoBlock.reason" class="expand-cell c-hand" [pRowToggler]="videoBlock" i18n-ngbTooltip ngbTooltip="More information" placement="top-left" container="body">
49 <span class="expander">
50 <i [ngClass]="expanded ? 'glyphicon glyphicon-menu-down' : 'glyphicon glyphicon-menu-right'"></i>
51 </span>
52 </td>
53
54 <td>
55 <a [href]="getVideoUrl(videoBlock)" class="video-table-video-link" i18n-title title="Open video in a new tab" target="_blank" rel="noopener noreferrer">
56 <div class="video-table-video">
57 <div class="video-table-video-image">
58 <img [src]="videoBlock.video.thumbnailPath">
59 </div>
60 <div class="video-table-video-text">
61 <div>
62 <my-global-icon i18n-title title="The video was blocked due to automatic blocking of new videos" *ngIf="videoBlock.type == 2" iconName="robot"></my-global-icon>
63 {{ videoBlock.video.name }}
64 </div>
65 <div class="text-muted">by {{ videoBlock.video.channel?.displayName }} on {{ videoBlock.video.channel?.host }} </div>
66 </div>
67 </div>
68 </a>
69 </td>
70
71 <ng-container *ngIf="videoBlock.reason">
72 <td class="c-hand" [pRowToggler]="videoBlock">{{ booleanToText(videoBlock.video.nsfw) }}</td>
73 <td class="c-hand" [pRowToggler]="videoBlock">{{ booleanToText(videoBlock.unfederated) }}</td>
74 <td class="c-hand" [pRowToggler]="videoBlock">{{ videoBlock.createdAt | date: 'short' }}</td>
75 </ng-container>
76 <ng-container *ngIf="!videoBlock.reason">
77 <td>{{ booleanToText(videoBlock.video.nsfw) }}</td>
78 <td>{{ booleanToText(videoBlock.unfederated) }}</td>
79 <td>{{ videoBlock.createdAt | date: 'short' }}</td>
80 </ng-container>
81
82 <td class="action-cell">
83 <my-action-dropdown
84 [ngClass]="{ 'show': expanded }" placement="bottom-right" container="body"
85 i18n-label label="Actions" [actions]="videoBlocklistActions" [entry]="videoBlock"
86 ></my-action-dropdown>
87 </td>
88 </tr>
89 </ng-template>
90
91 <ng-template pTemplate="rowexpansion" let-videoBlock>
92 <tr>
93 <td class="expand-cell" colspan="6">
94 <div class="d-flex moderation-expanded">
95 <span class="col-2 moderation-expanded-label" i18n>Block reason:</span>
96 <span class="col-9 moderation-expanded-text" [innerHTML]="videoBlock.reasonHtml"></span>
97 </div>
98 </td>
99 </tr>
100 </ng-template>
101
102 <ng-template pTemplate="emptymessage">
103 <tr>
104 <td colspan="6">
105 <div class="empty-table-message">
106 <ng-container *ngIf="search" i18n>No blocked video found matching current filters.</ng-container>
107 <ng-container *ngIf="!search" i18n>No blocked video found.</ng-container>
108 </div>
109 </td>
110 </tr>
111 </ng-template>
112</p-table>
113
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss
new file mode 100644
index 000000000..43a365608
--- /dev/null
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.scss
@@ -0,0 +1,18 @@
1@import 'mixins';
2
3my-global-icon {
4 @include apply-svg-color(#7d7d7d);
5
6 width: 12px;
7 height: 12px;
8 position: relative;
9 top: -1px;
10}
11
12.input-group {
13 @include peertube-input-group(300px);
14
15 .dropdown-toggle::after {
16 margin-left: 0;
17 }
18}
diff --git a/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
new file mode 100644
index 000000000..e72ab5348
--- /dev/null
+++ b/client/src/app/+admin/moderation/video-block-list/video-block-list.component.ts
@@ -0,0 +1,196 @@
1import { Component, OnInit } from '@angular/core'
2import { SortMeta } from 'primeng/api'
3import { Notifier, ServerService } from '@app/core'
4import { ConfirmService } from '../../../core'
5import { RestPagination, RestTable, VideoBlockService } from '../../../shared'
6import { VideoBlocklist, VideoBlockType } from '../../../../../../shared'
7import { I18n } from '@ngx-translate/i18n-polyfill'
8import { DropdownAction } from '../../../shared/buttons/action-dropdown.component'
9import { Video } from '../../../shared/video/video.model'
10import { MarkdownService } from '@app/shared/renderer'
11import { Params, ActivatedRoute, Router } from '@angular/router'
12import { filter, switchMap } from 'rxjs/operators'
13import { VideoService } from '@app/shared/video/video.service'
14
15@Component({
16 selector: 'my-video-block-list',
17 templateUrl: './video-block-list.component.html',
18 styleUrls: [ '../moderation.component.scss', './video-block-list.component.scss' ]
19})
20export class VideoBlockListComponent extends RestTable implements OnInit {
21 blocklist: (VideoBlocklist & { reasonHtml?: string })[] = []
22 totalRecords = 0
23 sort: SortMeta = { field: 'createdAt', order: -1 }
24 pagination: RestPagination = { count: this.rowsPerPage, start: 0 }
25 listBlockTypeFilter: VideoBlockType = undefined
26
27 videoBlocklistActions: DropdownAction<VideoBlocklist>[][] = []
28
29 constructor (
30 private notifier: Notifier,
31 private serverService: ServerService,
32 private confirmService: ConfirmService,
33 private videoBlocklistService: VideoBlockService,
34 private markdownRenderer: MarkdownService,
35 private videoService: VideoService,
36 private route: ActivatedRoute,
37 private router: Router,
38 private i18n: I18n
39 ) {
40 super()
41
42 this.videoBlocklistActions = [
43 [
44 {
45 label: this.i18n('Internal actions'),
46 isHeader: true
47 },
48 {
49 label: this.i18n('Switch video block to manual'),
50 handler: videoBlock => {
51 this.videoBlocklistService.unblockVideo(videoBlock.video.id).pipe(
52 switchMap(_ => this.videoBlocklistService.blockVideo(videoBlock.video.id, undefined, true))
53 ).subscribe(
54 () => {
55 this.notifier.success(this.i18n('Video {{name}} switched to manual block.', { name: videoBlock.video.name }))
56 this.loadData()
57 },
58
59 err => this.notifier.error(err.message)
60 )
61 }
62 }
63 ],
64 [
65 {
66 label: this.i18n('Actions for the video'),
67 isHeader: true,
68 },
69 {
70 label: this.i18n('Unblock video'),
71 handler: videoBlock => this.unblockVideo(videoBlock)
72 },
73
74 {
75 label: this.i18n('Delete video'),
76 handler: async videoBlock => {
77 const res = await this.confirmService.confirm(
78 this.i18n('Do you really want to delete this video?'),
79 this.i18n('Delete')
80 )
81 if (res === false) return
82
83 this.videoService.removeVideo(videoBlock.video.id)
84 .subscribe(
85 () => {
86 this.notifier.success(this.i18n('Video deleted.'))
87 },
88
89 err => this.notifier.error(err.message)
90 )
91 }
92 }
93 ]
94 ]
95 }
96
97 ngOnInit () {
98 this.serverService.getConfig()
99 .subscribe(config => {
100 // don't filter if auto-blacklist is not enabled as this will be the only list
101 if (config.autoBlacklist.videos.ofUsers.enabled) {
102 this.listBlockTypeFilter = VideoBlockType.MANUAL
103 }
104 })
105
106 this.initialize()
107
108 this.route.queryParams
109 .pipe(filter(params => params.search !== undefined && params.search !== null))
110 .subscribe(params => {
111 this.search = params.search
112 this.setTableFilter(params.search)
113 this.loadData()
114 })
115 }
116
117 ngAfterViewInit () {
118 if (this.search) this.setTableFilter(this.search)
119 }
120
121 /* Table filter functions */
122 onBlockSearch (event: Event) {
123 this.onSearch(event)
124 this.setQueryParams((event.target as HTMLInputElement).value)
125 }
126
127 setQueryParams (search: string) {
128 const queryParams: Params = {}
129 if (search) Object.assign(queryParams, { search })
130 this.router.navigate([ '/admin/moderation/video-blocks/list' ], { queryParams })
131 }
132
133 resetTableFilter () {
134 this.setTableFilter('')
135 this.setQueryParams('')
136 this.resetSearch()
137 }
138 /* END Table filter functions */
139
140 getIdentifier () {
141 return 'VideoBlockListComponent'
142 }
143
144 getVideoUrl (videoBlock: VideoBlocklist) {
145 return Video.buildClientUrl(videoBlock.video.uuid)
146 }
147
148 booleanToText (value: boolean) {
149 if (value === true) return this.i18n('yes')
150
151 return this.i18n('no')
152 }
153
154 toHtml (text: string) {
155 return this.markdownRenderer.textMarkdownToHTML(text)
156 }
157
158 async unblockVideo (entry: VideoBlocklist) {
159 const confirmMessage = this.i18n(
160 'Do you really want to unblock this video? It will be available again in the videos list.'
161 )
162
163 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock'))
164 if (res === false) return
165
166 this.videoBlocklistService.unblockVideo(entry.video.id).subscribe(
167 () => {
168 this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: entry.video.name }))
169 this.loadData()
170 },
171
172 err => this.notifier.error(err.message)
173 )
174 }
175
176 protected loadData () {
177 this.videoBlocklistService.listBlocks({
178 pagination: this.pagination,
179 sort: this.sort,
180 search: this.search,
181 })
182 .subscribe(
183 async resultList => {
184 this.totalRecords = resultList.total
185
186 this.blocklist = resultList.data
187
188 for (const element of this.blocklist) {
189 Object.assign(element, { reasonHtml: await this.toHtml(element.reason) })
190 }
191 },
192
193 err => this.notifier.error(err.message)
194 )
195 }
196}
diff --git a/client/src/app/+admin/users/user-edit/user-edit.ts b/client/src/app/+admin/users/user-edit/user-edit.ts
index 6e2952c44..98249bcc1 100644
--- a/client/src/app/+admin/users/user-edit/user-edit.ts
+++ b/client/src/app/+admin/users/user-edit/user-edit.ts
@@ -88,7 +88,7 @@ export abstract class UserEdit extends FormReactive implements OnInit {
88 } 88 }
89 89
90 protected buildAdminFlags (formValue: any) { 90 protected buildAdminFlags (formValue: any) {
91 return formValue.byPassAutoBlacklist ? UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST : UserAdminFlag.NONE 91 return formValue.byPassAutoBlacklist ? UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK : UserAdminFlag.NONE
92 } 92 }
93 93
94 protected buildQuotaOptions () { 94 protected buildQuotaOptions () {
diff --git a/client/src/app/+admin/users/user-edit/user-update.component.ts b/client/src/app/+admin/users/user-edit/user-update.component.ts
index e0e1fbddf..f2bd8c8ec 100644
--- a/client/src/app/+admin/users/user-edit/user-update.component.ts
+++ b/client/src/app/+admin/users/user-edit/user-update.component.ts
@@ -125,7 +125,7 @@ export class UserUpdateComponent extends UserEdit implements OnInit, OnDestroy {
125 role: userJson.role.toString(), 125 role: userJson.role.toString(),
126 videoQuota: userJson.videoQuota, 126 videoQuota: userJson.videoQuota,
127 videoQuotaDaily: userJson.videoQuotaDaily, 127 videoQuotaDaily: userJson.videoQuotaDaily,
128 byPassAutoBlacklist: userJson.adminFlags & UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST 128 byPassAutoBlacklist: userJson.adminFlags & UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK
129 }) 129 })
130 } 130 }
131} 131}
diff --git a/client/src/app/+my-account/my-account-history/my-account-history.component.html b/client/src/app/+my-account/my-account-history/my-account-history.component.html
index d3a329e8f..817b929fe 100644
--- a/client/src/app/+my-account/my-account-history/my-account-history.component.html
+++ b/client/src/app/+my-account/my-account-history/my-account-history.component.html
@@ -17,6 +17,6 @@
17 <div class="video" *ngFor="let video of videos"> 17 <div class="video" *ngFor="let video of videos">
18 <my-video-miniature 18 <my-video-miniature
19 [video]="video" [displayAsRow]="true" 19 [video]="video" [displayAsRow]="true"
20 (videoRemoved)="removeVideoFromArray(video)" (videoBlacklisted)="removeVideoFromArray(video)"></my-video-miniature> 20 (videoRemoved)="removeVideoFromArray(video)" (videoBlocked)="removeVideoFromArray(video)"></my-video-miniature>
21 </div> 21 </div>
22</div> 22</div>
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
index 6ba1a1020..72e26ac28 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
@@ -35,8 +35,8 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
35 newVideoFromSubscription: this.i18n('New video from your subscriptions'), 35 newVideoFromSubscription: this.i18n('New video from your subscriptions'),
36 newCommentOnMyVideo: this.i18n('New comment on your video'), 36 newCommentOnMyVideo: this.i18n('New comment on your video'),
37 videoAbuseAsModerator: this.i18n('New video abuse'), 37 videoAbuseAsModerator: this.i18n('New video abuse'),
38 videoAutoBlacklistAsModerator: this.i18n('Video auto-blacklisted waiting review'), 38 videoAutoBlacklistAsModerator: this.i18n('Video blocked automatically waiting review'),
39 blacklistOnMyVideo: this.i18n('One of your video is blacklisted/unblacklisted'), 39 blacklistOnMyVideo: this.i18n('One of your video is blocked/unblocked'),
40 myVideoPublished: this.i18n('Video published (after transcoding/scheduled update)'), 40 myVideoPublished: this.i18n('Video published (after transcoding/scheduled update)'),
41 myVideoImportFinished: this.i18n('Video import finished'), 41 myVideoImportFinished: this.i18n('Video import finished'),
42 newUserRegistration: this.i18n('A new user registered on your instance'), 42 newUserRegistration: this.i18n('A new user registered on your instance'),
@@ -49,7 +49,7 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
49 49
50 this.rightNotifications = { 50 this.rightNotifications = {
51 videoAbuseAsModerator: UserRight.MANAGE_VIDEO_ABUSES, 51 videoAbuseAsModerator: UserRight.MANAGE_VIDEO_ABUSES,
52 videoAutoBlacklistAsModerator: UserRight.MANAGE_VIDEO_BLACKLIST, 52 videoAutoBlacklistAsModerator: UserRight.MANAGE_VIDEO_BLOCKS,
53 newUserRegistration: UserRight.MANAGE_USERS, 53 newUserRegistration: UserRight.MANAGE_USERS,
54 newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW, 54 newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW,
55 autoInstanceFollowing: UserRight.MANAGE_CONFIGURATION 55 autoInstanceFollowing: UserRight.MANAGE_CONFIGURATION
diff --git a/client/src/app/menu/menu.component.ts b/client/src/app/menu/menu.component.ts
index 015c14bce..79bf29e9c 100644
--- a/client/src/app/menu/menu.component.ts
+++ b/client/src/app/menu/menu.component.ts
@@ -33,7 +33,7 @@ export class MenuComponent implements OnInit {
33 [UserRight.MANAGE_USERS]: '/admin/users', 33 [UserRight.MANAGE_USERS]: '/admin/users',
34 [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends', 34 [UserRight.MANAGE_SERVER_FOLLOW]: '/admin/friends',
35 [UserRight.MANAGE_VIDEO_ABUSES]: '/admin/moderation/video-abuses', 35 [UserRight.MANAGE_VIDEO_ABUSES]: '/admin/moderation/video-abuses',
36 [UserRight.MANAGE_VIDEO_BLACKLIST]: '/admin/moderation/video-blacklist', 36 [UserRight.MANAGE_VIDEO_BLOCKS]: '/admin/moderation/video-blocks',
37 [UserRight.MANAGE_JOBS]: '/admin/jobs', 37 [UserRight.MANAGE_JOBS]: '/admin/jobs',
38 [UserRight.MANAGE_CONFIGURATION]: '/admin/config' 38 [UserRight.MANAGE_CONFIGURATION]: '/admin/config'
39 } 39 }
@@ -131,7 +131,7 @@ export class MenuComponent implements OnInit {
131 UserRight.MANAGE_USERS, 131 UserRight.MANAGE_USERS,
132 UserRight.MANAGE_SERVER_FOLLOW, 132 UserRight.MANAGE_SERVER_FOLLOW,
133 UserRight.MANAGE_VIDEO_ABUSES, 133 UserRight.MANAGE_VIDEO_ABUSES,
134 UserRight.MANAGE_VIDEO_BLACKLIST, 134 UserRight.MANAGE_VIDEO_BLOCKS,
135 UserRight.MANAGE_JOBS, 135 UserRight.MANAGE_JOBS,
136 UserRight.MANAGE_CONFIGURATION 136 UserRight.MANAGE_CONFIGURATION
137 ] 137 ]
diff --git a/client/src/app/search/search.component.html b/client/src/app/search/search.component.html
index 3cafc676d..d723606db 100644
--- a/client/src/app/search/search.component.html
+++ b/client/src/app/search/search.component.html
@@ -55,7 +55,7 @@
55 <my-video-miniature 55 <my-video-miniature
56 [video]="result" [user]="user" [displayAsRow]="true" [displayVideoActions]="!hideActions()" 56 [video]="result" [user]="user" [displayAsRow]="true" [displayVideoActions]="!hideActions()"
57 [useLazyLoadUrl]="advancedSearch.searchTarget === 'search-index'" 57 [useLazyLoadUrl]="advancedSearch.searchTarget === 'search-index'"
58 (videoBlacklisted)="removeVideoFromArray(result)" (videoRemoved)="removeVideoFromArray(result)" 58 (videoBlocked)="removeVideoFromArray(result)" (videoRemoved)="removeVideoFromArray(result)"
59 ></my-video-miniature> 59 ></my-video-miniature>
60 </div> 60 </div>
61 </ng-container> 61 </ng-container>
diff --git a/client/src/app/shared/forms/form-validators/index.ts b/client/src/app/shared/forms/form-validators/index.ts
index e3de3ae13..4a01b1622 100644
--- a/client/src/app/shared/forms/form-validators/index.ts
+++ b/client/src/app/shared/forms/form-validators/index.ts
@@ -6,7 +6,7 @@ export * from './login-validators.service'
6export * from './reset-password-validators.service' 6export * from './reset-password-validators.service'
7export * from './user-validators.service' 7export * from './user-validators.service'
8export * from './video-abuse-validators.service' 8export * from './video-abuse-validators.service'
9export * from './video-blacklist-validators.service' 9export * from './video-block-validators.service'
10export * from './video-channel-validators.service' 10export * from './video-channel-validators.service'
11export * from './video-comment-validators.service' 11export * from './video-comment-validators.service'
12export * from './video-validators.service' 12export * 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-block-validators.service.ts
index 07d1f264a..dc8257761 100644
--- a/client/src/app/shared/forms/form-validators/video-blacklist-validators.service.ts
+++ b/client/src/app/shared/forms/form-validators/video-block-validators.service.ts
@@ -4,15 +4,15 @@ import { Injectable } from '@angular/core'
4import { BuildFormValidator } from '@app/shared' 4import { BuildFormValidator } from '@app/shared'
5 5
6@Injectable() 6@Injectable()
7export class VideoBlacklistValidatorsService { 7export class VideoBlockValidatorsService {
8 readonly VIDEO_BLACKLIST_REASON: BuildFormValidator 8 readonly VIDEO_BLOCK_REASON: BuildFormValidator
9 9
10 constructor (private i18n: I18n) { 10 constructor (private i18n: I18n) {
11 this.VIDEO_BLACKLIST_REASON = { 11 this.VIDEO_BLOCK_REASON = {
12 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ], 12 VALIDATORS: [ Validators.minLength(2), Validators.maxLength(300) ],
13 MESSAGES: { 13 MESSAGES: {
14 'minlength': this.i18n('Blacklist reason must be at least 2 characters long.'), 14 'minlength': this.i18n('Block reason must be at least 2 characters long.'),
15 'maxlength': this.i18n('Blacklist reason cannot be more than 300 characters long.') 15 'maxlength': this.i18n('Block reason cannot be more than 300 characters long.')
16 } 16 }
17 } 17 }
18 } 18 }
diff --git a/client/src/app/shared/images/global-icon.component.ts b/client/src/app/shared/images/global-icon.component.ts
index d2700f6c3..169882685 100644
--- a/client/src/app/shared/images/global-icon.component.ts
+++ b/client/src/app/shared/images/global-icon.component.ts
@@ -56,7 +56,8 @@ const icons = {
56 'refresh': require('!!raw-loader?!../../../assets/images/global/refresh.svg').default, 56 'refresh': require('!!raw-loader?!../../../assets/images/global/refresh.svg').default,
57 'npm': require('!!raw-loader?!../../../assets/images/global/npm.svg').default, 57 'npm': require('!!raw-loader?!../../../assets/images/global/npm.svg').default,
58 'fullscreen': require('!!raw-loader?!../../../assets/images/global/fullscreen.svg').default, 58 'fullscreen': require('!!raw-loader?!../../../assets/images/global/fullscreen.svg').default,
59 'exit-fullscreen': require('!!raw-loader?!../../../assets/images/global/exit-fullscreen.svg').default 59 'exit-fullscreen': require('!!raw-loader?!../../../assets/images/global/exit-fullscreen.svg').default,
60 'robot': require('!!raw-loader?!../../../assets/images/global/robot.svg').default
60} 61}
61 62
62export type GlobalIconName = keyof typeof icons 63export type GlobalIconName = keyof typeof icons
diff --git a/client/src/app/shared/index.ts b/client/src/app/shared/index.ts
index 136730c91..8be578d9f 100644
--- a/client/src/app/shared/index.ts
+++ b/client/src/app/shared/index.ts
@@ -3,5 +3,5 @@ export * from './forms'
3export * from './rest' 3export * from './rest'
4export * from './users' 4export * from './users'
5export * from './video-abuse' 5export * from './video-abuse'
6export * from './video-blacklist' 6export * from './video-block'
7export * from './shared.module' 7export * from './shared.module'
diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts
index 813f76672..2035097d7 100644
--- a/client/src/app/shared/shared.module.ts
+++ b/client/src/app/shared/shared.module.ts
@@ -35,7 +35,7 @@ import {
35 UserValidatorsService, 35 UserValidatorsService,
36 VideoAbuseValidatorsService, 36 VideoAbuseValidatorsService,
37 VideoAcceptOwnershipValidatorsService, 37 VideoAcceptOwnershipValidatorsService,
38 VideoBlacklistValidatorsService, 38 VideoBlockValidatorsService,
39 VideoChangeOwnershipValidatorsService, 39 VideoChangeOwnershipValidatorsService,
40 VideoChannelValidatorsService, 40 VideoChannelValidatorsService,
41 VideoCommentValidatorsService, 41 VideoCommentValidatorsService,
@@ -78,7 +78,7 @@ import { VideoPlaylistElementMiniatureComponent } from '@app/shared/video-playli
78import { VideoPlaylistMiniatureComponent } from '@app/shared/video-playlist/video-playlist-miniature.component' 78import { VideoPlaylistMiniatureComponent } from '@app/shared/video-playlist/video-playlist-miniature.component'
79import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service' 79import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
80import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive' 80import { InfiniteScrollerDirective } from '@app/shared/video/infinite-scroller.directive'
81import { VideoBlacklistComponent } from '@app/shared/video/modals/video-blacklist.component' 81import { VideoBlockComponent } from '@app/shared/video/modals/video-block.component'
82import { VideoDownloadComponent } from '@app/shared/video/modals/video-download.component' 82import { VideoDownloadComponent } from '@app/shared/video/modals/video-download.component'
83import { VideoReportComponent } from '@app/shared/video/modals/video-report.component' 83import { VideoReportComponent } from '@app/shared/video/modals/video-report.component'
84import { RedundancyService } from '@app/shared/video/redundancy.service' 84import { RedundancyService } from '@app/shared/video/redundancy.service'
@@ -102,7 +102,7 @@ import { LoaderComponent } from './misc/loader.component'
102import { RestExtractor, RestService } from './rest' 102import { RestExtractor, RestService } from './rest'
103import { UserService } from './users' 103import { UserService } from './users'
104import { VideoAbuseService } from './video-abuse' 104import { VideoAbuseService } from './video-abuse'
105import { VideoBlacklistService } from './video-blacklist' 105import { VideoBlockService } from './video-block'
106import { VideoOwnershipService } from './video-ownership' 106import { VideoOwnershipService } from './video-ownership'
107import { FeedComponent } from './video/feed.component' 107import { FeedComponent } from './video/feed.component'
108import { VideoMiniatureComponent } from './video/video-miniature.component' 108import { VideoMiniatureComponent } from './video/video-miniature.component'
@@ -147,7 +147,7 @@ import { VideoService } from './video/video.service'
147 147
148 VideoDownloadComponent, 148 VideoDownloadComponent,
149 VideoReportComponent, 149 VideoReportComponent,
150 VideoBlacklistComponent, 150 VideoBlockComponent,
151 151
152 FeedComponent, 152 FeedComponent,
153 153
@@ -230,7 +230,7 @@ import { VideoService } from './video/video.service'
230 230
231 VideoDownloadComponent, 231 VideoDownloadComponent,
232 VideoReportComponent, 232 VideoReportComponent,
233 VideoBlacklistComponent, 233 VideoBlockComponent,
234 234
235 FeedComponent, 235 FeedComponent,
236 236
@@ -282,7 +282,7 @@ import { VideoService } from './video/video.service'
282 RestExtractor, 282 RestExtractor,
283 RestService, 283 RestService,
284 VideoAbuseService, 284 VideoAbuseService,
285 VideoBlacklistService, 285 VideoBlockService,
286 VideoOwnershipService, 286 VideoOwnershipService,
287 UserService, 287 UserService,
288 VideoService, 288 VideoService,
@@ -305,7 +305,7 @@ import { VideoService } from './video/video.service'
305 VideoCommentValidatorsService, 305 VideoCommentValidatorsService,
306 VideoValidatorsService, 306 VideoValidatorsService,
307 VideoCaptionsValidatorsService, 307 VideoCaptionsValidatorsService,
308 VideoBlacklistValidatorsService, 308 VideoBlockValidatorsService,
309 OverviewService, 309 OverviewService,
310 VideoChangeOwnershipValidatorsService, 310 VideoChangeOwnershipValidatorsService,
311 VideoAcceptOwnershipValidatorsService, 311 VideoAcceptOwnershipValidatorsService,
diff --git a/client/src/app/shared/users/user-notification.model.ts b/client/src/app/shared/users/user-notification.model.ts
index 7b8368d87..bc1861c64 100644
--- a/client/src/app/shared/users/user-notification.model.ts
+++ b/client/src/app/shared/users/user-notification.model.ts
@@ -96,7 +96,7 @@ export class UserNotification implements UserNotificationServer {
96 this.videoUrl = this.buildVideoUrl(this.video) 96 this.videoUrl = this.buildVideoUrl(this.video)
97 break 97 break
98 98
99 case UserNotificationType.UNBLACKLIST_ON_MY_VIDEO: 99 case UserNotificationType.UNBLOCK_ON_MY_VIDEO:
100 this.videoUrl = this.buildVideoUrl(this.video) 100 this.videoUrl = this.buildVideoUrl(this.video)
101 break 101 break
102 102
@@ -112,7 +112,7 @@ export class UserNotification implements UserNotificationServer {
112 this.videoUrl = this.buildVideoUrl(this.videoAbuse.video) 112 this.videoUrl = this.buildVideoUrl(this.videoAbuse.video)
113 break 113 break
114 114
115 case UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS: 115 case UserNotificationType.VIDEO_AUTO_BLOCK_FOR_MODERATORS:
116 this.videoAutoBlacklistUrl = '/admin/moderation/video-auto-blacklist/list' 116 this.videoAutoBlacklistUrl = '/admin/moderation/video-auto-blacklist/list'
117 // Backward compatibility where we did not assign videoBlacklist to this type of notification before 117 // Backward compatibility where we did not assign videoBlacklist to this type of notification before
118 if (!this.videoBlacklist) this.videoBlacklist = { id: null, video: this.video } 118 if (!this.videoBlacklist) this.videoBlacklist = { id: null, video: this.video }
@@ -120,7 +120,7 @@ export class UserNotification implements UserNotificationServer {
120 this.videoUrl = this.buildVideoUrl(this.videoBlacklist.video) 120 this.videoUrl = this.buildVideoUrl(this.videoBlacklist.video)
121 break 121 break
122 122
123 case UserNotificationType.BLACKLIST_ON_MY_VIDEO: 123 case UserNotificationType.BLOCK_ON_MY_VIDEO:
124 this.videoUrl = this.buildVideoUrl(this.videoBlacklist.video) 124 this.videoUrl = this.buildVideoUrl(this.videoBlacklist.video)
125 break 125 break
126 126
diff --git a/client/src/app/shared/users/user-notifications.component.html b/client/src/app/shared/users/user-notifications.component.html
index 8dbe6e329..5a102995a 100644
--- a/client/src/app/shared/users/user-notifications.component.html
+++ b/client/src/app/shared/users/user-notifications.component.html
@@ -26,19 +26,19 @@
26 </ng-template> 26 </ng-template>
27 </ng-container> 27 </ng-container>
28 28
29 <ng-container *ngSwitchCase="UserNotificationType.UNBLACKLIST_ON_MY_VIDEO"> 29 <ng-container *ngSwitchCase="UserNotificationType.UNBLOCK_ON_MY_VIDEO">
30 <my-global-icon iconName="undo"></my-global-icon> 30 <my-global-icon iconName="undo"></my-global-icon>
31 31
32 <div class="message" i18n> 32 <div class="message" i18n>
33 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been unblacklisted 33 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been unblocked
34 </div> 34 </div>
35 </ng-container> 35 </ng-container>
36 36
37 <ng-container *ngSwitchCase="UserNotificationType.BLACKLIST_ON_MY_VIDEO"> 37 <ng-container *ngSwitchCase="UserNotificationType.BLOCK_ON_MY_VIDEO">
38 <my-global-icon iconName="no"></my-global-icon> 38 <my-global-icon iconName="no"></my-global-icon>
39 39
40 <div class="message" i18n> 40 <div class="message" i18n>
41 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been blacklisted 41 Your video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been blocked
42 </div> 42 </div>
43 </ng-container> 43 </ng-container>
44 44
@@ -50,11 +50,11 @@
50 </div> 50 </div>
51 </ng-container> 51 </ng-container>
52 52
53 <ng-container *ngSwitchCase="UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS"> 53 <ng-container *ngSwitchCase="UserNotificationType.VIDEO_AUTO_BLOCK_FOR_MODERATORS">
54 <my-global-icon iconName="no"></my-global-icon> 54 <my-global-icon iconName="no"></my-global-icon>
55 55
56 <div class="message" i18n> 56 <div class="message" i18n>
57 The recently added video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been <a (click)="markAsRead(notification)" [routerLink]="notification.videoAutoBlacklistUrl">auto-blacklisted</a> 57 The recently added video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been <a (click)="markAsRead(notification)" [routerLink]="notification.videoAutoBlacklistUrl">auto-blocked</a>
58 </div> 58 </div>
59 </ng-container> 59 </ng-container>
60 60
diff --git a/client/src/app/shared/video-blacklist/index.ts b/client/src/app/shared/video-blacklist/index.ts
deleted file mode 100644
index bfb026441..000000000
--- a/client/src/app/shared/video-blacklist/index.ts
+++ /dev/null
@@ -1 +0,0 @@
1export * from './video-blacklist.service'
diff --git a/client/src/app/shared/video-blacklist/video-blacklist.service.ts b/client/src/app/shared/video-blacklist/video-blacklist.service.ts
deleted file mode 100644
index c0e13a651..000000000
--- a/client/src/app/shared/video-blacklist/video-blacklist.service.ts
+++ /dev/null
@@ -1,89 +0,0 @@
1import { catchError, map, concatMap, toArray } from 'rxjs/operators'
2import { HttpClient, HttpParams } from '@angular/common/http'
3import { Injectable } from '@angular/core'
4import { SortMeta } from 'primeng/api'
5import { from as observableFrom, Observable } from 'rxjs'
6import { VideoBlacklist, VideoBlacklistType, ResultList } from '../../../../../shared'
7import { Video } from '../video/video.model'
8import { environment } from '../../../environments/environment'
9import { RestExtractor, RestPagination, RestService } from '../rest'
10import { ComponentPaginationLight } from '../rest/component-pagination.model'
11
12@Injectable()
13export class VideoBlacklistService {
14 private static BASE_VIDEOS_URL = environment.apiUrl + '/api/v1/videos/'
15
16 constructor (
17 private authHttp: HttpClient,
18 private restService: RestService,
19 private restExtractor: RestExtractor
20 ) {}
21
22 listBlacklist (options: {
23 pagination: RestPagination,
24 sort: SortMeta,
25 search?: string
26 type?: VideoBlacklistType
27 }): Observable<ResultList<VideoBlacklist>> {
28 const { pagination, sort, search, type } = options
29
30 let params = new HttpParams()
31 params = this.restService.addRestGetParams(params, pagination, sort)
32
33 if (search) params = params.append('search', search)
34 if (type) params = params.append('type', type.toString())
35
36 return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
37 .pipe(
38 map(res => this.restExtractor.convertResultListDateToHuman(res)),
39 catchError(res => this.restExtractor.handleError(res))
40 )
41 }
42
43 getAutoBlacklistedAsVideoList (videoPagination: ComponentPaginationLight): Observable<ResultList<Video>> {
44 const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
45
46 // prioritize first created since waiting longest
47 const AUTO_BLACKLIST_SORT = 'createdAt'
48
49 let params = new HttpParams()
50 params = this.restService.addRestGetParams(params, pagination, AUTO_BLACKLIST_SORT)
51
52 params = params.set('type', VideoBlacklistType.AUTO_BEFORE_PUBLISHED.toString())
53
54 return this.authHttp.get<ResultList<VideoBlacklist>>(VideoBlacklistService.BASE_VIDEOS_URL + 'blacklist', { params })
55 .pipe(
56 map(res => {
57 return {
58 total: res.total,
59 data: res.data.map(videoBlacklist => new Video(videoBlacklist.video))
60 }
61 }),
62 catchError(res => this.restExtractor.handleError(res))
63 )
64 }
65
66 removeVideoFromBlacklist (videoIdArgs: number | number[]) {
67 const videoIds = Array.isArray(videoIdArgs) ? videoIdArgs : [ videoIdArgs ]
68
69 return observableFrom(videoIds)
70 .pipe(
71 concatMap(id => this.authHttp.delete(VideoBlacklistService.BASE_VIDEOS_URL + id + '/blacklist')),
72 toArray(),
73 catchError(err => this.restExtractor.handleError(err))
74 )
75 }
76
77 blacklistVideo (videoId: number, reason: string, unfederate: boolean) {
78 const body = {
79 unfederate,
80 reason
81 }
82
83 return this.authHttp.post(VideoBlacklistService.BASE_VIDEOS_URL + videoId + '/blacklist', body)
84 .pipe(
85 map(this.restExtractor.extractDataBool),
86 catchError(res => this.restExtractor.handleError(res))
87 )
88 }
89}
diff --git a/client/src/app/shared/video-block/index.ts b/client/src/app/shared/video-block/index.ts
new file mode 100644
index 000000000..a99551a38
--- /dev/null
+++ b/client/src/app/shared/video-block/index.ts
@@ -0,0 +1 @@
export * from './video-block.service'
diff --git a/client/src/app/shared/video-block/video-block.service.ts b/client/src/app/shared/video-block/video-block.service.ts
new file mode 100644
index 000000000..67ca1d85b
--- /dev/null
+++ b/client/src/app/shared/video-block/video-block.service.ts
@@ -0,0 +1,77 @@
1import { catchError, map, concatMap, toArray } from 'rxjs/operators'
2import { HttpClient, HttpParams } from '@angular/common/http'
3import { Injectable } from '@angular/core'
4import { SortMeta } from 'primeng/api'
5import { from as observableFrom, Observable } from 'rxjs'
6import { VideoBlocklist, VideoBlockType, ResultList } from '../../../../../shared'
7import { environment } from '../../../environments/environment'
8import { RestExtractor, RestPagination, RestService } from '../rest'
9
10@Injectable()
11export class VideoBlockService {
12 private static BASE_VIDEOS_URL = environment.apiUrl + '/api/v1/videos/'
13
14 constructor (
15 private authHttp: HttpClient,
16 private restService: RestService,
17 private restExtractor: RestExtractor
18 ) {}
19
20 listBlocks (options: {
21 pagination: RestPagination
22 sort: SortMeta
23 search?: string
24 type?: VideoBlockType
25 }): Observable<ResultList<VideoBlocklist>> {
26 const { pagination, sort, search, type } = options
27
28 let params = new HttpParams()
29 params = this.restService.addRestGetParams(params, pagination, sort)
30
31 if (search) {
32 const filters = this.restService.parseQueryStringFilter(search, {
33 type: {
34 prefix: 'type:',
35 handler: v => {
36 if (v === 'manual') return VideoBlockType.MANUAL
37 if (v === 'auto') return VideoBlockType.AUTO_BEFORE_PUBLISHED
38
39 return undefined
40 }
41 }
42 })
43
44 params = this.restService.addObjectParams(params, filters)
45 }
46
47 return this.authHttp.get<ResultList<VideoBlocklist>>(VideoBlockService.BASE_VIDEOS_URL + 'blacklist', { params })
48 .pipe(
49 map(res => this.restExtractor.convertResultListDateToHuman(res)),
50 catchError(res => this.restExtractor.handleError(res))
51 )
52 }
53
54 unblockVideo (videoIdArgs: number | number[]) {
55 const videoIds = Array.isArray(videoIdArgs) ? videoIdArgs : [ videoIdArgs ]
56
57 return observableFrom(videoIds)
58 .pipe(
59 concatMap(id => this.authHttp.delete(VideoBlockService.BASE_VIDEOS_URL + id + '/blacklist')),
60 toArray(),
61 catchError(err => this.restExtractor.handleError(err))
62 )
63 }
64
65 blockVideo (videoId: number, reason: string, unfederate: boolean) {
66 const body = {
67 unfederate,
68 reason
69 }
70
71 return this.authHttp.post(VideoBlockService.BASE_VIDEOS_URL + videoId + '/blacklist', body)
72 .pipe(
73 map(this.restExtractor.extractDataBool),
74 catchError(res => this.restExtractor.handleError(res))
75 )
76 }
77}
diff --git a/client/src/app/shared/video/abstract-video-list.html b/client/src/app/shared/video/abstract-video-list.html
index cd8a5b840..8ce3b25b0 100644
--- a/client/src/app/shared/video/abstract-video-list.html
+++ b/client/src/app/shared/video/abstract-video-list.html
@@ -39,7 +39,7 @@
39 [fitWidth]="true" 39 [fitWidth]="true"
40 [video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType" 40 [video]="video" [user]="user" [ownerDisplayType]="ownerDisplayType"
41 [displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions" 41 [displayVideoActions]="displayVideoActions" [displayOptions]="displayOptions"
42 (videoBlacklisted)="removeVideoFromArray(video)" (videoRemoved)="removeVideoFromArray(video)" 42 (videoBlocked)="removeVideoFromArray(video)" (videoRemoved)="removeVideoFromArray(video)"
43 > 43 >
44 </my-video-miniature> 44 </my-video-miniature>
45 </ng-container> 45 </ng-container>
diff --git a/client/src/app/shared/video/modals/video-blacklist.component.html b/client/src/app/shared/video/modals/video-block.component.html
index 8f06a6b02..a8dd30b5e 100644
--- a/client/src/app/shared/video/modals/video-blacklist.component.html
+++ b/client/src/app/shared/video/modals/video-block.component.html
@@ -1,12 +1,12 @@
1<ng-template #modal> 1<ng-template #modal>
2 <div class="modal-header"> 2 <div class="modal-header">
3 <h4 i18n class="modal-title">Blacklist video</h4> 3 <h4 i18n class="modal-title">Blocklist video</h4>
4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon> 4 <my-global-icon iconName="cross" aria-label="Close" role="button" (click)="hide()"></my-global-icon>
5 </div> 5 </div>
6 6
7 <div class="modal-body"> 7 <div class="modal-body">
8 8
9 <form novalidate [formGroup]="form" (ngSubmit)="blacklist()"> 9 <form novalidate [formGroup]="form" (ngSubmit)="block()">
10 <div class="form-group"> 10 <div class="form-group">
11 <textarea 11 <textarea
12 i18n-placeholder placeholder="Reason..." formControlName="reason" 12 i18n-placeholder placeholder="Reason..." formControlName="reason"
diff --git a/client/src/app/shared/video/modals/video-blacklist.component.scss b/client/src/app/shared/video/modals/video-block.component.scss
index afcdb9a16..afcdb9a16 100644
--- a/client/src/app/shared/video/modals/video-blacklist.component.scss
+++ b/client/src/app/shared/video/modals/video-block.component.scss
diff --git a/client/src/app/shared/video/modals/video-blacklist.component.ts b/client/src/app/shared/video/modals/video-block.component.ts
index 6ef9c250b..1a25e0578 100644
--- a/client/src/app/shared/video/modals/video-blacklist.component.ts
+++ b/client/src/app/shared/video/modals/video-block.component.ts
@@ -1,24 +1,24 @@
1import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' 1import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
2import { Notifier, RedirectService } from '@app/core' 2import { Notifier, RedirectService } from '@app/core'
3import { VideoBlacklistService } from '../../../shared/video-blacklist' 3import { VideoBlockService } from '../../video-block'
4import { I18n } from '@ngx-translate/i18n-polyfill' 4import { I18n } from '@ngx-translate/i18n-polyfill'
5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 5import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
6import { NgbModal } from '@ng-bootstrap/ng-bootstrap' 6import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
7import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' 7import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref'
8import { FormReactive, VideoBlacklistValidatorsService } from '@app/shared/forms' 8import { FormReactive, VideoBlockValidatorsService } from '@app/shared/forms'
9import { Video } from '@app/shared/video/video.model' 9import { Video } from '@app/shared/video/video.model'
10 10
11@Component({ 11@Component({
12 selector: 'my-video-blacklist', 12 selector: 'my-video-block',
13 templateUrl: './video-blacklist.component.html', 13 templateUrl: './video-block.component.html',
14 styleUrls: [ './video-blacklist.component.scss' ] 14 styleUrls: [ './video-block.component.scss' ]
15}) 15})
16export class VideoBlacklistComponent extends FormReactive implements OnInit { 16export class VideoBlockComponent extends FormReactive implements OnInit {
17 @Input() video: Video = null 17 @Input() video: Video = null
18 18
19 @ViewChild('modal', { static: true }) modal: NgbModal 19 @ViewChild('modal', { static: true }) modal: NgbModal
20 20
21 @Output() videoBlacklisted = new EventEmitter() 21 @Output() videoBlocked = new EventEmitter()
22 22
23 error: string = null 23 error: string = null
24 24
@@ -27,10 +27,9 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
27 constructor ( 27 constructor (
28 protected formValidatorService: FormValidatorService, 28 protected formValidatorService: FormValidatorService,
29 private modalService: NgbModal, 29 private modalService: NgbModal,
30 private videoBlacklistValidatorsService: VideoBlacklistValidatorsService, 30 private videoBlockValidatorsService: VideoBlockValidatorsService,
31 private videoBlacklistService: VideoBlacklistService, 31 private videoBlocklistService: VideoBlockService,
32 private notifier: Notifier, 32 private notifier: Notifier,
33 private redirectService: RedirectService,
34 private i18n: I18n 33 private i18n: I18n
35 ) { 34 ) {
36 super() 35 super()
@@ -40,7 +39,7 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
40 const defaultValues = { unfederate: 'true' } 39 const defaultValues = { unfederate: 'true' }
41 40
42 this.buildForm({ 41 this.buildForm({
43 reason: this.videoBlacklistValidatorsService.VIDEO_BLACKLIST_REASON, 42 reason: this.videoBlockValidatorsService.VIDEO_BLOCK_REASON,
44 unfederate: null 43 unfederate: null
45 }, defaultValues) 44 }, defaultValues)
46 } 45 }
@@ -54,20 +53,20 @@ export class VideoBlacklistComponent extends FormReactive implements OnInit {
54 this.openedModal = null 53 this.openedModal = null
55 } 54 }
56 55
57 blacklist () { 56 block () {
58 const reason = this.form.value[ 'reason' ] || undefined 57 const reason = this.form.value[ 'reason' ] || undefined
59 const unfederate = this.video.isLocal ? this.form.value[ 'unfederate' ] : undefined 58 const unfederate = this.video.isLocal ? this.form.value[ 'unfederate' ] : undefined
60 59
61 this.videoBlacklistService.blacklistVideo(this.video.id, reason, unfederate) 60 this.videoBlocklistService.blockVideo(this.video.id, reason, unfederate)
62 .subscribe( 61 .subscribe(
63 () => { 62 () => {
64 this.notifier.success(this.i18n('Video blacklisted.')) 63 this.notifier.success(this.i18n('Video blocked.'))
65 this.hide() 64 this.hide()
66 65
67 this.video.blacklisted = true 66 this.video.blacklisted = true
68 this.video.blacklistedReason = reason 67 this.video.blockedReason = reason
69 68
70 this.videoBlacklisted.emit() 69 this.videoBlocked.emit()
71 }, 70 },
72 71
73 err => this.notifier.error(err.message) 72 err => this.notifier.error(err.message)
diff --git a/client/src/app/shared/video/video-actions-dropdown.component.html b/client/src/app/shared/video/video-actions-dropdown.component.html
index ec03fa55d..3c8271b65 100644
--- a/client/src/app/shared/video/video-actions-dropdown.component.html
+++ b/client/src/app/shared/video/video-actions-dropdown.component.html
@@ -17,5 +17,5 @@
17 17
18 <my-video-download #videoDownloadModal></my-video-download> 18 <my-video-download #videoDownloadModal></my-video-download>
19 <my-video-report #videoReportModal [video]="video"></my-video-report> 19 <my-video-report #videoReportModal [video]="video"></my-video-report>
20 <my-video-blacklist #videoBlacklistModal [video]="video" (videoBlacklisted)="onVideoBlacklisted()"></my-video-blacklist> 20 <my-video-block #videoBlockModal [video]="video" (videoBlocked)="onVideoBlocked()"></my-video-block>
21</ng-container> 21</ng-container>
diff --git a/client/src/app/shared/video/video-actions-dropdown.component.ts b/client/src/app/shared/video/video-actions-dropdown.component.ts
index 4e5fc6476..1f5763610 100644
--- a/client/src/app/shared/video/video-actions-dropdown.component.ts
+++ b/client/src/app/shared/video/video-actions-dropdown.component.ts
@@ -9,8 +9,8 @@ import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
9import { VideoAddToPlaylistComponent } from '@app/shared/video-playlist/video-add-to-playlist.component' 9import { VideoAddToPlaylistComponent } from '@app/shared/video-playlist/video-add-to-playlist.component'
10import { VideoDownloadComponent } from '@app/shared/video/modals/video-download.component' 10import { VideoDownloadComponent } from '@app/shared/video/modals/video-download.component'
11import { VideoReportComponent } from '@app/shared/video/modals/video-report.component' 11import { VideoReportComponent } from '@app/shared/video/modals/video-report.component'
12import { VideoBlacklistComponent } from '@app/shared/video/modals/video-blacklist.component' 12import { VideoBlockComponent } from '@app/shared/video/modals/video-block.component'
13import { VideoBlacklistService } from '@app/shared/video-blacklist' 13import { VideoBlockService } from '@app/shared/video-block'
14import { ScreenService } from '@app/shared/misc/screen.service' 14import { ScreenService } from '@app/shared/misc/screen.service'
15import { VideoCaption } from '@shared/models' 15import { VideoCaption } from '@shared/models'
16import { RedundancyService } from '@app/shared/video/redundancy.service' 16import { RedundancyService } from '@app/shared/video/redundancy.service'
@@ -36,7 +36,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
36 36
37 @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent 37 @ViewChild('videoDownloadModal') videoDownloadModal: VideoDownloadComponent
38 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent 38 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
39 @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent 39 @ViewChild('videoBlockModal') videoBlockModal: VideoBlockComponent
40 40
41 @Input() video: Video | VideoDetails 41 @Input() video: Video | VideoDetails
42 @Input() videoCaptions: VideoCaption[] = [] 42 @Input() videoCaptions: VideoCaption[] = []
@@ -59,8 +59,8 @@ export class VideoActionsDropdownComponent implements OnChanges {
59 @Input() buttonDirection: DropdownDirection = 'vertical' 59 @Input() buttonDirection: DropdownDirection = 'vertical'
60 60
61 @Output() videoRemoved = new EventEmitter() 61 @Output() videoRemoved = new EventEmitter()
62 @Output() videoUnblacklisted = new EventEmitter() 62 @Output() videoUnblocked = new EventEmitter()
63 @Output() videoBlacklisted = new EventEmitter() 63 @Output() videoBlocked = new EventEmitter()
64 @Output() modalOpened = new EventEmitter() 64 @Output() modalOpened = new EventEmitter()
65 65
66 videoActions: DropdownAction<{ video: Video }>[][] = [] 66 videoActions: DropdownAction<{ video: Video }>[][] = []
@@ -71,7 +71,7 @@ export class VideoActionsDropdownComponent implements OnChanges {
71 private authService: AuthService, 71 private authService: AuthService,
72 private notifier: Notifier, 72 private notifier: Notifier,
73 private confirmService: ConfirmService, 73 private confirmService: ConfirmService,
74 private videoBlacklistService: VideoBlacklistService, 74 private videoBlocklistService: VideoBlockService,
75 private screenService: ScreenService, 75 private screenService: ScreenService,
76 private videoService: VideoService, 76 private videoService: VideoService,
77 private redundancyService: RedundancyService, 77 private redundancyService: RedundancyService,
@@ -117,10 +117,10 @@ export class VideoActionsDropdownComponent implements OnChanges {
117 this.videoReportModal.show() 117 this.videoReportModal.show()
118 } 118 }
119 119
120 showBlacklistModal () { 120 showBlockModal () {
121 this.modalOpened.emit() 121 this.modalOpened.emit()
122 122
123 this.videoBlacklistModal.show() 123 this.videoBlockModal.show()
124 } 124 }
125 125
126 /* Actions checker */ 126 /* Actions checker */
@@ -133,12 +133,12 @@ export class VideoActionsDropdownComponent implements OnChanges {
133 return this.video.isRemovableBy(this.user) 133 return this.video.isRemovableBy(this.user)
134 } 134 }
135 135
136 isVideoBlacklistable () { 136 isVideoBlockable () {
137 return this.video.isBlackistableBy(this.user) 137 return this.video.isBlockableBy(this.user)
138 } 138 }
139 139
140 isVideoUnblacklistable () { 140 isVideoUnblockable () {
141 return this.video.isUnblacklistableBy(this.user) 141 return this.video.isUnblockableBy(this.user)
142 } 142 }
143 143
144 isVideoDownloadable () { 144 isVideoDownloadable () {
@@ -151,22 +151,22 @@ export class VideoActionsDropdownComponent implements OnChanges {
151 151
152 /* Action handlers */ 152 /* Action handlers */
153 153
154 async unblacklistVideo () { 154 async unblockVideo () {
155 const confirmMessage = this.i18n( 155 const confirmMessage = this.i18n(
156 'Do you really want to remove this video from the blacklist? It will be available again in the videos list.' 156 'Do you really want to unblock this video? It will be available again in the videos list.'
157 ) 157 )
158 158
159 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblacklist')) 159 const res = await this.confirmService.confirm(confirmMessage, this.i18n('Unblock'))
160 if (res === false) return 160 if (res === false) return
161 161
162 this.videoBlacklistService.removeVideoFromBlacklist(this.video.id).subscribe( 162 this.videoBlocklistService.unblockVideo(this.video.id).subscribe(
163 () => { 163 () => {
164 this.notifier.success(this.i18n('Video {{name}} removed from the blacklist.', { name: this.video.name })) 164 this.notifier.success(this.i18n('Video {{name}} unblocked.', { name: this.video.name }))
165 165
166 this.video.blacklisted = false 166 this.video.blacklisted = false
167 this.video.blacklistedReason = null 167 this.video.blockedReason = null
168 168
169 this.videoUnblacklisted.emit() 169 this.videoUnblocked.emit()
170 }, 170 },
171 171
172 err => this.notifier.error(err.message) 172 err => this.notifier.error(err.message)
@@ -203,8 +203,8 @@ export class VideoActionsDropdownComponent implements OnChanges {
203 ) 203 )
204 } 204 }
205 205
206 onVideoBlacklisted () { 206 onVideoBlocked () {
207 this.videoBlacklisted.emit() 207 this.videoBlocked.emit()
208 } 208 }
209 209
210 getPlaylistDropdownPlacement () { 210 getPlaylistDropdownPlacement () {
@@ -239,16 +239,16 @@ export class VideoActionsDropdownComponent implements OnChanges {
239 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable() 239 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable()
240 }, 240 },
241 { 241 {
242 label: this.i18n('Blacklist'), 242 label: this.i18n('Block'),
243 handler: () => this.showBlacklistModal(), 243 handler: () => this.showBlockModal(),
244 iconName: 'no', 244 iconName: 'no',
245 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlacklistable() 245 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlockable()
246 }, 246 },
247 { 247 {
248 label: this.i18n('Unblacklist'), 248 label: this.i18n('Unblock'),
249 handler: () => this.unblacklistVideo(), 249 handler: () => this.unblockVideo(),
250 iconName: 'undo', 250 iconName: 'undo',
251 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblacklistable() 251 isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblockable()
252 }, 252 },
253 { 253 {
254 label: this.i18n('Mirror'), 254 label: this.i18n('Mirror'),
diff --git a/client/src/app/shared/video/video-miniature.component.html b/client/src/app/shared/video/video-miniature.component.html
index 3e23cf18c..575505f63 100644
--- a/client/src/app/shared/video/video-miniature.component.html
+++ b/client/src/app/shared/video/video-miniature.component.html
@@ -43,9 +43,9 @@
43 </div> 43 </div>
44 </div> 44 </div>
45 45
46 <div *ngIf="displayOptions.blacklistInfo && video.blacklisted" class="video-info-blacklisted"> 46 <div *ngIf="displayOptions.blacklistInfo && video.blacklisted" class="video-info-blocked">
47 <span class="blacklisted-label" i18n>Blacklisted</span> 47 <span class="blocked-label" i18n>Blocked</span>
48 <span class="blacklisted-reason" *ngIf="video.blacklistedReason">{{ video.blacklistedReason }}</span> 48 <span class="blocked-reason" *ngIf="video.blockedReason">{{ video.blockedReason }}</span>
49 </div> 49 </div>
50 50
51 <div i18n *ngIf="displayOptions.nsfw && video.nsfw" class="video-info-nsfw"> 51 <div i18n *ngIf="displayOptions.nsfw && video.nsfw" class="video-info-nsfw">
@@ -57,7 +57,7 @@
57 <!-- FIXME: remove bottom placement when overflow is fixed in bootstrap dropdown: https://github.com/ng-bootstrap/ng-bootstrap/issues/3495 --> 57 <!-- FIXME: remove bottom placement when overflow is fixed in bootstrap dropdown: https://github.com/ng-bootstrap/ng-bootstrap/issues/3495 -->
58 <my-video-actions-dropdown 58 <my-video-actions-dropdown
59 *ngIf="showActions" [video]="video" [displayOptions]="videoActionsDisplayOptions" placement="bottom-left bottom-right left auto" 59 *ngIf="showActions" [video]="video" [displayOptions]="videoActionsDisplayOptions" placement="bottom-left bottom-right left auto"
60 (videoRemoved)="onVideoRemoved()" (videoBlacklisted)="onVideoBlacklisted()" (videoUnblacklisted)="onVideoUnblacklisted()" 60 (videoRemoved)="onVideoRemoved()" (videoBlocked)="onVideoBlocked()" (videoUnblocked)="onVideoUnblocked()"
61 ></my-video-actions-dropdown> 61 ></my-video-actions-dropdown>
62 </div> 62 </div>
63 </div> 63 </div>
diff --git a/client/src/app/shared/video/video-miniature.component.scss b/client/src/app/shared/video/video-miniature.component.scss
index 849bd54bb..34f34f228 100644
--- a/client/src/app/shared/video/video-miniature.component.scss
+++ b/client/src/app/shared/video/video-miniature.component.scss
@@ -45,15 +45,15 @@ $more-margin-right: 15px;
45 } 45 }
46 46
47 .video-info-privacy, 47 .video-info-privacy,
48 .video-info-blacklisted .blacklisted-label, 48 .video-info-blocked .blocked-label,
49 .video-info-nsfw { 49 .video-info-nsfw {
50 font-weight: $font-semibold; 50 font-weight: $font-semibold;
51 } 51 }
52 52
53 .video-info-blacklisted { 53 .video-info-blocked {
54 color: red; 54 color: red;
55 55
56 .blacklisted-reason::before { 56 .blocked-reason::before {
57 content: ' - '; 57 content: ' - ';
58 } 58 }
59 } 59 }
@@ -160,7 +160,7 @@ $more-margin-right: 15px;
160 margin-top: 5px; 160 margin-top: 5px;
161 } 161 }
162 162
163 .video-info-blacklisted { 163 .video-info-blocked {
164 margin-top: 3px; 164 margin-top: 3px;
165 } 165 }
166 } 166 }
diff --git a/client/src/app/shared/video/video-miniature.component.ts b/client/src/app/shared/video/video-miniature.component.ts
index aa1726ca7..f0b0992e2 100644
--- a/client/src/app/shared/video/video-miniature.component.ts
+++ b/client/src/app/shared/video/video-miniature.component.ts
@@ -59,8 +59,8 @@ export class VideoMiniatureComponent implements OnInit {
59 59
60 @Input() useLazyLoadUrl = false 60 @Input() useLazyLoadUrl = false
61 61
62 @Output() videoBlacklisted = new EventEmitter() 62 @Output() videoBlocked = new EventEmitter()
63 @Output() videoUnblacklisted = new EventEmitter() 63 @Output() videoUnblocked = new EventEmitter()
64 @Output() videoRemoved = new EventEmitter() 64 @Output() videoRemoved = new EventEmitter()
65 65
66 videoActionsDisplayOptions: VideoActionsDisplayType = { 66 videoActionsDisplayOptions: VideoActionsDisplayType = {
@@ -184,12 +184,12 @@ export class VideoMiniatureComponent implements OnInit {
184 this.loadWatchLater() 184 this.loadWatchLater()
185 } 185 }
186 186
187 onVideoBlacklisted () { 187 onVideoBlocked () {
188 this.videoBlacklisted.emit() 188 this.videoBlocked.emit()
189 } 189 }
190 190
191 onVideoUnblacklisted () { 191 onVideoUnblocked () {
192 this.videoUnblacklisted.emit() 192 this.videoUnblocked.emit()
193 } 193 }
194 194
195 onVideoRemoved () { 195 onVideoRemoved () {
diff --git a/client/src/app/shared/video/video.model.ts b/client/src/app/shared/video/video.model.ts
index 97759f9c1..2b3d915ef 100644
--- a/client/src/app/shared/video/video.model.ts
+++ b/client/src/app/shared/video/video.model.ts
@@ -54,7 +54,7 @@ export class Video implements VideoServerModel {
54 state?: VideoConstant<VideoState> 54 state?: VideoConstant<VideoState>
55 scheduledUpdate?: VideoScheduleUpdate 55 scheduledUpdate?: VideoScheduleUpdate
56 blacklisted?: boolean 56 blacklisted?: boolean
57 blacklistedReason?: string 57 blockedReason?: string
58 58
59 account: { 59 account: {
60 id: number 60 id: number
@@ -140,7 +140,7 @@ export class Video implements VideoServerModel {
140 if (this.state) this.state.label = peertubeTranslate(this.state.label, translations) 140 if (this.state) this.state.label = peertubeTranslate(this.state.label, translations)
141 141
142 this.blacklisted = hash.blacklisted 142 this.blacklisted = hash.blacklisted
143 this.blacklistedReason = hash.blacklistedReason 143 this.blockedReason = hash.blacklistedReason
144 144
145 this.userHistory = hash.userHistory 145 this.userHistory = hash.userHistory
146 146
@@ -163,12 +163,12 @@ export class Video implements VideoServerModel {
163 return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.REMOVE_ANY_VIDEO)) 163 return user && this.isLocal === true && (this.account.name === user.username || user.hasRight(UserRight.REMOVE_ANY_VIDEO))
164 } 164 }
165 165
166 isBlackistableBy (user: AuthUser) { 166 isBlockableBy (user: AuthUser) {
167 return this.blacklisted !== true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true 167 return this.blacklisted !== true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLOCKS) === true
168 } 168 }
169 169
170 isUnblacklistableBy (user: AuthUser) { 170 isUnblockableBy (user: AuthUser) {
171 return this.blacklisted === true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) === true 171 return this.blacklisted === true && user && user.hasRight(UserRight.MANAGE_VIDEO_BLOCKS) === true
172 } 172 }
173 173
174 isUpdatableBy (user: AuthUser) { 174 isUpdatableBy (user: AuthUser) {
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 433543a7b..63103e2e7 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.html
+++ b/client/src/app/videos/+video-watch/video-watch.component.html
@@ -29,8 +29,8 @@
29 </div> 29 </div>
30 30
31 <div class="col-md-12 alert alert-danger" *ngIf="video?.blacklisted"> 31 <div class="col-md-12 alert alert-danger" *ngIf="video?.blacklisted">
32 <div class="blacklisted-label" i18n>This video is blacklisted.</div> 32 <div class="blocked-label" i18n>This video is blocked.</div>
33 {{ video.blacklistedReason }} 33 {{ video.blockedReason }}
34 </div> 34 </div>
35 </div> 35 </div>
36 36
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 8be0bab1d..e0d41117a 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/videos/+video-watch/video-watch.component.scss
@@ -45,7 +45,7 @@ $video-info-margin-left: 44px;
45 } 45 }
46} 46}
47 47
48.blacklisted-label { 48.blocked-label {
49 font-weight: $font-semibold; 49 font-weight: $font-semibold;
50} 50}
51 51
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 3790c7f6a..9f726cf35 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -335,7 +335,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
335 this.videoCaptionService.listCaptions(videoId) 335 this.videoCaptionService.listCaptions(videoId)
336 ]) 336 ])
337 .pipe( 337 .pipe(
338 // If 401, the video is private or blacklisted so redirect to 404 338 // If 401, the video is private or blocklisted so redirect to 404
339 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])) 339 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]))
340 ) 340 )
341 .subscribe(([ video, captionsResult ]) => { 341 .subscribe(([ video, captionsResult ]) => {
@@ -364,7 +364,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
364 364
365 this.playlistService.getVideoPlaylist(playlistId) 365 this.playlistService.getVideoPlaylist(playlistId)
366 .pipe( 366 .pipe(
367 // If 401, the video is private or blacklisted so redirect to 404 367 // If 401, the video is private or blocklisted so redirect to 404
368 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])) 368 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ]))
369 ) 369 )
370 .subscribe(playlist => { 370 .subscribe(playlist => {
diff --git a/client/src/app/videos/recommendations/recommended-videos.component.html b/client/src/app/videos/recommendations/recommended-videos.component.html
index c6bdfee46..e4568c309 100644
--- a/client/src/app/videos/recommendations/recommended-videos.component.html
+++ b/client/src/app/videos/recommendations/recommended-videos.component.html
@@ -13,7 +13,7 @@
13 </div> 13 </div>
14 14
15 <div *ngFor="let video of (videos$ | async); let i = index; let length = count"> 15 <div *ngFor="let video of (videos$ | async); let i = index; let length = count">
16 <my-video-miniature [displayOptions]="displayOptions" [video]="video" [user]="user" (videoBlacklisted)="onVideoRemoved()" (videoRemoved)="onVideoRemoved()"> 16 <my-video-miniature [displayOptions]="displayOptions" [video]="video" [user]="user" (videoBlocked)="onVideoRemoved()" (videoRemoved)="onVideoRemoved()">
17 </my-video-miniature> 17 </my-video-miniature>
18 18
19 <hr *ngIf="!playlist && i == 0 && length > 1" /> 19 <hr *ngIf="!playlist && i == 0 && length > 1" />
diff --git a/client/src/assets/images/global/robot.svg b/client/src/assets/images/global/robot.svg
new file mode 100644
index 000000000..46db9baef
--- /dev/null
+++ b/client/src/assets/images/global/robot.svg
@@ -0,0 +1,11 @@
1<svg xmlns="http://www.w3.org/2000/svg" height="24px" width="24px" viewBox="0 0 24 24">
2 <defs/>
3 <g fill="none" fill-rule="evenodd">
4 <rect width="22" height="14" x="1" y="7" stroke="#000" stroke-width="2" rx="2"/>
5 <path fill="#000" d="M11 3h2v4h-2z"/>
6 <circle cx="12" cy="2" r="2" fill="#000"/>
7 <circle cx="18" cy="12" r="2" fill="#000"/>
8 <circle cx="6" cy="12" r="2" fill="#000"/>
9 <path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 15c0 1.1.9 2 2 2h0a2 2 0 002-2"/>
10 </g>
11</svg>
diff --git a/server/controllers/api/videos/blacklist.ts b/server/controllers/api/videos/blacklist.ts
index 3b25ceea2..2c6948923 100644
--- a/server/controllers/api/videos/blacklist.ts
+++ b/server/controllers/api/videos/blacklist.ts
@@ -23,14 +23,14 @@ const blacklistRouter = express.Router()
23 23
24blacklistRouter.post('/:videoId/blacklist', 24blacklistRouter.post('/:videoId/blacklist',
25 authenticate, 25 authenticate,
26 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), 26 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLOCKS),
27 asyncMiddleware(videosBlacklistAddValidator), 27 asyncMiddleware(videosBlacklistAddValidator),
28 asyncMiddleware(addVideoToBlacklistController) 28 asyncMiddleware(addVideoToBlacklistController)
29) 29)
30 30
31blacklistRouter.get('/blacklist', 31blacklistRouter.get('/blacklist',
32 authenticate, 32 authenticate,
33 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), 33 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLOCKS),
34 paginationValidator, 34 paginationValidator,
35 blacklistSortValidator, 35 blacklistSortValidator,
36 setBlacklistSort, 36 setBlacklistSort,
@@ -41,14 +41,14 @@ blacklistRouter.get('/blacklist',
41 41
42blacklistRouter.put('/:videoId/blacklist', 42blacklistRouter.put('/:videoId/blacklist',
43 authenticate, 43 authenticate,
44 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), 44 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLOCKS),
45 asyncMiddleware(videosBlacklistUpdateValidator), 45 asyncMiddleware(videosBlacklistUpdateValidator),
46 asyncMiddleware(updateVideoBlacklistController) 46 asyncMiddleware(updateVideoBlacklistController)
47) 47)
48 48
49blacklistRouter.delete('/:videoId/blacklist', 49blacklistRouter.delete('/:videoId/blacklist',
50 authenticate, 50 authenticate,
51 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLACKLIST), 51 ensureUserHasRight(UserRight.MANAGE_VIDEO_BLOCKS),
52 asyncMiddleware(videosBlacklistRemoveValidator), 52 asyncMiddleware(videosBlacklistRemoveValidator),
53 asyncMiddleware(removeVideoFromBlacklistController) 53 asyncMiddleware(removeVideoFromBlacklistController)
54) 54)
diff --git a/server/helpers/custom-validators/video-blacklist.ts b/server/helpers/custom-validators/video-blacklist.ts
index 17cb3b00b..de6726b8f 100644
--- a/server/helpers/custom-validators/video-blacklist.ts
+++ b/server/helpers/custom-validators/video-blacklist.ts
@@ -1,7 +1,7 @@
1import validator from 'validator' 1import validator from 'validator'
2import { exists } from './misc' 2import { exists } from './misc'
3import { CONSTRAINTS_FIELDS } from '../../initializers/constants' 3import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
4import { VideoBlacklistType } from '../../../shared/models/videos' 4import { VideoBlockType } from '../../../shared/models/videos'
5 5
6const VIDEO_BLACKLIST_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_BLACKLIST 6const VIDEO_BLACKLIST_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_BLACKLIST
7 7
@@ -10,7 +10,7 @@ function isVideoBlacklistReasonValid (value: string) {
10} 10}
11 11
12function isVideoBlacklistTypeValid (value: any) { 12function isVideoBlacklistTypeValid (value: any) {
13 return exists(value) && validator.isInt('' + value) && VideoBlacklistType[value] !== undefined 13 return exists(value) && validator.isInt('' + value) && VideoBlockType[value] !== undefined
14} 14}
15 15
16// --------------------------------------------------------------------------- 16// ---------------------------------------------------------------------------
diff --git a/server/initializers/migrations/0350-video-blacklist-type.ts b/server/initializers/migrations/0350-video-blacklist-type.ts
index f79ae5ec7..22c82e431 100644
--- a/server/initializers/migrations/0350-video-blacklist-type.ts
+++ b/server/initializers/migrations/0350-video-blacklist-type.ts
@@ -1,5 +1,5 @@
1import * as Sequelize from 'sequelize' 1import * as Sequelize from 'sequelize'
2import { VideoBlacklistType } from '../../../shared/models/videos' 2import { VideoBlockType } from '../../../shared/models/videos'
3 3
4async function up (utils: { 4async function up (utils: {
5 transaction: Sequelize.Transaction 5 transaction: Sequelize.Transaction
@@ -18,7 +18,7 @@ async function up (utils: {
18 } 18 }
19 19
20 { 20 {
21 const query = 'UPDATE "videoBlacklist" SET "type" = ' + VideoBlacklistType.MANUAL 21 const query = 'UPDATE "videoBlacklist" SET "type" = ' + VideoBlockType.MANUAL
22 await utils.sequelize.query(query) 22 await utils.sequelize.query(query)
23 } 23 }
24 24
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts
index 89f91e031..3e90bb57e 100644
--- a/server/lib/notifier.ts
+++ b/server/lib/notifier.ts
@@ -387,7 +387,7 @@ class Notifier {
387 } 387 }
388 388
389 private async notifyModeratorsOfVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo) { 389 private async notifyModeratorsOfVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo) {
390 const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_BLACKLIST) 390 const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_BLOCKS)
391 if (moderators.length === 0) return 391 if (moderators.length === 0) return
392 392
393 logger.info('Notifying %s moderators of video auto-blacklist %s.', moderators.length, videoBlacklist.Video.url) 393 logger.info('Notifying %s moderators of video auto-blacklist %s.', moderators.length, videoBlacklist.Video.url)
@@ -398,7 +398,7 @@ class Notifier {
398 398
399 async function notificationCreator (user: MUserWithNotificationSetting) { 399 async function notificationCreator (user: MUserWithNotificationSetting) {
400 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 400 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
401 type: UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS, 401 type: UserNotificationType.VIDEO_AUTO_BLOCK_FOR_MODERATORS,
402 userId: user.id, 402 userId: user.id,
403 videoBlacklistId: videoBlacklist.id 403 videoBlacklistId: videoBlacklist.id
404 }) 404 })
@@ -426,7 +426,7 @@ class Notifier {
426 426
427 async function notificationCreator (user: MUserWithNotificationSetting) { 427 async function notificationCreator (user: MUserWithNotificationSetting) {
428 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 428 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
429 type: UserNotificationType.BLACKLIST_ON_MY_VIDEO, 429 type: UserNotificationType.BLOCK_ON_MY_VIDEO,
430 userId: user.id, 430 userId: user.id,
431 videoBlacklistId: videoBlacklist.id 431 videoBlacklistId: videoBlacklist.id
432 }) 432 })
@@ -454,7 +454,7 @@ class Notifier {
454 454
455 async function notificationCreator (user: MUserWithNotificationSetting) { 455 async function notificationCreator (user: MUserWithNotificationSetting) {
456 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({ 456 const notification = await UserNotificationModel.create<UserNotificationModelForApi>({
457 type: UserNotificationType.UNBLACKLIST_ON_MY_VIDEO, 457 type: UserNotificationType.UNBLOCK_ON_MY_VIDEO,
458 userId: user.id, 458 userId: user.id,
459 videoId: video.id 459 videoId: video.id
460 }) 460 })
diff --git a/server/lib/video-blacklist.ts b/server/lib/video-blacklist.ts
index bd60c6201..f1657e8f1 100644
--- a/server/lib/video-blacklist.ts
+++ b/server/lib/video-blacklist.ts
@@ -8,7 +8,7 @@ import {
8 MVideoFullLight, 8 MVideoFullLight,
9 MVideoWithBlacklistLight 9 MVideoWithBlacklistLight
10} from '@server/typings/models' 10} from '@server/typings/models'
11import { UserRight, VideoBlacklistCreate, VideoBlacklistType } from '../../shared/models' 11import { UserRight, VideoBlacklistCreate, VideoBlockType } from '../../shared/models'
12import { UserAdminFlag } from '../../shared/models/users/user-flag.model' 12import { UserAdminFlag } from '../../shared/models/users/user-flag.model'
13import { logger } from '../helpers/logger' 13import { logger } from '../helpers/logger'
14import { CONFIG } from '../initializers/config' 14import { CONFIG } from '../initializers/config'
@@ -39,7 +39,7 @@ async function autoBlacklistVideoIfNeeded (parameters: {
39 videoId: video.id, 39 videoId: video.id,
40 unfederated: true, 40 unfederated: true,
41 reason: 'Auto-blacklisted. Moderator review required.', 41 reason: 'Auto-blacklisted. Moderator review required.',
42 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 42 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
43 } 43 }
44 const [ videoBlacklist ] = await VideoBlacklistModel.findOrCreate<MVideoBlacklistVideo>({ 44 const [ videoBlacklist ] = await VideoBlacklistModel.findOrCreate<MVideoBlacklistVideo>({
45 where: { 45 where: {
@@ -64,7 +64,7 @@ async function blacklistVideo (videoInstance: MVideoAccountLight, options: Video
64 videoId: videoInstance.id, 64 videoId: videoInstance.id,
65 unfederated: options.unfederate === true, 65 unfederated: options.unfederate === true,
66 reason: options.reason, 66 reason: options.reason,
67 type: VideoBlacklistType.MANUAL 67 type: VideoBlockType.MANUAL
68 } 68 }
69 ) 69 )
70 blacklist.Video = videoInstance 70 blacklist.Video = videoInstance
@@ -94,7 +94,7 @@ async function unblacklistVideo (videoBlacklist: MVideoBlacklist, video: MVideoF
94 94
95 Notifier.Instance.notifyOnVideoUnblacklist(video) 95 Notifier.Instance.notifyOnVideoUnblacklist(video)
96 96
97 if (videoBlacklistType === VideoBlacklistType.AUTO_BEFORE_PUBLISHED) { 97 if (videoBlacklistType === VideoBlockType.AUTO_BEFORE_PUBLISHED) {
98 Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video) 98 Notifier.Instance.notifyOnVideoPublishedAfterRemovedFromAutoBlacklist(video)
99 99
100 // Delete on object so new video notifications will send 100 // Delete on object so new video notifications will send
@@ -126,7 +126,7 @@ function autoBlacklistNeeded (parameters: {
126 if (!CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED || !user) return false 126 if (!CONFIG.AUTO_BLACKLIST.VIDEOS.OF_USERS.ENABLED || !user) return false
127 if (isRemote || isNew === false) return false 127 if (isRemote || isNew === false) return false
128 128
129 if (user.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) || user.hasAdminFlag(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)) return false 129 if (user.hasRight(UserRight.MANAGE_VIDEO_BLOCKS) || user.hasAdminFlag(UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK)) return false
130 130
131 return true 131 return true
132} 132}
diff --git a/server/models/account/user.ts b/server/models/account/user.ts
index fbd3080c6..4ea175583 100644
--- a/server/models/account/user.ts
+++ b/server/models/account/user.ts
@@ -739,11 +739,11 @@ export class UserModel extends Model<UserModel> {
739 const videoUserId = video.VideoChannel.Account.userId 739 const videoUserId = video.VideoChannel.Account.userId
740 740
741 if (video.isBlacklisted()) { 741 if (video.isBlacklisted()) {
742 return videoUserId === this.id || this.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) 742 return videoUserId === this.id || this.hasRight(UserRight.MANAGE_VIDEO_BLOCKS)
743 } 743 }
744 744
745 if (video.privacy === VideoPrivacy.PRIVATE) { 745 if (video.privacy === VideoPrivacy.PRIVATE) {
746 return video.VideoChannel && videoUserId === this.id || this.hasRight(UserRight.MANAGE_VIDEO_BLACKLIST) 746 return video.VideoChannel && videoUserId === this.id || this.hasRight(UserRight.MANAGE_VIDEO_BLOCKS)
747 } 747 }
748 748
749 if (video.privacy === VideoPrivacy.INTERNAL) return true 749 if (video.privacy === VideoPrivacy.INTERNAL) return true
diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts
index 8cbfe362e..70a6ecb03 100644
--- a/server/models/video/video-blacklist.ts
+++ b/server/models/video/video-blacklist.ts
@@ -3,7 +3,7 @@ import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '..
3import { VideoModel } from './video' 3import { VideoModel } from './video'
4import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' 4import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
5import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' 5import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
6import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos' 6import { VideoBlocklist, VideoBlockType } from '../../../shared/models/videos'
7import { CONSTRAINTS_FIELDS } from '../../initializers/constants' 7import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
8import { FindOptions } from 'sequelize' 8import { FindOptions } from 'sequelize'
9import { ThumbnailModel } from './thumbnail' 9import { ThumbnailModel } from './thumbnail'
@@ -34,7 +34,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
34 @Default(null) 34 @Default(null)
35 @Is('VideoBlacklistType', value => throwIfNotValid(value, isVideoBlacklistTypeValid, 'type')) 35 @Is('VideoBlacklistType', value => throwIfNotValid(value, isVideoBlacklistTypeValid, 'type'))
36 @Column 36 @Column
37 type: VideoBlacklistType 37 type: VideoBlockType
38 38
39 @CreatedAt 39 @CreatedAt
40 createdAt: Date 40 createdAt: Date
@@ -59,7 +59,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
59 count: number 59 count: number
60 sort: SortType 60 sort: SortType
61 search?: string 61 search?: string
62 type?: VideoBlacklistType 62 type?: VideoBlockType
63 }) { 63 }) {
64 const { start, count, sort, search, type } = parameters 64 const { start, count, sort, search, type } = parameters
65 65
@@ -119,7 +119,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
119 return VideoBlacklistModel.findOne(query) 119 return VideoBlacklistModel.findOne(query)
120 } 120 }
121 121
122 toFormattedJSON (this: MVideoBlacklistFormattable): VideoBlacklist { 122 toFormattedJSON (this: MVideoBlacklistFormattable): VideoBlocklist {
123 return { 123 return {
124 id: this.id, 124 id: this.id,
125 createdAt: this.createdAt, 125 createdAt: this.createdAt,
diff --git a/server/tests/api/check-params/users.ts b/server/tests/api/check-params/users.ts
index 6e737af15..94d47408a 100644
--- a/server/tests/api/check-params/users.ts
+++ b/server/tests/api/check-params/users.ts
@@ -188,7 +188,7 @@ describe('Test users API validators', function () {
188 videoQuota: -1, 188 videoQuota: -1,
189 videoQuotaDaily: -1, 189 videoQuotaDaily: -1,
190 role: UserRole.USER, 190 role: UserRole.USER,
191 adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST 191 adminFlags: UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK
192 } 192 }
193 193
194 it('Should fail with a too small username', async function () { 194 it('Should fail with a too small username', async function () {
diff --git a/server/tests/api/check-params/video-blacklist.ts b/server/tests/api/check-params/video-blacklist.ts
index 145f43980..b96c26989 100644
--- a/server/tests/api/check-params/video-blacklist.ts
+++ b/server/tests/api/check-params/video-blacklist.ts
@@ -24,7 +24,7 @@ import {
24 checkBadSortPagination, 24 checkBadSortPagination,
25 checkBadStartPagination 25 checkBadStartPagination
26} from '../../../../shared/extra-utils/requests/check-api-params' 26} from '../../../../shared/extra-utils/requests/check-api-params'
27import { VideoBlacklistType, VideoDetails } from '../../../../shared/models/videos' 27import { VideoBlockType, VideoDetails } from '../../../../shared/models/videos'
28import { expect } from 'chai' 28import { expect } from 'chai'
29 29
30describe('Test video blacklist API validators', function () { 30describe('Test video blacklist API validators', function () {
@@ -243,7 +243,7 @@ describe('Test video blacklist API validators', function () {
243 }) 243 })
244 244
245 it('Should succeed with the correct parameters', async function () { 245 it('Should succeed with the correct parameters', async function () {
246 await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, type: VideoBlacklistType.MANUAL }) 246 await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, type: VideoBlockType.MANUAL })
247 }) 247 })
248 }) 248 })
249 249
diff --git a/server/tests/api/users/users.ts b/server/tests/api/users/users.ts
index c0cbce360..af5a5fd25 100644
--- a/server/tests/api/users/users.ts
+++ b/server/tests/api/users/users.ts
@@ -265,7 +265,7 @@ describe('Test users', function () {
265 username: user.username, 265 username: user.username,
266 password: user.password, 266 password: user.password,
267 videoQuota: 2 * 1024 * 1024, 267 videoQuota: 2 * 1024 * 1024,
268 adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST 268 adminFlags: UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK
269 }) 269 })
270 }) 270 })
271 271
@@ -292,7 +292,7 @@ describe('Test users', function () {
292 } 292 }
293 293
294 expect(userMe.adminFlags).to.be.undefined 294 expect(userMe.adminFlags).to.be.undefined
295 expect(userGet.adminFlags).to.equal(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST) 295 expect(userGet.adminFlags).to.equal(UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK)
296 296
297 expect(userMe.specialPlaylists).to.have.lengthOf(1) 297 expect(userMe.specialPlaylists).to.have.lengthOf(1)
298 expect(userMe.specialPlaylists[0].type).to.equal(VideoPlaylistType.WATCH_LATER) 298 expect(userMe.specialPlaylists[0].type).to.equal(VideoPlaylistType.WATCH_LATER)
diff --git a/server/tests/api/videos/video-blacklist.ts b/server/tests/api/videos/video-blacklist.ts
index 67bc0114c..6e15893f3 100644
--- a/server/tests/api/videos/video-blacklist.ts
+++ b/server/tests/api/videos/video-blacklist.ts
@@ -25,7 +25,7 @@ import {
25} from '../../../../shared/extra-utils/index' 25} from '../../../../shared/extra-utils/index'
26import { doubleFollow } from '../../../../shared/extra-utils/server/follows' 26import { doubleFollow } from '../../../../shared/extra-utils/server/follows'
27import { waitJobs } from '../../../../shared/extra-utils/server/jobs' 27import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
28import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos' 28import { VideoBlocklist, VideoBlockType } from '../../../../shared/models/videos'
29import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model' 29import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
30import { User, UserRole } from '../../../../shared/models/users' 30import { User, UserRole } from '../../../../shared/models/users'
31import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports' 31import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
@@ -127,7 +127,7 @@ describe('Test video blacklist', function () {
127 const res = await getBlacklistedVideosList({ 127 const res = await getBlacklistedVideosList({
128 url: servers[0].url, 128 url: servers[0].url,
129 token: servers[0].accessToken, 129 token: servers[0].accessToken,
130 type: VideoBlacklistType.MANUAL 130 type: VideoBlockType.MANUAL
131 }) 131 })
132 132
133 expect(res.body.total).to.equal(2) 133 expect(res.body.total).to.equal(2)
@@ -141,7 +141,7 @@ describe('Test video blacklist', function () {
141 const res = await getBlacklistedVideosList({ 141 const res = await getBlacklistedVideosList({
142 url: servers[0].url, 142 url: servers[0].url,
143 token: servers[0].accessToken, 143 token: servers[0].accessToken,
144 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 144 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
145 }) 145 })
146 146
147 expect(res.body.total).to.equal(0) 147 expect(res.body.total).to.equal(0)
@@ -219,7 +219,7 @@ describe('Test video blacklist', function () {
219 }) 219 })
220 220
221 describe('When removing a blacklisted video', function () { 221 describe('When removing a blacklisted video', function () {
222 let videoToRemove: VideoBlacklist 222 let videoToRemove: VideoBlocklist
223 let blacklist = [] 223 let blacklist = []
224 224
225 it('Should not have any video in videos list on server 1', async function () { 225 it('Should not have any video in videos list on server 1', async function () {
@@ -328,7 +328,7 @@ describe('Test video blacklist', function () {
328 it('Should have the correct video blacklist unfederate attribute', async function () { 328 it('Should have the correct video blacklist unfederate attribute', async function () {
329 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: 'createdAt' }) 329 const res = await getBlacklistedVideosList({ url: servers[0].url, token: servers[0].accessToken, sort: 'createdAt' })
330 330
331 const blacklistedVideos: VideoBlacklist[] = res.body.data 331 const blacklistedVideos: VideoBlocklist[] = res.body.data
332 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID) 332 const video3Blacklisted = blacklistedVideos.find(b => b.video.uuid === video3UUID)
333 const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID) 333 const video4Blacklisted = blacklistedVideos.find(b => b.video.uuid === video4UUID)
334 334
@@ -396,7 +396,7 @@ describe('Test video blacklist', function () {
396 url: servers[0].url, 396 url: servers[0].url,
397 accessToken: servers[0].accessToken, 397 accessToken: servers[0].accessToken,
398 username: user.username, 398 username: user.username,
399 adminFlags: UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST, 399 adminFlags: UserAdminFlag.BYPASS_VIDEO_AUTO_BLOCK,
400 password: user.password, 400 password: user.password,
401 role: UserRole.USER 401 role: UserRole.USER
402 }) 402 })
@@ -413,7 +413,7 @@ describe('Test video blacklist', function () {
413 const res = await getBlacklistedVideosList({ 413 const res = await getBlacklistedVideosList({
414 url: servers[0].url, 414 url: servers[0].url,
415 token: servers[0].accessToken, 415 token: servers[0].accessToken,
416 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 416 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
417 }) 417 })
418 418
419 expect(res.body.total).to.equal(1) 419 expect(res.body.total).to.equal(1)
@@ -434,7 +434,7 @@ describe('Test video blacklist', function () {
434 url: servers[0].url, 434 url: servers[0].url,
435 token: servers[0].accessToken, 435 token: servers[0].accessToken,
436 sort: 'createdAt', 436 sort: 'createdAt',
437 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 437 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
438 }) 438 })
439 439
440 expect(res.body.total).to.equal(2) 440 expect(res.body.total).to.equal(2)
@@ -453,7 +453,7 @@ describe('Test video blacklist', function () {
453 url: servers[0].url, 453 url: servers[0].url,
454 token: servers[0].accessToken, 454 token: servers[0].accessToken,
455 sort: 'createdAt', 455 sort: 'createdAt',
456 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 456 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
457 }) 457 })
458 458
459 expect(res.body.total).to.equal(3) 459 expect(res.body.total).to.equal(3)
@@ -466,7 +466,7 @@ describe('Test video blacklist', function () {
466 const res = await getBlacklistedVideosList({ 466 const res = await getBlacklistedVideosList({
467 url: servers[0].url, 467 url: servers[0].url,
468 token: servers[0].accessToken, 468 token: servers[0].accessToken,
469 type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED 469 type: VideoBlockType.AUTO_BEFORE_PUBLISHED
470 }) 470 })
471 471
472 expect(res.body.total).to.equal(3) 472 expect(res.body.total).to.equal(3)
diff --git a/shared/extra-utils/users/user-notifications.ts b/shared/extra-utils/users/user-notifications.ts
index bd00894c4..6f85bd450 100644
--- a/shared/extra-utils/users/user-notifications.ts
+++ b/shared/extra-utils/users/user-notifications.ts
@@ -455,7 +455,7 @@ async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUU
455} 455}
456 456
457async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) { 457async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
458 const notificationType = UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS 458 const notificationType = UserNotificationType.VIDEO_AUTO_BLOCK_FOR_MODERATORS
459 459
460 function notificationChecker (notification: UserNotification, type: CheckerType) { 460 function notificationChecker (notification: UserNotification, type: CheckerType) {
461 if (type === 'presence') { 461 if (type === 'presence') {
@@ -486,8 +486,8 @@ async function checkNewBlacklistOnMyVideo (
486 blacklistType: 'blacklist' | 'unblacklist' 486 blacklistType: 'blacklist' | 'unblacklist'
487) { 487) {
488 const notificationType = blacklistType === 'blacklist' 488 const notificationType = blacklistType === 'blacklist'
489 ? UserNotificationType.BLACKLIST_ON_MY_VIDEO 489 ? UserNotificationType.BLOCK_ON_MY_VIDEO
490 : UserNotificationType.UNBLACKLIST_ON_MY_VIDEO 490 : UserNotificationType.UNBLOCK_ON_MY_VIDEO
491 491
492 function notificationChecker (notification: UserNotification) { 492 function notificationChecker (notification: UserNotification) {
493 expect(notification).to.not.be.undefined 493 expect(notification).to.not.be.undefined
diff --git a/shared/extra-utils/videos/video-blacklist.ts b/shared/extra-utils/videos/video-blacklist.ts
index ba139ef95..c06b2aa5d 100644
--- a/shared/extra-utils/videos/video-blacklist.ts
+++ b/shared/extra-utils/videos/video-blacklist.ts
@@ -1,5 +1,5 @@
1import * as request from 'supertest' 1import * as request from 'supertest'
2import { VideoBlacklistType } from '../../models/videos' 2import { VideoBlockType } from '../../models/videos'
3import { makeGetRequest } from '..' 3import { makeGetRequest } from '..'
4 4
5function addVideoToBlacklist ( 5function addVideoToBlacklist (
@@ -45,7 +45,7 @@ function getBlacklistedVideosList (parameters: {
45 url: string 45 url: string
46 token: string 46 token: string
47 sort?: string 47 sort?: string
48 type?: VideoBlacklistType 48 type?: VideoBlockType
49 specialStatus?: number 49 specialStatus?: number
50}) { 50}) {
51 const { url, token, sort, type, specialStatus = 200 } = parameters 51 const { url, token, sort, type, specialStatus = 200 } = parameters
diff --git a/shared/models/users/user-flag.model.ts b/shared/models/users/user-flag.model.ts
index f5759f18f..e8b5a5c50 100644
--- a/shared/models/users/user-flag.model.ts
+++ b/shared/models/users/user-flag.model.ts
@@ -1,4 +1,4 @@
1export enum UserAdminFlag { 1export enum UserAdminFlag {
2 NONE = 0, 2 NONE = 0,
3 BY_PASS_VIDEO_AUTO_BLACKLIST = 1 << 0 3 BYPASS_VIDEO_AUTO_BLOCK = 1 << 0
4} 4}
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts
index e9be1ca7f..2329503a8 100644
--- a/shared/models/users/user-notification.model.ts
+++ b/shared/models/users/user-notification.model.ts
@@ -5,8 +5,8 @@ export enum UserNotificationType {
5 NEW_COMMENT_ON_MY_VIDEO = 2, 5 NEW_COMMENT_ON_MY_VIDEO = 2,
6 NEW_VIDEO_ABUSE_FOR_MODERATORS = 3, 6 NEW_VIDEO_ABUSE_FOR_MODERATORS = 3,
7 7
8 BLACKLIST_ON_MY_VIDEO = 4, 8 BLOCK_ON_MY_VIDEO = 4,
9 UNBLACKLIST_ON_MY_VIDEO = 5, 9 UNBLOCK_ON_MY_VIDEO = 5,
10 10
11 MY_VIDEO_PUBLISHED = 6, 11 MY_VIDEO_PUBLISHED = 6,
12 12
@@ -17,7 +17,7 @@ export enum UserNotificationType {
17 NEW_FOLLOW = 10, 17 NEW_FOLLOW = 10,
18 COMMENT_MENTION = 11, 18 COMMENT_MENTION = 11,
19 19
20 VIDEO_AUTO_BLACKLIST_FOR_MODERATORS = 12, 20 VIDEO_AUTO_BLOCK_FOR_MODERATORS = 12,
21 21
22 NEW_INSTANCE_FOLLOWER = 13, 22 NEW_INSTANCE_FOLLOWER = 13,
23 23
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts
index 2f88a65de..3fb760709 100644
--- a/shared/models/users/user-right.enum.ts
+++ b/shared/models/users/user-right.enum.ts
@@ -20,7 +20,7 @@ export enum UserRight {
20 MANAGE_ACCOUNTS_BLOCKLIST, 20 MANAGE_ACCOUNTS_BLOCKLIST,
21 MANAGE_SERVERS_BLOCKLIST, 21 MANAGE_SERVERS_BLOCKLIST,
22 22
23 MANAGE_VIDEO_BLACKLIST, 23 MANAGE_VIDEO_BLOCKS,
24 24
25 REMOVE_ANY_VIDEO, 25 REMOVE_ANY_VIDEO,
26 REMOVE_ANY_VIDEO_CHANNEL, 26 REMOVE_ANY_VIDEO_CHANNEL,
diff --git a/shared/models/users/user-role.ts b/shared/models/users/user-role.ts
index 2b08b5850..30ec5edce 100644
--- a/shared/models/users/user-role.ts
+++ b/shared/models/users/user-role.ts
@@ -19,7 +19,7 @@ const userRoleRights: { [ id in UserRole ]: UserRight[] } = {
19 ], 19 ],
20 20
21 [UserRole.MODERATOR]: [ 21 [UserRole.MODERATOR]: [
22 UserRight.MANAGE_VIDEO_BLACKLIST, 22 UserRight.MANAGE_VIDEO_BLOCKS,
23 UserRight.MANAGE_VIDEO_ABUSES, 23 UserRight.MANAGE_VIDEO_ABUSES,
24 UserRight.REMOVE_ANY_VIDEO, 24 UserRight.REMOVE_ANY_VIDEO,
25 UserRight.REMOVE_ANY_VIDEO_CHANNEL, 25 UserRight.REMOVE_ANY_VIDEO_CHANNEL,
diff --git a/shared/models/videos/blacklist/video-blacklist.model.ts b/shared/models/videos/blacklist/video-blacklist.model.ts
index a6e0ef175..e6090b1e9 100644
--- a/shared/models/videos/blacklist/video-blacklist.model.ts
+++ b/shared/models/videos/blacklist/video-blacklist.model.ts
@@ -1,15 +1,15 @@
1import { Video } from '../video.model' 1import { Video } from '../video.model'
2 2
3export enum VideoBlacklistType { 3export enum VideoBlockType {
4 MANUAL = 1, 4 MANUAL = 1,
5 AUTO_BEFORE_PUBLISHED = 2 5 AUTO_BEFORE_PUBLISHED = 2
6} 6}
7 7
8export interface VideoBlacklist { 8export interface VideoBlocklist {
9 id: number 9 id: number
10 unfederated: boolean 10 unfederated: boolean
11 reason?: string 11 reason?: string
12 type: VideoBlacklistType 12 type: VideoBlockType
13 13
14 video: Video 14 video: Video
15 15