feat: Implement custom emojis

This commit is contained in:
Jesse Wierzbinski 2024-12-02 22:21:04 +01:00
parent bb5de77bb1
commit 348b1ba2b0
No known key found for this signature in database
12 changed files with 77 additions and 20 deletions

49
plugins/EmojiRenderer.ts Normal file
View file

@ -0,0 +1,49 @@
import type { Emoji } from "@versia/client/types";
import { SettingIds } from "~/settings";
const emojisRegex =
/\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?(\u200D(\p{RI}\p{RI}|\p{Emoji}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?))*/gu;
const incorrectEmojisRegex = /^[#*0-9©®]$/;
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive<HTMLElement, Emoji[]>("render-emojis", {
beforeMount(el, binding) {
const shouldRenderEmoji = useSetting(SettingIds.CustomEmojis);
const emojiFont = useSetting(SettingIds.EmojiTheme);
// Replace emoji shortcodes with images
if (shouldRenderEmoji.value.value) {
el.innerHTML = el.innerHTML.replace(
/:([a-zA-Z0-9_-]+):/g,
(match, emoji) => {
const emojiData = binding.value.find(
(e) => e.shortcode === emoji,
);
if (!emojiData) {
return match;
}
const image = document.createElement("img");
image.src = emojiData.url;
image.alt = `:${emoji}:`;
image.title = emojiData.shortcode;
image.className =
"h-[1lh] align-middle inline not-prose hover:scale-110 transition-transform duration-75 ease-in-out";
return image.outerHTML;
},
);
}
if (emojiFont.value.value !== "native") {
el.innerHTML = el.innerHTML.replace(emojisRegex, (match) => {
if (incorrectEmojisRegex.test(match)) {
return match;
}
return `<img src="/emojis/${emojiFont}/${match}.svg" alt="${match}" class="h-[1em] inline not-prose hover:scale-110 transition-transform duration-75 ease-in-out">`;
});
}
},
});
});