merge: Show signup reason in user admin screen (resolves #1090) (!1114)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1114

Closes #1090

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
Hazelnoot 2025-06-14 17:30:17 +00:00
commit f6964f6e27
9 changed files with 36 additions and 16 deletions

4
locales/index.d.ts vendored
View file

@ -13257,6 +13257,10 @@ export interface Locale extends ILocale {
* ActivityPub user data in its raw form. These fields are public and accessible to other instances. * ActivityPub user data in its raw form. These fields are public and accessible to other instances.
*/ */
"rawApDescription": string; "rawApDescription": string;
/**
* Signup Reason
*/
"signupReason": string;
} }
declare const locales: { declare const locales: {
[lang: string]: Locale; [lang: string]: Locale;

View file

@ -13,6 +13,7 @@ import { type WebhookEventTypes } from '@/models/Webhook.js';
import { CustomEmojiService } from '@/core/CustomEmojiService.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js'; import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
import { QueueService } from '@/core/QueueService.js'; import { QueueService } from '@/core/QueueService.js';
import { IdService } from '@/core/IdService.js';
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js'; import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
const oneDayMillis = 24 * 60 * 60 * 1000; const oneDayMillis = 24 * 60 * 60 * 1000;
@ -166,6 +167,7 @@ export class WebhookTestService {
private userWebhookService: UserWebhookService, private userWebhookService: UserWebhookService,
private systemWebhookService: SystemWebhookService, private systemWebhookService: SystemWebhookService,
private queueService: QueueService, private queueService: QueueService,
private readonly idService: IdService,
) { ) {
} }
@ -449,6 +451,8 @@ export class WebhookTestService {
offsetX: it.offsetX, offsetX: it.offsetX,
offsetY: it.offsetY, offsetY: it.offsetY,
})), })),
createdAt: this.idService.parse(user.id).date.toISOString(),
description: '',
isBot: user.isBot, isBot: user.isBot,
isCat: user.isCat, isCat: user.isCat,
emojis: await this.customEmojiService.populateEmojis(user.emojis, user.host), emojis: await this.customEmojiService.populateEmojis(user.emojis, user.host),

View file

@ -73,6 +73,16 @@ export const packedUserLiteSchema = {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true, optional: false,
}, },
description: {
type: 'string',
nullable: true, optional: false,
example: 'Hi masters, I am Ai!',
},
createdAt: {
type: 'string',
nullable: false, optional: false,
format: 'date-time',
},
avatarDecorations: { avatarDecorations: {
type: 'array', type: 'array',
nullable: false, optional: false, nullable: false, optional: false,
@ -278,11 +288,6 @@ export const packedUserDetailedNotMeOnlySchema = {
nullable: false, optional: false, nullable: false, optional: false,
}, },
}, },
createdAt: {
type: 'string',
nullable: false, optional: false,
format: 'date-time',
},
updatedAt: { updatedAt: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true, optional: false,
@ -324,11 +329,6 @@ export const packedUserDetailedNotMeOnlySchema = {
nullable: false, optional: false, nullable: false, optional: false,
example: false, example: false,
}, },
description: {
type: 'string',
nullable: true, optional: false,
example: 'Hi masters, I am Ai!',
},
location: { location: {
type: 'string', type: 'string',
nullable: true, optional: false, nullable: true, optional: false,

View file

@ -221,6 +221,10 @@ export const meta = {
}, },
}, },
}, },
signupReason: {
type: 'string',
optional: false, nullable: true,
},
}, },
}, },
} as const; } as const;

View file

@ -652,7 +652,7 @@ export async function sendEnvResetRequest() {
// 与えられた値を強制的にエラーとみなす。この関数は型安全性を破壊するため、異常系のアサーション以外で用いられるべきではない。 // 与えられた値を強制的にエラーとみなす。この関数は型安全性を破壊するため、異常系のアサーション以外で用いられるべきではない。
// FIXME(misskey-js): misskey-jsがエラー情報を公開するようになったらこの関数を廃止する // FIXME(misskey-js): misskey-jsがエラー情報を公開するようになったらこの関数を廃止する
export function castAsError(obj: Record<string, unknown>): { error: ApiError } { export function castAsError(obj: object | null | undefined): { error: ApiError } {
return obj as { error: ApiError }; return obj as { error: ApiError };
} }

View file

@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>{{ email }}</div> <div>{{ email }}</div>
</div> </div>
<div> <div>
<div :class="$style.label">Reason</div> <div :class="$style.label">{{ i18n.ts.signupReason }}</div>
<div>{{ reason }}</div> <div>{{ reason }}</div>
</div> </div>
</div> </div>

View file

@ -130,6 +130,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</FormSection> </FormSection>
<FormSection v-else-if="info.signupReason">
<template #label>{{ i18n.ts.signupReason }}</template>
{{ info.signupReason }}
</FormSection>
<FormSection v-if="!isSystem && user && iAmModerator"> <FormSection v-if="!isSystem && user && iAmModerator">
<div class="_gaps"> <div class="_gaps">
<MkSwitch v-model="silenced" @update:modelValue="toggleSilence">{{ i18n.ts.silence }}</MkSwitch> <MkSwitch v-model="silenced" @update:modelValue="toggleSilence">{{ i18n.ts.silence }}</MkSwitch>

View file

@ -4246,6 +4246,10 @@ export type components = {
/** Format: url */ /** Format: url */
avatarUrl: string | null; avatarUrl: string | null;
avatarBlurhash: string | null; avatarBlurhash: string | null;
/** @example Hi masters, I am Ai! */
description: string | null;
/** Format: date-time */
createdAt: string;
avatarDecorations: { avatarDecorations: {
/** Format: id */ /** Format: id */
id: string; id: string;
@ -4304,8 +4308,6 @@ export type components = {
movedTo: string | null; movedTo: string | null;
alsoKnownAs: string[] | null; alsoKnownAs: string[] | null;
/** Format: date-time */ /** Format: date-time */
createdAt: string;
/** Format: date-time */
updatedAt: string | null; updatedAt: string | null;
/** Format: date-time */ /** Format: date-time */
lastFetchedAt: string | null; lastFetchedAt: string | null;
@ -4319,8 +4321,6 @@ export type components = {
isSilenced: boolean; isSilenced: boolean;
/** @example false */ /** @example false */
isSuspended: boolean; isSuspended: boolean;
/** @example Hi masters, I am Ai! */
description: string | null;
location: string | null; location: string | null;
/** @example 2018-03-12 */ /** @example 2018-03-12 */
birthday: string | null; birthday: string | null;
@ -11236,6 +11236,7 @@ export type operations = {
remoteFollowing: number; remoteFollowing: number;
remoteFollowers: number; remoteFollowers: number;
}; };
signupReason: string | null;
}; };
}; };
}; };

View file

@ -628,3 +628,5 @@ noteFooterLabel: "Note controls"
rawUserDescription: "Packed user data in its raw form. Most of these fields are public and visible to all users." rawUserDescription: "Packed user data in its raw form. Most of these fields are public and visible to all users."
rawInfoDescription: "Extended user data in its raw form. These fields are private and can only be accessed by moderators." rawInfoDescription: "Extended user data in its raw form. These fields are private and can only be accessed by moderators."
rawApDescription: "ActivityPub user data in its raw form. These fields are public and accessible to other instances." rawApDescription: "ActivityPub user data in its raw form. These fields are public and accessible to other instances."
signupReason: "Signup Reason"