feat: support custom emojis from other servers
parent
f3a0a5af3f
commit
6d66bbbc5d
|
@ -0,0 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import type { Account } from 'masto'
|
||||
|
||||
defineProps<{
|
||||
account: Account
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img :src="account.avatar" :alt="account.username" rounded bg-gray:10>
|
||||
</template>
|
|
@ -21,11 +21,11 @@ const createdAt = $computed(() => {
|
|||
<div flex flex-col gap-2>
|
||||
<div p1>
|
||||
<NuxtLink :to="`/@${account.acct}`">
|
||||
<img :src="account.avatar" rounded w-20 h-20>
|
||||
<AccountAvatar :account="account" w-20 h-20 />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<NuxtLink flex flex-col :to="`/@${account.acct}`">
|
||||
<CommonRichContent font-bold :content="getDisplayName(account)" />
|
||||
<CommonRichContent font-bold :content="getDisplayName(account)" :emojis="account.emojis" />
|
||||
<p op50>
|
||||
@{{ account.acct }}
|
||||
</p>
|
||||
|
|
|
@ -11,11 +11,11 @@ const { link = true } = defineProps<{
|
|||
<div flex gap-2>
|
||||
<div p1>
|
||||
<NuxtLink :to="link ? `/@${account.acct}` : null">
|
||||
<img :src="account.avatar" rounded w-10 h-10 bg-gray:10>
|
||||
<AccountAvatar :account="account" w-10 h-10 />
|
||||
</NuxtLink>
|
||||
</div>
|
||||
<NuxtLink flex flex-col :to="link ? `/@${account.acct}` : null">
|
||||
<CommonRichContent font-bold :content="getDisplayName(account)" />
|
||||
<CommonRichContent font-bold :content="getDisplayName(account)" :emojis="account.emojis" />
|
||||
<p op35 text-sm>
|
||||
@{{ account.acct }}
|
||||
</p>
|
||||
|
|
|
@ -8,7 +8,7 @@ defineProps<{
|
|||
|
||||
<template>
|
||||
<NuxtLink :href="`/@${account.acct}`" flex gap-2 font-bold items-center>
|
||||
<img :src="account.avatar" class="w-5 h-5 rounded">
|
||||
<CommonRichContent :content="getDisplayName(account)" />
|
||||
<AccountAvatar :account="account" w-5 h-5 />
|
||||
<CommonRichContent :content="getDisplayName(account)" :emojis="account.emojis" />
|
||||
</NuxtLink>
|
||||
</template>
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
import type { Emoji } from 'masto'
|
||||
import type { PropType } from 'vue'
|
||||
import { emojisArrayToObject } from '~/composables/utils'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
emojis: {
|
||||
type: Array as PropType<Emoji[]>,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const serverInfos = useServerInfo(currentServer.value)
|
||||
const emojiObject = emojisArrayToObject(props.emojis || [])
|
||||
|
||||
return () => h(
|
||||
'div',
|
||||
{ class: 'rich-content' },
|
||||
contentToVNode(props.content, undefined, serverInfos.value?.customEmojis),
|
||||
contentToVNode(props.content, undefined, emojiObject),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
|
|
@ -8,6 +8,6 @@ const { status } = defineProps<{
|
|||
|
||||
<template>
|
||||
<div class="status-body">
|
||||
<CommonRichContent :content="status.content" />
|
||||
<CommonRichContent :content="status.content" :emojis="status.emojis" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { emojisArrayToObject } from './utils'
|
||||
import type { ServerInfo } from '~/types'
|
||||
|
||||
const ServerInfoTTL = 60 * 60 * 1000 * 12 // 12 hour
|
||||
|
@ -19,7 +20,7 @@ async function _fetchServerInfo(server: string) {
|
|||
Object.assign(serverInfos.value[server], r)
|
||||
}),
|
||||
masto.customEmojis.fetchAll().then((r) => {
|
||||
serverInfos.value[server].customEmojis = Object.fromEntries(r.map(i => [i.shortcode, i]))
|
||||
serverInfos.value[server].customEmojis = emojisArrayToObject(r)
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { Emoji } from 'masto'
|
||||
|
||||
export function getDataUrlFromArr(arr: Uint8ClampedArray, w: number, h: number) {
|
||||
if (typeof w === 'undefined' || typeof h === 'undefined')
|
||||
w = h = Math.sqrt(arr.length / 4)
|
||||
|
@ -14,3 +16,7 @@ export function getDataUrlFromArr(arr: Uint8ClampedArray, w: number, h: number)
|
|||
|
||||
return canvas.toDataURL()
|
||||
}
|
||||
|
||||
export function emojisArrayToObject(emojis: Emoji[]) {
|
||||
return Object.fromEntries(emojis.map(i => [i.shortcode, i]))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import AccountAvatar from '~~/components/account/AccountAvatar.vue'
|
||||
|
||||
const params = useRoute().params
|
||||
const id = computed(() => params.post as string)
|
||||
|
||||
|
@ -12,8 +14,8 @@ const { data: context } = await useAsyncData(`${id}-context`, () => masto.status
|
|||
<StatusCard :status="comment" border="t border" pt-4 />
|
||||
</template>
|
||||
<StatusDetails :status="status" border="t border" pt-4 />
|
||||
<div border="t border" p6 flex gap-4>
|
||||
<img :src="currentUser?.account?.avatar" rounded w-10 h-10 bg-gray:10>
|
||||
<div v-if="currentUser" border="t border" p6 flex gap-4>
|
||||
<AccountAvatar :account="currentUser.account" w-10 h-10 />
|
||||
<PublishWidget
|
||||
w-full
|
||||
:draft-key="`reply-${id}`"
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
modelValue?: boolean
|
||||
}>()
|
||||
|
||||
const params = useRoute().params
|
||||
const user = $computed(() => params.user as string)
|
||||
|
||||
|
|
Loading…
Reference in New Issue