fix(sns): sync my timeline count and auto load more

This commit is contained in:
aits2026
2026-03-06 11:03:11 +08:00
parent 4f40b4af49
commit a62ba8e167
3 changed files with 24 additions and 9 deletions

View File

@@ -441,6 +441,14 @@ export function ContactSnsTimelineDialog({
timelineLoadingMore timelineLoadingMore
]) ])
const handleBodyScroll = useCallback((event: React.UIEvent<HTMLDivElement>) => {
const element = event.currentTarget
const remaining = element.scrollHeight - element.scrollTop - element.clientHeight
if (remaining <= 160) {
loadMore()
}
}, [loadMore])
const toggleRankMode = useCallback((mode: ContactSnsRankMode) => { const toggleRankMode = useCallback((mode: ContactSnsRankMode) => {
setRankMode((previous) => (previous === mode ? null : mode)) setRankMode((previous) => (previous === mode ? null : mode))
}, []) }, [])
@@ -534,7 +542,10 @@ export function ContactSnsTimelineDialog({
</div> </div>
<div className="contact-sns-dialog-body"> <div
className="contact-sns-dialog-body"
onScroll={handleBodyScroll}
>
{timelinePosts.length > 0 && ( {timelinePosts.length > 0 && (
<div className="contact-sns-dialog-posts-list"> <div className="contact-sns-dialog-posts-list">
{timelinePosts.map((post) => ( {timelinePosts.map((post) => (

View File

@@ -101,6 +101,12 @@
.feed-my-timeline-count { .feed-my-timeline-count {
color: var(--text-primary); color: var(--text-primary);
font-weight: 600; font-weight: 600;
display: inline-flex;
align-items: center;
.spin {
animation: spin 0.8s linear infinite;
}
} }
&.ready { &.ready {

View File

@@ -1,5 +1,5 @@
import { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from 'react' import { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from 'react'
import { RefreshCw, Search, X, Download, FolderOpen, FileJson, FileText, Image, CheckCircle, AlertCircle, Calendar, Users, Info, ChevronLeft, ChevronRight, Shield, ShieldOff } from 'lucide-react' import { RefreshCw, Search, X, Download, FolderOpen, FileJson, FileText, Image, CheckCircle, AlertCircle, Calendar, Users, Info, ChevronLeft, ChevronRight, Shield, ShieldOff, Loader2 } from 'lucide-react'
import JumpToDateDialog from '../components/JumpToDateDialog' import JumpToDateDialog from '../components/JumpToDateDialog'
import './SnsPage.scss' import './SnsPage.scss'
import { SnsPost } from '../types/sns' import { SnsPost } from '../types/sns'
@@ -274,18 +274,16 @@ export default function SnsPage() {
}, [authorTimelineTarget, contacts]) }, [authorTimelineTarget, contacts])
const myTimelineCount = useMemo(() => { const myTimelineCount = useMemo(() => {
if (typeof overviewStats.myPosts === 'number' && Number.isFinite(overviewStats.myPosts) && overviewStats.myPosts >= 0) {
return Math.floor(overviewStats.myPosts)
}
if (resolvedCurrentUserContact?.postCountStatus === 'ready' && typeof resolvedCurrentUserContact.postCount === 'number') { if (resolvedCurrentUserContact?.postCountStatus === 'ready' && typeof resolvedCurrentUserContact.postCount === 'number') {
return normalizePostCount(resolvedCurrentUserContact.postCount) return normalizePostCount(resolvedCurrentUserContact.postCount)
} }
return null return null
}, [normalizePostCount, overviewStats.myPosts, resolvedCurrentUserContact]) }, [normalizePostCount, resolvedCurrentUserContact])
const myTimelineCountLoading = Boolean( const myTimelineCountLoading = Boolean(
overviewStatsStatus === 'loading' resolvedCurrentUserContact
|| resolvedCurrentUserContact?.postCountStatus === 'loading' ? resolvedCurrentUserContact.postCountStatus !== 'ready'
: overviewStatsStatus === 'loading' || contactsLoading
) )
const openCurrentUserTimeline = useCallback(() => { const openCurrentUserTimeline = useCallback(() => {
@@ -980,7 +978,7 @@ export default function SnsPage() {
{myTimelineCount !== null {myTimelineCount !== null
? `${myTimelineCount.toLocaleString('zh-CN')}` ? `${myTimelineCount.toLocaleString('zh-CN')}`
: myTimelineCountLoading : myTimelineCountLoading
? '...' ? <Loader2 size={14} className="spin" aria-hidden="true" />
: '--'} : '--'}
</span> </span>
</button> </button>