Fixed 267U.pre2

This commit is contained in:
2026-07-26 18:25:37 +09:00
parent 50bfaeafdf
commit 317d00a284
1286 changed files with 80222 additions and 1 deletions
+184
View File
@@ -0,0 +1,184 @@
import { emojiRegex } from "./emoji-regex.js";
import { fetchMeta } from "./fetch-meta.js";
import { Emojis, UserEmojis, UserGroups, Users } from "../models/index.js";
import { toPunyNullable } from "./convert-host.js";
import { IsNull } from "typeorm";
import { resolveUser } from "../remote/resolve-user.js";
const legacies = new Map([
[
"like",
"👍"
],
[
"love",
"❤️"
],
[
"laugh",
"😆"
],
[
"hmm",
"🤔"
],
[
"surprise",
"😮"
],
[
"congrats",
"🎉"
],
[
"angry",
"💢"
],
[
"confused",
"😥"
],
[
"rip",
"😇"
],
[
"pudding",
"🍮"
],
[
"star",
"⭐"
]
]);
export async function getFallbackReaction() {
const meta = await fetchMeta();
return meta.defaultReaction;
}
export function convertLegacyReactions(reactions) {
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(reaction, reacterHost, recurse = true) {
if (!reaction) return await getFallbackReaction();
reacterHost = toPunyNullable(reacterHost);
// Convert string-type reactions to unicode
const emoji = legacies.get(reaction) || (reaction === "♥️" ? "❤️" : null);
if (emoji) return emoji;
// Allow unicode reactions
const match = emojiRegex.exec(reaction);
if (match) {
const unicode = match[0];
return unicode;
}
const custom = reaction.match(/^:([^:\s]+):$/);
if (custom) {
const decoded = decodeReaction(reaction);
if (decoded.name) {
const groupCustom = decoded.name.match(/^([a-z0-9_]{1,64})@@([a-zA-Z0-9_]{1,64})$/);
if (groupCustom) {
const group = await UserGroups.findOneBy({
username: groupCustom[2].toLowerCase()
});
const groupEmoji = group ? await UserEmojis.findOneBy({
name: groupCustom[1],
userGroupId: group.id,
glyph: false
}) : null;
if (groupEmoji) return `:${groupCustom[1]}@@${group.username}:`;
}
const emoji = await Emojis.findOneBy({
host: decoded.host ?? reacterHost ?? IsNull(),
name: decoded.name
});
if (emoji) return emoji.host ? `:${emoji.name}@${emoji.host}:` : `:${emoji.name}:`;
}
if (await isUserReaction(reaction)) return reaction;
}
return recurse && reacterHost == null && reaction !== null ? await toDbReaction(`:${reaction}:`, reacterHost, false) : await getFallbackReaction();
}
export function decodeReaction(str) {
const custom = str.match(/^:([^:\s]+):$/);
if (custom) {
const body = custom[1];
const parts = body.split("@");
const name = parts[0];
const host = parts.length === 2 ? parts[1] || null : null;
return {
reaction: host ? `:${name}@${host}:` : str,
name,
host
};
}
return {
reaction: str,
name: undefined,
host: undefined
};
}
async function isUserReaction(reaction) {
const body = reaction.slice(1, -1);
const icon = body.match(/^@([^@:\s]+)(?:@([^@:\s]+))?$/);
if (icon) {
return await findUser(icon[1], icon[2] ?? null) != null;
}
if (/^@@[a-zA-Z0-9_]{1,64}$/.test(body)) return false;
const groupCustom = body.match(/^([a-z0-9_]{1,64})@@([a-zA-Z0-9_]{1,64})$/);
if (groupCustom) {
const group = await UserGroups.findOneBy({
username: groupCustom[2].toLowerCase()
});
if (!group) return false;
return await UserEmojis.findOneBy({
name: groupCustom[1],
userGroupId: group.id,
glyph: false
}) != null;
}
const parts = body.split("@");
if (parts.length !== 2 && parts.length !== 3) return false;
const [name, username, host] = parts;
if (!name || !username) return false;
const user = await findUser(username, host ?? null);
if (!user) return false;
return await UserEmojis.findOneBy({
name,
userId: user.id
}) != null;
}
async function findUser(username, host) {
const normalizedHost = toPunyNullable(host);
const user = await Users.findOneBy({
usernameLower: username.toLowerCase(),
host: normalizedHost ?? IsNull()
});
if (user) return user;
if (normalizedHost == null) return null;
return resolveUser(username, normalizedHost).catch(()=>null);
}
export function convertLegacyReaction(reaction) {
const decoded = decodeReaction(reaction).reaction;
if (legacies.has(decoded)) return legacies.get(decoded);
return decoded;
}