From 41372168b6e4a7aea0ee0d8cd4fb0ee41aded53e Mon Sep 17 00:00:00 2001 From: hjlarry Date: Wed, 23 Jul 2025 10:04:16 +0800 Subject: [PATCH] refactor code --- .../workflow-app/components/workflow-main.tsx | 38 +++-------- .../hooks/use-workflow-websocket.ts | 46 ++++++------- .../workflow/store/websocket-store.ts | 68 ++++++++----------- web/service/demo/online-user.ts | 4 -- 4 files changed, 59 insertions(+), 97 deletions(-) diff --git a/web/app/components/workflow-app/components/workflow-main.tsx b/web/app/components/workflow-app/components/workflow-main.tsx index 5ed4b1b627..ab23bb3d95 100644 --- a/web/app/components/workflow-app/components/workflow-main.tsx +++ b/web/app/components/workflow-app/components/workflow-main.tsx @@ -21,7 +21,6 @@ import { import { useStore, useWorkflowStore } from '@/app/components/workflow/store' import { useWebSocketStore } from '@/app/components/workflow/store/websocket-store' import { useCollaborativeCursors } from '../hooks' -import { connectOnlineUserWebSocket } from '@/service/demo/online-user' import type { OnlineUser } from '@/service/demo/online-user' type WorkflowMainProps = Pick @@ -37,8 +36,7 @@ const WorkflowMain = ({ const lastEmitTimeRef = useRef(0) const lastPositionRef = useRef<{ x: number; y: number } | null>(null) - // WebSocket connection for collaboration - const { emit } = useWebSocketStore() + const { emit, getSocket } = useWebSocketStore() const handleWorkflowDataUpdate = useCallback((payload: any) => { const { @@ -61,7 +59,6 @@ const WorkflowMain = ({ } }, [featuresStore, workflowStore]) - // Handle mouse movement for collaboration with throttling (1 second) const handleMouseMove = useCallback((event: MouseEvent) => { if (!containerRef.current) return @@ -74,8 +71,7 @@ const WorkflowMain = ({ const now = Date.now() const timeSinceLastEmit = now - lastEmitTimeRef.current - // Throttle to 1 second (1000ms) - if (timeSinceLastEmit >= 1000) { + if (timeSinceLastEmit >= 300) { lastEmitTimeRef.current = now lastPositionRef.current = { x, y } @@ -84,7 +80,7 @@ const WorkflowMain = ({ y, }) } - else { + else { // Update position for potential future emit lastPositionRef.current = { x, y } } @@ -126,7 +122,7 @@ const WorkflowMain = ({ useEffect(() => { if (!appId) return - const socket = connectOnlineUserWebSocket(appId) + const socket = getSocket(appId) const handleOnlineUsersUpdate = (data: { users: OnlineUser[] }) => { const usersMap = data.users.reduce((acc, user) => { @@ -227,7 +223,7 @@ const WorkflowMain = ({ return (
{userName} diff --git a/web/app/components/workflow-app/hooks/use-workflow-websocket.ts b/web/app/components/workflow-app/hooks/use-workflow-websocket.ts index c615c2a4db..31afe1b9d8 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-websocket.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-websocket.ts @@ -2,47 +2,43 @@ import { useEffect, useState } from 'react' import { useWebSocketStore } from '@/app/components/workflow/store/websocket-store' export function useCollaborativeCursors(appId: string) { - const { on, connect, disconnect } = useWebSocketStore() const [cursors, setCursors] = useState>({}) const [myUserId, setMyUserId] = useState(null) + const { getSocket, on } = useWebSocketStore() useEffect(() => { if (!appId) return - connect(appId) - return () => { - disconnect() + const socket = getSocket(appId) + + const handleConnect = () => { + setMyUserId(socket.id || 'unknown') } - }, [appId, connect, disconnect]) - useEffect(() => { - const unsubscribe = on('mouseMove', (update) => { - const userId = update.userId || update.user_id - const data = update.data || update - - if (userId && data) { + const unsubscribeMouseMove = on('mouseMove', (update: any) => { + if (update.userId !== myUserId) { setCursors(prev => ({ ...prev, - [userId]: { - x: data.x, - y: data.y, - userId, + [update.userId]: { + x: update.data.x, + y: update.data.y, + userId: update.userId, + timestamp: update.timestamp, }, })) } }) - return unsubscribe - }, [on]) + if (socket.connected) + handleConnect() + else + socket.on('connect', handleConnect) - useEffect(() => { - const unsubscribe = on('connected', (data) => { - if (data.userId || data.user_id) - setMyUserId(data.userId || data.user_id) - }) - - return unsubscribe - }, [on]) + return () => { + unsubscribeMouseMove() + socket.off('connect', handleConnect) + } + }, [appId, getSocket, on, myUserId]) return { cursors, myUserId } } diff --git a/web/app/components/workflow/store/websocket-store.ts b/web/app/components/workflow/store/websocket-store.ts index f6288e6603..41fd594d8e 100644 --- a/web/app/components/workflow/store/websocket-store.ts +++ b/web/app/components/workflow/store/websocket-store.ts @@ -1,63 +1,55 @@ import { create } from 'zustand' -import { connectOnlineUserWebSocket, disconnectOnlineUserWebSocket } from '@/service/demo/online-user' +import { connectOnlineUserWebSocket } from '@/service/demo/online-user' type WebSocketInstance = ReturnType type WebSocketStore = { socket: WebSocketInstance | null - isConnected: boolean listeners: Map void>> - // Actions - connect: (appId: string) => void - disconnect: () => void + isConnected: () => boolean + getSocket: (appId: string) => WebSocketInstance emit: (eventType: string, data: any) => void on: (eventType: string, handler: (data: any) => void) => () => void } export const useWebSocketStore = create((set, get) => ({ socket: null, - isConnected: false, listeners: new Map(), - connect: (appId: string) => { - const socket = connectOnlineUserWebSocket(appId) - - socket.on('collaboration_update', (update: { - type: string - userId: string - data: any - timestamp: number - }) => { - const { listeners } = get() - const eventListeners = listeners.get(update.type) - if (eventListeners) { - eventListeners.forEach((handler) => { - try { - handler(update) - } - catch (error) { - console.error(`Error in collaboration event handler for ${update.type}:`, error) - } - }) - } - }) - - set({ socket, isConnected: true }) + isConnected: () => { + const { socket } = get() + return socket?.connected || false }, - disconnect: () => { - const { socket } = get() - if (socket) { - socket.off('collaboration_update') - disconnectOnlineUserWebSocket() + getSocket: (appId: string) => { + let { socket } = get() + if (!socket) { + socket = connectOnlineUserWebSocket(appId) + + socket.on('collaboration_update', (update) => { + const { listeners } = get() + const eventListeners = listeners.get(update.type) + if (eventListeners) { + eventListeners.forEach((handler) => { + try { + handler(update) + } + catch (error) { + console.error(`Error in collaboration event handler for ${update.type}:`, error) + } + }) + } + }) + + set({ socket }) } - set({ socket: null, isConnected: false, listeners: new Map() }) + return socket }, emit: (eventType: string, data: any) => { - const { socket, isConnected } = get() - if (socket && isConnected) { + const { socket } = get() + if (socket?.connected) { socket.emit('collaboration_event', { type: eventType, data, diff --git a/web/service/demo/online-user.ts b/web/service/demo/online-user.ts index 50ff7232f5..9d190f982b 100644 --- a/web/service/demo/online-user.ts +++ b/web/service/demo/online-user.ts @@ -34,10 +34,6 @@ export function connectOnlineUserWebSocket(appId: string): Socket { console.log('WebSocket disconnected') }) - socket.on('online_users', (data) => { - console.log('Online users:', data) - }) - socket.on('connect_error', (err) => { console.error('WebSocket connection error:', err) })