mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
fix(chat): show group member count loading and failed states
This commit is contained in:
@@ -3026,6 +3026,16 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
color: var(--text-tertiary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.failed {
|
||||||
|
color: #b45309;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -260,6 +260,8 @@ interface SessionExportCacheMeta {
|
|||||||
source: 'memory' | 'disk' | 'fresh'
|
source: 'memory' | 'disk' | 'fresh'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GroupMessageCountStatus = 'loading' | 'ready' | 'failed'
|
||||||
|
|
||||||
interface GroupPanelMember {
|
interface GroupPanelMember {
|
||||||
username: string
|
username: string
|
||||||
displayName: string
|
displayName: string
|
||||||
@@ -271,6 +273,7 @@ interface GroupPanelMember {
|
|||||||
isOwner?: boolean
|
isOwner?: boolean
|
||||||
isFriend: boolean
|
isFriend: boolean
|
||||||
messageCount: number
|
messageCount: number
|
||||||
|
messageCountStatus: GroupMessageCountStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SessionListCachePayload {
|
interface SessionListCachePayload {
|
||||||
@@ -1131,7 +1134,10 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
}
|
}
|
||||||
}, [applySessionDetailStats, currentSessionId, isLoadingRelationStats])
|
}, [applySessionDetailStats, currentSessionId, isLoadingRelationStats])
|
||||||
|
|
||||||
const normalizeGroupPanelMembers = useCallback((payload: GroupPanelMember[]): GroupPanelMember[] => {
|
const normalizeGroupPanelMembers = useCallback((
|
||||||
|
payload: GroupPanelMember[],
|
||||||
|
options?: { messageCountStatus?: GroupMessageCountStatus }
|
||||||
|
): GroupPanelMember[] => {
|
||||||
const membersPayload = Array.isArray(payload) ? payload : []
|
const membersPayload = Array.isArray(payload) ? payload : []
|
||||||
return membersPayload
|
return membersPayload
|
||||||
.map((member: GroupPanelMember): GroupPanelMember | null => {
|
.map((member: GroupPanelMember): GroupPanelMember | null => {
|
||||||
@@ -1144,6 +1150,9 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
member.nickname ||
|
member.nickname ||
|
||||||
username
|
username
|
||||||
)
|
)
|
||||||
|
const rawStatus = member.messageCountStatus
|
||||||
|
const normalizedStatus: GroupMessageCountStatus = options?.messageCountStatus
|
||||||
|
?? (rawStatus === 'loading' || rawStatus === 'failed' ? rawStatus : 'ready')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
username,
|
username,
|
||||||
@@ -1155,7 +1164,8 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
groupNickname: member.groupNickname,
|
groupNickname: member.groupNickname,
|
||||||
isOwner: Boolean(member.isOwner),
|
isOwner: Boolean(member.isOwner),
|
||||||
isFriend: Boolean(member.isFriend),
|
isFriend: Boolean(member.isFriend),
|
||||||
messageCount: Number.isFinite(member.messageCount) ? Math.max(0, Math.floor(member.messageCount)) : 0
|
messageCount: Number.isFinite(member.messageCount) ? Math.max(0, Math.floor(member.messageCount)) : 0,
|
||||||
|
messageCountStatus: normalizedStatus
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((member: GroupPanelMember | null): member is GroupPanelMember => Boolean(member))
|
.filter((member: GroupPanelMember | null): member is GroupPanelMember => Boolean(member))
|
||||||
@@ -1166,7 +1176,8 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
const friendDiff = Number(b.isFriend) - Number(a.isFriend)
|
const friendDiff = Number(b.isFriend) - Number(a.isFriend)
|
||||||
if (friendDiff !== 0) return friendDiff
|
if (friendDiff !== 0) return friendDiff
|
||||||
|
|
||||||
if (a.messageCount !== b.messageCount) return b.messageCount - a.messageCount
|
const canSortByCount = a.messageCountStatus === 'ready' && b.messageCountStatus === 'ready'
|
||||||
|
if (canSortByCount && a.messageCount !== b.messageCount) return b.messageCount - a.messageCount
|
||||||
return a.displayName.localeCompare(b.displayName, 'zh-Hans-CN')
|
return a.displayName.localeCompare(b.displayName, 'zh-Hans-CN')
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
@@ -1241,6 +1252,21 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const setGroupMembersCountStatus = useCallback((
|
||||||
|
status: GroupMessageCountStatus,
|
||||||
|
options?: { onlyWhenNotReady?: boolean }
|
||||||
|
) => {
|
||||||
|
setGroupPanelMembers((prev) => {
|
||||||
|
if (!Array.isArray(prev) || prev.length === 0) return prev
|
||||||
|
if (options?.onlyWhenNotReady && prev.some((member) => member.messageCountStatus === 'ready')) {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
const next = normalizeGroupPanelMembers(prev, { messageCountStatus: status })
|
||||||
|
const changed = next.some((member, index) => member.messageCountStatus !== prev[index]?.messageCountStatus)
|
||||||
|
return changed ? next : prev
|
||||||
|
})
|
||||||
|
}, [normalizeGroupPanelMembers])
|
||||||
|
|
||||||
const syncGroupMembersMyCountFromDetail = useCallback((chatroomId: string, myMessageCount: number) => {
|
const syncGroupMembersMyCountFromDetail = useCallback((chatroomId: string, myMessageCount: number) => {
|
||||||
if (!chatroomId || !chatroomId.includes('@chatroom')) return
|
if (!chatroomId || !chatroomId.includes('@chatroom')) return
|
||||||
const normalizedCount = Number.isFinite(myMessageCount) ? Math.max(0, Math.floor(myMessageCount)) : 0
|
const normalizedCount = Number.isFinite(myMessageCount) ? Math.max(0, Math.floor(myMessageCount)) : 0
|
||||||
@@ -1319,6 +1345,7 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
const refreshMessageCountsInBackground = (forceRefresh: boolean) => {
|
const refreshMessageCountsInBackground = (forceRefresh: boolean) => {
|
||||||
startedBackgroundRefresh = true
|
startedBackgroundRefresh = true
|
||||||
setIsRefreshingGroupMembers(true)
|
setIsRefreshingGroupMembers(true)
|
||||||
|
setGroupMembersCountStatus('loading', { onlyWhenNotReady: true })
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try {
|
try {
|
||||||
const countsResult = await getGroupMembersPanelDataWithTimeout(
|
const countsResult = await getGroupMembersPanelDataWithTimeout(
|
||||||
@@ -1329,10 +1356,14 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
if (requestSeq !== groupMembersRequestSeqRef.current) return
|
if (requestSeq !== groupMembersRequestSeqRef.current) return
|
||||||
if (!countsResult.success || !Array.isArray(countsResult.data)) {
|
if (!countsResult.success || !Array.isArray(countsResult.data)) {
|
||||||
setGroupMembersError('成员列表已加载,发言统计稍后再试')
|
setGroupMembersError('成员列表已加载,发言统计稍后再试')
|
||||||
|
setGroupMembersCountStatus('failed', { onlyWhenNotReady: true })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const membersWithCounts = normalizeGroupPanelMembers(countsResult.data as GroupPanelMember[])
|
const membersWithCounts = normalizeGroupPanelMembers(
|
||||||
|
countsResult.data as GroupPanelMember[],
|
||||||
|
{ messageCountStatus: 'ready' }
|
||||||
|
)
|
||||||
setGroupPanelMembers(membersWithCounts)
|
setGroupPanelMembers(membersWithCounts)
|
||||||
syncGroupMyMessagesFromMembers(chatroomId, membersWithCounts)
|
syncGroupMyMessagesFromMembers(chatroomId, membersWithCounts)
|
||||||
setGroupMembersError(null)
|
setGroupMembersError(null)
|
||||||
@@ -1341,6 +1372,7 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
} catch {
|
} catch {
|
||||||
if (requestSeq !== groupMembersRequestSeqRef.current) return
|
if (requestSeq !== groupMembersRequestSeqRef.current) return
|
||||||
setGroupMembersError('成员列表已加载,发言统计稍后再试')
|
setGroupMembersError('成员列表已加载,发言统计稍后再试')
|
||||||
|
setGroupMembersCountStatus('failed', { onlyWhenNotReady: true })
|
||||||
} finally {
|
} finally {
|
||||||
if (requestSeq === groupMembersRequestSeqRef.current) {
|
if (requestSeq === groupMembersRequestSeqRef.current) {
|
||||||
setIsRefreshingGroupMembers(false)
|
setIsRefreshingGroupMembers(false)
|
||||||
@@ -1350,9 +1382,13 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cacheFresh && cached) {
|
if (cacheFresh && cached) {
|
||||||
setGroupPanelMembers(cached.members)
|
const cachedMembers = normalizeGroupPanelMembers(
|
||||||
|
cached.members,
|
||||||
|
{ messageCountStatus: cached.includeMessageCounts ? 'ready' : 'loading' }
|
||||||
|
)
|
||||||
|
setGroupPanelMembers(cachedMembers)
|
||||||
if (cached.includeMessageCounts) {
|
if (cached.includeMessageCounts) {
|
||||||
syncGroupMyMessagesFromMembers(chatroomId, cached.members)
|
syncGroupMyMessagesFromMembers(chatroomId, cachedMembers)
|
||||||
}
|
}
|
||||||
setGroupMembersError(null)
|
setGroupMembersError(null)
|
||||||
setGroupMembersLoadingHint('')
|
setGroupMembersLoadingHint('')
|
||||||
@@ -1368,9 +1404,13 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
|
|
||||||
setGroupMembersError(null)
|
setGroupMembersError(null)
|
||||||
if (hasCachedMembers && cached) {
|
if (hasCachedMembers && cached) {
|
||||||
setGroupPanelMembers(cached.members)
|
const cachedMembers = normalizeGroupPanelMembers(
|
||||||
|
cached.members,
|
||||||
|
{ messageCountStatus: cached.includeMessageCounts ? 'ready' : 'loading' }
|
||||||
|
)
|
||||||
|
setGroupPanelMembers(cachedMembers)
|
||||||
if (cached.includeMessageCounts) {
|
if (cached.includeMessageCounts) {
|
||||||
syncGroupMyMessagesFromMembers(chatroomId, cached.members)
|
syncGroupMyMessagesFromMembers(chatroomId, cachedMembers)
|
||||||
}
|
}
|
||||||
setIsRefreshingGroupMembers(true)
|
setIsRefreshingGroupMembers(true)
|
||||||
setGroupMembersLoadingHint('')
|
setGroupMembersLoadingHint('')
|
||||||
@@ -1402,7 +1442,10 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const members = normalizeGroupPanelMembers(membersResult.data as GroupPanelMember[])
|
const members = normalizeGroupPanelMembers(
|
||||||
|
membersResult.data as GroupPanelMember[],
|
||||||
|
{ messageCountStatus: 'loading' }
|
||||||
|
)
|
||||||
setGroupPanelMembers(members)
|
setGroupPanelMembers(members)
|
||||||
setGroupMembersError(null)
|
setGroupMembersError(null)
|
||||||
updateGroupMembersPanelCache(chatroomId, members, false)
|
updateGroupMembersPanelCache(chatroomId, members, false)
|
||||||
@@ -3831,7 +3874,13 @@ function ChatPage(props: ChatPageProps) {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span className="group-member-count">{member.messageCount.toLocaleString()} 条</span>
|
<span className={`group-member-count ${member.messageCountStatus}`}>
|
||||||
|
{member.messageCountStatus === 'loading'
|
||||||
|
? '统计中'
|
||||||
|
: member.messageCountStatus === 'failed'
|
||||||
|
? '统计失败'
|
||||||
|
: `${member.messageCount.toLocaleString()} 条`}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user