✨ 更新部分CSS 添加TS7.0依赖 有待配置
This commit is contained in:
@@ -4,14 +4,17 @@ import { DataAnomaly, defaultMetaData } from '~/types/PostMetaData';
|
||||
import type { PostMetaData } from '~/types/PostMetaData';
|
||||
import breakpointsHelper from '~/utils/BreakpointsHelper';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
article?: PostMetaData;
|
||||
withDefaults(defineProps<{
|
||||
metaData?: PostMetaData;
|
||||
}>(),
|
||||
{
|
||||
article: () => defaultMetaData,
|
||||
metaData: () => defaultMetaData,
|
||||
});
|
||||
|
||||
function dateFormat(date: Date | DataAnomaly) {
|
||||
function dateFormat(date: Date | DataAnomaly | undefined) {
|
||||
if (!date) {
|
||||
return 'date undefined';
|
||||
}
|
||||
if (date === DataAnomaly.DataNotFound || date === DataAnomaly.Invalid) {
|
||||
return date;
|
||||
}
|
||||
@@ -24,7 +27,10 @@ function dateFormat(date: Date | DataAnomaly) {
|
||||
});
|
||||
}
|
||||
|
||||
function getCostTime(length: number | DataAnomaly) {
|
||||
function getCostTime(length: number | DataAnomaly | undefined) {
|
||||
if (!length) {
|
||||
return 'length undefined';
|
||||
}
|
||||
if (length === DataAnomaly.DataNotFound || length === DataAnomaly.Invalid) {
|
||||
return length;
|
||||
}
|
||||
@@ -43,45 +49,50 @@ function getCostTime(length: number | DataAnomaly) {
|
||||
<template>
|
||||
<div class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64 transition-all duration-500">
|
||||
<div class="text-4xl">
|
||||
{{ props.article.title }}
|
||||
{{ metaData?.title }}
|
||||
</div>
|
||||
<div class="flex items-center mt-2 max-w-96 overflow-hidden">
|
||||
|
||||
<div title="发布时间" class="flex items-center">
|
||||
<Icon name="lucide:clock-arrow-up"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ dateFormat(props.article.published_at) }}
|
||||
{{ dateFormat(metaData?.published_at) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="分类" class="flex items-center ml-2">
|
||||
<Icon name="material-symbols:category"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ props.article.category }}
|
||||
{{ metaData?.category }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="字数" class="flex items-center ml-2">
|
||||
<Icon name="fluent:text-word-count-20-filled"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ props.article.word_count }}字
|
||||
{{ metaData?.word_count }}字
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="预计阅读时间" class="flex items-center ml-2">
|
||||
<Icon name="octicon:stopwatch-16"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ getCostTime(props.article.word_count) }}
|
||||
{{ getCostTime(metaData?.word_count) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="metaData?.isPinned" class="flex items-center ml-2">
|
||||
<Icon name="codicon:pinned"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
置顶
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex mt-2 justify-between h-28">
|
||||
<div>
|
||||
<div class="">
|
||||
{{ props.article.description }}
|
||||
<div class="overflow-y-auto">
|
||||
{{ metaData?.description }}
|
||||
</div>
|
||||
</div>
|
||||
<Transition
|
||||
enter-active-class="transition-opacity duration-500 ease-in-out"
|
||||
enter-from-class="opacity-0"
|
||||
@@ -92,12 +103,12 @@ function getCostTime(length: number | DataAnomaly) {
|
||||
>
|
||||
<TechStackCard
|
||||
v-if="breakpointsHelper.greater('lg').value"
|
||||
:async-key="'stack:' + props.article.id"
|
||||
:tech-stack="props.article.tech_stack"
|
||||
:tech-stack-icon-names="props.article.tech_stack_icon_names"
|
||||
:tech-stack-theme-colors="props.article.tech_stack_theme_colors"
|
||||
:tech-stack-percent="props.article.tech_stack_percent"
|
||||
class="w-64"
|
||||
:async-key="'stack:' + metaData?.id"
|
||||
:tech-stack="metaData?.tech_stack"
|
||||
:tech-stack-icon-names="metaData?.tech_stack_icon_names"
|
||||
:tech-stack-theme-colors="metaData?.tech_stack_theme_colors"
|
||||
:tech-stack-percent="metaData?.tech_stack_percent"
|
||||
class="min-w-64"
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
@@ -106,19 +117,19 @@ function getCostTime(length: number | DataAnomaly) {
|
||||
<div class="flex mt-2">
|
||||
<div title="创建时间" class="flex items-center">
|
||||
<Icon name="lucide:file-clock"/>
|
||||
<div class="ml-1">{{ dateFormat(props.article.created_at) }}</div>
|
||||
<div class="ml-1">{{ dateFormat(metaData?.created_at) }}</div>
|
||||
</div>
|
||||
<div v-if="Array.isArray(props.article.updated_at)" class="flex items-center ml-2">
|
||||
<div v-if="Array.isArray(metaData?.updated_at)" class="flex items-center ml-2">
|
||||
<Icon name="lucide:clock-alert" title="上次更新时间"/>
|
||||
<HoverContent>
|
||||
<template #content>
|
||||
<div class="ml-1">
|
||||
{{ dateFormat(props.article.updated_at[props.article.updated_at.length - 1]) }}
|
||||
{{ dateFormat(metaData?.updated_at[metaData?.updated_at.length - 1]) }}
|
||||
</div>
|
||||
</template>
|
||||
<template #hoverContent>
|
||||
<div class="p-1 pr-2">
|
||||
<div v-for="(date,index) of props.article.updated_at" :key="index">
|
||||
<div v-for="(date,index) of metaData?.updated_at" :key="index">
|
||||
<div class="block whitespace-nowrap">
|
||||
{{ '第' + index + '次更新' + dateFormat(date) }}
|
||||
</div>
|
||||
@@ -129,12 +140,12 @@ function getCostTime(length: number | DataAnomaly) {
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="Array.isArray(props.article.tags)" class="flex items-top">
|
||||
<div v-if="Array.isArray(metaData?.tags)" class="flex items-top">
|
||||
<Icon name="clarity:tags-solid" class="mt-1"/>
|
||||
<div>
|
||||
<div v-for="(tag,index) of props.article.tags" :key="index" class="inline-block">
|
||||
<div v-for="(tag,index) of metaData?.tags" :key="index" class="inline-block">
|
||||
<div class="ml-1 inline">{{ tag }}</div>
|
||||
<div v-if="index !== props.article.tags.length - 1" class="inline">,</div>
|
||||
<div v-if="index !== metaData?.tags.length - 1" class="inline">,</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,13 +5,17 @@ import type { PostMetaData } from '~/types/PostMetaData';
|
||||
import useColorModeStore from '~/stores/colorModeStore';
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
rambling?: PostMetaData;
|
||||
metaData?: PostMetaData;
|
||||
}>(),
|
||||
{
|
||||
rambling: () => defaultMetaData,
|
||||
metaData: () => defaultMetaData,
|
||||
});
|
||||
const { data: rawbody } = useAsyncData(async () => (await queryCollection('content').where('id', '=', props.rambling.id).first())?.rawbody);
|
||||
const collapsed = ref(false);
|
||||
const { data: rawbody } = useAsyncData('simpleCard:' + props.metaData.id, async () => (await queryCollection('content').where('id', '=', props.metaData.id).first())?.rawbody);
|
||||
const collapsed = ref(true);
|
||||
const typeChinese = new Map<string, string>([
|
||||
['rambling', '絮语'],
|
||||
['announcement', '公告'],
|
||||
]);
|
||||
|
||||
function dateFormat(date: Date | DataAnomaly) {
|
||||
if (date === DataAnomaly.DataNotFound || date === DataAnomaly.Invalid) {
|
||||
@@ -42,7 +46,7 @@ function getCostTime(length: number | DataAnomaly) {
|
||||
}
|
||||
|
||||
const safeEditorId = computed(() => {
|
||||
const encoded = btoa(encodeURIComponent(props.rambling.id))
|
||||
const encoded = btoa(encodeURIComponent(props.metaData.id))
|
||||
.replace(/[+/=]/g, '_'); // 替换 Base64 中的特殊字符
|
||||
return `rambling_${encoded}`;
|
||||
});
|
||||
@@ -98,41 +102,48 @@ onUnmounted(() => {
|
||||
class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64 transition-all duration-500"
|
||||
@click="reverseCollapsed">
|
||||
<div class="text-4xl">
|
||||
絮语:{{ props.rambling.title }}
|
||||
{{ (typeChinese.get(metaData.type) || 'unknown Type') + ':' }}{{ props.metaData.title }}
|
||||
</div>
|
||||
<div class="flex items-center mt-2 max-w-96 overflow-hidden">
|
||||
<div class="flex items-center mt-2 max-w-[400px] overflow-hidden">
|
||||
|
||||
<div title="发布时间" class="flex items-center">
|
||||
<Icon name="lucide:clock-arrow-up"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ dateFormat(props.rambling.published_at) }}
|
||||
{{ dateFormat(props.metaData.published_at) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="分类" class="flex items-center ml-2">
|
||||
<Icon name="material-symbols:category"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ props.rambling.category }}
|
||||
{{ props.metaData.category }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="字数" class="flex items-center ml-2">
|
||||
<Icon name="fluent:text-word-count-20-filled"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ props.rambling.word_count }}字
|
||||
{{ props.metaData.word_count }}字
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div title="预计阅读时间" class="flex items-center ml-2">
|
||||
<Icon name="octicon:stopwatch-16"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
{{ getCostTime(props.rambling.word_count) }}
|
||||
{{ getCostTime(props.metaData.word_count) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="metaData.isPinned" class="flex items-center ml-2">
|
||||
<Icon name="codicon:pinned"/>
|
||||
<div class="ml-1 text-nowrap">
|
||||
置顶
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
class="relative flex mt-2 justify-between overflow-hidden transition-all duration-300 ease-in-out dura"
|
||||
class="relative flex mt-2 justify-between overflow-hidden transition-all duration-300 ease-in-out min-h-[8.5rem]"
|
||||
:class="{'max-h-[8.5rem]' : collapsed, 'max-h-[100vh]':!collapsed}">
|
||||
<ReadonlyMdEditor
|
||||
v-if="rawbody" :editor-id="safeEditorId" :markdown="rawbody!"
|
||||
@@ -150,19 +161,19 @@ onUnmounted(() => {
|
||||
<div class="flex mt-2">
|
||||
<div title="创建时间" class="flex items-center">
|
||||
<Icon name="lucide:file-clock"/>
|
||||
<div class="ml-1">{{ dateFormat(props.rambling.created_at) }}</div>
|
||||
<div class="ml-1">{{ dateFormat(props.metaData.created_at) }}</div>
|
||||
</div>
|
||||
<div v-if="Array.isArray(props.rambling.updated_at)" class="flex items-center ml-2">
|
||||
<div v-if="Array.isArray(props.metaData.updated_at)" class="flex items-center ml-2">
|
||||
<Icon name="lucide:clock-alert" title="上次更新时间"/>
|
||||
<HoverContent>
|
||||
<template #content>
|
||||
<div class="ml-1">
|
||||
{{ dateFormat(props.rambling.updated_at[props.rambling.updated_at.length - 1]) }}
|
||||
{{ dateFormat(props.metaData.updated_at[props.metaData.updated_at.length - 1]) }}
|
||||
</div>
|
||||
</template>
|
||||
<template #hoverContent>
|
||||
<div class="p-1 pr-2">
|
||||
<div v-for="(date,index) of props.rambling.updated_at" :key="index">
|
||||
<div v-for="(date,index) of props.metaData.updated_at" :key="index">
|
||||
<div class="block whitespace-nowrap">
|
||||
{{ '第' + index + '次更新' + dateFormat(date) }}
|
||||
</div>
|
||||
Reference in New Issue
Block a user