diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 5e24e49f8..1006e3f5a 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1267,7 +1267,7 @@ export default class Misskey implements MegalodonInterface { return status; } - public async addMentionsToStatus(status: Entity.Status, cache: AccountCache) : Promise { + public async addMentionsToStatus(status: Entity.Status, cache: AccountCache) : Promise { if (status.mentions.length > 0) return status; @@ -1277,29 +1277,39 @@ export default class Misskey implements MegalodonInterface { if (status.quote != null) status.quote = await this.addMentionsToStatus(status.quote, cache); - status.mentions = (await this.getMentions(status.plain_content!, cache)).filter(p => p != null); - for (const m of status.mentions.filter((value, index, array) => array.indexOf(value) === index)) { - if (m.acct == m.username) - status.content = status.content.replace(new RegExp(`(?<=^|\\s|>)@${m.acct}@${this.baseUrlToHost(this.baseUrl)}(?=[^a-zA-Z0-9]|$)`, 'g'), `@${m.acct}`); - status.content = status.content.replace(new RegExp(`(?<=^|\\s|>)@${m.acct}(?=[^a-zA-Z0-9]|$)`, 'g'), `@${m.acct}`); - } - return status; - } + const idx = status.account.acct.indexOf('@'); + const origin = idx < 0 ? null : status.account.acct.substring(idx + 1); - public async getMentions(text: string, cache: AccountCache): Promise { + status.mentions = (await this.getMentions(status.plain_content!, origin, cache)).filter(p => p != null); + for (const m of status.mentions.filter((value, index, array) => array.indexOf(value) === index)) { + const regexFull = new RegExp(`(?<=^|\\s|>)@${m.acct}(?=[^a-zA-Z0-9]|$)`, 'gi'); + const regexLocalUser = new RegExp(`(?<=^|\\s|>)@${m.acct}@${this.baseUrlToHost(this.baseUrl)}(?=[^a-zA-Z0-9]|$)`, 'gi'); + const regexRemoteUser = new RegExp(`(?<=^|\\s|>)@${m.username}(?=[^a-zA-Z0-9@]|$)`, 'gi'); + + if (m.acct == m.username) + status.content = status.content.replace(regexLocalUser, `@${m.acct}`); + else if (!status.content.match(regexFull)) + status.content = status.content.replace(regexRemoteUser, `@${m.acct}`); + + status.content = status.content.replace(regexFull, `@${m.acct}`); + } + return status; + } + + public async getMentions(text: string, origin: string | null, cache: AccountCache): Promise { const mentions :Entity.Mention[] = []; if (text == undefined) return mentions; - const mentionMatch = text.matchAll(/(?<=^|\s)@(?[a-zA-Z0-9_]+)(?:@(?[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)|)(?=[^a-zA-Z0-9]|$)/g,); + const mentionMatch = text.matchAll(/(?<=^|\s)@(?[a-zA-Z0-9_]+)(?:@(?[a-zA-Z0-9-.]+\.[a-zA-Z0-9-]+)|)(?=[^a-zA-Z0-9]|$)/g,); - for (const m of mentionMatch) { + for (const m of mentionMatch) { try { if (m.groups == null) continue; - const account = await this.getAccountByNameCached(m.groups.user, m.groups.host, cache); + const account = await this.getAccountByNameCached(m.groups.user, m.groups.host ?? origin, cache); if (account == null) continue; @@ -1312,10 +1322,10 @@ export default class Misskey implements MegalodonInterface { }); } catch {} - } + } - return mentions; - } + return mentions; + } public async getAccountByNameCached(user: string, host: string | null, cache: AccountCache): Promise { const acctToFind = host == null ? user : `${user}@${host}`;