enhance(backend/frontend): モデレーションノートをユーザーのプロフィールページからも閲覧および編集できるように

This commit is contained in:
syuilo 2023-05-06 09:51:06 +09:00
parent bd1c2abffc
commit 10ff379b4c
3 changed files with 31 additions and 10 deletions

View File

@ -34,6 +34,7 @@
* デフォルトがオフになるので、ロールタイムラインを表示する場合はオンにしてください。
- ロールに強制的にNSFWを付与するポリシーを追加
* アップロード済みのファイルはNSFWにならない為注意してください。
- モデレーションノートがユーザーのプロフィールページからも閲覧および編集できるようになりました。
- カスタム絵文字のライセンスを複数でセットできるようになりました。
- 管理者が予約ユーザー名を設定できるようになりました。
- Fix: フォローリクエストの通知が残る問題を修正

View File

@ -292,7 +292,7 @@ export class UserEntityService implements OnModuleInit {
public async pack<ExpectsMe extends boolean | null = null, D extends boolean = false>(
src: User['id'] | User,
me?: { id: User['id'] } | null | undefined,
me?: { id: User['id']; isRoot: boolean; } | null | undefined,
options?: {
detail?: D,
includeSecrets?: boolean,
@ -308,6 +308,7 @@ export class UserEntityService implements OnModuleInit {
const meId = me ? me.id : null;
const isMe = meId === user.id;
const iAmModerator = me ? await this.roleService.isModerator(me) : false;
const relation = meId && !isMe && opts.detail ? await this.getRelation(meId, user.id) : null;
const pins = opts.detail ? await this.userNotePiningsRepository.createQueryBuilder('pin')
@ -411,6 +412,7 @@ export class UserEntityService implements OnModuleInit {
userId: meId,
targetUserId: user.id,
}).then(row => row?.memo ?? null),
moderationNote: iAmModerator ? profile!.moderationNote : null,
} : {}),
...(opts.detail && isMe ? {

View File

@ -7,7 +7,7 @@
<!-- <div class="punished" v-if="user.isSilenced"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSilenced }}</div> -->
<div class="profile _gaps">
<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo" />
<MkAccountMoved v-if="user.movedTo" :moved-to="user.movedTo"/>
<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!" class="warn"/>
<div :key="user.id" class="main _panel">
@ -42,6 +42,17 @@
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
</div>
</div>
<div v-if="user.roles.length > 0" class="roles">
<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }">
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/>
{{ role.name }}
</span>
</div>
<div v-if="iAmModerator" class="moderationNote">
<MkTextarea v-model="moderationNote" manual-save>
<template #label>Moderation note</template>
</MkTextarea>
</div>
<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}">
<div class="heading" v-text="i18n.ts.memo"/>
<textarea
@ -53,12 +64,6 @@
@input="adjustMemoTextarea"
/>
</div>
<div v-if="user.roles.length > 0" class="roles">
<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }">
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/>
{{ role.name }}
</span>
</div>
<div class="description">
<MkOmit>
<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$i"/>
@ -134,6 +139,7 @@ import MkNote from '@/components/MkNote.vue';
import MkFollowButton from '@/components/MkFollowButton.vue';
import MkAccountMoved from '@/components/MkAccountMoved.vue';
import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
import MkTextarea from '@/components/MkTextarea.vue';
import MkOmit from '@/components/MkOmit.vue';
import MkInfo from '@/components/MkInfo.vue';
import { getScrollPosition } from '@/scripts/scroll';
@ -143,7 +149,7 @@ import { userPage } from '@/filters/user';
import * as os from '@/os';
import { useRouter } from '@/router';
import { i18n } from '@/i18n';
import { $i } from '@/account';
import { $i, iAmModerator } from '@/account';
import { dateString } from '@/filters/date';
import { confetti } from '@/scripts/confetti';
import MkNotes from '@/components/MkNotes.vue';
@ -168,8 +174,12 @@ let rootEl = $ref<null | HTMLElement>(null);
let bannerEl = $ref<null | HTMLElement>(null);
let memoTextareaEl = $ref<null | HTMLElement>(null);
let memoDraft = $ref(props.user.memo);
let isEditingMemo = $ref(false);
let moderationNote = $ref(props.user.moderationNote);
watch($$(moderationNote), async () => {
await os.api('admin/update-user-note', { userId: props.user.id, text: moderationNote });
});
const pagination = {
endpoint: 'users/notes' as const,
@ -426,6 +436,10 @@ onUnmounted(() => {
}
}
> .moderationNote {
margin: 12px 24px 0 154px;
}
> .memo {
margin: 12px 24px 0 154px;
background: transparent;
@ -593,6 +607,10 @@ onUnmounted(() => {
justify-content: center;
}
> .moderationNote {
margin: 16px 16px 0 16px;
}
> .memo {
margin: 16px 16px 0 16px;
}