From 5f30bff461fb95bd7a39cb629bec7f76d64dad77 Mon Sep 17 00:00:00 2001 From: Nya Candy Date: Tue, 30 Jul 2024 20:57:56 +0800 Subject: [PATCH] fix(wip): add emojis & tag support for update --- .../backend/src/core/NoteUpdateService.ts | 45 ++++++++++++++++++- .../core/activitypub/models/ApNoteService.ts | 13 +++++- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/core/NoteUpdateService.ts b/packages/backend/src/core/NoteUpdateService.ts index 40d5f1746..e4b2529e4 100644 --- a/packages/backend/src/core/NoteUpdateService.ts +++ b/packages/backend/src/core/NoteUpdateService.ts @@ -28,6 +28,14 @@ import { IdService } from '@/core/IdService.js'; import { trackPromise } from '@/misc/promise-tracker.js'; import { extractMentions } from '@/misc/extract-mentions.js'; import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js'; +import { extractHashtags } from "@/misc/extract-hashtags.js"; +import { extractCustomEmojisFromMfm } from "@/misc/extract-custom-emojis-from-mfm.js"; +import { UtilityService } from "@/core/UtilityService.js"; + +type Option = Pick & { + apHashtags?: string[] | null; + apEmojis?: string[] | null; +} @Injectable() export class NoteUpdateService { @@ -59,6 +67,7 @@ export class NoteUpdateService { private perUserNotesChart: PerUserNotesChart, private instanceChart: InstanceChart, private idService: IdService, + private utilityService: UtilityService, ) {} /** @@ -67,7 +76,7 @@ export class NoteUpdateService { * @param note Note to update * @param ps New note info */ - async update(user: { id: MiUser['id']; uri: MiUser['uri']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, ps: Pick, quiet = false, updater?: MiUser) { + async update(user: { id: MiUser['id']; uri: MiUser['uri']; host: MiUser['host']; isBot: MiUser['isBot']; }, note: MiNote, ps: Option, quiet = false, updater?: MiUser) { if (!ps.updatedAt) { throw new Error('update time is required'); } @@ -77,9 +86,41 @@ export class NoteUpdateService { return; } + // Parse tags & emojis + const data = ps; + + const meta = await this.metaService.fetch(); + + let tags = data.apHashtags; + let emojis = data.apEmojis; + + // Parse MFM if needed + if (!tags || !emojis) { + const tokens = (data.text ? mfm.parse(data.text)! : []); + const cwTokens = data.cw ? mfm.parse(data.cw)! : []; + // Not include poll data + + const combinedTokens = tokens.concat(cwTokens); + + tags = data.apHashtags ?? extractHashtags(combinedTokens); + + emojis = data.apEmojis ?? extractCustomEmojisFromMfm(combinedTokens); + } + + // if the host is media-silenced, custom emojis are not allowed + if (this.utilityService.isMediaSilencedHost(meta.mediaSilencedHosts, user.host)) emojis = []; + + tags = tags.filter(tag => Array.from(tag).length <= 128).splice(0, 32); + const newNote = { ...note, - ...ps, // Overwrite updated fields + + // Overwrite updated fields + text: ps.text, + cw: ps.cw, + updatedAt: ps.updatedAt, + tags, + emojis, }; if (!quiet) { diff --git a/packages/backend/src/core/activitypub/models/ApNoteService.ts b/packages/backend/src/core/activitypub/models/ApNoteService.ts index 5edac2d5c..5b910419c 100644 --- a/packages/backend/src/core/activitypub/models/ApNoteService.ts +++ b/packages/backend/src/core/activitypub/models/ApNoteService.ts @@ -354,7 +354,7 @@ export class ApNoteService { throw new Error('invalid note.attributedTo: ' + note.attributedTo); } - const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as MiRemoteUser; + const apHashtags = extractApHashtags(note.tag); const cw = note.summary || null; @@ -368,9 +368,20 @@ export class ApNoteService { text = this.apMfmService.htmlToMfm(note.content, note.tag); } + const actor = await this.apPersonService.resolvePerson(getOneApId(note.attributedTo), resolver) as MiRemoteUser; + + const emojis = await this.extractEmojis(note.tag ?? [], actor.host).catch(e => { + this.logger.info(`extractEmojis: ${e}`); + return []; + }); + + const apEmojis = emojis.map(emoji => emoji.name); + await this.noteUpdateService.update(actor, originNote, { cw, text, + apHashtags, + apEmojis, updatedAt: new Date(note.updated), }, silent); }