|
|
@ -1,5 +1,6 @@ |
|
|
<script setup lang="ts"> |
|
|
<script setup lang="ts"> |
|
|
import { unwrapApiBody, type ApiResponse } from '../../utils/http/factory' |
|
|
import { unwrapApiBody, type ApiResponse } from '../../utils/http/factory' |
|
|
|
|
|
import { extractFrontMatterDesc, stripFrontMatter } from '../../utils/markdown-front-matter' |
|
|
import { renderSafeMarkdown } from '../../utils/render-markdown' |
|
|
import { renderSafeMarkdown } from '../../utils/render-markdown' |
|
|
import { |
|
|
import { |
|
|
formatOccurredOnDisplay, |
|
|
formatOccurredOnDisplay, |
|
|
@ -123,9 +124,27 @@ function timelineItemKey(e: PublicTimelineItem, i: number): string | number { |
|
|
return e.id ?? i |
|
|
return e.id ?? i |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const bioHtml = computed(() => |
|
|
/** 主页生平:有 front matter 的 desc 时只展示 desc;否则展示全文(兼容无 FM 的简介) */ |
|
|
data.value?.bio?.markdown ? renderSafeMarkdown(data.value.bio.markdown) : '', |
|
|
const bioHtml = computed(() => { |
|
|
) |
|
|
const md = data.value?.bio?.markdown |
|
|
|
|
|
if (!md?.trim()) { |
|
|
|
|
|
return '' |
|
|
|
|
|
} |
|
|
|
|
|
const desc = extractFrontMatterDesc(md) |
|
|
|
|
|
if (desc) { |
|
|
|
|
|
return renderSafeMarkdown(desc) |
|
|
|
|
|
} |
|
|
|
|
|
return renderSafeMarkdown(md) |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
/** 「查看全文」:正文在去掉 FM 后仍有内容时才显示(避免仅有 desc 时链到空页) */ |
|
|
|
|
|
const showBioReadMore = computed(() => { |
|
|
|
|
|
const md = data.value?.bio?.markdown |
|
|
|
|
|
if (!md?.trim()) { |
|
|
|
|
|
return false |
|
|
|
|
|
} |
|
|
|
|
|
return stripFrontMatter(md).trim().length > 0 |
|
|
|
|
|
}) |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<template> |
|
|
<template> |
|
|
@ -154,12 +173,12 @@ const bioHtml = computed(() => |
|
|
</h1> |
|
|
</h1> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div v-if="data.bio?.markdown" class="space-y-3"> |
|
|
<div v-if="data.bio?.markdown && bioHtml" class="space-y-3"> |
|
|
<div |
|
|
<div |
|
|
class="prose prose-neutral dark:prose-invert max-w-none prose-img:rounded-lg" |
|
|
class="prose prose-neutral dark:prose-invert max-w-none prose-img:rounded-lg" |
|
|
v-html="bioHtml" |
|
|
v-html="bioHtml" |
|
|
/> |
|
|
/> |
|
|
<div class="not-prose"> |
|
|
<div v-if="showBioReadMore" class="not-prose"> |
|
|
<NuxtLink |
|
|
<NuxtLink |
|
|
:to="`/@${slug}/about`" |
|
|
:to="`/@${slug}/about`" |
|
|
class="text-sm font-medium text-primary hover:underline" |
|
|
class="text-sm font-medium text-primary hover:underline" |
|
|
@ -351,12 +370,13 @@ const bioHtml = computed(() => |
|
|
<h1 class="text-center text-lg font-semibold text-highlighted lg:text-left lg:text-base"> |
|
|
<h1 class="text-center text-lg font-semibold text-highlighted lg:text-left lg:text-base"> |
|
|
{{ data.user.nickname || data.user.publicSlug || slug }} |
|
|
{{ data.user.nickname || data.user.publicSlug || slug }} |
|
|
</h1> |
|
|
</h1> |
|
|
<div v-if="data.bio?.markdown" class="space-y-2"> |
|
|
<div v-if="data.bio?.markdown && bioHtml" class="space-y-2"> |
|
|
<div |
|
|
<div |
|
|
class="bio-preview-scroll max-h-36 overflow-y-auto rounded-lg border border-default bg-elevated/30 p-3 text-xs leading-relaxed text-muted prose prose-neutral dark:prose-invert max-w-none prose-p:my-1 prose-img:rounded" |
|
|
class="bio-preview-scroll max-h-36 overflow-y-auto rounded-lg border border-default bg-elevated/30 p-3 text-xs leading-relaxed text-muted prose prose-neutral dark:prose-invert max-w-none prose-p:my-1 prose-img:rounded" |
|
|
v-html="bioHtml" |
|
|
v-html="bioHtml" |
|
|
/> |
|
|
/> |
|
|
<NuxtLink |
|
|
<NuxtLink |
|
|
|
|
|
v-if="showBioReadMore" |
|
|
:to="`/@${slug}/about`" |
|
|
:to="`/@${slug}/about`" |
|
|
class="text-xs font-medium text-primary hover:underline" |
|
|
class="text-xs font-medium text-primary hover:underline" |
|
|
> |
|
|
> |
|
|
|