diff options
Diffstat (limited to 'client')
11 files changed, 101 insertions, 27 deletions
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 8562e564b..89a04c078 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 | |||
@@ -42,7 +42,9 @@ export class MyAccountNotificationPreferencesComponent implements OnInit { | |||
42 | newFollow: this.i18n('You or your channel(s) has a new follower'), | 42 | newFollow: this.i18n('You or your channel(s) has a new follower'), |
43 | commentMention: this.i18n('Someone mentioned you in video comments'), | 43 | commentMention: this.i18n('Someone mentioned you in video comments'), |
44 | newInstanceFollower: this.i18n('Your instance has a new follower'), | 44 | newInstanceFollower: this.i18n('Your instance has a new follower'), |
45 | autoInstanceFollowing: this.i18n('Your instance auto followed another instance') | 45 | autoInstanceFollowing: this.i18n('Your instance auto followed another instance'), |
46 | abuseNewMessage: this.i18n('An abuse received a new message'), | ||
47 | abuseStateChange: this.i18n('One of your abuse has been accepted or rejected by moderators') | ||
46 | } | 48 | } |
47 | this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[] | 49 | this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[] |
48 | 50 | ||
diff --git a/client/src/app/core/renderer/html-renderer.service.ts b/client/src/app/core/renderer/html-renderer.service.ts index f0527c759..302d92ed9 100644 --- a/client/src/app/core/renderer/html-renderer.service.ts +++ b/client/src/app/core/renderer/html-renderer.service.ts | |||
@@ -3,19 +3,29 @@ import { LinkifierService } from './linkifier.service' | |||
3 | 3 | ||
4 | @Injectable() | 4 | @Injectable() |
5 | export class HtmlRendererService { | 5 | export class HtmlRendererService { |
6 | private sanitizeHtml: typeof import ('sanitize-html') | ||
6 | 7 | ||
7 | constructor (private linkifier: LinkifierService) { | 8 | constructor (private linkifier: LinkifierService) { |
8 | 9 | ||
9 | } | 10 | } |
10 | 11 | ||
12 | async convertToBr (text: string) { | ||
13 | await this.loadSanitizeHtml() | ||
14 | |||
15 | const html = text.replace(/\r?\n/g, '<br />') | ||
16 | |||
17 | return this.sanitizeHtml(html, { | ||
18 | allowedTags: [ 'br' ] | ||
19 | }) | ||
20 | } | ||
21 | |||
11 | async toSafeHtml (text: string) { | 22 | async toSafeHtml (text: string) { |
12 | // FIXME: import('..') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function | 23 | await this.loadSanitizeHtml() |
13 | const sanitizeHtml: typeof import ('sanitize-html') = (await import('sanitize-html') as any).default | ||
14 | 24 | ||
15 | // Convert possible markdown to html | 25 | // Convert possible markdown to html |
16 | const html = this.linkifier.linkify(text) | 26 | const html = this.linkifier.linkify(text) |
17 | 27 | ||
18 | return sanitizeHtml(html, { | 28 | return this.sanitizeHtml(html, { |
19 | allowedTags: [ 'a', 'p', 'span', 'br', 'strong', 'em', 'ul', 'ol', 'li' ], | 29 | allowedTags: [ 'a', 'p', 'span', 'br', 'strong', 'em', 'ul', 'ol', 'li' ], |
20 | allowedSchemes: [ 'http', 'https' ], | 30 | allowedSchemes: [ 'http', 'https' ], |
21 | allowedAttributes: { | 31 | allowedAttributes: { |
@@ -37,4 +47,9 @@ export class HtmlRendererService { | |||
37 | } | 47 | } |
38 | }) | 48 | }) |
39 | } | 49 | } |
50 | |||
51 | private async loadSanitizeHtml () { | ||
52 | // FIXME: import('..') returns a struct module, containing a "default" field corresponding to our sanitizeHtml function | ||
53 | this.sanitizeHtml = (await import('sanitize-html') as any).default | ||
54 | } | ||
40 | } | 55 | } |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html index 17b3742d6..d90b93fff 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html +++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.html | |||
@@ -42,6 +42,7 @@ | |||
42 | <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> | 42 | <th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th> |
43 | <th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th> | 43 | <th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th> |
44 | <th i18n style="width: 80px;">Messages</th> | 44 | <th i18n style="width: 80px;">Messages</th> |
45 | <th i18n *ngIf="isAdminView()" style="width: 100px;">Internal note</th> | ||
45 | <th style="width: 150px;"></th> | 46 | <th style="width: 150px;"></th> |
46 | </tr> | 47 | </tr> |
47 | </ng-template> | 48 | </ng-template> |
@@ -144,13 +145,11 @@ | |||
144 | 145 | ||
145 | </ng-container> | 146 | </ng-container> |
146 | 147 | ||
147 | |||
148 | <td class="c-hand" [pRowToggler]="abuse">{{ abuse.createdAt | date: 'short' }}</td> | 148 | <td class="c-hand" [pRowToggler]="abuse">{{ abuse.createdAt | date: 'short' }}</td> |
149 | 149 | ||
150 | <td class="c-hand abuse-states" [pRowToggler]="abuse"> | 150 | <td class="c-hand abuse-states" [pRowToggler]="abuse"> |
151 | <span *ngIf="isAbuseAccepted(abuse)" [title]="abuse.state.label" class="glyphicon glyphicon-ok"></span> | 151 | <span *ngIf="isAbuseAccepted(abuse)" [title]="abuse.state.label" class="glyphicon glyphicon-ok"></span> |
152 | <span *ngIf="isAbuseRejected(abuse)" [title]="abuse.state.label" class="glyphicon glyphicon-remove"></span> | 152 | <span *ngIf="isAbuseRejected(abuse)" [title]="abuse.state.label" class="glyphicon glyphicon-remove"></span> |
153 | <span *ngIf="abuse.moderationComment" container="body" placement="left auto" [ngbTooltip]="abuse.moderationComment" class="glyphicon glyphicon-comment"></span> | ||
154 | </td> | 153 | </td> |
155 | 154 | ||
156 | <td class="c-hand abuse-messages" (click)="openAbuseMessagesModal(abuse)"> | 155 | <td class="c-hand abuse-messages" (click)="openAbuseMessagesModal(abuse)"> |
@@ -161,6 +160,10 @@ | |||
161 | </ng-container> | 160 | </ng-container> |
162 | </td> | 161 | </td> |
163 | 162 | ||
163 | <td *ngIf="isAdminView()" class="internal-note" container="body" placement="left auto" [ngbTooltip]="abuse.moderationComment"> | ||
164 | {{ abuse.moderationComment }} | ||
165 | </td> | ||
166 | |||
164 | <td class="action-cell"> | 167 | <td class="action-cell"> |
165 | <my-action-dropdown | 168 | <my-action-dropdown |
166 | [ngClass]="{ 'show': expanded }" placement="bottom-right top-right left auto" container="body" | 169 | [ngClass]="{ 'show': expanded }" placement="bottom-right top-right left auto" container="body" |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts index 1d17c9ec9..21d2ea47d 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-list-table.component.ts | |||
@@ -278,7 +278,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV | |||
278 | isDisplayed: abuse => this.isLocalAbuse(abuse) | 278 | isDisplayed: abuse => this.isLocalAbuse(abuse) |
279 | }, | 279 | }, |
280 | { | 280 | { |
281 | label: this.i18n('Update note'), | 281 | label: this.i18n('Update internal note'), |
282 | handler: abuse => this.openModerationCommentModal(abuse), | 282 | handler: abuse => this.openModerationCommentModal(abuse), |
283 | isDisplayed: abuse => this.isAdminView() && !!abuse.moderationComment | 283 | isDisplayed: abuse => this.isAdminView() && !!abuse.moderationComment |
284 | }, | 284 | }, |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.html b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.html index cb965b71d..17e9ce4cf 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.html +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.html | |||
@@ -9,7 +9,7 @@ | |||
9 | </div> | 9 | </div> |
10 | 10 | ||
11 | <div class="modal-body"> | 11 | <div class="modal-body"> |
12 | <div class="messages" #messagesBlock> | 12 | <div class="messages"> |
13 | <div | 13 | <div |
14 | *ngFor="let message of abuseMessages" | 14 | *ngFor="let message of abuseMessages" |
15 | class="message-block" [ngClass]="{ 'by-moderator': message.byModerator, 'by-me': isMessageByMe(message) }" | 15 | class="message-block" [ngClass]="{ 'by-moderator': message.byModerator, 'by-me': isMessageByMe(message) }" |
@@ -18,7 +18,7 @@ | |||
18 | <div class="author">{{ message.account.name }}</div> | 18 | <div class="author">{{ message.account.name }}</div> |
19 | 19 | ||
20 | <div class="bubble"> | 20 | <div class="bubble"> |
21 | <div class="content">{{ message.message }}</div> | 21 | <div class="content" [innerHTML]="message.messageHtml"></div> |
22 | <div class="date">{{ message.createdAt | date }}</div> | 22 | <div class="date">{{ message.createdAt | date }}</div> |
23 | </div> | 23 | </div> |
24 | </div> | 24 | </div> |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.scss b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.scss index 4dd025fc4..4163722dd 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.scss +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.scss | |||
@@ -20,6 +20,7 @@ textarea { | |||
20 | display: flex; | 20 | display: flex; |
21 | flex-direction: column; | 21 | flex-direction: column; |
22 | overflow-y: scroll; | 22 | overflow-y: scroll; |
23 | max-height: 50vh; | ||
23 | } | 24 | } |
24 | 25 | ||
25 | .no-messages { | 26 | .no-messages { |
diff --git a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts index 03f5ad735..6686d91f4 100644 --- a/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts +++ b/client/src/app/shared/shared-abuse-list/abuse-message-modal.component.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' | 1 | import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core' |
2 | import { AuthService, Notifier } from '@app/core' | 2 | import { AuthService, Notifier, HtmlRendererService } from '@app/core' |
3 | import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' | 3 | import { AbuseValidatorsService, FormReactive, FormValidatorService } from '@app/shared/shared-forms' |
4 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' | 4 | import { NgbModal } from '@ng-bootstrap/ng-bootstrap' |
5 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' | 5 | import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap/modal/modal-ref' |
@@ -14,13 +14,12 @@ import { AbuseService } from '../shared-moderation' | |||
14 | }) | 14 | }) |
15 | export class AbuseMessageModalComponent extends FormReactive implements OnInit { | 15 | export class AbuseMessageModalComponent extends FormReactive implements OnInit { |
16 | @ViewChild('modal', { static: true }) modal: NgbModal | 16 | @ViewChild('modal', { static: true }) modal: NgbModal |
17 | @ViewChild('messagesBlock', { static: false }) messagesBlock: ElementRef | ||
18 | 17 | ||
19 | @Input() isAdminView: boolean | 18 | @Input() isAdminView: boolean |
20 | 19 | ||
21 | @Output() countMessagesUpdated = new EventEmitter<{ abuseId: number, countMessages: number }>() | 20 | @Output() countMessagesUpdated = new EventEmitter<{ abuseId: number, countMessages: number }>() |
22 | 21 | ||
23 | abuseMessages: AbuseMessage[] = [] | 22 | abuseMessages: (AbuseMessage & { messageHtml: string })[] = [] |
24 | textareaMessage: string | 23 | textareaMessage: string |
25 | sendingMessage = false | 24 | sendingMessage = false |
26 | noResults = false | 25 | noResults = false |
@@ -33,6 +32,7 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { | |||
33 | private abuseValidatorsService: AbuseValidatorsService, | 32 | private abuseValidatorsService: AbuseValidatorsService, |
34 | private modalService: NgbModal, | 33 | private modalService: NgbModal, |
35 | private i18n: I18n, | 34 | private i18n: I18n, |
35 | private htmlRenderer: HtmlRendererService, | ||
36 | private auth: AuthService, | 36 | private auth: AuthService, |
37 | private notifier: Notifier, | 37 | private notifier: Notifier, |
38 | private abuseService: AbuseService | 38 | private abuseService: AbuseService |
@@ -108,15 +108,21 @@ export class AbuseMessageModalComponent extends FormReactive implements OnInit { | |||
108 | private loadMessages () { | 108 | private loadMessages () { |
109 | this.abuseService.listAbuseMessages(this.abuse) | 109 | this.abuseService.listAbuseMessages(this.abuse) |
110 | .subscribe( | 110 | .subscribe( |
111 | res => { | 111 | async res => { |
112 | this.abuseMessages = res.data | 112 | this.abuseMessages = [] |
113 | |||
114 | for (const m of res.data) { | ||
115 | this.abuseMessages.push(Object.assign(m, { | ||
116 | messageHtml: await this.htmlRenderer.convertToBr(m.message) | ||
117 | })) | ||
118 | } | ||
119 | |||
113 | this.noResults = this.abuseMessages.length === 0 | 120 | this.noResults = this.abuseMessages.length === 0 |
114 | 121 | ||
115 | setTimeout(() => { | 122 | setTimeout(() => { |
116 | if (!this.messagesBlock) return | 123 | // Don't use ViewChild: it is not supported inside a ng-template |
117 | 124 | const messagesBlock = document.querySelector('.messages') | |
118 | const element = this.messagesBlock.nativeElement as HTMLElement | 125 | messagesBlock.scroll(0, messagesBlock.scrollHeight) |
119 | element.scrollIntoView({ block: 'end', inline: 'nearest' }) | ||
120 | }) | 126 | }) |
121 | }, | 127 | }, |
122 | 128 | ||
diff --git a/client/src/app/shared/shared-main/users/user-notification.model.ts b/client/src/app/shared/shared-main/users/user-notification.model.ts index 61b48a806..a068daaac 100644 --- a/client/src/app/shared/shared-main/users/user-notification.model.ts +++ b/client/src/app/shared/shared-main/users/user-notification.model.ts | |||
@@ -1,5 +1,14 @@ | |||
1 | import { | ||
2 | AbuseState, | ||
3 | ActorInfo, | ||
4 | FollowState, | ||
5 | UserNotification as UserNotificationServer, | ||
6 | UserNotificationType, | ||
7 | VideoInfo, | ||
8 | UserRight | ||
9 | } from '@shared/models' | ||
1 | import { Actor } from '../account/actor.model' | 10 | import { Actor } from '../account/actor.model' |
2 | import { ActorInfo, Avatar, FollowState, UserNotification as UserNotificationServer, UserNotificationType, VideoInfo } from '@shared/models' | 11 | import { AuthUser } from '@app/core' |
3 | 12 | ||
4 | export class UserNotification implements UserNotificationServer { | 13 | export class UserNotification implements UserNotificationServer { |
5 | id: number | 14 | id: number |
@@ -27,6 +36,7 @@ export class UserNotification implements UserNotificationServer { | |||
27 | 36 | ||
28 | abuse?: { | 37 | abuse?: { |
29 | id: number | 38 | id: number |
39 | state: AbuseState | ||
30 | 40 | ||
31 | video?: VideoInfo | 41 | video?: VideoInfo |
32 | 42 | ||
@@ -69,13 +79,14 @@ export class UserNotification implements UserNotificationServer { | |||
69 | videoUrl?: string | 79 | videoUrl?: string |
70 | commentUrl?: any[] | 80 | commentUrl?: any[] |
71 | abuseUrl?: string | 81 | abuseUrl?: string |
82 | abuseQueryParams?: { [id: string]: string } = {} | ||
72 | videoAutoBlacklistUrl?: string | 83 | videoAutoBlacklistUrl?: string |
73 | accountUrl?: string | 84 | accountUrl?: string |
74 | videoImportIdentifier?: string | 85 | videoImportIdentifier?: string |
75 | videoImportUrl?: string | 86 | videoImportUrl?: string |
76 | instanceFollowUrl?: string | 87 | instanceFollowUrl?: string |
77 | 88 | ||
78 | constructor (hash: UserNotificationServer) { | 89 | constructor (hash: UserNotificationServer, user: AuthUser) { |
79 | this.id = hash.id | 90 | this.id = hash.id |
80 | this.type = hash.type | 91 | this.type = hash.type |
81 | this.read = hash.read | 92 | this.read = hash.read |
@@ -122,12 +133,25 @@ export class UserNotification implements UserNotificationServer { | |||
122 | 133 | ||
123 | case UserNotificationType.NEW_ABUSE_FOR_MODERATORS: | 134 | case UserNotificationType.NEW_ABUSE_FOR_MODERATORS: |
124 | this.abuseUrl = '/admin/moderation/abuses/list' | 135 | this.abuseUrl = '/admin/moderation/abuses/list' |
136 | this.abuseQueryParams.search = '#' + this.abuse.id | ||
125 | 137 | ||
126 | if (this.abuse.video) this.videoUrl = this.buildVideoUrl(this.abuse.video) | 138 | if (this.abuse.video) this.videoUrl = this.buildVideoUrl(this.abuse.video) |
127 | else if (this.abuse.comment) this.commentUrl = this.buildCommentUrl(this.abuse.comment) | 139 | else if (this.abuse.comment) this.commentUrl = this.buildCommentUrl(this.abuse.comment) |
128 | else if (this.abuse.account) this.accountUrl = this.buildAccountUrl(this.abuse.account) | 140 | else if (this.abuse.account) this.accountUrl = this.buildAccountUrl(this.abuse.account) |
129 | break | 141 | break |
130 | 142 | ||
143 | case UserNotificationType.ABUSE_STATE_CHANGE: | ||
144 | this.abuseUrl = '/my-account/abuses' | ||
145 | this.abuseQueryParams.search = '#' + this.abuse.id | ||
146 | break | ||
147 | |||
148 | case UserNotificationType.ABUSE_NEW_MESSAGE: | ||
149 | this.abuseUrl = user.hasRight(UserRight.MANAGE_ABUSES) | ||
150 | ? '/admin/moderation/abuses/list' | ||
151 | : '/my-account/abuses' | ||
152 | this.abuseQueryParams.search = '#' + this.abuse.id | ||
153 | break | ||
154 | |||
131 | case UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS: | 155 | case UserNotificationType.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS: |
132 | this.videoAutoBlacklistUrl = '/admin/moderation/video-auto-blacklist/list' | 156 | this.videoAutoBlacklistUrl = '/admin/moderation/video-auto-blacklist/list' |
133 | // Backward compatibility where we did not assign videoBlacklist to this type of notification before | 157 | // Backward compatibility where we did not assign videoBlacklist to this type of notification before |
diff --git a/client/src/app/shared/shared-main/users/user-notification.service.ts b/client/src/app/shared/shared-main/users/user-notification.service.ts index ecc66ecdb..7b9dc34be 100644 --- a/client/src/app/shared/shared-main/users/user-notification.service.ts +++ b/client/src/app/shared/shared-main/users/user-notification.service.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { catchError, map, tap } from 'rxjs/operators' | 1 | import { catchError, map, tap } from 'rxjs/operators' |
2 | import { HttpClient, HttpParams } from '@angular/common/http' | 2 | import { HttpClient, HttpParams } from '@angular/common/http' |
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { ComponentPaginationLight, RestExtractor, RestService, User, UserNotificationSocket } from '@app/core' | 4 | import { ComponentPaginationLight, RestExtractor, RestService, User, UserNotificationSocket, AuthService } from '@app/core' |
5 | import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '@shared/models' | 5 | import { ResultList, UserNotification as UserNotificationServer, UserNotificationSetting } from '@shared/models' |
6 | import { environment } from '../../../../environments/environment' | 6 | import { environment } from '../../../../environments/environment' |
7 | import { UserNotification } from './user-notification.model' | 7 | import { UserNotification } from './user-notification.model' |
@@ -14,6 +14,7 @@ export class UserNotificationService { | |||
14 | 14 | ||
15 | constructor ( | 15 | constructor ( |
16 | private authHttp: HttpClient, | 16 | private authHttp: HttpClient, |
17 | private auth: AuthService, | ||
17 | private restExtractor: RestExtractor, | 18 | private restExtractor: RestExtractor, |
18 | private restService: RestService, | 19 | private restService: RestService, |
19 | private userNotificationSocket: UserNotificationSocket | 20 | private userNotificationSocket: UserNotificationSocket |
@@ -84,6 +85,6 @@ export class UserNotificationService { | |||
84 | } | 85 | } |
85 | 86 | ||
86 | private formatNotification (notification: UserNotificationServer) { | 87 | private formatNotification (notification: UserNotificationServer) { |
87 | return new UserNotification(notification) | 88 | return new UserNotification(notification, this.auth.getUser()) |
88 | } | 89 | } |
89 | } | 90 | } |
diff --git a/client/src/app/shared/shared-main/users/user-notifications.component.html b/client/src/app/shared/shared-main/users/user-notifications.component.html index 8127ae979..a56a0859b 100644 --- a/client/src/app/shared/shared-main/users/user-notifications.component.html +++ b/client/src/app/shared/shared-main/users/user-notifications.component.html | |||
@@ -46,20 +46,38 @@ | |||
46 | <my-global-icon iconName="flag" aria-hidden="true"></my-global-icon> | 46 | <my-global-icon iconName="flag" aria-hidden="true"></my-global-icon> |
47 | 47 | ||
48 | <div class="message" *ngIf="notification.videoUrl" i18n> | 48 | <div class="message" *ngIf="notification.videoUrl" i18n> |
49 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl">A new video abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.abuse.video.name }}</a> | 49 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">A new video abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.abuse.video.name }}</a> |
50 | </div> | 50 | </div> |
51 | 51 | ||
52 | <div class="message" *ngIf="notification.commentUrl" i18n> | 52 | <div class="message" *ngIf="notification.commentUrl" i18n> |
53 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl">A new comment abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">{{ notification.abuse.comment.video.name }}</a> | 53 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">A new comment abuse</a> has been created on video <a (click)="markAsRead(notification)" [routerLink]="notification.commentUrl">{{ notification.abuse.comment.video.name }}</a> |
54 | </div> | 54 | </div> |
55 | 55 | ||
56 | <div class="message" *ngIf="notification.accountUrl" i18n> | 56 | <div class="message" *ngIf="notification.accountUrl" i18n> |
57 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl">A new account abuse</a> has been created on account <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.abuse.account.displayName }}</a> | 57 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">A new account abuse</a> has been created on account <a (click)="markAsRead(notification)" [routerLink]="notification.accountUrl">{{ notification.abuse.account.displayName }}</a> |
58 | </div> | 58 | </div> |
59 | 59 | ||
60 | <!-- Deleted entity associated to the abuse --> | 60 | <!-- Deleted entity associated to the abuse --> |
61 | <div class="message" *ngIf="!notification.videoUrl && !notification.commentUrl && !notification.accountUrl" i18n> | 61 | <div class="message" *ngIf="!notification.videoUrl && !notification.commentUrl && !notification.accountUrl" i18n> |
62 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl">A new abuse</a> has been created | 62 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">A new abuse</a> has been created |
63 | </div> | ||
64 | </ng-container> | ||
65 | |||
66 | <ng-container *ngSwitchCase="UserNotificationType.ABUSE_STATE_CHANGE"> | ||
67 | <my-global-icon iconName="flag" aria-hidden="true"></my-global-icon> | ||
68 | |||
69 | <div class="message" i18n> | ||
70 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">Your abuse {{ notification.abuse.id }}</a> has been | ||
71 | <ng-container *ngIf="isAccepted(notification)">accepted</ng-container> | ||
72 | <ng-container *ngIf="!isAccepted(notification)">rejected</ng-container> | ||
73 | </div> | ||
74 | </ng-container> | ||
75 | |||
76 | <ng-container *ngSwitchCase="UserNotificationType.ABUSE_NEW_MESSAGE"> | ||
77 | <my-global-icon iconName="flag" aria-hidden="true"></my-global-icon> | ||
78 | |||
79 | <div class="message" i18n> | ||
80 | <a (click)="markAsRead(notification)" [routerLink]="notification.abuseUrl" [queryParams]="notification.abuseQueryParams">Abuse {{ notification.abuse.id }}</a> has a new message | ||
63 | </div> | 81 | </div> |
64 | </ng-container> | 82 | </ng-container> |
65 | 83 | ||
diff --git a/client/src/app/shared/shared-main/users/user-notifications.component.ts b/client/src/app/shared/shared-main/users/user-notifications.component.ts index 7518dbdd0..387c49d94 100644 --- a/client/src/app/shared/shared-main/users/user-notifications.component.ts +++ b/client/src/app/shared/shared-main/users/user-notifications.component.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Subject } from 'rxjs' | 1 | import { Subject } from 'rxjs' |
2 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' | 2 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core' |
3 | import { ComponentPagination, hasMoreItems, Notifier } from '@app/core' | 3 | import { ComponentPagination, hasMoreItems, Notifier } from '@app/core' |
4 | import { UserNotificationType } from '@shared/models' | 4 | import { UserNotificationType, AbuseState } from '@shared/models' |
5 | import { UserNotification } from './user-notification.model' | 5 | import { UserNotification } from './user-notification.model' |
6 | import { UserNotificationService } from './user-notification.service' | 6 | import { UserNotificationService } from './user-notification.service' |
7 | 7 | ||
@@ -116,4 +116,8 @@ export class UserNotificationsComponent implements OnInit { | |||
116 | this.sortField = column | 116 | this.sortField = column |
117 | this.loadNotifications(true) | 117 | this.loadNotifications(true) |
118 | } | 118 | } |
119 | |||
120 | isAccepted (notification: UserNotification) { | ||
121 | return notification.abuse.state === AbuseState.ACCEPTED | ||
122 | } | ||
119 | } | 123 | } |