fix(presence): remove presence for a solo user (#1779)

This commit is contained in:
Waleed
2025-10-30 22:47:37 -07:00
committed by GitHub
parent 4a3c6d17e3
commit 6cd82f07ed
3 changed files with 15 additions and 20 deletions

View File

@@ -26,7 +26,6 @@ export function UserAvatar({
}: AvatarProps) {
const { gradient } = useMemo(() => getPresenceColors(connectionId, color), [connectionId, color])
// Determine avatar size
const sizeClass = {
sm: 'h-5 w-5 text-[10px]',
md: 'h-7 w-7 text-xs',
@@ -49,7 +48,7 @@ export function UserAvatar({
style={
{
background: hasAvatar ? undefined : gradient,
zIndex: 10 - index, // Higher index = lower z-index for stacking effect
zIndex: 10 - index,
} as CSSProperties
}
>
@@ -69,7 +68,6 @@ export function UserAvatar({
</div>
)
// If tooltip content is provided, wrap in tooltip
if (tooltipContent) {
return (
<Tooltip>

View File

@@ -1,9 +1,9 @@
'use client'
import { useMemo } from 'react'
import { useSession } from '@/lib/auth-client'
import { useSocket } from '@/contexts/socket-context'
// Socket presence user from server
interface SocketPresenceUser {
socketId: string
userId: string
@@ -13,7 +13,6 @@ interface SocketPresenceUser {
selection?: { type: 'block' | 'edge' | 'none'; id?: string }
}
// UI presence user for components
type PresenceUser = {
connectionId: string | number
name?: string
@@ -31,28 +30,30 @@ interface UsePresenceReturn {
/**
* Hook for managing user presence in collaborative workflows using Socket.IO
* Uses the existing Socket context to get real presence data
* Filters out the current user so only other collaborators are shown
*/
export function usePresence(): UsePresenceReturn {
const { presenceUsers, isConnected } = useSocket()
const { data: session } = useSession()
const currentUserId = session?.user?.id
const users = useMemo(() => {
// Deduplicate by userId - only show one presence per unique user
const uniqueUsers = new Map<string, SocketPresenceUser>()
presenceUsers.forEach((user) => {
// Keep the most recent presence for each user (last one wins)
uniqueUsers.set(user.userId, user)
})
return Array.from(uniqueUsers.values()).map((user) => ({
// Use userId as connectionId since we've deduplicated
connectionId: user.userId,
name: user.userName,
color: undefined, // Let the avatar component generate colors
info: user.selection?.type ? `Editing ${user.selection.type}` : undefined,
avatarUrl: user.avatarUrl,
}))
}, [presenceUsers])
return Array.from(uniqueUsers.values())
.filter((user) => user.userId !== currentUserId)
.map((user) => ({
connectionId: user.userId,
name: user.userName,
color: undefined,
info: user.selection?.type ? `Editing ${user.selection.type}` : undefined,
avatarUrl: user.avatarUrl,
}))
}, [presenceUsers, currentUserId])
return {
users,

View File

@@ -63,13 +63,11 @@ export function setupWorkflowHandlers(
return
}
// Ensure user only joins one workflow at a time
const currentWorkflowId = roomManager.getWorkflowIdForSocket(socket.id)
if (currentWorkflowId) {
socket.leave(currentWorkflowId)
roomManager.cleanupUserFromRoom(socket.id, currentWorkflowId)
// Broadcast updated presence list to all remaining users
roomManager.broadcastPresenceUpdate(currentWorkflowId)
}
@@ -119,7 +117,6 @@ export function setupWorkflowHandlers(
const workflowState = await getWorkflowState(workflowId)
socket.emit('workflow-state', workflowState)
// Broadcast updated presence list to all users in the room
roomManager.broadcastPresenceUpdate(workflowId)
const uniqueUserCount = roomManager.getUniqueUserCount(workflowId)
@@ -166,7 +163,6 @@ export function setupWorkflowHandlers(
socket.leave(workflowId)
roomManager.cleanupUserFromRoom(socket.id, workflowId)
// Broadcast updated presence list to all remaining users
roomManager.broadcastPresenceUpdate(workflowId)
logger.info(`User ${session.userId} (${session.userName}) left workflow ${workflowId}`)