Revert "refactor: 🔥 remove legacy reactions"

This reverts commit c119abc36c.
This commit is contained in:
ThatOneCalculator 2023-09-20 22:42:37 -07:00
parent 05b7fd0fc5
commit b13e0b0a54
No known key found for this signature in database
GPG Key ID: 8703CACD01000000
5 changed files with 183 additions and 10 deletions

View File

@ -0,0 +1,28 @@
export default function (reaction: string): string {
switch (reaction) {
case "like":
return "👍";
case "love":
return "❤️";
case "laugh":
return "😆";
case "hmm":
return "🤔";
case "surprise":
return "😮";
case "congrats":
return "🎉";
case "angry":
return "💢";
case "confused":
return "😥";
case "rip":
return "😇";
case "pudding":
return "🍮";
case "star":
return "⭐";
default:
return reaction;
}
}

View File

@ -4,11 +4,60 @@ import { Emojis } from "@/models/index.js";
import { toPunyNullable } from "./convert-host.js"; import { toPunyNullable } from "./convert-host.js";
import { IsNull } from "typeorm"; import { IsNull } from "typeorm";
const legacies = new Map([
["like", "👍"],
["love", "❤️"],
["laugh", "😆"],
["hmm", "🤔"],
["surprise", "😮"],
["congrats", "🎉"],
["angry", "💢"],
["confused", "😥"],
["rip", "😇"],
["pudding", "🍮"],
["star", "⭐"],
]);
export async function getFallbackReaction() { export async function getFallbackReaction() {
const meta = await fetchMeta(); const meta = await fetchMeta();
return meta.defaultReaction; return meta.defaultReaction;
} }
export function convertLegacyReactions(reactions: Record<string, number>) {
const _reactions = new Map();
const decodedReactions = new Map();
for (const reaction in reactions) {
if (reactions[reaction] <= 0) continue;
let decodedReaction;
if (decodedReactions.has(reaction)) {
decodedReaction = decodedReactions.get(reaction);
} else {
decodedReaction = decodeReaction(reaction);
decodedReactions.set(reaction, decodedReaction);
}
let emoji = legacies.get(decodedReaction.reaction);
if (emoji) {
_reactions.set(emoji, (_reactions.get(emoji) || 0) + reactions[reaction]);
} else {
_reactions.set(
reaction,
(_reactions.get(reaction) || 0) + reactions[reaction],
);
}
}
const _reactions2 = new Map();
for (const [reaction, count] of _reactions) {
const decodedReaction = decodedReactions.get(reaction);
_reactions2.set(decodedReaction.reaction, count);
}
return Object.fromEntries(_reactions2);
}
export async function toDbReaction( export async function toDbReaction(
reaction?: string | null, reaction?: string | null,
reacterHost?: string | null, reacterHost?: string | null,
@ -17,7 +66,9 @@ export async function toDbReaction(
reacterHost = toPunyNullable(reacterHost); reacterHost = toPunyNullable(reacterHost);
if (reaction === "♥️") return "❤️"; // Convert string-type reactions to unicode
const emoji = legacies.get(reaction) || (reaction === "♥️" ? "❤️" : null);
if (emoji) return emoji;
// Allow unicode reactions // Allow unicode reactions
const match = emojiRegex.exec(reaction); const match = emojiRegex.exec(reaction);
@ -77,3 +128,9 @@ export function decodeReaction(str: string): DecodedReaction {
host: undefined, host: undefined,
}; };
} }
export function convertLegacyReaction(reaction: string): string {
const decoded = decodeReaction(reaction).reaction;
if (legacies.has(decoded)) return legacies.get(decoded)!;
return decoded;
}

View File

@ -2,8 +2,8 @@ import { db } from "@/db/postgre.js";
import { NoteReaction } from "@/models/entities/note-reaction.js"; import { NoteReaction } from "@/models/entities/note-reaction.js";
import { Notes, Users } from "../index.js"; import { Notes, Users } from "../index.js";
import type { Packed } from "@/misc/schema.js"; import type { Packed } from "@/misc/schema.js";
import { convertLegacyReaction } from "@/misc/reaction-lib.js";
import type { User } from "@/models/entities/user.js"; import type { User } from "@/models/entities/user.js";
import { decodeReaction } from "@/misc/reaction-lib.js";
export const NoteReactionRepository = db.getRepository(NoteReaction).extend({ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
async pack( async pack(
@ -27,9 +27,10 @@ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
id: reaction.id, id: reaction.id,
createdAt: reaction.createdAt.toISOString(), createdAt: reaction.createdAt.toISOString(),
user: await Users.pack(reaction.user ?? reaction.userId, me), user: await Users.pack(reaction.user ?? reaction.userId, me),
type: decodeReaction(reaction.reaction).reaction, type: convertLegacyReaction(reaction.reaction),
...(opts.withNote ...(opts.withNote
? { ? {
// may throw error
note: await Notes.pack(reaction.note ?? reaction.noteId, me), note: await Notes.pack(reaction.note ?? reaction.noteId, me),
} }
: {}), : {}),
@ -40,7 +41,7 @@ export const NoteReactionRepository = db.getRepository(NoteReaction).extend({
src: NoteReaction[], src: NoteReaction[],
me?: { id: User["id"] } | null | undefined, me?: { id: User["id"] } | null | undefined,
options?: { options?: {
withNote: boolean; withNote: booleam;
}, },
): Promise<Packed<"NoteReaction">[]> { ): Promise<Packed<"NoteReaction">[]> {
const reactions = await Promise.allSettled( const reactions = await Promise.allSettled(

View File

@ -14,7 +14,11 @@ import {
import type { Packed } from "@/misc/schema.js"; import type { Packed } from "@/misc/schema.js";
import { nyaize } from "@/misc/nyaize.js"; import { nyaize } from "@/misc/nyaize.js";
import { awaitAll } from "@/prelude/await-all.js"; import { awaitAll } from "@/prelude/await-all.js";
import { decodeReaction } from "@/misc/reaction-lib.js"; import {
convertLegacyReaction,
convertLegacyReactions,
decodeReaction,
} from "@/misc/reaction-lib.js";
import type { NoteReaction } from "@/models/entities/note-reaction.js"; import type { NoteReaction } from "@/models/entities/note-reaction.js";
import { import {
aggregateNoteEmojis, aggregateNoteEmojis,
@ -73,7 +77,7 @@ async function populateMyReaction(
if (_hint_?.myReactions) { if (_hint_?.myReactions) {
const reaction = _hint_.myReactions.get(note.id); const reaction = _hint_.myReactions.get(note.id);
if (reaction) { if (reaction) {
return decodeReaction(reaction.reaction).reaction; return convertLegacyReaction(reaction.reaction);
} else if (reaction === null) { } else if (reaction === null) {
return undefined; return undefined;
} }
@ -86,7 +90,7 @@ async function populateMyReaction(
}); });
if (reaction) { if (reaction) {
return decodeReaction(reaction.reaction).reaction; return convertLegacyReaction(reaction.reaction);
} }
return undefined; return undefined;
@ -178,7 +182,7 @@ export const NoteRepository = db.getRepository(Note).extend({
let text = note.text; let text = note.text;
if (note.name && (note.url ?? note.uri)) { if (note.name && (note.url ?? note.uri)) {
text = `${note.name}\n${(note.text || "").trim()}\n\n${ text = `${note.name}\n${(note.text || "").trim()}\n\n${
note.url ?? note.uri note.url ?? note.uri
}`; }`;
} }
@ -217,7 +221,7 @@ export const NoteRepository = db.getRepository(Note).extend({
note.visibility === "specified" ? note.visibleUserIds : undefined, note.visibility === "specified" ? note.visibleUserIds : undefined,
renoteCount: note.renoteCount, renoteCount: note.renoteCount,
repliesCount: note.repliesCount, repliesCount: note.repliesCount,
reactions: note.reactions, reactions: convertLegacyReactions(note.reactions),
reactionEmojis: reactionEmoji, reactionEmojis: reactionEmoji,
emojis: noteEmoji, emojis: noteEmoji,
tags: note.tags.length > 0 ? note.tags : undefined, tags: note.tags.length > 0 ? note.tags : undefined,
@ -298,7 +302,7 @@ export const NoteRepository = db.getRepository(Note).extend({
if (meId) { if (meId) {
const renoteIds = notes const renoteIds = notes
.filter((n) => n.renoteId != null) .filter((n) => n.renoteId != null)
.map((n) => n.renoteId); .map((n) => n.renoteId!);
const targets = [...notes.map((n) => n.id), ...renoteIds]; const targets = [...notes.map((n) => n.id), ...renoteIds];
const myReactions = await NoteReactions.findBy({ const myReactions = await NoteReactions.findBy({
userId: meId, userId: meId,

View File

@ -0,0 +1,83 @@
/*
import * as assert from 'assert';
import { toDbReaction } from '../src/misc/reaction-lib.js';
describe('toDbReaction', async () => {
it('既存の文字列リアクションはそのまま', async () => {
assert.strictEqual(await toDbReaction('like'), 'like');
});
it('Unicodeプリンは寿司化不能とするため文字列化しない', async () => {
assert.strictEqual(await toDbReaction('🍮'), '🍮');
});
it('プリン以外の既存のリアクションは文字列化する like', async () => {
assert.strictEqual(await toDbReaction('👍'), 'like');
});
it('プリン以外の既存のリアクションは文字列化する love', async () => {
assert.strictEqual(await toDbReaction('❤️'), 'love');
});
it('プリン以外の既存のリアクションは文字列化する love 異体字セレクタなし', async () => {
assert.strictEqual(await toDbReaction('❤'), 'love');
});
it('プリン以外の既存のリアクションは文字列化する laugh', async () => {
assert.strictEqual(await toDbReaction('😆'), 'laugh');
});
it('プリン以外の既存のリアクションは文字列化する hmm', async () => {
assert.strictEqual(await toDbReaction('🤔'), 'hmm');
});
it('プリン以外の既存のリアクションは文字列化する surprise', async () => {
assert.strictEqual(await toDbReaction('😮'), 'surprise');
});
it('プリン以外の既存のリアクションは文字列化する congrats', async () => {
assert.strictEqual(await toDbReaction('🎉'), 'congrats');
});
it('プリン以外の既存のリアクションは文字列化する angry', async () => {
assert.strictEqual(await toDbReaction('💢'), 'angry');
});
it('プリン以外の既存のリアクションは文字列化する confused', async () => {
assert.strictEqual(await toDbReaction('😥'), 'confused');
});
it('プリン以外の既存のリアクションは文字列化する rip', async () => {
assert.strictEqual(await toDbReaction('😇'), 'rip');
});
it('それ以外はUnicodeのまま', async () => {
assert.strictEqual(await toDbReaction('🍅'), '🍅');
});
it('異体字セレクタ除去', async () => {
assert.strictEqual(await toDbReaction('㊗️'), '㊗');
});
it('異体字セレクタ除去 必要なし', async () => {
assert.strictEqual(await toDbReaction('㊗'), '㊗');
});
it('fallback - undefined', async () => {
assert.strictEqual(await toDbReaction(undefined), 'like');
});
it('fallback - null', async () => {
assert.strictEqual(await toDbReaction(null), 'like');
});
it('fallback - empty', async () => {
assert.strictEqual(await toDbReaction(''), 'like');
});
it('fallback - unknown', async () => {
assert.strictEqual(await toDbReaction('unknown'), 'like');
});
});
*/