wip: duet (3)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
interface OgData {
|
||||
image?: string
|
||||
title?: string
|
||||
description?: string
|
||||
url?: string
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
link: string
|
||||
}>()
|
||||
|
||||
// Unique key per component instance so multiple BlogLink usages (even of the
|
||||
// same URL) don't share/collide their async data state.
|
||||
const instanceId = useId()
|
||||
const { data: og } = await useAsyncData<Partial<OgData>>(
|
||||
`blog-link-${instanceId}`,
|
||||
() => $fetch('/api/ogimage', { params: { url: props.link } }),
|
||||
{ default: () => ({}) }
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
:href="props.link" target="_blank" rel="noopener noreferrer"
|
||||
class="block ml-auto mr-auto mt-2 mb-2 sm:max-w-[55%] max-w-[75%] rounded-xl overflow-hidden border border-slate-200 hover:border-slate-400 transition-colors bg-white group no-underline"
|
||||
>
|
||||
|
||||
<img
|
||||
v-if="og?.image" :src="og.image" :alt="og?.title || props.link"
|
||||
class="w-full max-h-[320px] object-cover block" loading="lazy"
|
||||
>
|
||||
|
||||
<div v-if="og?.title || og?.description" class="p-4">
|
||||
<h3 v-if="og?.title" class="text-lg font-semibold text-slate-800 group-hover:underline">{{ og.title }}</h3>
|
||||
<p v-if="og?.description" class="text-sm text-slate-500 mt-1 line-clamp-2">{{ og.description }}</p>
|
||||
<p class="text-xs text-slate-400 mt-2 pb-1 leading-relaxed truncate">{{ props.link }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Fallback when no metadata could be retrieved -->
|
||||
<div v-else class="p-4">
|
||||
<h3 class="text-lg text-center font-semibold text-slate-800 group-hover:underline break-all">{{ props.link }}</h3>
|
||||
</div>
|
||||
|
||||
<div v-if="$slots.default" class="ml-auto mr-auto mt-2 w-fit max-w-[80%] slot pb-4">
|
||||
<slot />
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.slot > * {
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user