From 044cc02c82fc0f44d19f262b3517766f8fe36e5b Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Sat, 18 Apr 2026 21:41:20 +0800 Subject: [PATCH] feat(public): profile preview slices and links to full list pages Made-with: Cursor --- app/pages/@[publicSlug]/index.vue | 276 +++++++++++++++++++++++--------------- 1 file changed, 168 insertions(+), 108 deletions(-) diff --git a/app/pages/@[publicSlug]/index.vue b/app/pages/@[publicSlug]/index.vue index fcc320c..9e594eb 100644 --- a/app/pages/@[publicSlug]/index.vue +++ b/app/pages/@[publicSlug]/index.vue @@ -14,21 +14,9 @@ const route = useRoute() const slug = computed(() => route.params.publicSlug as string) const { mode } = usePublicProfileLayoutMode() -const PAGE_SIZE = 8 - -const postsPage = ref(1) -const timelinePage = ref(1) -const rssPage = ref(1) - type ReadingSection = 'posts' | 'timeline' | 'rss' const readingSection = ref('posts') -watch(slug, () => { - postsPage.value = 1 - timelinePage.value = 1 - rssPage.value = 1 -}) - type PublicPostListItem = { title: string excerpt: string @@ -38,6 +26,7 @@ type PublicPostListItem = { } type PublicTimelineItem = { + id?: number title?: string | null occurredOn?: Date | string | null linkUrl?: string | null @@ -50,9 +39,9 @@ type Payload = { user: { publicSlug: string | null; nickname: string | null; avatar: string | null } bio: { markdown: string } | null links: { label: string; url: string; visibility: string }[] - posts: PublicPostListItem[] - timeline: PublicTimelineItem[] - rssItems: PublicRssListItem[] + posts: { items: PublicPostListItem[]; total: number } + timeline: { items: PublicTimelineItem[]; total: number } + rssItems: { items: PublicRssListItem[]; total: number } } function rssPublicHref(it: PublicRssListItem): string | undefined { @@ -87,10 +76,10 @@ const { data, pending, error } = await useAsyncData( ) function firstReadingSection(d: Payload): ReadingSection { - if (d.posts.length) { + if (d.posts.total > 0) { return 'posts' } - if (d.timeline.length) { + if (d.timeline.total > 0) { return 'timeline' } return 'rss' @@ -98,12 +87,12 @@ function firstReadingSection(d: Payload): ReadingSection { function readingSectionValid(d: Payload, s: ReadingSection): boolean { if (s === 'posts') { - return d.posts.length > 0 + return d.posts.total > 0 } if (s === 'timeline') { - return d.timeline.length > 0 + return d.timeline.total > 0 } - return d.rssItems.length > 0 + return d.rssItems.total > 0 } watch([data, mode], () => { @@ -111,7 +100,7 @@ watch([data, mode], () => { return } const d = data.value - if (!d.posts.length && !d.timeline.length && !d.rssItems.length) { + if (!d.posts.total && !d.timeline.total && !d.rssItems.total) { return } if (!readingSectionValid(d, readingSection.value)) { @@ -129,15 +118,9 @@ function selectReadingSection(s: ReadingSection) { }) } -function slicePage(list: T[], page: number): T[] { - const p = Math.max(1, page) - const start = (p - 1) * PAGE_SIZE - return list.slice(start, start + PAGE_SIZE) +function timelineItemKey(e: PublicTimelineItem, i: number): string | number { + return e.id ?? i } - -const postsChunk = computed(() => slicePage(data.value?.posts ?? [], postsPage.value)) -const timelineChunk = computed(() => slicePage(data.value?.timeline ?? [], timelinePage.value)) -const rssChunk = computed(() => slicePage(data.value?.rssItems ?? [], rssPage.value))