Skip to content

Commit

Permalink
Enhance: 連合向けのノート配信を軽量化 (misskey-dev#13192)
Browse files Browse the repository at this point in the history
* AP HTML表現をシンプルに

* a

* CHANGELOG

* リンク
  • Loading branch information
mei23 authored and AyumuNekozuki committed Feb 16, 2024
1 parent 1d55242 commit 694ded0
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
- Fix: properly handle cc followers
- Fix: ジョブに関する設定の名前を修正 relashionshipJobPerSec -> relationshipJobPerSec
- Fix: コントロールパネル->モデレーション->「誰でも新規登録できるようにする」の初期値をONからOFFに変更 #13122
- Enhance: 連合向けのノート配信を軽量化 #13192

### Service Worker
- Enhance: オフライン表示のデザインを改善・多言語対応
Expand Down
4 changes: 4 additions & 0 deletions packages/backend/src/core/MfmService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,10 @@ export class MfmService {
},

text: (node) => {
if (!node.props.text.match(/[\r\n]/)) {
return doc.createTextNode(node.props.text);
}

const el = doc.createElement('span');
const nodes = node.props.text.split(/\r\n|\r|\n/).map(x => doc.createTextNode(x));

Expand Down
19 changes: 16 additions & 3 deletions packages/backend/src/core/activitypub/ApMfmService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,21 @@ export class ApMfmService {
}

@bindThis
public getNoteHtml(note: MiNote): string | null {
if (!note.text) return '';
return this.mfmService.toHtml(mfm.parse(note.text), JSON.parse(note.mentionedRemoteUsers));
public getNoteHtml(note: MiNote, apAppend?: string) {
let noMisskeyContent = false;
const srcMfm = (note.text ?? '') + (apAppend ?? '');

const parsed = mfm.parse(srcMfm);

if (!apAppend && parsed?.every(n => ['text', 'unicodeEmoji', 'emojiCode', 'mention', 'hashtag', 'url'].includes(n.type))) {
noMisskeyContent = true;
}

const content = this.mfmService.toHtml(parsed, JSON.parse(note.mentionedRemoteUsers));

return {
content,
noMisskeyContent,
};
}
}
23 changes: 10 additions & 13 deletions packages/backend/src/core/activitypub/ApRendererService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,17 +389,15 @@ export class ApRendererService {
poll = await this.pollsRepository.findOneBy({ noteId: note.id });
}

let apText = text;
let apAppend = '';

if (quote) {
apText += `\n\nRE: ${quote}`;
apAppend += `\n\nRE: ${quote}`;
}

const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw;

const content = this.apMfmService.getNoteHtml(Object.assign({}, note, {
text: apText,
}));
const { content, noMisskeyContent } = this.apMfmService.getNoteHtml(note, apAppend);

const emojis = await this.getEmojis(note.emojis);
const apemojis = emojis.filter(emoji => !emoji.localOnly).map(emoji => this.renderEmoji(emoji));
Expand All @@ -412,9 +410,6 @@ export class ApRendererService {

const asPoll = poll ? {
type: 'Question',
content: this.apMfmService.getNoteHtml(Object.assign({}, note, {
text: text,
})),
[poll.expiresAt && poll.expiresAt < new Date() ? 'closed' : 'endTime']: poll.expiresAt,
[poll.multiple ? 'anyOf' : 'oneOf']: poll.choices.map((text, i) => ({
type: 'Note',
Expand All @@ -432,11 +427,13 @@ export class ApRendererService {
attributedTo,
summary: summary ?? undefined,
content: content ?? undefined,
_misskey_content: text,
source: {
content: text,
mediaType: 'text/x.misskeymarkdown',
},
...(noMisskeyContent ? {} : {
_misskey_content: text,
source: {
content: text,
mediaType: 'text/x.misskeymarkdown',
},
}),
_misskey_quote: quote,
quoteUrl: quote,
published: this.idService.parse(note.id).date.toISOString(),
Expand Down
44 changes: 44 additions & 0 deletions packages/backend/test/unit/ApMfmService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as assert from 'assert';
import { Test } from '@nestjs/testing';

import { CoreModule } from '@/core/CoreModule.js';
import { ApMfmService } from '@/core/activitypub/ApMfmService.js';
import { GlobalModule } from '@/GlobalModule.js';
import { MiNote } from '@/models/Note.js';

describe('ApMfmService', () => {
let apMfmService: ApMfmService;

beforeAll(async () => {
const app = await Test.createTestingModule({
imports: [GlobalModule, CoreModule],
}).compile();
apMfmService = app.get<ApMfmService>(ApMfmService);
});

describe('getNoteHtml', () => {
test('Do not provide _misskey_content for simple text', () => {
const note: MiNote = {
text: 'テキスト #タグ @mention 🍊 :emoji: https://example.com',
mentionedRemoteUsers: '[]',
} as any;

const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);

assert.equal(noMisskeyContent, true, 'noMisskeyContent');
assert.equal(content, '<p>テキスト <a href="http://misskey.local/tags/タグ" rel="tag">#タグ</a> <a href="http://misskey.local/@mention" class="u-url mention">@mention</a> 🍊 ​:emoji:​ <a href="https://example.com">https://example.com</a></p>', 'content');
});

test('Provide _misskey_content for MFM', () => {
const note: MiNote = {
text: '$[tada foo]',
mentionedRemoteUsers: '[]',
} as any;

const { content, noMisskeyContent } = apMfmService.getNoteHtml(note);

assert.equal(noMisskeyContent, false, 'noMisskeyContent');
assert.equal(content, '<p><i>foo</i></p>', 'content');
});
});
});
6 changes: 6 additions & 0 deletions packages/backend/test/unit/MfmService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ describe('MfmService', () => {
const output = '<p><span>foo<br>bar<br>baz</span></p>';
assert.equal(mfmService.toHtml(mfm.parse(input)), output);
});

test('Do not generate unnecessary span', () => {
const input = 'foo $[tada bar]';
const output = '<p>foo <i>bar</i></p>';
assert.equal(mfmService.toHtml(mfm.parse(input)), output);
});
});

describe('fromHtml', () => {
Expand Down

0 comments on commit 694ded0

Please sign in to comment.