This commit is contained in:
tamaina 2023-01-22 14:53:24 +00:00
parent a5f54580a9
commit 2f6c45e118
12 changed files with 114 additions and 37 deletions

View file

@ -2,6 +2,8 @@ import { Inject, Injectable } from '@nestjs/common';
import { DataSource, In, IsNull } from 'typeorm'; import { DataSource, In, IsNull } from 'typeorm';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { IdService } from '@/core/IdService.js'; import { IdService } from '@/core/IdService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { DriveFile } from '@/models/entities/DriveFile.js';
import type { Emoji } from '@/models/entities/Emoji.js'; import type { Emoji } from '@/models/entities/Emoji.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
@ -17,6 +19,8 @@ export class CustomEmojiService {
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private idService: IdService, private idService: IdService,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
} }
@ -42,6 +46,10 @@ export class CustomEmojiService {
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: await this.emojiEntityService.pack(emoji.id),
});
return emoji; return emoji;
} }
} }

View file

@ -3,6 +3,8 @@ import { DataSource, In } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -35,6 +37,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.emojisRepository) @Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const emojis = await this.emojisRepository.findBy({ const emojis = await this.emojisRepository.findBy({
@ -49,6 +54,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} }
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: await this.emojiEntityService.packMany(ps.ids),
});
}); });
} }
} }

View file

@ -2,12 +2,10 @@ import { Inject, Injectable } from '@nestjs/common';
import rndstr from 'rndstr'; import rndstr from 'rndstr';
import { DataSource } from 'typeorm'; import { DataSource } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { DriveFilesRepository, EmojisRepository } from '@/models/index.js'; import type { DriveFilesRepository } from '@/models/index.js';
import { IdService } from '@/core/IdService.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { GlobalEventService } from '@/core/GlobalEventService.js'; import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { ApiError } from '../../../error.js'; import { ApiError } from '../../../error.js';
export const meta = { export const meta = {
@ -39,43 +37,26 @@ export const paramDef = {
@Injectable() @Injectable()
export default class extends Endpoint<typeof meta, typeof paramDef> { export default class extends Endpoint<typeof meta, typeof paramDef> {
constructor( constructor(
@Inject(DI.db)
private db: DataSource,
@Inject(DI.driveFilesRepository) @Inject(DI.driveFilesRepository)
private driveFilesRepository: DriveFilesRepository, private driveFilesRepository: DriveFilesRepository,
@Inject(DI.emojisRepository) private customEmojiService: CustomEmojiService,
private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private idService: IdService,
private globalEventService: GlobalEventService,
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const file = await this.driveFilesRepository.findOneBy({ id: ps.fileId }); const driveFile = await this.driveFilesRepository.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (driveFile == null) throw new ApiError(meta.errors.noSuchFile);
const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`; const name = driveFile.name.split('.')[0].match(/^[a-z0-9_]+$/) ? driveFile.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`;
const emoji = await this.emojisRepository.insert({ const emoji = await this.customEmojiService.add({
id: this.idService.genId(), driveFile,
updatedAt: new Date(), name,
name: name,
category: null, category: null,
host: null,
aliases: [], aliases: [],
originalUrl: file.url, host: null,
publicUrl: file.webpublicUrl ?? file.url,
type: file.webpublicType ?? file.type,
}).then(x => this.emojisRepository.findOneByOrFail(x.identifiers[0]));
await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: await this.emojiEntityService.pack(emoji.id),
}); });
this.moderationLogService.insertModerationLog(me, 'addEmoji', { this.moderationLogService.insertModerationLog(me, 'addEmoji', {

View file

@ -4,6 +4,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -35,6 +37,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const emojis = await this.emojisRepository.findBy({ const emojis = await this.emojisRepository.findBy({
@ -43,13 +47,15 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
for (const emoji of emojis) { for (const emoji of emojis) {
await this.emojisRepository.delete(emoji.id); await this.emojisRepository.delete(emoji.id);
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.moderationLogService.insertModerationLog(me, 'deleteEmoji', { this.moderationLogService.insertModerationLog(me, 'deleteEmoji', {
emoji: emoji, emoji: emoji,
}); });
} }
this.globalEventService.publishBroadcastStream('emojiDeleted', {
emojis: await this.emojiEntityService.packMany(emojis),
});
}); });
} }
} }

View file

@ -5,6 +5,8 @@ import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ModerationLogService } from '@/core/ModerationLogService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js';
import { ApiError } from '../../../error.js'; import { ApiError } from '../../../error.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -42,6 +44,8 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private moderationLogService: ModerationLogService, private moderationLogService: ModerationLogService,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const emoji = await this.emojisRepository.findOneBy({ id: ps.id }); const emoji = await this.emojisRepository.findOneBy({ id: ps.id });
@ -52,6 +56,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiDeleted', {
emojis: [ await this.emojiEntityService.pack(emoji) ],
});
this.moderationLogService.insertModerationLog(me, 'deleteEmoji', { this.moderationLogService.insertModerationLog(me, 'deleteEmoji', {
emoji: emoji, emoji: emoji,
}); });

View file

@ -3,6 +3,8 @@ import { DataSource, In } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -35,6 +37,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.emojisRepository) @Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const emojis = await this.emojisRepository.findBy({ const emojis = await this.emojisRepository.findBy({
@ -49,6 +54,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} }
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: await this.emojiEntityService.packMany(ps.ids),
});
}); });
} }
} }

View file

@ -3,6 +3,8 @@ import { DataSource, In } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -35,6 +37,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.emojisRepository) @Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
await this.emojisRepository.update({ await this.emojisRepository.update({
@ -45,6 +50,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: await this.emojiEntityService.packMany(ps.ids),
});
}); });
} }
} }

View file

@ -3,6 +3,8 @@ import { DataSource, In } from 'typeorm';
import { Endpoint } from '@/server/api/endpoint-base.js'; import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -37,6 +39,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.emojisRepository) @Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
await this.emojisRepository.update({ await this.emojisRepository.update({
@ -47,6 +52,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: await this.emojiEntityService.packMany(ps.ids),
});
}); });
} }
} }

View file

@ -4,6 +4,8 @@ import { Endpoint } from '@/server/api/endpoint-base.js';
import type { EmojisRepository } from '@/models/index.js'; import type { EmojisRepository } from '@/models/index.js';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import { ApiError } from '../../../error.js'; import { ApiError } from '../../../error.js';
import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
export const meta = { export const meta = {
tags: ['admin'], tags: ['admin'],
@ -48,6 +50,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
@Inject(DI.emojisRepository) @Inject(DI.emojisRepository)
private emojisRepository: EmojisRepository, private emojisRepository: EmojisRepository,
private emojiEntityService: EmojiEntityService,
private globalEventService: GlobalEventService,
) { ) {
super(meta, paramDef, async (ps, me) => { super(meta, paramDef, async (ps, me) => {
const emoji = await this.emojisRepository.findOneBy({ id: ps.id }); const emoji = await this.emojisRepository.findOneBy({ id: ps.id });
@ -62,6 +67,22 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
}); });
await this.db.queryResultCache!.remove(['meta_emojis']); await this.db.queryResultCache!.remove(['meta_emojis']);
const updated = await this.emojiEntityService.pack(emoji.id);
if (emoji.name === ps.name) {
this.globalEventService.publishBroadcastStream('emojiUpdated', {
emojis: [ updated ],
});
} else {
this.globalEventService.publishBroadcastStream('emojiDeleted', {
emojis: [ emoji ],
});
this.globalEventService.publishBroadcastStream('emojiAdded', {
emoji: updated,
});
}
}); });
} }
} }

View file

@ -49,6 +49,16 @@ export interface BroadcastTypes {
emojiAdded: { emojiAdded: {
emoji: Packed<'Emoji'>; emoji: Packed<'Emoji'>;
}; };
emojiUpdated: {
emojis: Packed<'Emoji'>[];
};
emojiDeleted: {
emojis: {
id?: string;
name: string;
[other: string]: any;
}[];
};
} }
export interface UserStreamTypes { export interface UserStreamTypes {

View file

@ -2,6 +2,7 @@ import { apiGet } from './os';
import { miLocalStorage } from './local-storage'; import { miLocalStorage } from './local-storage';
import { shallowRef, computed, markRaw } from 'vue'; import { shallowRef, computed, markRaw } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import { stream } from '@/stream';
const storageCache = miLocalStorage.getItem('emojis'); const storageCache = miLocalStorage.getItem('emojis');
export const customEmojis = shallowRef<Misskey.entities.CustomEmoji[]>(storageCache ? JSON.parse(storageCache) : []); export const customEmojis = shallowRef<Misskey.entities.CustomEmoji[]>(storageCache ? JSON.parse(storageCache) : []);
@ -14,7 +15,18 @@ export const customEmojiCategories = computed<string[]>(() => {
}); });
fetchCustomEmojis(); fetchCustomEmojis();
window.setInterval(fetchCustomEmojis, 1000 * 60 * 10);
stream.on('emojiAdded', emojiData => {
customEmojis.value = [ emojiData.emoji, ...customEmojis.value ]
});
stream.on('emojiUpdated', emojiData => {
customEmojis.value = customEmojis.value.map(item => emojiData.emojis.find(search => search.name === item.name) as Misskey.entities.CustomEmoji ?? item);
});
stream.on('emojiDeleted', emojiData => {
customEmojis.value = customEmojis.value.filter(item => !emojiData.emojis.some(search => search.name === item.name))
});
export async function fetchCustomEmojis() { export async function fetchCustomEmojis() {
const now = Date.now(); const now = Date.now();

View file

@ -338,11 +338,6 @@ import { fetchCustomEmojis } from './custom-emojis';
} }
}); });
stream.on('emojiAdded', emojiData => {
// TODO
//store.commit('instance/set', );
});
for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) { for (const plugin of ColdDeviceStorage.get('plugins').filter(p => p.active)) {
import('./plugin').then(({ install }) => { import('./plugin').then(({ install }) => {
install(plugin); install(plugin);