diff --git a/app.vue b/app.vue index 20dd1ed6..01c46abe 100644 --- a/app.vue +++ b/app.vue @@ -2,6 +2,7 @@ setupI18n() setupFontSize() setupPageHeader() +setupEmojis() provideGlobalCommands() // We want to trigger rerendering the page when account changes diff --git a/composables/content-parse.ts b/composables/content-parse.ts index d96e2269..20441e0f 100644 --- a/composables/content-parse.ts +++ b/composables/content-parse.ts @@ -2,6 +2,8 @@ import type { Emoji } from 'masto' import type { Node } from 'ultrahtml' import { TEXT_NODE, parse, render, walkSync } from 'ultrahtml' +const EMOJI_REGEX = /(\p{Emoji_Presentation})/ug + const decoder = process.client ? document.createElement('textarea') : null as any as HTMLTextAreaElement export function decodeHtml(text: string) { decoder.innerHTML = text @@ -21,6 +23,7 @@ export function parseMastodonHTML(html: string, customEmojis: Record` return `:${name}:` }) + .replace(EMOJI_REGEX, '') if (markdown) { // handle code blocks diff --git a/composables/setups.ts b/composables/setups.ts index 77479775..d00ec038 100644 --- a/composables/setups.ts +++ b/composables/setups.ts @@ -1,6 +1,7 @@ import { pwaInfo } from 'virtual:pwa-info' import type { Link } from '@unhead/schema' import type { Directions } from 'vue-i18n-routing' +import { init as initEmojis } from 'emoji-mart' import { APP_NAME, STORAGE_KEY_LANG } from '~/constants' import type { LocaleObject } from '#i18n' @@ -74,3 +75,9 @@ export async function setupI18n() { }) }) } + +export function setupEmojis() { + initEmojis({ + data: () => import('@emoji-mart/data').then(r => r.default), + }) +} diff --git a/public/fonts/seguiemj.ttf b/public/fonts/seguiemj.ttf new file mode 100644 index 00000000..3a455801 Binary files /dev/null and b/public/fonts/seguiemj.ttf differ diff --git a/styles/global.css b/styles/global.css index e007448c..6963019f 100644 --- a/styles/global.css +++ b/styles/global.css @@ -4,31 +4,36 @@ html { @font-face { font-display: swap; - font-family: "DM Mono"; + font-family: 'DM Mono'; font-style: normal; font-weight: 400; - src: url(/fonts/DM-mono-v10.ttf) format("truetype"); + src: url(/fonts/DM-mono-v10.ttf) format('truetype'); } @font-face { font-display: swap; - font-family: "DM Sans"; + font-family: 'DM Sans'; font-style: normal; font-weight: 400; - src: url(/fonts/DM-sans-v11.ttf) format("truetype"); + src: url(/fonts/DM-sans-v11.ttf) format('truetype'); } @font-face { font-display: swap; - font-family: "DM Serif Display"; + font-family: 'DM Serif Display'; font-style: normal; font-weight: 400; - src: url(/fonts/DM-serif-display-v10.ttf) format("truetype"); + src: url(/fonts/DM-serif-display-v10.ttf) format('truetype'); } @font-face { font-display: swap; - font-family: "Homemade Apple"; + font-family: 'Homemade Apple'; font-style: normal; font-weight: 400; - src: url(/fonts/homemade-apple-v18.ttf) format("truetype"); + src: url(/fonts/homemade-apple-v18.ttf) format('truetype'); +} +@font-face { + font-display: swap; + font-family: 'EmojiMart'; + src: url('/fonts/seguiemj.ttf') format('truetype'); } * { @@ -99,7 +104,8 @@ body { } } } - b, strong { + b, + strong { --at-apply: font-bold; } p { @@ -113,7 +119,8 @@ body { } .code-block { - --at-apply: font-mono bg-code text-base p3 mt-2 rounded overflow-auto leading-1.6em; + --at-apply: font-mono bg-code text-base p3 mt-2 rounded overflow-auto + leading-1.6em; .shiki { background: transparent !important; @@ -152,7 +159,9 @@ body { } } -html, body, #__nuxt { +html, +body, +#__nuxt { height: 100vh; margin: 0; padding: 0; @@ -184,6 +193,10 @@ body { em-emoji-picker { --border-radius: 0; } +em-emoji { + font-size: 1.2em; + line-height: 1em; +} footer { a {