From a282e4d8a072cd56db8c393be7715bda420a243d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 28 Feb 2022 10:41:23 +0100 Subject: Continue user mute in ban modal PR --- .../users/user-list/user-list.component.html | 20 ++++++---- .../users/user-list/user-list.component.scss | 4 ++ .../users/user-list/user-list.component.ts | 42 +++++++++++++++++--- client/src/app/helpers/utils/url.ts | 5 +++ .../app/shared/shared-main/account/actor.model.ts | 8 ++-- .../shared/shared-moderation/blocklist.service.ts | 15 ++++--- .../user-ban-modal.component.html | 17 ++++---- .../user-ban-modal.component.scss | 5 +++ .../shared-moderation/user-ban-modal.component.ts | 41 +++++++++---------- .../user-moderation-dropdown.component.ts | 46 +++++++++++++++------- 10 files changed, 137 insertions(+), 66 deletions(-) diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.html b/client/src/app/+admin/overview/users/user-list/user-list.component.html index 7eb89fea1..0662e3ac3 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.html +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.html @@ -62,10 +62,10 @@ {{ getColumn('username').label }} + {{ getColumn('role').label }} {{ getColumn('email').label }} {{ getColumn('quota').label }} {{ getColumn('quotaDaily').label }} - {{ getColumn('role').label }} {{ getColumn('pluginAuth').label }} {{ getColumn('createdAt').label }} {{ getColumn('lastLoginDate').label }} @@ -84,8 +84,9 @@ - + @@ -99,6 +100,14 @@ + +
Muted
+
Banned
+ + + + {{ user.roleLabel }} + {{ user.roleLabel }} @@ -138,11 +147,6 @@ - - {{ user.roleLabel }} - {{ user.roleLabel }} - - {{ user.pluginAuth }} diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.scss b/client/src/app/+admin/overview/users/user-list/user-list.component.scss index 335bd2995..8160703f0 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.scss +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.scss @@ -23,6 +23,10 @@ tr.banned > td { font-weight: $font-semibold; } +.badges-username { + margin-left: 15px; +} + .user-table-primary-text .glyphicon { @include margin-left(0.1rem); diff --git a/client/src/app/+admin/overview/users/user-list/user-list.component.ts b/client/src/app/+admin/overview/users/user-list/user-list.component.ts index 9a9d0f5c6..d22e1355e 100644 --- a/client/src/app/+admin/overview/users/user-list/user-list.component.ts +++ b/client/src/app/+admin/overview/users/user-list/user-list.component.ts @@ -2,9 +2,10 @@ import { SortMeta } from 'primeng/api' import { Component, OnInit, ViewChild } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { AuthService, ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core' +import { getAPIHost } from '@app/helpers' import { AdvancedInputFilter } from '@app/shared/shared-forms' -import { DropdownAction } from '@app/shared/shared-main' -import { UserBanModalComponent } from '@app/shared/shared-moderation' +import { Actor, DropdownAction } from '@app/shared/shared-main' +import { AccountMutedStatus, BlocklistService, UserBanModalComponent, UserModerationDisplayType } from '@app/shared/shared-moderation' import { UserAdminService } from '@app/shared/shared-users' import { User, UserRole } from '@shared/models' @@ -23,7 +24,7 @@ type UserForList = User & { export class UserListComponent extends RestTable implements OnInit { @ViewChild('userBanModal', { static: true }) userBanModal: UserBanModalComponent - users: User[] = [] + users: (User & { accountMutedStatus: AccountMutedStatus })[] = [] totalRecords = 0 sort: SortMeta = { field: 'createdAt', order: 1 } @@ -47,6 +48,12 @@ export class UserListComponent extends RestTable implements OnInit { } ] + userModerationDisplayOptions: UserModerationDisplayType = { + instanceAccount: true, + instanceUser: true, + myAccount: false + } + requiresEmailVerification = false private _selectedColumns: string[] @@ -58,6 +65,7 @@ export class UserListComponent extends RestTable implements OnInit { private confirmService: ConfirmService, private serverService: ServerService, private auth: AuthService, + private blocklist: BlocklistService, private userAdminService: UserAdminService ) { super() @@ -115,9 +123,9 @@ export class UserListComponent extends RestTable implements OnInit { this.columns = [ { id: 'username', label: $localize`Username` }, + { id: 'role', label: $localize`Role` }, { id: 'email', label: $localize`Email` }, { id: 'quota', label: $localize`Video quota` }, - { id: 'role', label: $localize`Role` }, { id: 'createdAt', label: $localize`Created` } ] @@ -237,11 +245,35 @@ export class UserListComponent extends RestTable implements OnInit { search: this.search }).subscribe({ next: resultList => { - this.users = resultList.data + this.users = resultList.data.map(u => ({ + ...u, + + accountMutedStatus: { + ...u.account, + + nameWithHost: Actor.CREATE_BY_STRING(u.account.name, u.account.host), + + mutedByInstance: false, + mutedByUser: false, + mutedServerByInstance: false, + mutedServerByUser: false + } + })) this.totalRecords = resultList.total + + this.loadMutedStatus() }, error: err => this.notifier.error(err.message) }) } + + private loadMutedStatus () { + this.blocklist.getStatus({ accounts: this.users.map(u => u.username + '@' + getAPIHost()) }) + .subscribe(blockStatus => { + for (const user of this.users) { + user.accountMutedStatus.mutedByInstance = blockStatus.accounts[user.username + '@' + getAPIHost()].blockedByServer + } + }) + } } diff --git a/client/src/app/helpers/utils/url.ts b/client/src/app/helpers/utils/url.ts index b3cded8f4..08c27e3c1 100644 --- a/client/src/app/helpers/utils/url.ts +++ b/client/src/app/helpers/utils/url.ts @@ -13,6 +13,10 @@ function getAbsoluteAPIUrl () { return absoluteAPIUrl } +function getAPIHost () { + return new URL(getAbsoluteAPIUrl()).host +} + function getAbsoluteEmbedUrl () { let absoluteEmbedUrl = environment.originServerUrl if (!absoluteEmbedUrl) { @@ -52,5 +56,6 @@ function objectToFormData (obj: any, form?: FormData, namespace?: string) { export { objectToFormData, getAbsoluteAPIUrl, + getAPIHost, getAbsoluteEmbedUrl } diff --git a/client/src/app/shared/shared-main/account/actor.model.ts b/client/src/app/shared/shared-main/account/actor.model.ts index a54f51aa4..bd693860d 100644 --- a/client/src/app/shared/shared-main/account/actor.model.ts +++ b/client/src/app/shared/shared-main/account/actor.model.ts @@ -1,4 +1,4 @@ -import { getAbsoluteAPIUrl } from '@app/helpers' +import { getAbsoluteAPIUrl, getAPIHost } from '@app/helpers' import { Actor as ServerActor, ActorImage } from '@shared/models' export abstract class Actor implements ServerActor { @@ -32,8 +32,7 @@ export abstract class Actor implements ServerActor { } static CREATE_BY_STRING (accountName: string, host: string, forceHostname = false) { - const absoluteAPIUrl = getAbsoluteAPIUrl() - const thisHost = new URL(absoluteAPIUrl).host + const thisHost = getAPIHost() if (host.trim() === thisHost && !forceHostname) return accountName @@ -41,8 +40,7 @@ export abstract class Actor implements ServerActor { } static IS_LOCAL (host: string) { - const absoluteAPIUrl = getAbsoluteAPIUrl() - const thisHost = new URL(absoluteAPIUrl).host + const thisHost = getAPIHost() return host.trim() === thisHost } diff --git a/client/src/app/shared/shared-moderation/blocklist.service.ts b/client/src/app/shared/shared-moderation/blocklist.service.ts index f4836c6c4..3e92c2831 100644 --- a/client/src/app/shared/shared-moderation/blocklist.service.ts +++ b/client/src/app/shared/shared-moderation/blocklist.service.ts @@ -1,5 +1,6 @@ import { SortMeta } from 'primeng/api' -import { catchError, map } from 'rxjs/operators' +import { from } from 'rxjs' +import { catchError, concatMap, map, toArray } from 'rxjs/operators' import { HttpClient, HttpParams } from '@angular/common/http' import { Injectable } from '@angular/core' import { RestExtractor, RestPagination, RestService } from '@app/core' @@ -120,11 +121,15 @@ export class BlocklistService { ) } - blockAccountByInstance (account: Pick) { - const body = { accountName: account.nameWithHost } + blockAccountByInstance (accountsArg: Pick | Pick[]) { + const accounts = Array.isArray(accountsArg) ? accountsArg : [ accountsArg ] - return this.authHttp.post(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', body) - .pipe(catchError(err => this.restExtractor.handleError(err))) + return from(accounts) + .pipe( + concatMap(a => this.authHttp.post(BlocklistService.BASE_SERVER_BLOCKLIST_URL + '/accounts', { accountName: a.nameWithHost })), + toArray(), + catchError(err => this.restExtractor.handleError(err)) + ) } unblockAccountByInstance (account: Pick) { diff --git a/client/src/app/shared/shared-moderation/user-ban-modal.component.html b/client/src/app/shared/shared-moderation/user-ban-modal.component.html index 6c83cc9cc..2b6726bdc 100644 --- a/client/src/app/shared/shared-moderation/user-ban-modal.component.html +++ b/client/src/app/shared/shared-moderation/user-ban-modal.component.html @@ -1,11 +1,15 @@