From 8ca56654a176ee8f350d31282c6cac4a59f58499 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 9 Jul 2020 11:58:46 +0200 Subject: Add ability to report comments in front end --- .../abuse-list/abuse-details.component.html | 54 +++++++++---- .../abuse-list/abuse-details.component.ts | 5 +- .../abuse-list/abuse-list.component.html | 89 +++++++++++++--------- .../abuse-list/abuse-list.component.scss | 2 +- .../moderation/abuse-list/abuse-list.component.ts | 77 +++++++++++++------ .../+admin/moderation/moderation.component.scss | 41 +++++++--- .../src/app/+admin/moderation/moderation.routes.ts | 2 +- 7 files changed, 184 insertions(+), 86 deletions(-) (limited to 'client/src/app/+admin/moderation') diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-details.component.html b/client/src/app/+admin/moderation/abuse-list/abuse-details.component.html index d031ea8ed..cba9cfb73 100644 --- a/client/src/app/+admin/moderation/abuse-list/abuse-details.component.html +++ b/client/src/app/+admin/moderation/abuse-list/abuse-details.component.html @@ -3,10 +3,13 @@
- -
+
Reportee - + Avatar
- {{ abuse.video.channel.ownerAccount ? abuse.video.channel.ownerAccount.nameWithHost : '' }} + {{ abuse.flaggedAccount ? abuse.flaggedAccount.nameWithHost : '' }}
- + + {abuse.countReportsForReportee, plural, =1 {1 report} other {{{ abuse.countReportsForReportee }} reports}}
@@ -45,7 +56,7 @@
Updated - +
@@ -60,34 +71,45 @@ -
+
Reported part - {{ startAt }} - {{ endAt }} + {{ startAt }} - {{ endAt }}
Note - +
- +
-
-
+
+
The video was deleted The video was blocked
+
+ +
+
+ Comment: +
+ +
+
diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-details.component.ts b/client/src/app/+admin/moderation/abuse-list/abuse-details.component.ts index 8f87630b8..fb0f65764 100644 --- a/client/src/app/+admin/moderation/abuse-list/abuse-details.component.ts +++ b/client/src/app/+admin/moderation/abuse-list/abuse-details.component.ts @@ -31,15 +31,16 @@ export class AbuseDetailsComponent { } get startAt () { - return durationToString(this.abuse.startAt) + return durationToString(this.abuse.video.startAt) } get endAt () { - return durationToString(this.abuse.endAt) + return durationToString(this.abuse.video.endAt) } getPredefinedReasons () { if (!this.abuse.predefinedReasons) return [] + return this.abuse.predefinedReasons.map(r => ({ id: r, label: this.predefinedReasonsTranslations[r] diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html index 333438269..1ad73e38a 100644 --- a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html +++ b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.html @@ -38,7 +38,7 @@ Reporter - Video + Video/Comment/Account Created State @@ -54,7 +54,7 @@ - +
{{ abuse.reporterAccount.displayName }} - {{ abuse.reporterAccount.nameWithHost }} + {{ abuse.reporterAccount.nameWithHost }}
+ + + Deleted account + - - -
-
- - - {{ abuse.nth }}/{{ abuse.count }} - + + + + +
+
+ + + {{ abuse.nth }}/{{ abuse.count }} + +
+ +
+
+ + + {{ abuse.video.name }} +
+
by {{ abuse.video.channel?.displayName }} on {{ abuse.video.channel?.host }}
+
-
+ + + + +
+
+ Deleted +
+ +
- - {{ abuse.video.name }} +
-
by {{ abuse.video.channel?.displayName }} on {{ abuse.video.channel?.host }}
+
by {{ abuse.video.channel?.displayName }} on {{ abuse.video.channel?.host }}
- - + + - -
-
- Deleted -
-
-
- {{ abuse.video.name }} - -
-
by {{ abuse.video.channel?.displayName }} on {{ abuse.video.channel?.host }}
-
-
- + + + + + + + {{ abuse.createdAt | date: 'short' }} - + diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.scss b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.scss index 8eee15b64..c22f98c47 100644 --- a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.scss +++ b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.scss @@ -10,7 +10,7 @@ @include disable-default-a-behaviour; } -.video-abuse-states .glyphicon-comment { +.abuse-states .glyphicon-comment { margin-left: 0.5rem; } diff --git a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts index 427ec4d5d..1ea61ed37 100644 --- a/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts +++ b/client/src/app/+admin/moderation/abuse-list/abuse-list.component.ts @@ -2,7 +2,7 @@ import { SortMeta } from 'primeng/api' import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils' import { environment } from 'src/environments/environment' import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core' -import { DomSanitizer } from '@angular/platform-browser' +import { DomSanitizer, SafeHtml } from '@angular/platform-browser' import { ActivatedRoute, Params, Router } from '@angular/router' import { ConfirmService, MarkdownService, Notifier, RestPagination, RestTable } from '@app/core' import { Account, Actor, DropdownAction, Video, VideoService } from '@app/shared/shared-main' @@ -10,15 +10,20 @@ import { AbuseService, BlocklistService, VideoBlockService } from '@app/shared/s import { I18n } from '@ngx-translate/i18n-polyfill' import { Abuse, AbuseState } from '@shared/models' import { ModerationCommentModalComponent } from './moderation-comment-modal.component' +import truncate from 'lodash-es/truncate' export type ProcessedAbuse = Abuse & { moderationCommentHtml?: string, reasonHtml?: string - embedHtml?: string + embedHtml?: SafeHtml updatedAt?: Date // override bare server-side definitions with rich client-side definitions - reporterAccount: Account + reporterAccount?: Account + flaggedAccount?: Account + + truncatedCommentHtml?: string + commentHtml?: string video: Abuse['video'] & { channel: Abuse['video']['channel'] & { @@ -92,11 +97,11 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn { label: this.i18n('Actions for the video'), isHeader: true, - isDisplayed: abuse => !abuse.video.deleted + isDisplayed: abuse => abuse.video && !abuse.video.deleted }, { label: this.i18n('Block video'), - isDisplayed: abuse => !abuse.video.deleted && !abuse.video.blacklisted, + isDisplayed: abuse => abuse.video && !abuse.video.deleted && !abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.blockVideo(abuse.video.id, undefined, true) .subscribe( @@ -112,7 +117,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn }, { label: this.i18n('Unblock video'), - isDisplayed: abuse => !abuse.video.deleted && abuse.video.blacklisted, + isDisplayed: abuse => abuse.video && !abuse.video.deleted && abuse.video.blacklisted, handler: abuse => { this.videoBlocklistService.unblockVideo(abuse.video.id) .subscribe( @@ -128,7 +133,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn }, { label: this.i18n('Delete video'), - isDisplayed: abuse => !abuse.video.deleted, + isDisplayed: abuse => abuse.video && !abuse.video.deleted, handler: async abuse => { const res = await this.confirmService.confirm( this.i18n('Do you really want to delete this video?'), @@ -152,10 +157,12 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn [ { label: this.i18n('Actions for the reporter'), - isHeader: true + isHeader: true, + isDisplayed: abuse => !!abuse.reporterAccount }, { label: this.i18n('Mute reporter'), + isDisplayed: abuse => !!abuse.reporterAccount, handler: async abuse => { const account = abuse.reporterAccount as Account @@ -175,7 +182,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn }, { label: this.i18n('Mute server'), - isDisplayed: abuse => !abuse.reporterAccount.userId, + isDisplayed: abuse => abuse.reporterAccount && !abuse.reporterAccount.userId, handler: async abuse => { this.blocklistService.blockServerByInstance(abuse.reporterAccount.host) .subscribe( @@ -231,7 +238,7 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn const queryParams: Params = {} if (search) Object.assign(queryParams, { search }) - this.router.navigate([ '/admin/moderation/video-abuses/list' ], { queryParams }) + this.router.navigate([ '/admin/moderation/abuses/list' ], { queryParams }) } resetTableFilter () { @@ -253,6 +260,10 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn return Video.buildClientUrl(abuse.video.uuid) } + getCommentUrl (abuse: Abuse) { + return Video.buildClientUrl(abuse.comment.video.uuid) + ';threadId=' + abuse.comment.threadId + } + getVideoEmbed (abuse: Abuse) { return buildVideoEmbed( buildVideoLink({ @@ -300,23 +311,45 @@ export class AbuseListComponent extends RestTable implements OnInit, AfterViewIn }).subscribe( async resultList => { this.totalRecords = resultList.total - const abuses = [] - for (const abuse of resultList.data) { - Object.assign(abuse, { - reasonHtml: await this.toHtml(abuse.reason), - moderationCommentHtml: await this.toHtml(abuse.moderationComment), - embedHtml: this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse)), - reporterAccount: new Account(abuse.reporterAccount) - }) + this.abuses = [] + + for (const a of resultList.data) { + const abuse = a as ProcessedAbuse + + abuse.reasonHtml = await this.toHtml(abuse.reason) + abuse.moderationCommentHtml = await this.toHtml(abuse.moderationComment) + + if (abuse.video) { + abuse.embedHtml = this.sanitizer.bypassSecurityTrustHtml(this.getVideoEmbed(abuse)) + + if (abuse.video.channel?.ownerAccount) { + abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount) + } + } + + if (abuse.comment) { + if (abuse.comment.deleted) { + abuse.truncatedCommentHtml = abuse.commentHtml = this.i18n('Deleted comment') + } else { + const truncated = truncate(abuse.comment.text, { length: 100 }) + abuse.truncatedCommentHtml = await this.markdownRenderer.textMarkdownToHTML(truncated, true) + abuse.commentHtml = await this.markdownRenderer.textMarkdownToHTML(abuse.comment.text, true) + } + } + + if (abuse.reporterAccount) { + abuse.reporterAccount = new Account(abuse.reporterAccount) + } + + if (abuse.flaggedAccount) { + abuse.flaggedAccount = new Account(abuse.flaggedAccount) + } - if (abuse.video.channel?.ownerAccount) abuse.video.channel.ownerAccount = new Account(abuse.video.channel.ownerAccount) if (abuse.updatedAt === abuse.createdAt) delete abuse.updatedAt - abuses.push(abuse as ProcessedAbuse) + this.abuses.push(abuse) } - - this.abuses = abuses }, err => this.notifier.error(err.message) diff --git a/client/src/app/+admin/moderation/moderation.component.scss b/client/src/app/+admin/moderation/moderation.component.scss index 0ec420af9..f73c71dc5 100644 --- a/client/src/app/+admin/moderation/moderation.component.scss +++ b/client/src/app/+admin/moderation/moderation.component.scss @@ -25,18 +25,18 @@ vertical-align: top; text-align: right; } - + .moderation-expanded-text { display: inline-flex; word-wrap: break-word; - + ::ng-deep p:last-child { margin-bottom: 0px !important; } } } -.video-table-states { +.table-states { & > :not(:first-child) { margin-left: .4rem; } @@ -59,6 +59,7 @@ p-calendar { .screenratio { div { @include miniature-thumbnail; + display: inline-flex; justify-content: center; align-items: center; @@ -72,6 +73,11 @@ p-calendar { }; } +.comment-html { + background-color: #ececec; + padding: 10px; +} + .chip { @include chip; } @@ -83,16 +89,32 @@ my-action-dropdown.show { } -.video-table-video-link { +.table-video-link { @include disable-outline; + position: relative; top: 3px; } -.video-table-video { +.table-comment-link { + @include disable-outline; + + color: var(--mainForegroundColor); + + ::ng-deep p:last-child { + margin: 0; + } +} + +.comment-flagged-account { + font-size: 11px; + color: var(--greyForegroundColor); +} + +.table-video { display: inline-flex; - .video-table-video-image { + .table-video-image { @include miniature-thumbnail; $image-height: 45px; @@ -118,7 +140,7 @@ my-action-dropdown.show { color: pvar(--inputPlaceholderColor); } - .video-table-video-image-label { + .table-video-image-label { @include static-thumbnail-overlay; position: absolute; border-radius: 3px; @@ -130,7 +152,7 @@ my-action-dropdown.show { } } - .video-table-video-text { + .table-video-text { display: inline-flex; flex-direction: column; justify-content: center; @@ -145,7 +167,8 @@ my-action-dropdown.show { } div + div { - font-size: 80%; + color: var(--greyForegroundColor); + font-size: 11px; } } } diff --git a/client/src/app/+admin/moderation/moderation.routes.ts b/client/src/app/+admin/moderation/moderation.routes.ts index 1e207e5e8..8a31a54dc 100644 --- a/client/src/app/+admin/moderation/moderation.routes.ts +++ b/client/src/app/+admin/moderation/moderation.routes.ts @@ -33,7 +33,7 @@ export const ModerationRoutes: Routes = [ data: { userRight: UserRight.MANAGE_ABUSES, meta: { - title: 'Video reports' + title: 'Reports' } } }, -- cgit v1.2.3