From 84db15694d7223d6f46bae6340542b4c24e9bcb3 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Sun, 4 Nov 2018 03:32:20 +0900
Subject: [PATCH] Do not send needless emojis in note
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

投稿作成時に含まれている絵文字を保存しておくように

SEE: https://github.com/syuilo/misskey/pull/3085#issuecomment-435608434
---
 src/models/emoji.ts         | 11 -----------
 src/models/note.ts          | 20 ++++++++++++++++++--
 src/services/note/create.ts | 18 ++++++++++++++++--
 3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/src/models/emoji.ts b/src/models/emoji.ts
index fdedd28513..8e75868e62 100644
--- a/src/models/emoji.ts
+++ b/src/models/emoji.ts
@@ -16,14 +16,3 @@ export type IEmoji = {
 	aliases?: string[];
 	updatedAt?: Date;
 };
-
-export const packEmojis = async (
-	host: string,
-	// MeiTODO: filter
-) => {
-	return await Emoji.find({ host }, {
-		fields: {
-			_id: false
-		}
-	});
-};
diff --git a/src/models/note.ts b/src/models/note.ts
index 684e8c3b1e..6856d6d07d 100644
--- a/src/models/note.ts
+++ b/src/models/note.ts
@@ -12,7 +12,7 @@ import { packMany as packFileMany, IDriveFile } from './drive-file';
 import Favorite from './favorite';
 import Following from './following';
 import config from '../config';
-import { packEmojis } from './emoji';
+import Emoji from './emoji';
 
 const Note = db.get<INote>('notes');
 Note.createIndex('uri', { sparse: true, unique: true });
@@ -50,6 +50,7 @@ export type INote = {
 	text: string;
 	tags: string[];
 	tagsLower: string[];
+	emojis: string[];
 	cw: string;
 	userId: mongo.ObjectID;
 	appId: mongo.ObjectID;
@@ -231,7 +232,22 @@ export const pack = async (
 
 	// _note._userを消す前か、_note.userを解決した後でないとホストがわからない
 	if (_note._user) {
-		_note.emojis = packEmojis(_note._user.host);
+		const host = _note._user.host;
+		// 互換性のため。(古いMisskeyではNoteにemojisが無い)
+		if (_note.emojis == null) {
+			_note.emojis = Emoji.find({
+				host: host
+			}, {
+				fields: { _id: false }
+			});
+		} else {
+			_note.emojis = Emoji.find({
+				name: { $in: _note.emojis },
+				host: host
+			}, {
+				fields: { _id: false }
+			});
+		}
 	}
 
 	// Rename _id to id
diff --git a/src/services/note/create.ts b/src/services/note/create.ts
index 7e97740edd..ac8bcf034d 100644
--- a/src/services/note/create.ts
+++ b/src/services/note/create.ts
@@ -30,6 +30,7 @@ import { erase, unique } from '../../prelude/array';
 import insertNoteUnread from './unread';
 import registerInstance from '../register-instance';
 import Instance from '../../models/instance';
+import { TextElementEmoji } from '../../mfm/parse/elements/emoji';
 
 type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';
 
@@ -146,6 +147,8 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
 
 	const tags = extractHashtags(tokens);
 
+	const emojis = extractEmojis(tokens);
+
 	const mentionedUsers = await extractMentionedUsers(tokens);
 
 	if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) {
@@ -160,7 +163,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise<
 		});
 	}
 
-	const note = await insertNote(user, data, tags, mentionedUsers);
+	const note = await insertNote(user, data, tags, emojis, mentionedUsers);
 
 	res(note);
 
@@ -371,7 +374,7 @@ async function publish(user: IUser, note: INote, noteObj: any, reply: INote, ren
 	publishToUserLists(note, noteObj);
 }
 
-async function insertNote(user: IUser, data: Option, tags: string[], mentionedUsers: IUser[]) {
+async function insertNote(user: IUser, data: Option, tags: string[], emojis: string[], mentionedUsers: IUser[]) {
 	const insert: any = {
 		createdAt: data.createdAt,
 		fileIds: data.files ? data.files.map(file => file._id) : [],
@@ -382,6 +385,7 @@ async function insertNote(user: IUser, data: Option, tags: string[], mentionedUs
 		cw: data.cw == null ? null : data.cw,
 		tags,
 		tagsLower: tags.map(tag => tag.toLowerCase()),
+		emojis,
 		userId: user._id,
 		viaMobile: data.viaMobile,
 		geo: data.geo || null,
@@ -449,6 +453,16 @@ function extractHashtags(tokens: ReturnType<typeof parse>): string[] {
 	return unique(hashtags);
 }
 
+function extractEmojis(tokens: ReturnType<typeof parse>): string[] {
+	// Extract emojis
+	const emojis = tokens
+		.filter(t => t.type == 'emoji')
+		.map(t => (t as TextElementEmoji).emoji)
+		.filter(emoji => emoji.length <= 100);
+
+	return unique(emojis);
+}
+
 function index(note: INote) {
 	if (note.text == null || config.elasticsearch == null) return;