feat(emoji): 管理用のカスタム絵文字フィールドの追加 (MisskeyIO#397)
This commit is contained in:
parent
c4cc9dae87
commit
8befa531a5
|
@ -1052,6 +1052,7 @@ hiddenTags: "Hidden hashtags"
|
||||||
hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines."
|
hiddenTagsDescription: "Select tags which will not shown on trend list.\nMultiple tags could be registered by lines."
|
||||||
notesSearchNotAvailable: "Note search is unavailable."
|
notesSearchNotAvailable: "Note search is unavailable."
|
||||||
license: "License"
|
license: "License"
|
||||||
|
request: "Request"
|
||||||
unfavoriteConfirm: "Really remove from favorites?"
|
unfavoriteConfirm: "Really remove from favorites?"
|
||||||
myClips: "My clips"
|
myClips: "My clips"
|
||||||
drivecleaner: "Drive Cleaner"
|
drivecleaner: "Drive Cleaner"
|
||||||
|
|
4
locales/index.d.ts
vendored
4
locales/index.d.ts
vendored
|
@ -4220,6 +4220,10 @@ export interface Locale extends ILocale {
|
||||||
* ライセンス
|
* ライセンス
|
||||||
*/
|
*/
|
||||||
"license": string;
|
"license": string;
|
||||||
|
/**
|
||||||
|
* リクエスト
|
||||||
|
*/
|
||||||
|
"request": string;
|
||||||
/**
|
/**
|
||||||
* お気に入り解除しますか?
|
* お気に入り解除しますか?
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1051,6 +1051,7 @@ hiddenTags: "非表示ハッシュタグ"
|
||||||
hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。"
|
hiddenTagsDescription: "設定したタグをトレンドに表示させないようにします。改行で区切って複数設定できます。"
|
||||||
notesSearchNotAvailable: "ノート検索は利用できません。"
|
notesSearchNotAvailable: "ノート検索は利用できません。"
|
||||||
license: "ライセンス"
|
license: "ライセンス"
|
||||||
|
request: "リクエスト"
|
||||||
unfavoriteConfirm: "お気に入り解除しますか?"
|
unfavoriteConfirm: "お気に入り解除しますか?"
|
||||||
myClips: "自分のクリップ"
|
myClips: "自分のクリップ"
|
||||||
drivecleaner: "ドライブクリーナー"
|
drivecleaner: "ドライブクリーナー"
|
||||||
|
|
|
@ -1051,6 +1051,7 @@ hiddenTags: "숨긴 해시태그"
|
||||||
hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다."
|
hiddenTagsDescription: "설정한 태그를 트렌드에 표시하지 않도록 합니다. 줄 바꿈으로 하나씩 나눠서 설정할 수 있습니다."
|
||||||
notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다."
|
notesSearchNotAvailable: "노트 검색을 이용하실 수 없습니다."
|
||||||
license: "라이선스"
|
license: "라이선스"
|
||||||
|
request: "요청"
|
||||||
unfavoriteConfirm: "즐겨찾기를 해제하시겠습니까?"
|
unfavoriteConfirm: "즐겨찾기를 해제하시겠습니까?"
|
||||||
myClips: "내 클립"
|
myClips: "내 클립"
|
||||||
drivecleaner: "드라이브 정리"
|
drivecleaner: "드라이브 정리"
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and other misskey contributors
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export class EmojiMoreFields1706723072096 {
|
||||||
|
name = 'EmojiMoreFields1706723072096'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "emoji" ADD "requestedBy" character varying(1024)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "emoji" ADD "memo" character varying(8192) NOT NULL DEFAULT ''`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "memo"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "emoji" DROP COLUMN "requestedBy"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,6 +66,8 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
license: string | null;
|
license: string | null;
|
||||||
isSensitive: boolean;
|
isSensitive: boolean;
|
||||||
localOnly: boolean;
|
localOnly: boolean;
|
||||||
|
requestedBy: string | null;
|
||||||
|
memo: string | null;
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][];
|
roleIdsThatCanBeUsedThisEmojiAsReaction: MiRole['id'][];
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: MiRole['id'][];
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: MiRole['id'][];
|
||||||
}, moderator?: MiUser): Promise<MiEmoji> {
|
}, moderator?: MiUser): Promise<MiEmoji> {
|
||||||
|
@ -82,6 +84,8 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
license: data.license,
|
license: data.license,
|
||||||
isSensitive: data.isSensitive,
|
isSensitive: data.isSensitive,
|
||||||
localOnly: data.localOnly,
|
localOnly: data.localOnly,
|
||||||
|
requestedBy: data.requestedBy,
|
||||||
|
memo: data.memo,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: data.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: data.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
||||||
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
|
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
|
||||||
|
@ -113,6 +117,8 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
license?: string | null;
|
license?: string | null;
|
||||||
isSensitive?: boolean;
|
isSensitive?: boolean;
|
||||||
localOnly?: boolean;
|
localOnly?: boolean;
|
||||||
|
requestedBy?: string | null;
|
||||||
|
memo?: string | null;
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][];
|
roleIdsThatCanBeUsedThisEmojiAsReaction?: MiRole['id'][];
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: MiRole['id'][];
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: MiRole['id'][];
|
||||||
}, moderator?: MiUser): Promise<void> {
|
}, moderator?: MiUser): Promise<void> {
|
||||||
|
@ -131,6 +137,8 @@ export class CustomEmojiService implements OnApplicationShutdown {
|
||||||
originalUrl: data.driveFile != null ? data.driveFile.url : undefined,
|
originalUrl: data.driveFile != null ? data.driveFile.url : undefined,
|
||||||
publicUrl: data.driveFile != null ? (data.driveFile.webpublicUrl ?? data.driveFile.url) : undefined,
|
publicUrl: data.driveFile != null ? (data.driveFile.webpublicUrl ?? data.driveFile.url) : undefined,
|
||||||
type: data.driveFile != null ? (data.driveFile.webpublicType ?? data.driveFile.type) : undefined,
|
type: data.driveFile != null ? (data.driveFile.webpublicType ?? data.driveFile.type) : undefined,
|
||||||
|
requestedBy: data.requestedBy ?? undefined,
|
||||||
|
memo: data.memo ?? undefined,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction ?? undefined,
|
roleIdsThatCanBeUsedThisEmojiAsReaction: data.roleIdsThatCanBeUsedThisEmojiAsReaction ?? undefined,
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: data.roleIdsThatCanNotBeUsedThisEmojiAsReaction ?? undefined,
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: data.roleIdsThatCanNotBeUsedThisEmojiAsReaction ?? undefined,
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,12 +9,15 @@ import type { EmojisRepository } from '@/models/_.js';
|
||||||
import type { Packed } from '@/misc/json-schema.js';
|
import type { Packed } from '@/misc/json-schema.js';
|
||||||
import type { MiEmoji } from '@/models/Emoji.js';
|
import type { MiEmoji } from '@/models/Emoji.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { IdService } from '@/core/IdService.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class EmojiEntityService {
|
export class EmojiEntityService {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.emojisRepository)
|
@Inject(DI.emojisRepository)
|
||||||
private emojisRepository: EmojisRepository,
|
private emojisRepository: EmojisRepository,
|
||||||
|
|
||||||
|
private idService: IdService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,4 +78,39 @@ export class EmojiEntityService {
|
||||||
.filter(result => result.status === 'fulfilled')
|
.filter(result => result.status === 'fulfilled')
|
||||||
.map(result => (result as PromiseFulfilledResult<Packed<'EmojiDetailed'>>).value);
|
.map(result => (result as PromiseFulfilledResult<Packed<'EmojiDetailed'>>).value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
public async packInternal(
|
||||||
|
src: MiEmoji['id'] | MiEmoji,
|
||||||
|
): Promise<Packed<'EmojiDetailed'>> {
|
||||||
|
const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: emoji.id,
|
||||||
|
createdAt: this.idService.parse(emoji.id).date.toISOString(),
|
||||||
|
updatedAt: emoji.updatedAt?.toISOString() ?? null,
|
||||||
|
aliases: emoji.aliases,
|
||||||
|
name: emoji.name,
|
||||||
|
category: emoji.category,
|
||||||
|
host: emoji.host,
|
||||||
|
// || emoji.originalUrl してるのは後方互換性のため(publicUrlはstringなので??はだめ)
|
||||||
|
url: emoji.publicUrl || emoji.originalUrl,
|
||||||
|
license: emoji.license,
|
||||||
|
isSensitive: emoji.isSensitive,
|
||||||
|
localOnly: emoji.localOnly,
|
||||||
|
requestedBy: emoji.requestedBy,
|
||||||
|
memo: emoji.memo,
|
||||||
|
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
||||||
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@bindThis
|
||||||
|
public async packInternalMany(
|
||||||
|
emojis: (MiEmoji['id'] | MiEmoji)[],
|
||||||
|
) : Promise<Packed<'EmojiDetailed'>[]> {
|
||||||
|
return (await Promise.allSettled(emojis.map(x => this.packInternal(x))))
|
||||||
|
.filter(result => result.status === 'fulfilled')
|
||||||
|
.map(result => (result as PromiseFulfilledResult<Packed<'EmojiDetailed'>>).value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,16 @@ export class MiEmoji {
|
||||||
})
|
})
|
||||||
public isSensitive: boolean;
|
public isSensitive: boolean;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 1024, nullable: true,
|
||||||
|
})
|
||||||
|
public requestedBy: string | null;
|
||||||
|
|
||||||
|
@Column('varchar', {
|
||||||
|
length: 8192, default: '',
|
||||||
|
})
|
||||||
|
public memo: string | null;
|
||||||
|
|
||||||
// TODO: 定期ジョブで存在しなくなったロールIDを除去するようにする
|
// TODO: 定期ジョブで存在しなくなったロールIDを除去するようにする
|
||||||
@Column('varchar', {
|
@Column('varchar', {
|
||||||
array: true, length: 128, default: '{}',
|
array: true, length: 128, default: '{}',
|
||||||
|
|
|
@ -60,6 +60,16 @@ export const packedEmojiDetailedSchema = {
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
format: 'id',
|
format: 'id',
|
||||||
},
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true, nullable: false,
|
||||||
|
format: 'date-time',
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true, nullable: true,
|
||||||
|
format: 'date-time',
|
||||||
|
},
|
||||||
aliases: {
|
aliases: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
|
@ -98,6 +108,14 @@ export const packedEmojiDetailedSchema = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
optional: false, nullable: false,
|
optional: false, nullable: false,
|
||||||
},
|
},
|
||||||
|
requestedBy: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true, nullable: true,
|
||||||
|
},
|
||||||
|
memo: {
|
||||||
|
type: 'string',
|
||||||
|
optional: true, nullable: true,
|
||||||
|
},
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: {
|
roleIdsThatCanBeUsedThisEmojiAsReaction: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
optional: true, nullable: false,
|
optional: true, nullable: false,
|
||||||
|
|
|
@ -102,6 +102,8 @@ export class ImportCustomEmojisProcessorService {
|
||||||
license: emojiInfo.license,
|
license: emojiInfo.license,
|
||||||
isSensitive: emojiInfo.isSensitive,
|
isSensitive: emojiInfo.isSensitive,
|
||||||
localOnly: emojiInfo.localOnly,
|
localOnly: emojiInfo.localOnly,
|
||||||
|
requestedBy: emojiInfo.requestedBy,
|
||||||
|
memo: emojiInfo.memo,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
|
roleIdsThatCanBeUsedThisEmojiAsReaction: [],
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: [],
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: [],
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,6 +50,8 @@ export const paramDef = {
|
||||||
license: { type: 'string', nullable: true },
|
license: { type: 'string', nullable: true },
|
||||||
isSensitive: { type: 'boolean' },
|
isSensitive: { type: 'boolean' },
|
||||||
localOnly: { type: 'boolean' },
|
localOnly: { type: 'boolean' },
|
||||||
|
requestedBy: { type: 'string', nullable: true },
|
||||||
|
memo: { type: 'string', nullable: true },
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
|
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'misskey:id',
|
format: 'misskey:id',
|
||||||
|
@ -89,6 +91,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
license: ps.license ?? null,
|
license: ps.license ?? null,
|
||||||
isSensitive: ps.isSensitive ?? false,
|
isSensitive: ps.isSensitive ?? false,
|
||||||
localOnly: ps.localOnly ?? false,
|
localOnly: ps.localOnly ?? false,
|
||||||
|
requestedBy: ps.requestedBy ?? null,
|
||||||
|
memo: ps.memo ?? null,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
|
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: ps.roleIdsThatCanNotBeUsedThisEmojiAsReaction ?? [],
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: ps.roleIdsThatCanNotBeUsedThisEmojiAsReaction ?? [],
|
||||||
}, me);
|
}, me);
|
||||||
|
|
|
@ -106,6 +106,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
license: emoji.license,
|
license: emoji.license,
|
||||||
isSensitive: emoji.isSensitive,
|
isSensitive: emoji.isSensitive,
|
||||||
localOnly: emoji.localOnly,
|
localOnly: emoji.localOnly,
|
||||||
|
requestedBy: emoji.requestedBy,
|
||||||
|
memo: emoji.memo,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
roleIdsThatCanBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
||||||
}, me);
|
}, me);
|
||||||
|
|
|
@ -106,7 +106,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
.limit(ps.limit)
|
.limit(ps.limit)
|
||||||
.getMany();
|
.getMany();
|
||||||
|
|
||||||
return this.emojiEntityService.packDetailedMany(emojis);
|
return this.emojiEntityService.packInternalMany(emojis);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import type { MiEmoji } from '@/models/Emoji.js';
|
||||||
import { QueryService } from '@/core/QueryService.js';
|
import { QueryService } from '@/core/QueryService.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
|
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
|
||||||
//import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
|
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
@ -88,28 +87,26 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
let emojis: MiEmoji[];
|
let emojis: MiEmoji[];
|
||||||
|
|
||||||
if (ps.query) {
|
if (ps.query) {
|
||||||
//q.andWhere('emoji.name ILIKE :q', { q: `%${ sqlLikeEscape(ps.query) }%` });
|
if (ps.query.startsWith(':') && ps.query.endsWith(':') && ps.query.length > 2) {
|
||||||
//const emojis = await q.limit(ps.limit).getMany();
|
// 登録名と完全一致の検索
|
||||||
|
q.andWhere('emoji.name = :q', { q: ps.query.slice(1, -1) });
|
||||||
|
|
||||||
emojis = await q.getMany();
|
emojis = await q.limit(ps.limit).getMany();
|
||||||
const queryarry = ps.query.match(/\:([a-z0-9_]*)\:/g);
|
|
||||||
|
|
||||||
if (queryarry) {
|
|
||||||
emojis = emojis.filter(emoji =>
|
|
||||||
queryarry.includes(`:${emoji.name}:`),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
emojis = emojis.filter(emoji =>
|
// 登録名、エイリアス、カテゴリーの部分一致の検索
|
||||||
emoji.name.includes(ps.query!) ||
|
// TODO: クエリーで処理したいが、aliasesがarrayなので複雑になりすぎるためいったん放置
|
||||||
emoji.aliases.some(a => a.includes(ps.query!)) ||
|
emojis = (await q.getMany())
|
||||||
emoji.category?.includes(ps.query!));
|
.filter(emoji =>
|
||||||
|
emoji.name.includes(ps.query!) ||
|
||||||
|
emoji.aliases.some(a => a.includes(ps.query!)) ||
|
||||||
|
emoji.category?.includes(ps.query!))
|
||||||
|
.splice(ps.limit + 1);
|
||||||
}
|
}
|
||||||
emojis.splice(ps.limit + 1);
|
|
||||||
} else {
|
} else {
|
||||||
emojis = await q.limit(ps.limit).getMany();
|
emojis = await q.limit(ps.limit).getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.emojiEntityService.packDetailedMany(emojis);
|
return this.emojiEntityService.packInternalMany(emojis);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ export const paramDef = {
|
||||||
license: { type: 'string', nullable: true },
|
license: { type: 'string', nullable: true },
|
||||||
isSensitive: { type: 'boolean' },
|
isSensitive: { type: 'boolean' },
|
||||||
localOnly: { type: 'boolean' },
|
localOnly: { type: 'boolean' },
|
||||||
|
requestedBy: { type: 'string', nullable: true },
|
||||||
|
memo: { type: 'string', nullable: true },
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
|
roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'misskey:id',
|
format: 'misskey:id',
|
||||||
|
@ -98,6 +100,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
license: ps.license ?? null,
|
license: ps.license ?? null,
|
||||||
isSensitive: ps.isSensitive,
|
isSensitive: ps.isSensitive,
|
||||||
localOnly: ps.localOnly,
|
localOnly: ps.localOnly,
|
||||||
|
requestedBy: ps.requestedBy ?? null,
|
||||||
|
memo: ps.memo ?? null,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction,
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: ps.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: ps.roleIdsThatCanNotBeUsedThisEmojiAsReaction,
|
||||||
}, me);
|
}, me);
|
||||||
|
|
|
@ -224,7 +224,8 @@ const setCategoryBulk = async () => {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
category: result,
|
category: result,
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const setLicenseBulk = async () => {
|
const setLicenseBulk = async () => {
|
||||||
|
@ -237,7 +238,8 @@ const setLicenseBulk = async () => {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
license: result,
|
license: result,
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const addTagBulk = async () => {
|
const addTagBulk = async () => {
|
||||||
|
@ -249,7 +251,8 @@ const addTagBulk = async () => {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
aliases: result.split(' '),
|
aliases: result.split(' '),
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeTagBulk = async () => {
|
const removeTagBulk = async () => {
|
||||||
|
@ -261,7 +264,8 @@ const removeTagBulk = async () => {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
aliases: result.split(' '),
|
aliases: result.split(' '),
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTagBulk = async () => {
|
const setTagBulk = async () => {
|
||||||
|
@ -273,7 +277,8 @@ const setTagBulk = async () => {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
aliases: result.split(' '),
|
aliases: result.split(' '),
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const delBulk = async () => {
|
const delBulk = async () => {
|
||||||
|
@ -285,7 +290,8 @@ const delBulk = async () => {
|
||||||
await os.apiWithDialog('admin/emoji/delete-bulk', {
|
await os.apiWithDialog('admin/emoji/delete-bulk', {
|
||||||
ids: selectedEmojis.value,
|
ids: selectedEmojis.value,
|
||||||
});
|
});
|
||||||
emojisPaginationComponent.value.reload();
|
selectedEmojis.value = [];
|
||||||
|
emojisPaginationComponent.value?.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerActions = computed(() => [{
|
const headerActions = computed(() => [{
|
||||||
|
|
|
@ -49,6 +49,20 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkTextarea v-model="license" :mfmAutocomplete="true">
|
<MkTextarea v-model="license" :mfmAutocomplete="true">
|
||||||
<template #label>{{ i18n.ts.license }}</template>
|
<template #label>{{ i18n.ts.license }}</template>
|
||||||
</MkTextarea>
|
</MkTextarea>
|
||||||
|
<MkInput v-model="requestedBy" autocapitalize="off">
|
||||||
|
<template #label>{{ i18n.ts.request }}</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkTextarea v-model="memo" :mfmAutocomplete="true">
|
||||||
|
<template #label>{{ i18n.ts.memo }}</template>
|
||||||
|
</MkTextarea>
|
||||||
|
<MkKeyValue v-if="createdAt" oneline>
|
||||||
|
<template #key>{{ i18n.ts.createdAt }}</template>
|
||||||
|
<template #value><span class="_monospace"><MkTime :time="createdAt" :mode="'detail'"/></span></template>
|
||||||
|
</MkKeyValue>
|
||||||
|
<MkKeyValue v-if="updatedAt" oneline>
|
||||||
|
<template #key>{{ i18n.ts.updatedAt }}</template>
|
||||||
|
<template #value><span class="_monospace"><MkTime :time="updatedAt" :mode="'detail'"/></span></template>
|
||||||
|
</MkKeyValue>
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReaction }}</template>
|
<template #label>{{ i18n.ts.rolesThatCanBeUsedThisEmojiAsReaction }}</template>
|
||||||
<template #suffix>{{ rolesThatCanBeUsedThisEmojiAsReaction.length === 0 ? i18n.ts.all : rolesThatCanBeUsedThisEmojiAsReaction.length }}</template>
|
<template #suffix>{{ rolesThatCanBeUsedThisEmojiAsReaction.length === 0 ? i18n.ts.all : rolesThatCanBeUsedThisEmojiAsReaction.length }}</template>
|
||||||
|
@ -111,6 +125,7 @@ import { customEmojiCategories } from '@/custom-emojis.js';
|
||||||
import MkSwitch from '@/components/MkSwitch.vue';
|
import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
import { selectFile } from '@/scripts/select-file.js';
|
import { selectFile } from '@/scripts/select-file.js';
|
||||||
import MkRolePreview from '@/components/MkRolePreview.vue';
|
import MkRolePreview from '@/components/MkRolePreview.vue';
|
||||||
|
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
emoji?: any,
|
emoji?: any,
|
||||||
|
@ -120,9 +135,13 @@ const windowEl = ref<InstanceType<typeof MkWindow> | null>(null);
|
||||||
const name = ref<string>(props.emoji ? props.emoji.name : '');
|
const name = ref<string>(props.emoji ? props.emoji.name : '');
|
||||||
const category = ref<string>(props.emoji ? props.emoji.category : '');
|
const category = ref<string>(props.emoji ? props.emoji.category : '');
|
||||||
const aliases = ref<string>(props.emoji ? props.emoji.aliases.join(' ') : '');
|
const aliases = ref<string>(props.emoji ? props.emoji.aliases.join(' ') : '');
|
||||||
|
const createdAt = ref<string | null>(props.emoji ? props.emoji.createdAt : null);
|
||||||
|
const updatedAt = ref<string | null>(props.emoji ? props.emoji.updatedAt : null);
|
||||||
const license = ref<string>(props.emoji ? (props.emoji.license ?? '') : '');
|
const license = ref<string>(props.emoji ? (props.emoji.license ?? '') : '');
|
||||||
const isSensitive = ref(props.emoji ? props.emoji.isSensitive : false);
|
const isSensitive = ref(props.emoji ? props.emoji.isSensitive : false);
|
||||||
const localOnly = ref(props.emoji ? props.emoji.localOnly : false);
|
const localOnly = ref(props.emoji ? props.emoji.localOnly : false);
|
||||||
|
const requestedBy = ref(props.emoji ? props.emoji.requestedBy : '');
|
||||||
|
const memo = ref(props.emoji ? props.emoji.memo : '');
|
||||||
const roleIdsThatCanBeUsedThisEmojiAsReaction = ref(props.emoji ? props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : []);
|
const roleIdsThatCanBeUsedThisEmojiAsReaction = ref(props.emoji ? props.emoji.roleIdsThatCanBeUsedThisEmojiAsReaction : []);
|
||||||
const rolesThatCanBeUsedThisEmojiAsReaction = ref<Misskey.entities.Role[]>([]);
|
const rolesThatCanBeUsedThisEmojiAsReaction = ref<Misskey.entities.Role[]>([]);
|
||||||
const roleIdsThatCanNotBeUsedThisEmojiAsReaction = ref(props.emoji ? props.emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction : []);
|
const roleIdsThatCanNotBeUsedThisEmojiAsReaction = ref(props.emoji ? props.emoji.roleIdsThatCanNotBeUsedThisEmojiAsReaction : []);
|
||||||
|
@ -178,6 +197,8 @@ async function done() {
|
||||||
license: license.value === '' ? null : license.value,
|
license: license.value === '' ? null : license.value,
|
||||||
isSensitive: isSensitive.value,
|
isSensitive: isSensitive.value,
|
||||||
localOnly: localOnly.value,
|
localOnly: localOnly.value,
|
||||||
|
requestedBy: requestedBy.value,
|
||||||
|
memo: memo.value,
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction: rolesThatCanBeUsedThisEmojiAsReaction.value.map(x => x.id),
|
roleIdsThatCanBeUsedThisEmojiAsReaction: rolesThatCanBeUsedThisEmojiAsReaction.value.map(x => x.id),
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction: rolesThatCanNotBeUsedThisEmojiAsReaction.value.map(x => x.id),
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction: rolesThatCanNotBeUsedThisEmojiAsReaction.value.map(x => x.id),
|
||||||
};
|
};
|
||||||
|
|
|
@ -4527,6 +4527,10 @@ export type components = {
|
||||||
EmojiDetailed: {
|
EmojiDetailed: {
|
||||||
/** Format: id */
|
/** Format: id */
|
||||||
id: string;
|
id: string;
|
||||||
|
/** Format: date-time */
|
||||||
|
createdAt?: string;
|
||||||
|
/** Format: date-time */
|
||||||
|
updatedAt?: string | null;
|
||||||
aliases: string[];
|
aliases: string[];
|
||||||
name: string;
|
name: string;
|
||||||
category: string | null;
|
category: string | null;
|
||||||
|
@ -4536,6 +4540,8 @@ export type components = {
|
||||||
license: string | null;
|
license: string | null;
|
||||||
isSensitive: boolean;
|
isSensitive: boolean;
|
||||||
localOnly: boolean;
|
localOnly: boolean;
|
||||||
|
requestedBy?: string | null;
|
||||||
|
memo?: string | null;
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
||||||
};
|
};
|
||||||
|
@ -6682,6 +6688,8 @@ export type operations = {
|
||||||
license?: string | null;
|
license?: string | null;
|
||||||
isSensitive?: boolean;
|
isSensitive?: boolean;
|
||||||
localOnly?: boolean;
|
localOnly?: boolean;
|
||||||
|
requestedBy?: string | null;
|
||||||
|
memo?: string | null;
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
||||||
};
|
};
|
||||||
|
@ -7311,6 +7319,8 @@ export type operations = {
|
||||||
license?: string | null;
|
license?: string | null;
|
||||||
isSensitive?: boolean;
|
isSensitive?: boolean;
|
||||||
localOnly?: boolean;
|
localOnly?: boolean;
|
||||||
|
requestedBy?: string | null;
|
||||||
|
memo?: string | null;
|
||||||
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanBeUsedThisEmojiAsReaction?: string[];
|
||||||
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
roleIdsThatCanNotBeUsedThisEmojiAsReaction?: string[];
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue