mirror of
https://github.com/langgenius/dify.git
synced 2026-05-13 08:57:28 +08:00
refactor(web): remove redundant useUnifiedDrag abstraction layer
Simplify file drop hooks by removing the unnecessary useUnifiedDrag wrapper that became redundant after internal node drag was migrated to react-arborist's built-in system. Now useFolderFileDrop and useRootFileDrop directly use useFileDrop, reducing code complexity and eliminating unused treeChildren prop drilling.
This commit is contained in:
parent
2151676db1
commit
ee91c9d5f1
@ -72,7 +72,7 @@ const FileTree: React.FC<FileTreeProps> = ({ className }) => {
|
|||||||
handleRootDragOver,
|
handleRootDragOver,
|
||||||
handleRootDrop,
|
handleRootDrop,
|
||||||
resetRootDragCounter,
|
resetRootDragCounter,
|
||||||
} = useRootFileDrop({ treeChildren })
|
} = useRootFileDrop()
|
||||||
|
|
||||||
// Root dropzone highlight (when dragging to root, not to a specific folder)
|
// Root dropzone highlight (when dragging to root, not to a specific folder)
|
||||||
const isRootDropzone = dragOverFolderId === ROOT_ID
|
const isRootDropzone = dragOverFolderId === ROOT_ID
|
||||||
@ -200,8 +200,8 @@ const FileTree: React.FC<FileTreeProps> = ({ className }) => {
|
|||||||
}, [treeChildren])
|
}, [treeChildren])
|
||||||
|
|
||||||
const renderTreeNode = useCallback((props: NodeRendererProps<TreeNodeData>) => {
|
const renderTreeNode = useCallback((props: NodeRendererProps<TreeNodeData>) => {
|
||||||
return <TreeNode {...props} treeChildren={treeChildren} />
|
return <TreeNode {...props} />
|
||||||
}, [treeChildren])
|
}, [])
|
||||||
|
|
||||||
useSyncTreeWithActiveTab({
|
useSyncTreeWithActiveTab({
|
||||||
treeRef,
|
treeRef,
|
||||||
|
|||||||
@ -20,11 +20,9 @@ import TreeEditInput from './tree-edit-input'
|
|||||||
import TreeGuideLines from './tree-guide-lines'
|
import TreeGuideLines from './tree-guide-lines'
|
||||||
import { TreeNodeIcon } from './tree-node-icon'
|
import { TreeNodeIcon } from './tree-node-icon'
|
||||||
|
|
||||||
type TreeNodeProps = NodeRendererProps<TreeNodeData> & {
|
type TreeNodeProps = NodeRendererProps<TreeNodeData>
|
||||||
treeChildren: TreeNodeData[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const TreeNode = ({ node, style, dragHandle, treeChildren }: TreeNodeProps) => {
|
const TreeNode = ({ node, style, dragHandle }: TreeNodeProps) => {
|
||||||
const { t } = useTranslation('workflow')
|
const { t } = useTranslation('workflow')
|
||||||
const isFolder = node.data.node_type === 'folder'
|
const isFolder = node.data.node_type === 'folder'
|
||||||
const isSelected = node.isSelected
|
const isSelected = node.isSelected
|
||||||
@ -77,7 +75,7 @@ const TreeNode = ({ node, style, dragHandle, treeChildren }: TreeNodeProps) => {
|
|||||||
} = useTreeNodeHandlers({ node })
|
} = useTreeNodeHandlers({ node })
|
||||||
|
|
||||||
// Get file drop visual state (for external file uploads)
|
// Get file drop visual state (for external file uploads)
|
||||||
const { isDragOver: isFileDragOver, isBlinking, dragHandlers } = useFolderFileDrop({ node, treeChildren })
|
const { isDragOver: isFileDragOver, isBlinking, dragHandlers } = useFolderFileDrop({ node })
|
||||||
|
|
||||||
// Combine internal drag target (willReceiveDrop) with external file drag (isFileDragOver)
|
// Combine internal drag target (willReceiveDrop) with external file drag (isFileDragOver)
|
||||||
const isDragOver = isFileDragOver || (isFolder && node.willReceiveDrop)
|
const isDragOver = isFileDragOver || (isFolder && node.willReceiveDrop)
|
||||||
|
|||||||
@ -4,11 +4,10 @@
|
|||||||
|
|
||||||
import type { NodeApi } from 'react-arborist'
|
import type { NodeApi } from 'react-arborist'
|
||||||
import type { TreeNodeData } from '../type'
|
import type { TreeNodeData } from '../type'
|
||||||
import type { AppAssetTreeView } from '@/types/app-asset'
|
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { useStore } from '@/app/components/workflow/store'
|
import { useStore } from '@/app/components/workflow/store'
|
||||||
import { isDragEvent } from '../utils/drag-utils'
|
import { isFileDrag } from '../utils/drag-utils'
|
||||||
import { useUnifiedDrag } from './use-unified-drag'
|
import { useFileDrop } from './use-file-drop'
|
||||||
|
|
||||||
type UseFolderFileDropReturn = {
|
type UseFolderFileDropReturn = {
|
||||||
isDragOver: boolean
|
isDragOver: boolean
|
||||||
@ -27,15 +26,14 @@ const AUTO_EXPAND_DELAY_MS = 2000
|
|||||||
|
|
||||||
type UseFolderFileDropOptions = {
|
type UseFolderFileDropOptions = {
|
||||||
node: NodeApi<TreeNodeData>
|
node: NodeApi<TreeNodeData>
|
||||||
treeChildren: AppAssetTreeView[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useFolderFileDrop({ node, treeChildren: _treeChildren }: UseFolderFileDropOptions): UseFolderFileDropReturn {
|
export function useFolderFileDrop({ node }: UseFolderFileDropOptions): UseFolderFileDropReturn {
|
||||||
const isFolder = node.data.node_type === 'folder'
|
const isFolder = node.data.node_type === 'folder'
|
||||||
const dragOverFolderId = useStore(s => s.dragOverFolderId)
|
const dragOverFolderId = useStore(s => s.dragOverFolderId)
|
||||||
const isDragOver = isFolder && dragOverFolderId === node.data.id
|
const isDragOver = isFolder && dragOverFolderId === node.data.id
|
||||||
|
|
||||||
const { handleDragOver, handleDrop } = useUnifiedDrag()
|
const { handleDragOver, handleDrop } = useFileDrop()
|
||||||
|
|
||||||
const expandTimerRef = useRef<NodeJS.Timeout | null>(null)
|
const expandTimerRef = useRef<NodeJS.Timeout | null>(null)
|
||||||
const blinkTimerRef = useRef<NodeJS.Timeout | null>(null)
|
const blinkTimerRef = useRef<NodeJS.Timeout | null>(null)
|
||||||
@ -86,7 +84,7 @@ export function useFolderFileDrop({ node, treeChildren: _treeChildren }: UseFold
|
|||||||
}, [clearExpandTimer])
|
}, [clearExpandTimer])
|
||||||
|
|
||||||
const handleFolderDragEnter = useCallback((e: React.DragEvent) => {
|
const handleFolderDragEnter = useCallback((e: React.DragEvent) => {
|
||||||
if (!isFolder || !isDragEvent(e))
|
if (!isFolder || !isFileDrag(e))
|
||||||
return
|
return
|
||||||
dragCounterRef.current += 1
|
dragCounterRef.current += 1
|
||||||
if (dragCounterRef.current === 1)
|
if (dragCounterRef.current === 1)
|
||||||
@ -94,13 +92,13 @@ export function useFolderFileDrop({ node, treeChildren: _treeChildren }: UseFold
|
|||||||
}, [isFolder, scheduleAutoExpand])
|
}, [isFolder, scheduleAutoExpand])
|
||||||
|
|
||||||
const handleFolderDragOver = useCallback((e: React.DragEvent) => {
|
const handleFolderDragOver = useCallback((e: React.DragEvent) => {
|
||||||
if (!isFolder || !isDragEvent(e))
|
if (!isFolder || !isFileDrag(e))
|
||||||
return
|
return
|
||||||
handleDragOver(e, { folderId: node.data.id, isFolder: true })
|
handleDragOver(e, { folderId: node.data.id, isFolder: true })
|
||||||
}, [handleDragOver, isFolder, node.data.id])
|
}, [handleDragOver, isFolder, node.data.id])
|
||||||
|
|
||||||
const handleFolderDragLeave = useCallback((e: React.DragEvent) => {
|
const handleFolderDragLeave = useCallback((e: React.DragEvent) => {
|
||||||
if (!isFolder || !isDragEvent(e))
|
if (!isFolder || !isFileDrag(e))
|
||||||
return
|
return
|
||||||
dragCounterRef.current = Math.max(dragCounterRef.current - 1, 0)
|
dragCounterRef.current = Math.max(dragCounterRef.current - 1, 0)
|
||||||
if (dragCounterRef.current === 0)
|
if (dragCounterRef.current === 0)
|
||||||
|
|||||||
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
// Root-level file drop handler with drag counter to handle nested DOM events
|
// Root-level file drop handler with drag counter to handle nested DOM events
|
||||||
|
|
||||||
import type { AppAssetTreeView } from '@/types/app-asset'
|
|
||||||
import { useCallback, useRef } from 'react'
|
import { useCallback, useRef } from 'react'
|
||||||
import { isDragEvent } from '../utils/drag-utils'
|
import { isFileDrag } from '../utils/drag-utils'
|
||||||
import { useUnifiedDrag } from './use-unified-drag'
|
import { useFileDrop } from './use-file-drop'
|
||||||
|
|
||||||
type UseRootFileDropReturn = {
|
type UseRootFileDropReturn = {
|
||||||
handleRootDragEnter: (e: React.DragEvent) => void
|
handleRootDragEnter: (e: React.DragEvent) => void
|
||||||
@ -15,16 +14,12 @@ type UseRootFileDropReturn = {
|
|||||||
resetRootDragCounter: () => void
|
resetRootDragCounter: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type UseRootFileDropOptions = {
|
export function useRootFileDrop(): UseRootFileDropReturn {
|
||||||
treeChildren: AppAssetTreeView[]
|
const { handleDragOver, handleDragLeave, handleDrop } = useFileDrop()
|
||||||
}
|
|
||||||
|
|
||||||
export function useRootFileDrop({ treeChildren: _treeChildren }: UseRootFileDropOptions): UseRootFileDropReturn {
|
|
||||||
const { handleDragOver, handleDragLeave, handleDrop } = useUnifiedDrag()
|
|
||||||
const dragCounterRef = useRef(0)
|
const dragCounterRef = useRef(0)
|
||||||
|
|
||||||
const handleRootDragEnter = useCallback((e: React.DragEvent) => {
|
const handleRootDragEnter = useCallback((e: React.DragEvent) => {
|
||||||
if (!isDragEvent(e))
|
if (!isFileDrag(e))
|
||||||
return
|
return
|
||||||
dragCounterRef.current += 1
|
dragCounterRef.current += 1
|
||||||
}, [])
|
}, [])
|
||||||
@ -34,7 +29,7 @@ export function useRootFileDrop({ treeChildren: _treeChildren }: UseRootFileDrop
|
|||||||
}, [handleDragOver])
|
}, [handleDragOver])
|
||||||
|
|
||||||
const handleRootDragLeave = useCallback((e: React.DragEvent) => {
|
const handleRootDragLeave = useCallback((e: React.DragEvent) => {
|
||||||
if (!isDragEvent(e))
|
if (!isFileDrag(e))
|
||||||
return
|
return
|
||||||
dragCounterRef.current = Math.max(dragCounterRef.current - 1, 0)
|
dragCounterRef.current = Math.max(dragCounterRef.current - 1, 0)
|
||||||
if (dragCounterRef.current === 0)
|
if (dragCounterRef.current === 0)
|
||||||
|
|||||||
@ -1,40 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
// Unified drag handler for external file uploads
|
|
||||||
// Internal node drag-move is now handled by react-arborist's built-in drag system
|
|
||||||
|
|
||||||
import { useCallback } from 'react'
|
|
||||||
import { isFileDrag } from '../utils/drag-utils'
|
|
||||||
import { useFileDrop } from './use-file-drop'
|
|
||||||
|
|
||||||
type DragTarget = {
|
|
||||||
folderId: string | null
|
|
||||||
isFolder: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useUnifiedDrag() {
|
|
||||||
const fileDrop = useFileDrop()
|
|
||||||
|
|
||||||
// Only handle external file drags - internal node drags are handled by react-arborist
|
|
||||||
const handleDragOver = useCallback((e: React.DragEvent, target: DragTarget) => {
|
|
||||||
if (isFileDrag(e))
|
|
||||||
fileDrop.handleDragOver(e, target)
|
|
||||||
}, [fileDrop])
|
|
||||||
|
|
||||||
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
|
||||||
if (isFileDrag(e))
|
|
||||||
fileDrop.handleDragLeave(e)
|
|
||||||
}, [fileDrop])
|
|
||||||
|
|
||||||
const handleDrop = useCallback((e: React.DragEvent, targetFolderId: string | null) => {
|
|
||||||
if (isFileDrag(e))
|
|
||||||
return fileDrop.handleDrop(e, targetFolderId)
|
|
||||||
}, [fileDrop])
|
|
||||||
|
|
||||||
return {
|
|
||||||
handleDragOver,
|
|
||||||
handleDragLeave,
|
|
||||||
handleDrop,
|
|
||||||
isUploading: fileDrop.isUploading,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user