diff --git a/components/account/AccountHoverWrapper.vue b/components/account/AccountHoverWrapper.vue
index ee9d6287..db52b3f0 100644
--- a/components/account/AccountHoverWrapper.vue
+++ b/components/account/AccountHoverWrapper.vue
@@ -1,17 +1,20 @@
-
+
-
+
diff --git a/components/status/StatusReplyingTo.vue b/components/status/StatusReplyingTo.vue
index ae5fa301..455f541b 100644
--- a/components/status/StatusReplyingTo.vue
+++ b/components/status/StatusReplyingTo.vue
@@ -5,7 +5,7 @@ const { status } = defineProps<{
status: Status
}>()
-const account = asyncComputed(() => fetchAccount(status.inReplyToAccountId!))
+const account = useAccountById(status.inReplyToAccountId!)
diff --git a/composables/cache.ts b/composables/cache.ts
index 5b7cbbb5..37d94af7 100644
--- a/composables/cache.ts
+++ b/composables/cache.ts
@@ -28,7 +28,7 @@ export function fetchStatus(id: string): Promise {
return promise
}
-export function fetchAccount(id: string): Promise {
+export function fetchAccountById(id: string): Promise {
const key = `account:${id}`
const cached = cache.get(key)
if (cached)
@@ -42,7 +42,7 @@ export function fetchAccount(id: string): Promise {
return promise
}
-export async function fetchAccountByName(acct: string): Promise {
+export async function fetchAccountByHandle(acct: string): Promise {
const key = `account:${acct}`
const cached = cache.get(key)
if (cached)
@@ -56,6 +56,14 @@ export async function fetchAccountByName(acct: string): Promise {
return account
}
+export function useAccountByHandle(acct: string) {
+ return useAsyncState(() => fetchAccountByHandle(acct), null).state
+}
+
+export function useAccountById(id: string) {
+ return useAsyncState(() => fetchAccountById(id), null).state
+}
+
export function cacheStatus(status: Status, override?: boolean) {
setCached(`status:${status.id}`, status, override)
}
diff --git a/composables/content.ts b/composables/content.ts
index c1a32418..4e3e87c0 100644
--- a/composables/content.ts
+++ b/composables/content.ts
@@ -5,6 +5,7 @@ import type { VNode } from 'vue'
import { Fragment, h, isVNode } from 'vue'
import { RouterLink } from 'vue-router'
import ContentCode from '~/components/content/ContentCode.vue'
+import AccountHoverWrapper from '~/components/account/AccountHoverWrapper.vue'
type Node = DefaultTreeAdapterMap['childNode']
type Element = DefaultTreeAdapterMap['element']
@@ -18,7 +19,9 @@ function handleMention(el: Element) {
if (matchUser) {
const [, server, username] = matchUser
// Handles need to ignore server subdomains
- href.value = `/@${username}@${server.replace(/(.+\.)(.+\..+)/, '$2')}`
+ const handle = `@${username}@${server.replace(/(.+\.)(.+\..+)/, '$2')}`
+ href.value = `/${handle}`
+ return h(AccountHoverWrapper, { handle, class: 'inline-block' }, () => nodeToVNode(el))
}
const matchTag = href.value.match(TagLinkRE)
if (matchTag) {
@@ -108,22 +111,13 @@ export function contentToVNode(
return h(Fragment, tree.childNodes.map(n => treeToVNode(n)))
}
-function treeToVNode(
- input: Node,
-): VNode | string | null {
- if (input.nodeName === '#text') {
+function nodeToVNode(node: Node): VNode | string | null {
+ if (node.nodeName === '#text') {
// @ts-expect-error casing
- const text = input.value as string
- return text
+ return input.value as string
}
- if ('childNodes' in input) {
- const node = handleNode(input)
- if (node == null)
- return null
- if (isVNode(node))
- return node
-
+ if ('childNodes' in node) {
const attrs = Object.fromEntries(node.attrs.map(i => [i.name, i.value]))
if (node.nodeName === 'a' && (attrs.href?.startsWith('/') || attrs.href?.startsWith('.'))) {
attrs.to = attrs.href
@@ -144,6 +138,25 @@ function treeToVNode(
return null
}
+function treeToVNode(
+ input: Node,
+): VNode | string | null {
+ if (input.nodeName === '#text') {
+ // @ts-expect-error casing
+ return input.value as string
+ }
+
+ if ('childNodes' in input) {
+ const node = handleNode(input)
+ if (node == null)
+ return null
+ if (isVNode(node))
+ return node
+ return nodeToVNode(node)
+ }
+ return null
+}
+
export function htmlToText(html: string) {
const tree = parseFragment(html)
return tree.childNodes.map(n => treeToText(n)).join('').trim()
diff --git a/pages/@[account]/index/followers.vue b/pages/@[account]/index/followers.vue
index 5b7ef1ed..a7109fb2 100644
--- a/pages/@[account]/index/followers.vue
+++ b/pages/@[account]/index/followers.vue
@@ -1,8 +1,8 @@
diff --git a/pages/@[account]/index/following.vue b/pages/@[account]/index/following.vue
index f6dff0dc..d08e6cae 100644
--- a/pages/@[account]/index/following.vue
+++ b/pages/@[account]/index/following.vue
@@ -1,8 +1,8 @@
diff --git a/pages/@[account]/index/index.vue b/pages/@[account]/index/index.vue
index e2790100..0b7de973 100644
--- a/pages/@[account]/index/index.vue
+++ b/pages/@[account]/index/index.vue
@@ -1,8 +1,8 @@