!isRenaming && handleNodeClick(node, e)}
onDoubleClick={() => !isRenaming && handleNodeDoubleClick(node)}
onContextMenu={(e) => handleContextMenu(e, node)}
draggable={node.type === 'file' && !isRenaming}
onDragStart={(e) => {
if (node.type === 'file' && !isRenaming) {
e.dataTransfer.effectAllowed = 'copy';
// Get all selected files for multi-file drag
const selectedFiles = selectedPaths && selectedPaths.has(node.path) && selectedPaths.size > 1
? Array.from(selectedPaths).map((p) => {
const name = p.split(/[/\\]/).pop() || '';
const ext = name.includes('.') ? name.split('.').pop() : '';
return { type: 'file', path: p, name, extension: ext };
})
: [{
type: 'file',
path: node.path,
name: node.name,
extension: node.name.includes('.') ? node.name.split('.').pop() : ''
}];
// Set drag data as JSON array for multi-file support
e.dataTransfer.setData('application/json', JSON.stringify(selectedFiles));
e.dataTransfer.setData('asset-path', node.path);
e.dataTransfer.setData('asset-name', node.name);
const ext = node.name.includes('.') ? node.name.split('.').pop() : '';
e.dataTransfer.setData('asset-extension', ext || '');
e.dataTransfer.setData('text/plain', node.path);
// Add GUID for new asset reference system
const assetRegistry = Core.services.tryResolve(AssetRegistryService) as AssetRegistryService | null;
if (assetRegistry) {
// Convert absolute path to relative path for GUID lookup
const relativePath = assetRegistry.absoluteToRelative(node.path);
if (relativePath) {
const guid = assetRegistry.getGuidByPath(relativePath);
if (guid) {
e.dataTransfer.setData('asset-guid', guid);
}
}
}
// 添加视觉反馈
e.currentTarget.style.opacity = '0.5';
}
}}
onDragEnd={(e) => {
// 恢复透明度
e.currentTarget.style.opacity = '1';
}}
>
{node.type === 'folder' ? (
node.expanded ? :
) : (
)}
{node.type === 'folder' ? (
node.name.toLowerCase() === 'plugins' || node.name.toLowerCase() === '.ecs' ? (
) : (
)
) : (
)}
{isRenaming ? (
setNewName(e.target.value)}
onBlur={() => handleRename(node)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleRename(node);
} else if (e.key === 'Escape') {
setRenamingNode(null);
}
}}
autoFocus
onClick={(e) => e.stopPropagation()}
/>
) : (
{node.name}
)}
{node.type === 'folder' && node.expanded && node.children && (
{node.children.map((child) => renderNode(child, level + 1))}
)}
);
};
if (loading) {
return Loading...
;
}
if (!rootPath || tree.length === 0) {
return {
const target = e.target as HTMLElement;
if (target.classList.contains('file-tree')) {
handleContextMenu(e, null);
}
}}
>
{filteredTree.map((node) => renderNode(node))}
{contextMenu && (