From 2a7b4da969cbd38e30f8fda2155f941097022e59 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Fri, 27 Jun 2025 20:02:03 -0700 Subject: [PATCH] fix(reconn): take workflow id from url --- .../[workspaceId]/w/[workflowId]/workflow.tsx | 22 +--------- apps/sim/contexts/socket-context.tsx | 40 +++++++++++++++++++ apps/sim/hooks/use-collaborative-workflow.ts | 11 +++-- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx index 7973c450b3..dc3509a813 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx @@ -122,7 +122,6 @@ const WorkflowContent = React.memo(() => { collaborativeUpdateParentId: updateParentId, isConnected, currentWorkflowId, - joinWorkflow, } = useCollaborativeWorkflow() const { emitSubblockUpdate } = useSocket() const { markAllAsRead } = useNotificationStore() @@ -356,25 +355,8 @@ const WorkflowContent = React.memo(() => { } }, [debouncedAutoLayout]) - // Listen for active workflow changes and join socket room - useEffect(() => { - const handleActiveWorkflowChanged = (event: CustomEvent) => { - const { workflowId } = event.detail - if (workflowId && isConnected) { - logger.info(`Active workflow changed to ${workflowId}, joining socket room`) - joinWorkflow(workflowId) - } - } - - window.addEventListener('active-workflow-changed', handleActiveWorkflowChanged as EventListener) - - return () => { - window.removeEventListener( - 'active-workflow-changed', - handleActiveWorkflowChanged as EventListener - ) - } - }, [isConnected, joinWorkflow]) + // Note: Workflow room joining is now handled automatically by socket connect event based on URL + // This eliminates the need for manual joining when active workflow changes // Note: Workflow initialization now handled by Socket.IO system diff --git a/apps/sim/contexts/socket-context.tsx b/apps/sim/contexts/socket-context.tsx index 05fe41382f..c98d172828 100644 --- a/apps/sim/contexts/socket-context.tsx +++ b/apps/sim/contexts/socket-context.tsx @@ -9,6 +9,7 @@ import { useRef, useState, } from 'react' +import { useParams } from 'next/navigation' import { io, type Socket } from 'socket.io-client' import { createLogger } from '@/lib/logs/console-logger' @@ -85,6 +86,10 @@ export function SocketProvider({ children, user }: SocketProviderProps) { const [currentWorkflowId, setCurrentWorkflowId] = useState(null) const [presenceUsers, setPresenceUsers] = useState([]) + // Get current workflow ID from URL params + const params = useParams() + const urlWorkflowId = params?.workflowId as string | undefined + // Use refs to store event handlers to avoid stale closures const eventHandlers = useRef<{ workflowOperation?: (data: any) => void @@ -169,6 +174,17 @@ export function SocketProvider({ children, user }: SocketProviderProps) { connected: socketInstance.connected, transport: socketInstance.io.engine?.transport?.name, }) + + // Automatically join the current workflow room based on URL + // This handles both initial connections and reconnections + if (urlWorkflowId) { + logger.info(`Joining workflow room after connection: ${urlWorkflowId}`) + socketInstance.emit('join-workflow', { + workflowId: urlWorkflowId, + }) + // Update our internal state to match the URL + setCurrentWorkflowId(urlWorkflowId) + } }) socketInstance.on('disconnect', (reason) => { @@ -214,6 +230,7 @@ export function SocketProvider({ children, user }: SocketProviderProps) { socketId: socketInstance.id, transport: socketInstance.io.engine?.transport?.name, }) + // Note: Workflow rejoining is handled by the 'connect' event which fires for both initial connections and reconnections }) socketInstance.on('reconnect_attempt', (attemptNumber) => { @@ -331,6 +348,29 @@ export function SocketProvider({ children, user }: SocketProviderProps) { } }, [user?.id]) + // Handle workflow room switching when URL changes (for navigation between workflows) + useEffect(() => { + if (!socket || !isConnected || !urlWorkflowId) return + + // If we're already in the correct workflow room, no need to switch + if (currentWorkflowId === urlWorkflowId) return + + logger.info(`URL workflow changed from ${currentWorkflowId} to ${urlWorkflowId}, switching rooms`) + + // Leave current workflow first if we're in one + if (currentWorkflowId) { + logger.info(`Leaving current workflow ${currentWorkflowId} before joining ${urlWorkflowId}`) + socket.emit('leave-workflow') + } + + // Join the new workflow room + logger.info(`Joining workflow room: ${urlWorkflowId}`) + socket.emit('join-workflow', { + workflowId: urlWorkflowId, + }) + setCurrentWorkflowId(urlWorkflowId) + }, [socket, isConnected, urlWorkflowId, currentWorkflowId]) + // Cleanup socket on component unmount useEffect(() => { return () => { diff --git a/apps/sim/hooks/use-collaborative-workflow.ts b/apps/sim/hooks/use-collaborative-workflow.ts index f05111d055..9353e28dae 100644 --- a/apps/sim/hooks/use-collaborative-workflow.ts +++ b/apps/sim/hooks/use-collaborative-workflow.ts @@ -37,10 +37,11 @@ export function useCollaborativeWorkflow() { // Track last applied position timestamps to prevent out-of-order updates const lastPositionTimestamps = useRef>(new Map()) - // Join workflow room when active workflow changes + // Clear position timestamps when switching workflows + // Note: Workflow joining is now handled automatically by socket connect event based on URL useEffect(() => { - if (activeWorkflowId && isConnected && currentWorkflowId !== activeWorkflowId) { - logger.info(`Joining workflow room: ${activeWorkflowId}`, { + if (activeWorkflowId && currentWorkflowId !== activeWorkflowId) { + logger.info(`Active workflow changed to: ${activeWorkflowId}`, { isConnected, currentWorkflowId, activeWorkflowId, @@ -49,10 +50,8 @@ export function useCollaborativeWorkflow() { // Clear position timestamps when switching workflows lastPositionTimestamps.current.clear() - - joinWorkflow(activeWorkflowId) } - }, [activeWorkflowId, isConnected, currentWorkflowId, joinWorkflow]) + }, [activeWorkflowId, isConnected, currentWorkflowId]) // Log connection status changes useEffect(() => {