2023-01-13 05:40:33 +01:00
|
|
|
import { emojiRegex } from "./emoji-regex.js";
|
|
|
|
import { fetchMeta } from "./fetch-meta.js";
|
|
|
|
import { Emojis } from "@/models/index.js";
|
|
|
|
import { toPunyNullable } from "./convert-host.js";
|
|
|
|
import { IsNull } from "typeorm";
|
2019-03-17 16:03:57 +01:00
|
|
|
|
2023-02-17 09:01:22 +01:00
|
|
|
export async function getFallbackReaction() {
|
2019-03-17 17:03:35 +01:00
|
|
|
const meta = await fetchMeta();
|
2023-01-05 05:06:48 +01:00
|
|
|
return meta.defaultReaction;
|
2019-03-17 16:03:57 +01:00
|
|
|
}
|
|
|
|
|
2023-09-21 07:48:50 +02:00
|
|
|
export function convertReactions(reactions: Record<string, number>) {
|
|
|
|
const result = new Map();
|
2023-09-21 07:42:37 +02:00
|
|
|
|
|
|
|
for (const reaction in reactions) {
|
2023-09-21 08:29:48 +02:00
|
|
|
if (reactions[reaction] <= 0) continue;
|
2023-09-21 07:42:37 +02:00
|
|
|
|
2023-09-21 08:29:48 +02:00
|
|
|
const decoded = decodeReaction(reaction).reaction;
|
|
|
|
result.set(decoded, (result.get(decoded) || 0) + reactions[reaction]);
|
2023-09-21 07:42:37 +02:00
|
|
|
}
|
|
|
|
|
2023-09-21 07:48:50 +02:00
|
|
|
return Object.fromEntries(result);
|
2023-09-21 07:42:37 +02:00
|
|
|
}
|
|
|
|
|
2023-01-13 05:40:33 +01:00
|
|
|
export async function toDbReaction(
|
|
|
|
reaction?: string | null,
|
|
|
|
reacterHost?: string | null,
|
|
|
|
): Promise<string> {
|
2023-02-17 09:01:22 +01:00
|
|
|
if (!reaction) return await getFallbackReaction();
|
2019-03-17 16:03:57 +01:00
|
|
|
|
2020-04-13 17:42:59 +02:00
|
|
|
reacterHost = toPunyNullable(reacterHost);
|
|
|
|
|
2023-09-21 07:48:50 +02:00
|
|
|
if (reaction === "♥️") return "❤️";
|
2019-03-17 16:03:57 +01:00
|
|
|
|
2023-02-05 12:36:50 +01:00
|
|
|
// Allow unicode reactions
|
|
|
|
const match = emojiRegex.exec(reaction);
|
|
|
|
if (match) {
|
|
|
|
const unicode = match[0];
|
|
|
|
return unicode;
|
|
|
|
}
|
|
|
|
|
2020-04-15 17:47:17 +02:00
|
|
|
const custom = reaction.match(/^:([\w+-]+)(?:@\.)?:$/);
|
2019-03-17 16:03:57 +01:00
|
|
|
if (custom) {
|
2020-04-13 17:42:59 +02:00
|
|
|
const name = custom[1];
|
2022-03-26 07:34:00 +01:00
|
|
|
const emoji = await Emojis.findOneBy({
|
2023-02-17 09:01:22 +01:00
|
|
|
host: reacterHost || IsNull(),
|
2020-04-13 17:42:59 +02:00
|
|
|
name,
|
2019-03-17 16:03:57 +01:00
|
|
|
});
|
|
|
|
|
2020-05-10 10:25:16 +02:00
|
|
|
if (emoji) return reacterHost ? `:${name}@${reacterHost}:` : `:${name}:`;
|
2019-03-17 16:03:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return await getFallbackReaction();
|
|
|
|
}
|
2020-01-29 20:37:25 +01:00
|
|
|
|
2020-04-13 17:42:59 +02:00
|
|
|
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 {
|
2023-01-13 05:40:33 +01:00
|
|
|
reaction: `:${name}@${host || "."}:`, // ローカル分は@以降を省略するのではなく.にする
|
2020-04-13 17:42:59 +02:00
|
|
|
name,
|
2021-12-09 15:58:30 +01:00
|
|
|
host,
|
2020-04-13 17:42:59 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
reaction: str,
|
|
|
|
name: undefined,
|
2021-12-09 15:58:30 +01:00
|
|
|
host: undefined,
|
2020-04-13 17:42:59 +02:00
|
|
|
};
|
|
|
|
}
|