import { publishNoteStream } from '../../stream'; import { renderLike } from '../../../remote/activitypub/renderer/like'; import renderUndo from '../../../remote/activitypub/renderer/undo'; import { renderActivity } from '../../../remote/activitypub/renderer'; import DeliverManager from '../../../remote/activitypub/deliver-manager'; import { IdentifiableError } from '../../../misc/identifiable-error'; import { User, IRemoteUser } from '../../../models/entities/user'; import { Note } from '../../../models/entities/note'; import { NoteReactions, Users, Notes } from '../../../models'; export default async (user: User, note: Note) => { // if already unreacted const exist = await NoteReactions.findOne({ noteId: note.id, userId: user.id, }); if (exist == null) { throw new IdentifiableError('60527ec9-b4cb-4a88-a6bd-32d3ad26817d', 'not reacted'); } // Delete reaction await NoteReactions.delete(exist.id); // Decrement reactions count const sql = `jsonb_set("reactions", '{${exist.reaction}}', (COALESCE("reactions"->>'${exist.reaction}', '0')::int - 1)::text::jsonb)`; await Notes.createQueryBuilder().update() .set({ reactions: () => sql, }) .where('id = :id', { id: note.id }) .execute(); Notes.decrement({ id: note.id }, 'score', 1); publishNoteStream(note.id, 'unreacted', { reaction: exist.reaction, userId: user.id }); //#region 配信 if (Users.isLocalUser(user) && !note.localOnly) { const content = renderActivity(renderUndo(renderLike(exist, note), user)); const dm = new DeliverManager(user, content); if (note.userHost !== null) { const reactee = await Users.findOne(note.userId) dm.addDirectRecipe(reactee as IRemoteUser); } dm.addFollowersRecipe(); dm.execute(); } //#endregion };