feat: カスタム絵文字ごとにそれをリアクションとして使えるロールを設定できるように
This commit is contained in:
		@@ -25,9 +25,24 @@ export const meta = {
 | 
			
		||||
export const paramDef = {
 | 
			
		||||
	type: 'object',
 | 
			
		||||
	properties: {
 | 
			
		||||
		name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
 | 
			
		||||
		fileId: { type: 'string', format: 'misskey:id' },
 | 
			
		||||
		category: {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
			nullable: true,
 | 
			
		||||
			description: 'Use `null` to reset the category.',
 | 
			
		||||
		},
 | 
			
		||||
		aliases: { type: 'array', items: {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
		} },
 | 
			
		||||
		license: { type: 'string', nullable: true },
 | 
			
		||||
		isSensitive: { type: 'boolean' },
 | 
			
		||||
		localOnly: { type: 'boolean' },
 | 
			
		||||
		roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
		} },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['fileId'],
 | 
			
		||||
	required: ['name', 'fileId'],
 | 
			
		||||
} as const;
 | 
			
		||||
 | 
			
		||||
// TODO: ロジックをサービスに切り出す
 | 
			
		||||
@@ -45,18 +60,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
 | 
			
		||||
 | 
			
		||||
			if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
 | 
			
		||||
 | 
			
		||||
			const name = driveFile.name.split('.')[0].match(/^[a-z0-9_]+$/) ? driveFile.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`;
 | 
			
		||||
 | 
			
		||||
			const emoji = await this.customEmojiService.add({
 | 
			
		||||
				driveFile,
 | 
			
		||||
				name,
 | 
			
		||||
				category: null,
 | 
			
		||||
				aliases: [],
 | 
			
		||||
				name: ps.name,
 | 
			
		||||
				category: ps.category ?? null,
 | 
			
		||||
				aliases: ps.aliases ?? [],
 | 
			
		||||
				host: null,
 | 
			
		||||
				license: null,
 | 
			
		||||
				license: ps.license ?? null,
 | 
			
		||||
				isSensitive: ps.isSensitive ?? false,
 | 
			
		||||
				localOnly: ps.localOnly ?? false,
 | 
			
		||||
				roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction ?? [],
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.moderationLogService.insertModerationLog(me, 'addEmoji', {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
import { Inject, Injectable } from '@nestjs/common';
 | 
			
		||||
import { Endpoint } from '@/server/api/endpoint-base.js';
 | 
			
		||||
import { CustomEmojiService } from '@/core/CustomEmojiService.js';
 | 
			
		||||
import type { DriveFilesRepository } from '@/models/index.js';
 | 
			
		||||
import { DI } from '@/di-symbols.js';
 | 
			
		||||
import { ApiError } from '../../../error.js';
 | 
			
		||||
 | 
			
		||||
export const meta = {
 | 
			
		||||
@@ -15,6 +17,11 @@ export const meta = {
 | 
			
		||||
			code: 'NO_SUCH_EMOJI',
 | 
			
		||||
			id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8',
 | 
			
		||||
		},
 | 
			
		||||
		noSuchFile: {
 | 
			
		||||
			message: 'No such file.',
 | 
			
		||||
			code: 'NO_SUCH_FILE',
 | 
			
		||||
			id: '14fb9fd9-0731-4e2f-aeb9-f09e4740333d',
 | 
			
		||||
		},
 | 
			
		||||
		sameNameEmojiExists: {
 | 
			
		||||
			message: 'Emoji that have same name already exists.',
 | 
			
		||||
			code: 'SAME_NAME_EMOJI_EXISTS',
 | 
			
		||||
@@ -28,6 +35,7 @@ export const paramDef = {
 | 
			
		||||
	properties: {
 | 
			
		||||
		id: { type: 'string', format: 'misskey:id' },
 | 
			
		||||
		name: { type: 'string', pattern: '^[a-zA-Z0-9_]+$' },
 | 
			
		||||
		fileId: { type: 'string', format: 'misskey:id' },
 | 
			
		||||
		category: {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
			nullable: true,
 | 
			
		||||
@@ -37,6 +45,11 @@ export const paramDef = {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
		} },
 | 
			
		||||
		license: { type: 'string', nullable: true },
 | 
			
		||||
		isSensitive: { type: 'boolean' },
 | 
			
		||||
		localOnly: { type: 'boolean' },
 | 
			
		||||
		roleIdsThatCanBeUsedThisEmojiAsReaction: { type: 'array', items: {
 | 
			
		||||
			type: 'string',
 | 
			
		||||
		} },
 | 
			
		||||
	},
 | 
			
		||||
	required: ['id', 'name', 'aliases'],
 | 
			
		||||
} as const;
 | 
			
		||||
@@ -45,14 +58,28 @@ export const paramDef = {
 | 
			
		||||
@Injectable()
 | 
			
		||||
export default class extends Endpoint<typeof meta, typeof paramDef> {
 | 
			
		||||
	constructor(
 | 
			
		||||
		@Inject(DI.driveFilesRepository)
 | 
			
		||||
		private driveFilesRepository: DriveFilesRepository,
 | 
			
		||||
 | 
			
		||||
		private customEmojiService: CustomEmojiService,
 | 
			
		||||
	) {
 | 
			
		||||
		super(meta, paramDef, async (ps, me) => {
 | 
			
		||||
			let driveFile;
 | 
			
		||||
 | 
			
		||||
			if (ps.fileId) {
 | 
			
		||||
				driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
 | 
			
		||||
				if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
 | 
			
		||||
			}
 | 
			
		||||
	
 | 
			
		||||
			await this.customEmojiService.update(ps.id, {
 | 
			
		||||
				driveFile,
 | 
			
		||||
				name: ps.name,
 | 
			
		||||
				category: ps.category ?? null,
 | 
			
		||||
				aliases: ps.aliases,
 | 
			
		||||
				license: ps.license ?? null,
 | 
			
		||||
				isSensitive: ps.isSensitive,
 | 
			
		||||
				localOnly: ps.localOnly,
 | 
			
		||||
				roleIdsThatCanBeUsedThisEmojiAsReaction: ps.roleIdsThatCanBeUsedThisEmojiAsReaction,
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user