mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 07:24:13 +00:00 
			
		
		
		
	リモートのカスタム絵文字リアクションを表示できるように (#6239)
* リモートのカスタム絵文字リアクションを表示できるように * AP * DBマイグレーション * ローカルのリアクションの. * fix * fix * fix * space
This commit is contained in:
		
							parent
							
								
									cda1803e59
								
							
						
					
					
						commit
						9b07c5af05
					
				
					 12 changed files with 185 additions and 41 deletions
				
			
		
							
								
								
									
										12
									
								
								migration/1586641139527-remote-reaction.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								migration/1586641139527-remote-reaction.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					import {MigrationInterface, QueryRunner} from "typeorm";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class remoteReaction1586641139527 implements MigrationInterface {
 | 
				
			||||||
 | 
					    name = 'remoteReaction1586641139527'
 | 
				
			||||||
 | 
					    public async up(queryRunner: QueryRunner): Promise<any> {
 | 
				
			||||||
 | 
					      await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(260)`, undefined);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async down(queryRunner: QueryRunner): Promise<any> {
 | 
				
			||||||
 | 
					      await queryRunner.query(`ALTER TABLE "note_reaction" ALTER COLUMN "reaction" TYPE character varying(130)`, undefined);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -301,6 +301,14 @@ export default Vue.extend({
 | 
				
			||||||
				case 'reacted': {
 | 
									case 'reacted': {
 | 
				
			||||||
					const reaction = body.reaction;
 | 
										const reaction = body.reaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (body.emoji) {
 | 
				
			||||||
 | 
											const emojis = this.appearNote.emojis || [];
 | 
				
			||||||
 | 
											if (!emojis.includes(body.emoji)) {
 | 
				
			||||||
 | 
												emojis.push(body.emoji);
 | 
				
			||||||
 | 
												Vue.set(this.appearNote, 'emojis', emojis);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (this.appearNote.reactions == null) {
 | 
										if (this.appearNote.reactions == null) {
 | 
				
			||||||
						Vue.set(this.appearNote, 'reactions', {});
 | 
											Vue.set(this.appearNote, 'reactions', {});
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@
 | 
				
			||||||
			<fa :icon="faReply" v-else-if="notification.type === 'reply'"/>
 | 
								<fa :icon="faReply" v-else-if="notification.type === 'reply'"/>
 | 
				
			||||||
			<fa :icon="faAt" v-else-if="notification.type === 'mention'"/>
 | 
								<fa :icon="faAt" v-else-if="notification.type === 'mention'"/>
 | 
				
			||||||
			<fa :icon="faQuoteLeft" v-else-if="notification.type === 'quote'"/>
 | 
								<fa :icon="faQuoteLeft" v-else-if="notification.type === 'quote'"/>
 | 
				
			||||||
			<x-reaction-icon v-else-if="notification.type === 'reaction'" :reaction="notification.reaction" :no-style="true"/>
 | 
								<x-reaction-icon v-else-if="notification.type === 'reaction'" :reaction="notification.reaction" :customEmojis="notification.note.emojis" :no-style="true"/>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<div class="tail">
 | 
						<div class="tail">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<mk-emoji :emoji="reaction.startsWith(':') ? null : reaction" :name="reaction.startsWith(':') ? reaction.substr(1, reaction.length - 2) : null" :is-reaction="true" :normal="true" :no-style="noStyle"/>
 | 
					<mk-emoji :emoji="reaction.startsWith(':') ? null : reaction" :name="reaction.startsWith(':') ? reaction.substr(1, reaction.length - 2) : null" :customEmojis="customEmojis" :is-reaction="true" :normal="true" :no-style="noStyle"/>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,10 @@ export default Vue.extend({
 | 
				
			||||||
			type: String,
 | 
								type: String,
 | 
				
			||||||
			required: true
 | 
								required: true
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							customEmojis: {
 | 
				
			||||||
 | 
								required: false,
 | 
				
			||||||
 | 
								default: () => []
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		noStyle: {
 | 
							noStyle: {
 | 
				
			||||||
			type: Boolean,
 | 
								type: Boolean,
 | 
				
			||||||
			required: false,
 | 
								required: false,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,7 @@
 | 
				
			||||||
	ref="reaction"
 | 
						ref="reaction"
 | 
				
			||||||
	v-particle
 | 
						v-particle
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
	<x-reaction-icon :reaction="reaction" ref="icon"/>
 | 
						<x-reaction-icon :reaction="reaction" :customEmojis="note.emojis" ref="icon"/>
 | 
				
			||||||
	<span>{{ count }}</span>
 | 
						<span>{{ count }}</span>
 | 
				
			||||||
</button>
 | 
					</button>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
import { emojiRegex } from './emoji-regex';
 | 
					import { emojiRegex } from './emoji-regex';
 | 
				
			||||||
import { fetchMeta } from './fetch-meta';
 | 
					import { fetchMeta } from './fetch-meta';
 | 
				
			||||||
import { Emojis } from '../models';
 | 
					import { Emojis } from '../models';
 | 
				
			||||||
 | 
					import { toPunyNullable } from './convert-host';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const legacies: Record<string, string> = {
 | 
					const legacies: Record<string, string> = {
 | 
				
			||||||
	'like':     '👍',
 | 
						'like':     '👍',
 | 
				
			||||||
| 
						 | 
					@ -40,12 +41,20 @@ export function convertLegacyReactions(reactions: Record<string, number>) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return _reactions;
 | 
						const _reactions2 = {} as Record<string, number>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (const reaction of Object.keys(_reactions)) {
 | 
				
			||||||
 | 
							_reactions2[decodeReaction(reaction).reaction] = _reactions[reaction];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return _reactions2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function toDbReaction(reaction?: string | null): Promise<string> {
 | 
					export async function toDbReaction(reaction?: string | null, reacterHost?: string | null): Promise<string> {
 | 
				
			||||||
	if (reaction == null) return await getFallbackReaction();
 | 
						if (reaction == null) return await getFallbackReaction();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reacterHost = toPunyNullable(reacterHost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 文字列タイプのリアクションを絵文字に変換
 | 
						// 文字列タイプのリアクションを絵文字に変換
 | 
				
			||||||
	if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
 | 
						if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,18 +70,58 @@ export async function toDbReaction(reaction?: string | null): Promise<string> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const custom = reaction.match(/^:([\w+-]+):$/);
 | 
						const custom = reaction.match(/^:([\w+-]+):$/);
 | 
				
			||||||
	if (custom) {
 | 
						if (custom) {
 | 
				
			||||||
 | 
							const name = custom[1];
 | 
				
			||||||
		const emoji = await Emojis.findOne({
 | 
							const emoji = await Emojis.findOne({
 | 
				
			||||||
			host: null,
 | 
								host: reacterHost || null,
 | 
				
			||||||
			name: custom[1],
 | 
								name,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (emoji) return reaction;
 | 
							if (emoji) return reacterHost ? `:${name}@${reacterHost}:` : `:${name}:`
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return await getFallbackReaction();
 | 
						return await getFallbackReaction();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DecodedReaction = {
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * リアクション名 (Unicode Emoji or ':name@hostname' or ':name@.')
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						reaction: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * name (カスタム絵文字の場合name, Emojiクエリに使う)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * host (カスタム絵文字の場合host, Emojiクエリに使う)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						host?: string | null;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function decodeReaction(str: string): DecodedReaction {
 | 
				
			||||||
 | 
						const custom = str.match(/^:([\w+-]+)(?:@([\w.-]+))?:$/);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (custom) {
 | 
				
			||||||
 | 
							const name = custom[1];
 | 
				
			||||||
 | 
							const host = custom[2] || null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								reaction: `:${name}@${host || '.'}:`,	// ローカル分は@以降を省略するのではなく.にする
 | 
				
			||||||
 | 
								name,
 | 
				
			||||||
 | 
								host
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							reaction: str,
 | 
				
			||||||
 | 
							name: undefined,
 | 
				
			||||||
 | 
							host: undefined
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function convertLegacyReaction(reaction: string): string {
 | 
					export function convertLegacyReaction(reaction: string): string {
 | 
				
			||||||
 | 
						reaction = decodeReaction(reaction).reaction;
 | 
				
			||||||
	if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
 | 
						if (Object.keys(legacies).includes(reaction)) return legacies[reaction];
 | 
				
			||||||
	return reaction;
 | 
						return reaction;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ export class NoteReaction {
 | 
				
			||||||
	public note: Note | null;
 | 
						public note: Note | null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Column('varchar', {
 | 
						@Column('varchar', {
 | 
				
			||||||
		length: 130
 | 
							length: 260
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	public reaction: string;
 | 
						public reaction: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,11 @@ import { Emojis, Users, PollVotes, DriveFiles, NoteReactions, Followings, Polls
 | 
				
			||||||
import { ensure } from '../../prelude/ensure';
 | 
					import { ensure } from '../../prelude/ensure';
 | 
				
			||||||
import { SchemaType } from '../../misc/schema';
 | 
					import { SchemaType } from '../../misc/schema';
 | 
				
			||||||
import { awaitAll } from '../../prelude/await-all';
 | 
					import { awaitAll } from '../../prelude/await-all';
 | 
				
			||||||
import { convertLegacyReaction, convertLegacyReactions } from '../../misc/reaction-lib';
 | 
					import { convertLegacyReaction, convertLegacyReactions, decodeReaction } from '../../misc/reaction-lib';
 | 
				
			||||||
import { toString } from '../../mfm/toString';
 | 
					import { toString } from '../../mfm/toString';
 | 
				
			||||||
import { parse } from '../../mfm/parse';
 | 
					import { parse } from '../../mfm/parse';
 | 
				
			||||||
 | 
					import { Emoji } from '../entities/emoji';
 | 
				
			||||||
 | 
					import { concat } from '../../prelude/array';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type PackedNote = SchemaType<typeof packedNoteSchema>;
 | 
					export type PackedNote = SchemaType<typeof packedNoteSchema>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,31 +131,61 @@ export class NoteRepository extends Repository<Note> {
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * 添付用emojisを解決する
 | 
				
			||||||
 | 
							 * @param emojiNames Note等に添付されたカスタム絵文字名 (:は含めない)
 | 
				
			||||||
 | 
							 * @param noteUserHost Noteのホスト
 | 
				
			||||||
 | 
							 * @param reactionNames Note等にリアクションされたカスタム絵文字名 (:は含めない)
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
		async function populateEmojis(emojiNames: string[], noteUserHost: string | null, reactionNames: string[]) {
 | 
							async function populateEmojis(emojiNames: string[], noteUserHost: string | null, reactionNames: string[]) {
 | 
				
			||||||
			const where = [] as {}[];
 | 
								let all = [] as {
 | 
				
			||||||
 | 
									name: string,
 | 
				
			||||||
 | 
									url: string
 | 
				
			||||||
 | 
								}[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// カスタム絵文字
 | 
				
			||||||
			if (emojiNames?.length > 0) {
 | 
								if (emojiNames?.length > 0) {
 | 
				
			||||||
				where.push({
 | 
									const tmp = await Emojis.find({
 | 
				
			||||||
					name: In(emojiNames),
 | 
										where: {
 | 
				
			||||||
					host: noteUserHost
 | 
											name: In(emojiNames),
 | 
				
			||||||
				});
 | 
											host: noteUserHost
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
										select: ['name', 'host', 'url']
 | 
				
			||||||
 | 
									}).then(emojis => emojis.map((emoji: Emoji) => {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											name: emoji.name,
 | 
				
			||||||
 | 
											url: emoji.url,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									all = concat([all, tmp]);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			reactionNames = reactionNames?.filter(x => x.match(/^:[^:]+:$/)).map(x => x.replace(/:/g, ''));
 | 
								const customReactions = reactionNames?.map(x => decodeReaction(x)).filter(x => x.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (reactionNames?.length > 0) {
 | 
								if (customReactions?.length > 0) {
 | 
				
			||||||
				where.push({
 | 
									const where = [] as {}[];
 | 
				
			||||||
					name: In(reactionNames),
 | 
					
 | 
				
			||||||
					host: null
 | 
									for (const customReaction of customReactions) {
 | 
				
			||||||
				});
 | 
										where.push({
 | 
				
			||||||
 | 
											name: customReaction.name,
 | 
				
			||||||
 | 
											host: customReaction.host
 | 
				
			||||||
 | 
										});
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									const tmp = await Emojis.find({
 | 
				
			||||||
 | 
										where,
 | 
				
			||||||
 | 
										select: ['name', 'host', 'url']
 | 
				
			||||||
 | 
									}).then(emojis => emojis.map((emoji: Emoji) => {
 | 
				
			||||||
 | 
										return {
 | 
				
			||||||
 | 
											name: `${emoji.name}@${emoji.host || '.'}`,	// @host付きでローカルは.
 | 
				
			||||||
 | 
											url: emoji.url,
 | 
				
			||||||
 | 
										};
 | 
				
			||||||
 | 
									}));
 | 
				
			||||||
 | 
									all = concat([all, tmp]);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (where.length === 0) return [];
 | 
								return all;
 | 
				
			||||||
 | 
					 | 
				
			||||||
			return Emojis.find({
 | 
					 | 
				
			||||||
				where,
 | 
					 | 
				
			||||||
				select: ['name', 'host', 'url', 'aliases']
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		async function populateMyReaction() {
 | 
							async function populateMyReaction() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import { IRemoteUser } from '../../../models/entities/user';
 | 
					import { IRemoteUser } from '../../../models/entities/user';
 | 
				
			||||||
import { ILike, getApId } from '../type';
 | 
					import { ILike, getApId } from '../type';
 | 
				
			||||||
import create from '../../../services/note/reaction/create';
 | 
					import create from '../../../services/note/reaction/create';
 | 
				
			||||||
import { fetchNote } from '../models/note';
 | 
					import { fetchNote, extractEmojis } from '../models/note';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default async (actor: IRemoteUser, activity: ILike) => {
 | 
					export default async (actor: IRemoteUser, activity: ILike) => {
 | 
				
			||||||
	const targetUri = getApId(activity.object);
 | 
						const targetUri = getApId(activity.object);
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,8 @@ export default async (actor: IRemoteUser, activity: ILike) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (actor.id === note.userId) return `skip: cannot react to my note`;
 | 
						if (actor.id === note.userId) return `skip: cannot react to my note`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						await extractEmojis(activity.tag || [], actor.host).catch(() => null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	await create(actor, note, activity._misskey_reaction || activity.content || activity.name);
 | 
						await create(actor, note, activity._misskey_reaction || activity.content || activity.name);
 | 
				
			||||||
	return `ok`;
 | 
						return `ok`;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,30 @@
 | 
				
			||||||
import config from '../../../config';
 | 
					import config from '../../../config';
 | 
				
			||||||
import { NoteReaction } from '../../../models/entities/note-reaction';
 | 
					import { NoteReaction } from '../../../models/entities/note-reaction';
 | 
				
			||||||
import { Note } from '../../../models/entities/note';
 | 
					import { Note } from '../../../models/entities/note';
 | 
				
			||||||
 | 
					import { Emojis } from '../../../models';
 | 
				
			||||||
 | 
					import renderEmoji from './emoji';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const renderLike = (noteReaction: NoteReaction, note: Note) => ({
 | 
					export const renderLike = async (noteReaction: NoteReaction, note: Note) => {
 | 
				
			||||||
	type: 'Like',
 | 
						const reaction = noteReaction.reaction;
 | 
				
			||||||
	id: `${config.url}/likes/${noteReaction.id}`,
 | 
					
 | 
				
			||||||
	actor: `${config.url}/users/${noteReaction.userId}`,
 | 
						const object =  {
 | 
				
			||||||
	object: note.uri ? note.uri : `${config.url}/notes/${noteReaction.noteId}`,
 | 
							type: 'Like',
 | 
				
			||||||
	content: noteReaction.reaction,
 | 
							id: `${config.url}/likes/${noteReaction.id}`,
 | 
				
			||||||
	_misskey_reaction: noteReaction.reaction
 | 
							actor: `${config.url}/users/${noteReaction.userId}`,
 | 
				
			||||||
});
 | 
							object: note.uri ? note.uri : `${config.url}/notes/${noteReaction.noteId}`,
 | 
				
			||||||
 | 
							content: reaction,
 | 
				
			||||||
 | 
							_misskey_reaction: reaction
 | 
				
			||||||
 | 
						} as any;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (reaction.startsWith(':')) {
 | 
				
			||||||
 | 
							const name = reaction.replace(/:/g, '');
 | 
				
			||||||
 | 
							const emoji = await Emojis.findOne({
 | 
				
			||||||
 | 
								name,
 | 
				
			||||||
 | 
								host: null
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (emoji) object.tag = [ renderEmoji(emoji) ];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return object;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,10 +4,10 @@ import { renderLike } from '../../../remote/activitypub/renderer/like';
 | 
				
			||||||
import DeliverManager from '../../../remote/activitypub/deliver-manager';
 | 
					import DeliverManager from '../../../remote/activitypub/deliver-manager';
 | 
				
			||||||
import { renderActivity } from '../../../remote/activitypub/renderer';
 | 
					import { renderActivity } from '../../../remote/activitypub/renderer';
 | 
				
			||||||
import { IdentifiableError } from '../../../misc/identifiable-error';
 | 
					import { IdentifiableError } from '../../../misc/identifiable-error';
 | 
				
			||||||
import { toDbReaction } from '../../../misc/reaction-lib';
 | 
					import { toDbReaction, decodeReaction } from '../../../misc/reaction-lib';
 | 
				
			||||||
import { User, IRemoteUser } from '../../../models/entities/user';
 | 
					import { User, IRemoteUser } from '../../../models/entities/user';
 | 
				
			||||||
import { Note } from '../../../models/entities/note';
 | 
					import { Note } from '../../../models/entities/note';
 | 
				
			||||||
import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles } from '../../../models';
 | 
					import { NoteReactions, Users, NoteWatchings, Notes, UserProfiles, Emojis } from '../../../models';
 | 
				
			||||||
import { Not } from 'typeorm';
 | 
					import { Not } from 'typeorm';
 | 
				
			||||||
import { perUserReactionsChart } from '../../chart';
 | 
					import { perUserReactionsChart } from '../../chart';
 | 
				
			||||||
import { genId } from '../../../misc/gen-id';
 | 
					import { genId } from '../../../misc/gen-id';
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ export default async (user: User, note: Note, reaction?: string) => {
 | 
				
			||||||
		throw new IdentifiableError('2d8e7297-1873-4c00-8404-792c68d7bef0', 'cannot react to my note');
 | 
							throw new IdentifiableError('2d8e7297-1873-4c00-8404-792c68d7bef0', 'cannot react to my note');
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reaction = await toDbReaction(reaction);
 | 
						reaction = await toDbReaction(reaction, user.host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const exist = await NoteReactions.findOne({
 | 
						const exist = await NoteReactions.findOne({
 | 
				
			||||||
		noteId: note.id,
 | 
							noteId: note.id,
 | 
				
			||||||
| 
						 | 
					@ -59,8 +59,27 @@ export default async (user: User, note: Note, reaction?: string) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	perUserReactionsChart.update(user, note);
 | 
						perUserReactionsChart.update(user, note);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// カスタム絵文字リアクションだったら絵文字情報も送る
 | 
				
			||||||
 | 
						const decodedReaction = decodeReaction(reaction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						let emoji = await Emojis.findOne({
 | 
				
			||||||
 | 
							where: {
 | 
				
			||||||
 | 
								name: decodedReaction.name,
 | 
				
			||||||
 | 
								host: decodedReaction.host
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							select: ['name', 'host', 'url']
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (emoji) {
 | 
				
			||||||
 | 
							emoji = {
 | 
				
			||||||
 | 
								name: emoji.host ? `${emoji.name}@${emoji.host}` : `${emoji.name}`,
 | 
				
			||||||
 | 
								url: emoji.url
 | 
				
			||||||
 | 
							} as any;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	publishNoteStream(note.id, 'reacted', {
 | 
						publishNoteStream(note.id, 'reacted', {
 | 
				
			||||||
		reaction: reaction,
 | 
							reaction: reaction,
 | 
				
			||||||
 | 
							emoji: emoji,
 | 
				
			||||||
		userId: user.id
 | 
							userId: user.id
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,7 +115,7 @@ export default async (user: User, note: Note, reaction?: string) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//#region 配信
 | 
						//#region 配信
 | 
				
			||||||
	if (Users.isLocalUser(user) && !note.localOnly) {
 | 
						if (Users.isLocalUser(user) && !note.localOnly) {
 | 
				
			||||||
		const content = renderActivity(renderLike(inserted, note));
 | 
							const content = renderActivity(await renderLike(inserted, note));
 | 
				
			||||||
		const dm = new DeliverManager(user, content);
 | 
							const dm = new DeliverManager(user, content);
 | 
				
			||||||
		if (note.userHost !== null) {
 | 
							if (note.userHost !== null) {
 | 
				
			||||||
			const reactee = await Users.findOne(note.userId)
 | 
								const reactee = await Users.findOne(note.userId)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ export default async (user: User, note: Note) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//#region 配信
 | 
						//#region 配信
 | 
				
			||||||
	if (Users.isLocalUser(user) && !note.localOnly) {
 | 
						if (Users.isLocalUser(user) && !note.localOnly) {
 | 
				
			||||||
		const content = renderActivity(renderUndo(renderLike(exist, note), user));
 | 
							const content = renderActivity(renderUndo(await renderLike(exist, note), user));
 | 
				
			||||||
		const dm = new DeliverManager(user, content);
 | 
							const dm = new DeliverManager(user, content);
 | 
				
			||||||
		if (note.userHost !== null) {
 | 
							if (note.userHost !== null) {
 | 
				
			||||||
			const reactee = await Users.findOne(note.userId)
 | 
								const reactee = await Users.findOne(note.userId)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue