Skip to content

Commit

Permalink
feat: show emoji tooltip (#2485)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinigami92 authored Dec 22, 2023
1 parent 74138a9 commit c0bb6e2
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ node_modules
*.log
dist
.output
.pnpm-store
.nuxt
.env
.DS_Store
Expand Down
30 changes: 30 additions & 0 deletions components/emoji/Emoji.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
const { as, alt, dataEmojiId } = $defineProps<{
as: string
alt?: string
dataEmojiId?: string
}>()
let title = $ref<string | undefined>()
if (alt) {
if (alt.startsWith(':')) {
title = alt.replace(/:/g, '')
}
else {
import('node-emoji').then(({ find }) => {
title = find(alt)?.key.replace(/_/g, ' ')
})
}
}
// if it has a data-emoji-id, use that as the title instead
if (dataEmojiId)
title = dataEmojiId
</script>

<template>
<component :is="as" v-bind="$attrs" :alt="alt" :data-emoji-id="dataEmojiId" :title="title">
<slot />
</component>
</template>
19 changes: 17 additions & 2 deletions composables/content-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { RouterLink } from 'vue-router'
import { decode } from 'tiny-decode'
import type { ContentParseOptions } from './content-parse'
import { parseMastodonHTML } from './content-parse'
import Emoji from '~/components/emoji/Emoji.vue'
import ContentCode from '~/components/content/ContentCode.vue'
import ContentMentionGroup from '~/components/content/ContentMentionGroup.vue'
import AccountHoverWrapper from '~/components/account/AccountHoverWrapper.vue'
Expand All @@ -19,8 +20,11 @@ function getTextualAstComponents(astChildren: Node[]): string {
}

/**
* Raw HTML to VNodes
*/
* Raw HTML to VNodes.
*
* @param content HTML content.
* @param options Options.
*/
export function contentToVNode(
content: string,
options?: ContentParseOptions,
Expand All @@ -43,6 +47,17 @@ export function nodeToVNode(node: Node): VNode | string | null {
if (node.name === 'mention-group')
return h(ContentMentionGroup, node.attributes, () => node.children.map(treeToVNode))

// add tooltip to emojis
if (node.name === 'picture' || (node.name === 'img' && node.attributes?.alt)) {
const props = node.attributes ?? {}
props.as = node.name
return h(
Emoji,
props,
() => node.children.map(treeToVNode),
)
}

if ('children' in node) {
if (node.name === 'a' && (node.attributes.href?.startsWith('/') || node.attributes.href?.startsWith('.'))) {
node.attributes.to = node.attributes.href
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"js-yaml": "^4.1.0",
"lru-cache": "^10.0.0",
"masto": "^5.11.3",
"node-emoji": "^2.1.3",
"nuxt-security": "^0.13.1",
"page-lifecycle": "^0.1.2",
"pinia": "^2.1.4",
Expand Down
39 changes: 39 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions tests/nuxt/__snapshots__/content-rich.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ exports[`content-rich > code frame no lang 1`] = `"<p><pre class="code-block">he
exports[`content-rich > custom emoji 1`] = `
"Daniel Roe
<picture alt=":nuxt:" class="custom-emoji" data-emoji-id="nuxt"
<picture class="custom-emoji" alt=":nuxt:" data-emoji-id="nuxt" title="nuxt"
><source
srcset="
https://media.webtoo.ls/custom_emojis/images/000/000/366/original/73330dfc9dda4078.png
Expand All @@ -67,6 +67,7 @@ exports[`content-rich > custom emoji 1`] = `
<img
src="https://media.webtoo.ls/custom_emojis/images/000/000/366/original/73330dfc9dda4078.png"
alt=":nuxt:"
title="nuxt"
/></picture>
"
`;
Expand Down Expand Up @@ -129,8 +130,8 @@ exports[`content-rich > link + mention 1`] = `
Happy
<img
src="/emojis/twemoji/1f917.svg"
alt="🤗"
class="iconify-emoji iconify-emoji--twemoji"
alt="🤗"
/>
we’re now using
<span class="h-card"
Expand Down

0 comments on commit c0bb6e2

Please sign in to comment.