aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+admin
diff options
context:
space:
mode:
authorRigel Kent <sendmemail@rigelk.eu>2020-06-22 13:00:39 +0200
committerGitHub <noreply@github.com>2020-06-22 13:00:39 +0200
commit1ebddadd0704812a4600c39cabe2268321e88331 (patch)
tree1cc8560e5b63e9976aa5411ba800a62cfe7b8ea9 /client/src/app/+admin
parent07aea1a2642fc9868cb01e30c322514029d5b95a (diff)
downloadPeerTube-1ebddadd0704812a4600c39cabe2268321e88331.tar.gz
PeerTube-1ebddadd0704812a4600c39cabe2268321e88331.tar.zst
PeerTube-1ebddadd0704812a4600c39cabe2268321e88331.zip
predefined report reasons & improved reporter UI (#2842)
- added `startAt` and `endAt` optional timestamps to help pin down reported sections of a video - added predefined report reasons - added video player with report modal
Diffstat (limited to 'client/src/app/+admin')
-rw-r--r--client/src/app/+admin/moderation/moderation.component.scss14
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.html16
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.ts37
-rw-r--r--client/src/app/+admin/moderation/video-abuse-list/video-abuse-list.component.ts19
4 files changed, 77 insertions, 9 deletions
diff --git a/client/src/app/+admin/moderation/moderation.component.scss b/client/src/app/+admin/moderation/moderation.component.scss
index ba68cf6f6..0ec420af9 100644
--- a/client/src/app/+admin/moderation/moderation.component.scss
+++ b/client/src/app/+admin/moderation/moderation.component.scss
@@ -42,6 +42,20 @@
42 } 42 }
43} 43}
44 44
45p-calendar {
46 display: block;
47
48 ::ng-deep {
49 .ui-widget-content {
50 min-width: 400px;
51 }
52
53 input {
54 @include peertube-input-text(100%);
55 }
56 }
57}
58
45.screenratio { 59.screenratio {
46 div { 60 div {
47 @include miniature-thumbnail; 61 @include miniature-thumbnail;
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 453a282d1..5512bb1de 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
@@ -57,6 +57,22 @@
57 <span class="col-9 moderation-expanded-text" [innerHTML]="videoAbuse.reasonHtml"></span> 57 <span class="col-9 moderation-expanded-text" [innerHTML]="videoAbuse.reasonHtml"></span>
58 </div> 58 </div>
59 59
60 <div *ngIf="getPredefinedReasons()" class="mt-2 d-flex">
61 <span class="col-3"></span>
62 <span class="col-9">
63 <a [routerLink]="[ '/admin/moderation/video-abuses/list' ]" [queryParams]="{ 'search': 'tag:' + reason.id }" class="chip rectangular bg-secondary text-light" *ngFor="let reason of getPredefinedReasons()">
64 <div>{{ reason.label }}</div>
65 </a>
66 </span>
67 </div>
68
69 <div *ngIf="videoAbuse.startAt" class="mt-2 d-flex">
70 <span class="col-3 moderation-expanded-label" i18n>Reported part</span>
71 <span class="col-9">
72 {{ startAt }}<ng-container *ngIf="videoAbuse.endAt"> - {{ endAt }}</ng-container>
73 </span>
74 </div>
75
60 <div class="mt-3 d-flex" *ngIf="videoAbuse.moderationComment"> 76 <div class="mt-3 d-flex" *ngIf="videoAbuse.moderationComment">
61 <span class="col-3 moderation-expanded-label" i18n>Note</span> 77 <span class="col-3 moderation-expanded-label" i18n>Note</span>
62 <span class="col-9 moderation-expanded-text" [innerHTML]="videoAbuse.moderationCommentHtml"></span> 78 <span class="col-9 moderation-expanded-text" [innerHTML]="videoAbuse.moderationCommentHtml"></span>
diff --git a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.ts b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.ts
index d9cb19845..13485124f 100644
--- a/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.ts
+++ b/client/src/app/+admin/moderation/video-abuse-list/video-abuse-details.component.ts
@@ -1,7 +1,9 @@
1import { Component, Input } from '@angular/core' 1import { Component, Input } from '@angular/core'
2import { Account } from '@app/shared/account/account.model'
3import { Actor } from '@app/shared/actor/actor.model' 2import { Actor } from '@app/shared/actor/actor.model'
3import { VideoAbusePredefinedReasonsString } from '../../../../../../shared/models/videos/abuse/video-abuse-reason.model'
4import { ProcessedVideoAbuse } from './video-abuse-list.component' 4import { ProcessedVideoAbuse } from './video-abuse-list.component'
5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { durationToString } from '@app/shared/misc/utils'
5 7
6@Component({ 8@Component({
7 selector: 'my-video-abuse-details', 9 selector: 'my-video-abuse-details',
@@ -11,6 +13,39 @@ import { ProcessedVideoAbuse } from './video-abuse-list.component'
11export class VideoAbuseDetailsComponent { 13export class VideoAbuseDetailsComponent {
12 @Input() videoAbuse: ProcessedVideoAbuse 14 @Input() videoAbuse: ProcessedVideoAbuse
13 15
16 private predefinedReasonsTranslations: { [key in VideoAbusePredefinedReasonsString]: string }
17
18 constructor (
19 private i18n: I18n
20 ) {
21 this.predefinedReasonsTranslations = {
22 violentOrRepulsive: this.i18n('Violent or Repulsive'),
23 hatefulOrAbusive: this.i18n('Hateful or Abusive'),
24 spamOrMisleading: this.i18n('Spam or Misleading'),
25 privacy: this.i18n('Privacy'),
26 rights: this.i18n('Rights'),
27 serverRules: this.i18n('Server rules'),
28 thumbnails: this.i18n('Thumbnails'),
29 captions: this.i18n('Captions')
30 }
31 }
32
33 get startAt () {
34 return durationToString(this.videoAbuse.startAt)
35 }
36
37 get endAt () {
38 return durationToString(this.videoAbuse.endAt)
39 }
40
41 getPredefinedReasons () {
42 if (!this.videoAbuse.predefinedReasons) return []
43 return this.videoAbuse.predefinedReasons.map(r => ({
44 id: r,
45 label: this.predefinedReasonsTranslations[r]
46 }))
47 }
48
14 switchToDefaultAvatar ($event: Event) { 49 switchToDefaultAvatar ($event: Event) {
15 ($event.target as HTMLImageElement).src = Actor.GET_DEFAULT_AVATAR_URL() 50 ($event.target as HTMLImageElement).src = Actor.GET_DEFAULT_AVATAR_URL()
16 } 51 }
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 a36acc2ab..d7f5beef3 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
@@ -11,13 +11,13 @@ import { ModerationCommentModalComponent } from './moderation-comment-modal.comp
11import { Video } from '../../../shared/video/video.model' 11import { Video } from '../../../shared/video/video.model'
12import { MarkdownService } from '@app/shared/renderer' 12import { MarkdownService } from '@app/shared/renderer'
13import { Actor } from '@app/shared/actor/actor.model' 13import { Actor } from '@app/shared/actor/actor.model'
14import { buildVideoLink, buildVideoEmbed } from 'src/assets/player/utils' 14import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils'
15import { getAbsoluteAPIUrl } from '@app/shared/misc/utils'
16import { DomSanitizer } from '@angular/platform-browser' 15import { DomSanitizer } from '@angular/platform-browser'
17import { BlocklistService } from '@app/shared/blocklist' 16import { BlocklistService } from '@app/shared/blocklist'
18import { VideoService } from '@app/shared/video/video.service' 17import { VideoService } from '@app/shared/video/video.service'
19import { ActivatedRoute, Params, Router } from '@angular/router' 18import { ActivatedRoute, Params, Router } from '@angular/router'
20import { filter } from 'rxjs/operators' 19import { filter } from 'rxjs/operators'
20import { environment } from 'src/environments/environment'
21 21
22export type ProcessedVideoAbuse = VideoAbuse & { 22export type ProcessedVideoAbuse = VideoAbuse & {
23 moderationCommentHtml?: string, 23 moderationCommentHtml?: string,
@@ -259,12 +259,15 @@ export class VideoAbuseListComponent extends RestTable implements OnInit, AfterV
259 } 259 }
260 260
261 getVideoEmbed (videoAbuse: VideoAbuse) { 261 getVideoEmbed (videoAbuse: VideoAbuse) {
262 const absoluteAPIUrl = getAbsoluteAPIUrl() 262 return buildVideoEmbed(
263 const embedUrl = buildVideoLink({ 263 buildVideoLink({
264 baseUrl: absoluteAPIUrl + '/videos/embed/' + videoAbuse.video.uuid, 264 baseUrl: `${environment.embedUrl}/videos/embed/${videoAbuse.video.uuid}`,
265 warningTitle: false 265 title: false,
266 }) 266 warningTitle: false,
267 return buildVideoEmbed(embedUrl) 267 startTime: videoAbuse.startAt,
268 stopTime: videoAbuse.endAt
269 })
270 )
268 } 271 }
269 272
270 switchToDefaultAvatar ($event: Event) { 273 switchToDefaultAvatar ($event: Event) {