mirror of https://github.com/langgenius/dify.git
refactor code
This commit is contained in:
parent
f4438b0a08
commit
41372168b6
|
|
@ -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<WorkflowProps, 'nodes' | 'edges' | 'viewport'>
|
||||
|
|
@ -37,8 +36,7 @@ const WorkflowMain = ({
|
|||
const lastEmitTimeRef = useRef<number>(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 (
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{ position: 'relative', width: '100%', height: '100%' }}
|
||||
className="relative h-full w-full"
|
||||
>
|
||||
<WorkflowWithInnerContext
|
||||
nodes={nodes}
|
||||
|
|
@ -261,14 +257,10 @@ const WorkflowMain = ({
|
|||
return (
|
||||
<div
|
||||
key={userId}
|
||||
className="pointer-events-none absolute z-[10000] -translate-x-0.5 -translate-y-0.5 transition-all duration-150 ease-out"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: cursor.x,
|
||||
top: cursor.y,
|
||||
pointerEvents: 'none',
|
||||
zIndex: 10000,
|
||||
transform: 'translate(-2px, -2px)',
|
||||
transition: 'left 0.15s ease-out, top 0.15s ease-out',
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
|
|
@ -277,9 +269,7 @@ const WorkflowMain = ({
|
|||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style={{
|
||||
filter: 'drop-shadow(0 2px 4px rgba(0,0,0,0.2))',
|
||||
}}
|
||||
className="drop-shadow-md"
|
||||
>
|
||||
<path
|
||||
d="M3 3L16 8L9 10L7 17L3 3Z"
|
||||
|
|
@ -291,21 +281,9 @@ const WorkflowMain = ({
|
|||
</svg>
|
||||
|
||||
<div
|
||||
className="absolute -top-0.5 left-[18px] max-w-[120px] overflow-hidden text-ellipsis whitespace-nowrap rounded px-1.5 py-0.5 text-[11px] font-medium text-white shadow-sm"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '18px',
|
||||
top: '-2px',
|
||||
backgroundColor: userColor,
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '11px',
|
||||
fontWeight: '500',
|
||||
whiteSpace: 'nowrap',
|
||||
boxShadow: '0 1px 3px rgba(0,0,0,0.2)',
|
||||
maxWidth: '120px',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
}}
|
||||
>
|
||||
{userName}
|
||||
|
|
|
|||
|
|
@ -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<Record<string, any>>({})
|
||||
const [myUserId, setMyUserId] = useState<string | null>(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 }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<typeof connectOnlineUserWebSocket>
|
||||
|
||||
type WebSocketStore = {
|
||||
socket: WebSocketInstance | null
|
||||
isConnected: boolean
|
||||
listeners: Map<string, Set<(data: any) => 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<WebSocketStore>((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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue