Update FileManager.vue
This commit is contained in:
@@ -400,60 +400,68 @@ const SCROLL_SPEED = 10; // px per interval,基础滚动速度
|
|||||||
const handleDragOver = (event: DragEvent) => {
|
const handleDragOver = (event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const isExternalFileDrag = event.dataTransfer?.types.includes('Files') ?? false;
|
const isExternalFileDrag = event.dataTransfer?.types.includes('Files') ?? false;
|
||||||
const isInternalDrag = !!draggedItem.value;
|
const isInternalDrag = !!draggedItem.value; // Check if an internal item is being dragged
|
||||||
|
|
||||||
// --- Determine Drop Effect ---
|
|
||||||
let effect: 'copy' | 'move' | 'none' = 'none';
|
let effect: 'copy' | 'move' | 'none' = 'none';
|
||||||
let currentTargetFilename: string | null = null;
|
let currentTargetFilename: string | null = null;
|
||||||
|
let highlightContainer = false; // Flag to control container highlighting
|
||||||
|
|
||||||
const targetElement = event.target as HTMLElement;
|
const targetElement = event.target as HTMLElement;
|
||||||
const targetRow = targetElement.closest('tr.file-row'); // Find closest row (folder or file)
|
const targetRow = targetElement.closest('tr.file-row');
|
||||||
// Safely access dataset only if targetRow is an HTMLElement
|
|
||||||
const targetFilename = (targetRow instanceof HTMLElement) ? targetRow.dataset.filename : undefined;
|
const targetFilename = (targetRow instanceof HTMLElement) ? targetRow.dataset.filename : undefined;
|
||||||
const targetIsFolder = targetRow?.classList.contains('folder-row');
|
const targetIsFolder = targetRow?.classList.contains('folder-row');
|
||||||
|
|
||||||
if (props.wsDeps.isConnected.value && isExternalFileDrag) {
|
if (props.wsDeps.isConnected.value) {
|
||||||
|
if (isExternalFileDrag) {
|
||||||
// External Drag (Upload)
|
// External Drag (Upload)
|
||||||
|
effect = 'copy'; // Always allow copy for external files
|
||||||
|
highlightContainer = true; // Highlight the container
|
||||||
|
|
||||||
|
// Determine the specific target folder for potential drop and row highlighting
|
||||||
if (targetIsFolder && targetFilename && targetFilename !== '..') {
|
if (targetIsFolder && targetFilename && targetFilename !== '..') {
|
||||||
effect = 'copy'; // Allow dropping into subfolders
|
currentTargetFilename = targetFilename; // Target is a subfolder row
|
||||||
currentTargetFilename = targetFilename;
|
|
||||||
} else if (!targetRow) {
|
|
||||||
effect = 'copy'; // Allow dropping into the main container area (current path)
|
|
||||||
currentTargetFilename = null; // No specific target row
|
|
||||||
} else {
|
} else {
|
||||||
effect = 'none'; // Don't allow dropping external files onto file rows or '..'
|
currentTargetFilename = null; // Target is the current directory (or invalid row)
|
||||||
currentTargetFilename = null;
|
|
||||||
}
|
}
|
||||||
isDraggingOver.value = (effect === 'copy'); // Set general drag-over state if allowed
|
|
||||||
|
|
||||||
} else if (isInternalDrag && draggedItem.value) {
|
} else if (isInternalDrag && draggedItem.value) {
|
||||||
// Internal Drag (Move)
|
// Internal Drag (Move)
|
||||||
|
highlightContainer = false; // Do not highlight the container for internal moves
|
||||||
|
|
||||||
if (targetIsFolder && targetFilename && targetFilename !== draggedItem.value.filename) {
|
if (targetIsFolder && targetFilename && targetFilename !== draggedItem.value.filename) {
|
||||||
// Allow dropping onto any folder row (including '..') except itself
|
// Allow dropping onto any folder row (including '..') except itself
|
||||||
effect = 'move';
|
effect = 'move';
|
||||||
currentTargetFilename = targetFilename;
|
currentTargetFilename = targetFilename; // Target is the specific folder row
|
||||||
} else {
|
} else {
|
||||||
|
// Invalid target for internal move
|
||||||
effect = 'none';
|
effect = 'none';
|
||||||
currentTargetFilename = null;
|
currentTargetFilename = null;
|
||||||
}
|
}
|
||||||
isDraggingOver.value = false; // Don't use general drag-over for internal moves
|
} else {
|
||||||
|
// Other drag types
|
||||||
|
effect = 'none';
|
||||||
|
currentTargetFilename = null;
|
||||||
|
highlightContainer = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not connected
|
||||||
|
effect = 'none';
|
||||||
|
currentTargetFilename = null;
|
||||||
|
highlightContainer = false;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// Other drag types or not connected
|
|
||||||
effect = 'none';
|
|
||||||
currentTargetFilename = null;
|
|
||||||
isDraggingOver.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Apply Drop Effect and Target Highlighting ---
|
// --- Apply Drop Effect and Target Highlighting ---
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.dropEffect = effect;
|
event.dataTransfer.dropEffect = effect;
|
||||||
}
|
}
|
||||||
|
isDraggingOver.value = highlightContainer; // Control container highlight based on flag
|
||||||
dragOverTarget.value = currentTargetFilename; // Set specific row target for highlighting
|
dragOverTarget.value = currentTargetFilename; // Set specific row target for highlighting
|
||||||
|
|
||||||
// --- 处理自动滚动 ---
|
// --- 处理自动滚动 ---
|
||||||
const container = fileListContainerRef.value;
|
const container = fileListContainerRef.value;
|
||||||
if (container && (isExternalFileDrag || draggedItem.value)) { // 仅在有效拖拽时处理滚动
|
// 仅在有效拖拽 (外部文件或内部文件) 且效果不是 'none' 时处理滚动
|
||||||
|
if (container && (isExternalFileDrag || isInternalDrag) && effect !== 'none') {
|
||||||
const rect = container.getBoundingClientRect();
|
const rect = container.getBoundingClientRect();
|
||||||
const mouseY = event.clientY - rect.top; // 鼠标在容器内的 Y 坐标
|
const mouseY = event.clientY - rect.top; // 鼠标在容器内的 Y 坐标
|
||||||
|
|
||||||
@@ -489,7 +497,7 @@ const handleDragOver = (event: DragEvent) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果拖拽无效或容器不存在,确保停止滚动
|
// 如果拖拽无效、效果为 'none' 或容器不存在,确保停止滚动
|
||||||
if (scrollIntervalId.value !== null) {
|
if (scrollIntervalId.value !== null) {
|
||||||
clearInterval(scrollIntervalId.value);
|
clearInterval(scrollIntervalId.value);
|
||||||
scrollIntervalId.value = null;
|
scrollIntervalId.value = null;
|
||||||
@@ -615,14 +623,30 @@ const handleDragLeaveRow = (targetItem: FileListItem) => {
|
|||||||
|
|
||||||
const handleDropOnRow = (targetItem: FileListItem, event: DragEvent) => {
|
const handleDropOnRow = (targetItem: FileListItem, event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation(); // 阻止事件冒泡到父容器的 drop 处理
|
// 检查是否是外部文件拖拽
|
||||||
|
const files = event.dataTransfer?.files;
|
||||||
|
if (files && files.length > 0) {
|
||||||
|
// 如果是外部文件拖拽,不阻止冒泡,让父容器的 handleDrop 处理上传
|
||||||
|
console.log(`[FileManager ${props.sessionId}] External file drop detected on row, letting parent handle.`);
|
||||||
|
// 不需要清除 draggedItem.value,因为外部拖拽时它应该为 null
|
||||||
|
// dragOverTarget.value = null; // 清除悬停状态 (父容器 handleDrop 会处理)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- 以下是处理内部文件移动的逻辑 ---
|
||||||
|
event.stopPropagation(); // 仅在处理内部移动时阻止冒泡
|
||||||
const sourceItem = draggedItem.value;
|
const sourceItem = draggedItem.value;
|
||||||
dragOverTarget.value = null; // 清除悬停状态
|
dragOverTarget.value = null; // 清除悬停状态
|
||||||
|
|
||||||
// 验证拖放操作的有效性 (与之前相同)
|
// 验证内部拖放操作的有效性
|
||||||
|
// 注意:这里的 !sourceItem 检查现在只会在非外部文件拖拽时发生,
|
||||||
|
// 如果 sourceItem 仍然是 null,说明不是有效的内部拖拽。
|
||||||
if (!sourceItem || sourceItem.filename === '..' || (targetItem.filename !== '..' && !targetItem.attrs.isDirectory) || sourceItem.filename === targetItem.filename) {
|
if (!sourceItem || sourceItem.filename === '..' || (targetItem.filename !== '..' && !targetItem.attrs.isDirectory) || sourceItem.filename === targetItem.filename) {
|
||||||
console.log(`[FileManager ${props.sessionId}] Drop on row ignored: Invalid target or source. Source: ${sourceItem?.filename}, Target: ${targetItem.filename}`);
|
console.log(`[FileManager ${props.sessionId}] Internal drop on row ignored: Invalid target or source. Source: ${sourceItem?.filename}, Target: ${targetItem.filename}`);
|
||||||
|
// 如果 sourceItem 存在但无效,才需要清除
|
||||||
|
if (sourceItem) {
|
||||||
draggedItem.value = null;
|
draggedItem.value = null;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1682,3 +1706,4 @@ td:nth-child(5) { /* Modified */
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user