update
This commit is contained in:
@@ -617,14 +617,16 @@ const {
|
|||||||
|
|
||||||
// --- 拖放逻辑 (使用 Composable) ---
|
// --- 拖放逻辑 (使用 Composable) ---
|
||||||
const {
|
const {
|
||||||
isDraggingOver, // 容器拖拽悬停状态 (外部文件)
|
// isDraggingOver, // 不再直接使用容器的悬停状态
|
||||||
dragOverTarget, // 行拖拽悬停目标 (内部/外部)
|
showExternalDropOverlay, // 新增:控制蒙版显示
|
||||||
|
dragOverTarget, // 行拖拽悬停目标 (内部)
|
||||||
// draggedItem, // 内部状态,不需要在 FileManager 中直接使用
|
// draggedItem, // 内部状态,不需要在 FileManager 中直接使用
|
||||||
// --- 事件处理器 ---
|
// --- 事件处理器 ---
|
||||||
handleDragEnter,
|
handleDragEnter,
|
||||||
handleDragOver,
|
handleDragOver, // 容器的 dragover (主要处理内部滚动)
|
||||||
handleDragLeave,
|
handleDragLeave,
|
||||||
handleDrop,
|
handleDrop, // 容器的 drop (主要用于清理)
|
||||||
|
handleOverlayDrop, // 新增:蒙版的 drop
|
||||||
handleDragStart,
|
handleDragStart,
|
||||||
handleDragEnd,
|
handleDragEnd,
|
||||||
handleDragOverRow,
|
handleDragOverRow,
|
||||||
@@ -1260,9 +1262,6 @@ defineExpose({ focusSearchInput, startPathEdit });
|
|||||||
<div
|
<div
|
||||||
ref="fileListContainerRef"
|
ref="fileListContainerRef"
|
||||||
class="flex-grow overflow-y-auto relative outline-none"
|
class="flex-grow overflow-y-auto relative outline-none"
|
||||||
:class="{
|
|
||||||
'outline-dashed outline-2 outline-offset-[-2px] outline-primary bg-primary/5': isDraggingOver
|
|
||||||
}"
|
|
||||||
@dragenter.prevent="handleDragEnter"
|
@dragenter.prevent="handleDragEnter"
|
||||||
@dragover.prevent="handleDragOver"
|
@dragover.prevent="handleDragOver"
|
||||||
@dragleave.prevent="handleDragLeave"
|
@dragleave.prevent="handleDragLeave"
|
||||||
@@ -1274,13 +1273,19 @@ defineExpose({ focusSearchInput, startPathEdit });
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
:style="{ '--row-size-multiplier': rowSizeMultiplier }"
|
:style="{ '--row-size-multiplier': rowSizeMultiplier }"
|
||||||
>
|
>
|
||||||
<!-- Drag over overlay text (optional) -->
|
<!-- 新增:外部文件拖拽蒙版 -->
|
||||||
<div v-if="isDraggingOver" class="absolute inset-0 flex items-center justify-center bg-black/60 text-white text-lg font-medium rounded pointer-events-none z-10">
|
<div
|
||||||
|
v-if="showExternalDropOverlay"
|
||||||
|
class="absolute inset-0 flex items-center justify-center bg-black/70 text-white text-xl font-semibold rounded z-50 pointer-events-auto"
|
||||||
|
@dragover.prevent
|
||||||
|
@dragleave.prevent="handleDragLeave"
|
||||||
|
@drop.prevent="handleOverlayDrop"
|
||||||
|
>
|
||||||
{{ t('fileManager.dropFilesHere', 'Drop files here to upload') }}
|
{{ t('fileManager.dropFilesHere', 'Drop files here to upload') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- File Table -->
|
<!-- File Table -->
|
||||||
<table ref="tableRef" class="w-full border-collapse table-fixed border-border rounded" @contextmenu.prevent>
|
<table ref="tableRef" class="w-full border-collapse table-fixed border-border rounded" :class="{'pointer-events-none': showExternalDropOverlay}" @contextmenu.prevent>
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col :style="{ width: `${colWidths.type}px` }">
|
<col :style="{ width: `${colWidths.type}px` }">
|
||||||
<col :style="{ width: `${colWidths.name}px` }">
|
<col :style="{ width: `${colWidths.name}px` }">
|
||||||
|
|||||||
@@ -29,9 +29,10 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
// --- 拖放状态 Refs ---
|
// --- 拖放状态 Refs ---
|
||||||
const isDraggingOver = ref(false); // 是否有文件拖拽悬停在容器上 (用于外部文件)
|
// const isDraggingOver = ref(false); // 不再使用,由 showExternalDropOverlay 替代外部拖拽状态
|
||||||
|
const showExternalDropOverlay = ref(false); // 新增:控制外部文件拖拽蒙版的显示
|
||||||
const draggedItem = ref<FileListItem | null>(null); // 内部拖拽时,被拖拽的项
|
const draggedItem = ref<FileListItem | null>(null); // 内部拖拽时,被拖拽的项
|
||||||
const dragOverTarget = ref<string | null>(null); // 内部/外部拖拽时,悬停的目标文件夹名称 (用于行高亮)
|
const dragOverTarget = ref<string | null>(null); // 内部拖拽时,悬停的目标文件夹名称 (用于行高亮)
|
||||||
const scrollIntervalId = ref<number | null>(null); // 自动滚动计时器 ID
|
const scrollIntervalId = ref<number | null>(null); // 自动滚动计时器 ID
|
||||||
|
|
||||||
// --- 自动滚动常量 ---
|
// --- 自动滚动常量 ---
|
||||||
@@ -48,63 +49,56 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
|
|
||||||
// --- 事件处理函数 ---
|
// --- 事件处理函数 ---
|
||||||
const handleDragEnter = (event: DragEvent) => {
|
const handleDragEnter = (event: DragEvent) => {
|
||||||
if (isConnected.value && event.dataTransfer?.types.includes('Files')) {
|
// 检查是否是外部文件拖拽
|
||||||
isDraggingOver.value = true;
|
const isExternalFileDrag = event.dataTransfer?.types.includes('Files') ?? false;
|
||||||
|
if (isConnected.value && isExternalFileDrag && !draggedItem.value) { // 确保不是内部拖拽触发
|
||||||
|
// console.log("[DragDrop] External file drag entered container.");
|
||||||
|
showExternalDropOverlay.value = true; // 显示蒙版
|
||||||
|
} else if (draggedItem.value) {
|
||||||
|
// console.log("[DragDrop] Internal item drag entered container area.");
|
||||||
|
// 内部拖拽进入容器但不在行上,可能需要处理效果,但不显示蒙版
|
||||||
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'none'; // 默认在容器空白处无效
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragOver = (event: DragEvent) => {
|
const handleDragOver = (event: DragEvent) => {
|
||||||
event.preventDefault(); // 必须阻止默认行为以允许 drop
|
// 这个函数现在主要负责处理内部拖拽时的自动滚动
|
||||||
|
// 外部文件拖拽的 dragover 由蒙版处理 (只阻止默认行为)
|
||||||
const isExternalFileDrag = event.dataTransfer?.types.includes('Files') ?? false;
|
const isExternalFileDrag = event.dataTransfer?.types.includes('Files') ?? false;
|
||||||
const isInternalDrag = !!draggedItem.value;
|
const isInternalDrag = !!draggedItem.value;
|
||||||
|
|
||||||
let effect: 'copy' | 'move' | 'none' = 'none';
|
// 1. 如果是外部文件拖拽,确保蒙版是显示的,并设置效果
|
||||||
let currentTargetFilename: string | null = null;
|
if (isExternalFileDrag && isConnected.value && !isInternalDrag) { // 再次确认不是内部拖拽
|
||||||
let highlightContainer = false;
|
showExternalDropOverlay.value = true; // 确保蒙版显示
|
||||||
|
event.preventDefault(); // 必须阻止默认行为以允许 drop
|
||||||
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy'; // 指示效果
|
||||||
|
// 外部拖拽时,不处理容器的自动滚动,因为鼠标在蒙版上
|
||||||
|
stopAutoScroll();
|
||||||
|
return; // 外部拖拽不由容器 handleDragOver 处理滚动
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 如果是内部拖拽
|
||||||
|
if (isInternalDrag && isConnected.value) {
|
||||||
|
// 内部拖拽时,dragover 主要由行处理 (handleDragOverRow)
|
||||||
|
// 但如果鼠标在行之间或空白区域,容器的 dragover 会触发
|
||||||
|
// 此时需要处理自动滚动,并阻止默认行为
|
||||||
|
event.preventDefault(); // 阻止默认行为(如文本选择),允许滚动逻辑
|
||||||
|
// 效果由 handleDragOverRow 设置,但在空白区域应为 none
|
||||||
const targetElement = event.target as HTMLElement;
|
const targetElement = event.target as HTMLElement;
|
||||||
const targetRow = targetElement.closest('tr.file-row');
|
const targetRow = targetElement.closest('tr.file-row');
|
||||||
const targetFilename = (targetRow instanceof HTMLElement) ? targetRow.dataset.filename : undefined;
|
if (!targetRow && event.dataTransfer) { // 如果不在行上
|
||||||
const targetIsFolder = targetRow?.classList.contains('folder-row');
|
event.dataTransfer.dropEffect = 'none';
|
||||||
|
dragOverTarget.value = null; // 清除行高亮
|
||||||
if (isConnected.value) {
|
} else if (event.dataTransfer) {
|
||||||
if (isExternalFileDrag) {
|
// 如果在行上,效果由 handleDragOverRow 控制,这里假设为 move
|
||||||
effect = 'copy';
|
event.dataTransfer.dropEffect = 'move';
|
||||||
highlightContainer = true;
|
|
||||||
if (targetIsFolder && targetFilename && targetFilename !== '..') {
|
|
||||||
currentTargetFilename = targetFilename;
|
|
||||||
} else {
|
|
||||||
currentTargetFilename = null;
|
|
||||||
}
|
|
||||||
} else if (isInternalDrag && draggedItem.value) {
|
|
||||||
highlightContainer = false;
|
|
||||||
if (targetIsFolder && targetFilename && targetFilename !== draggedItem.value.filename) {
|
|
||||||
effect = 'move';
|
|
||||||
currentTargetFilename = targetFilename;
|
|
||||||
} else {
|
|
||||||
effect = 'none';
|
|
||||||
currentTargetFilename = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
effect = 'none';
|
|
||||||
currentTargetFilename = null;
|
|
||||||
highlightContainer = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
effect = 'none';
|
|
||||||
currentTargetFilename = null;
|
|
||||||
highlightContainer = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.dataTransfer) {
|
|
||||||
event.dataTransfer.dropEffect = effect;
|
|
||||||
}
|
|
||||||
isDraggingOver.value = highlightContainer;
|
|
||||||
dragOverTarget.value = currentTargetFilename;
|
|
||||||
|
|
||||||
// --- 处理自动滚动 ---
|
// --- 处理自动滚动 ---
|
||||||
const container = fileListContainerRef.value;
|
const container = fileListContainerRef.value;
|
||||||
if (container && (isExternalFileDrag || isInternalDrag) && effect !== 'none') {
|
// 只有在内部拖拽且悬停目标有效(在行上)时才滚动
|
||||||
|
if (container && dragOverTarget.value) { // 依赖 handleDragOverRow 设置的 dragOverTarget
|
||||||
const rect = container.getBoundingClientRect();
|
const rect = container.getBoundingClientRect();
|
||||||
const mouseY = event.clientY - rect.top;
|
const mouseY = event.clientY - rect.top;
|
||||||
|
|
||||||
@@ -129,20 +123,43 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
}, 30);
|
}, 30);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stopAutoScroll();
|
stopAutoScroll(); // 在中间区域停止滚动
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stopAutoScroll();
|
stopAutoScroll(); // 如果不在滚动区域或目标无效,停止滚动
|
||||||
}
|
}
|
||||||
|
return; // 内部拖拽处理完毕
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 其他情况 (非文件、非内部拖拽、未连接)
|
||||||
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'none';
|
||||||
|
stopAutoScroll(); // 停止滚动
|
||||||
|
// 不一定需要阻止默认行为 event.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragLeave = (event: DragEvent) => {
|
const handleDragLeave = (event: DragEvent) => {
|
||||||
const target = event.relatedTarget as Node | null;
|
const target = event.relatedTarget as Node | null;
|
||||||
const container = (event.currentTarget as HTMLElement);
|
const container = (event.currentTarget as HTMLElement);
|
||||||
|
// 检查是否真的离开了容器边界
|
||||||
if (!target || !container.contains(target)) {
|
if (!target || !container.contains(target)) {
|
||||||
isDraggingOver.value = false;
|
// console.log("[DragDrop] Drag left container boundary.");
|
||||||
|
if (showExternalDropOverlay.value) {
|
||||||
|
// console.log("[DragDrop] Hiding external drop overlay due to leaving container.");
|
||||||
|
showExternalDropOverlay.value = false; // 隐藏蒙版
|
||||||
|
}
|
||||||
|
// isDraggingOver.value = false; // 不再使用
|
||||||
|
dragOverTarget.value = null; // 清除行高亮
|
||||||
|
stopAutoScroll(); // 停止滚动
|
||||||
|
} else {
|
||||||
|
// console.log("[DragDrop] Drag left fired but still inside container.");
|
||||||
|
// 鼠标仍在容器内(可能移到了子元素上),不隐藏蒙版或清除状态
|
||||||
|
// 但如果是内部拖拽移到了非行区域,需要清除行高亮
|
||||||
|
if (draggedItem.value) {
|
||||||
|
const relatedRow = (target instanceof HTMLElement) ? target.closest('tr.file-row') : null;
|
||||||
|
if (!relatedRow) {
|
||||||
dragOverTarget.value = null;
|
dragOverTarget.value = null;
|
||||||
stopAutoScroll();
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,48 +192,46 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
// --- 结束新增 ---
|
// --- 结束新增 ---
|
||||||
|
|
||||||
|
|
||||||
const handleDrop = (event: DragEvent) => {
|
// 新增:处理蒙版上的 Drop 事件
|
||||||
const wasDraggingOver = isDraggingOver.value;
|
const handleOverlayDrop = (event: DragEvent) => {
|
||||||
const currentDragTarget = dragOverTarget.value; // 拖放目标文件夹名称
|
event.preventDefault(); // 必须阻止,以防浏览器打开文件
|
||||||
isDraggingOver.value = false;
|
// console.log("[DragDrop] Drop event on overlay.");
|
||||||
dragOverTarget.value = null;
|
showExternalDropOverlay.value = false; // 隐藏蒙版
|
||||||
stopAutoScroll();
|
stopAutoScroll(); // 停止滚动
|
||||||
|
|
||||||
// --- 修改:使用 DataTransferItemList 和 webkitGetAsEntry 处理拖放 ---
|
|
||||||
const items = event.dataTransfer?.items;
|
const items = event.dataTransfer?.items;
|
||||||
if (!items || items.length === 0 || !isConnected.value) {
|
if (!items || items.length === 0 || !isConnected.value) {
|
||||||
if (draggedItem.value) draggedItem.value = null; // 清理内部拖拽状态
|
console.log("[DragDrop] Overlay drop ignored: No items or not connected.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查放置目标是否有效 (由 handleDragOver 决定)
|
console.log(`[DragDrop] Processing ${items.length} items from overlay drop.`);
|
||||||
// 对于外部文件,要么容器高亮 (wasDraggingOver),要么行高亮 (currentDragTarget)
|
|
||||||
// 注意:拖放到子文件夹的功能暂时移除,所有拖放都上传到当前目录或根目录
|
|
||||||
// 如果需要拖放到子文件夹,需要重新设计 targetFolderPath 的逻辑
|
|
||||||
// if (!wasDraggingOver && !currentDragTarget) {
|
|
||||||
// console.log(`[DragDrop] Drop ignored: Drop target was not valid according to handleDragOver.`);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
console.log(`[DragDrop] Drop event detected with ${items.length} items.`);
|
|
||||||
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
const item = items[i];
|
const item = items[i];
|
||||||
if (item.kind === 'file') {
|
if (item.kind === 'file') {
|
||||||
const entry = item.webkitGetAsEntry();
|
const entry = item.webkitGetAsEntry();
|
||||||
if (entry) {
|
if (entry) {
|
||||||
console.log(`[DragDrop] Processing entry: ${entry.name}, isFile: ${entry.isFile}, isDirectory: ${entry.isDirectory}`);
|
// console.log(`[DragDrop] Processing entry from overlay: ${entry.name}`);
|
||||||
traverseFileTree(entry); // 开始遍历文件树,初始相对路径为空
|
traverseFileTree(entry); // 处理文件/文件夹
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[DragDrop] Could not get entry for item ${i}`);
|
console.warn(`[DragDrop] Could not get entry for item ${i} from overlay.`);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`[DragDrop] Skipping non-file item kind: ${item.kind}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --- 结束修改 ---
|
}
|
||||||
|
};
|
||||||
|
|
||||||
draggedItem.value = null; // 确保清理内部拖拽状态
|
// 原有的 handleDrop (容器的 drop) 现在基本不需要了,
|
||||||
|
// 因为外部 drop 由蒙版处理,内部 drop 由行处理并阻止冒泡。
|
||||||
|
// 保留一个空的或只做清理的函数以防万一。
|
||||||
|
const handleDrop = (event: DragEvent) => {
|
||||||
|
// console.log("[DragDrop] Container drop event triggered (should be rare).");
|
||||||
|
// 清理所有状态以防异常情况
|
||||||
|
showExternalDropOverlay.value = false;
|
||||||
|
draggedItem.value = null; // 清理内部拖拽状态
|
||||||
|
dragOverTarget.value = null; // 清理行高亮
|
||||||
|
stopAutoScroll(); // 停止滚动
|
||||||
|
// 阻止默认行为以防万一
|
||||||
|
event.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragStart = (item: FileListItem) => {
|
const handleDragStart = (item: FileListItem) => {
|
||||||
@@ -235,7 +250,9 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDragOverRow = (targetItem: FileListItem, event: DragEvent) => {
|
const handleDragOverRow = (targetItem: FileListItem, event: DragEvent) => {
|
||||||
event.preventDefault(); // 允许 drop
|
event.preventDefault(); // 允许 drop 在行上
|
||||||
|
event.stopPropagation(); // 阻止事件冒泡到容器的 handleDragOver
|
||||||
|
|
||||||
// 内部拖拽逻辑: 只能拖拽非 '..' 项,目标必须是文件夹或 '..',且不能是自身
|
// 内部拖拽逻辑: 只能拖拽非 '..' 项,目标必须是文件夹或 '..',且不能是自身
|
||||||
if (!draggedItem.value || draggedItem.value.filename === '..' || (targetItem.filename !== '..' && (!targetItem.attrs.isDirectory || draggedItem.value.filename === targetItem.filename))) {
|
if (!draggedItem.value || draggedItem.value.filename === '..' || (targetItem.filename !== '..' && (!targetItem.attrs.isDirectory || draggedItem.value.filename === targetItem.filename))) {
|
||||||
if (event.dataTransfer) event.dataTransfer.dropEffect = 'none';
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'none';
|
||||||
@@ -244,7 +261,7 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
}
|
}
|
||||||
// 设置放置效果为 'move' 并记录目标
|
// 设置放置效果为 'move' 并记录目标
|
||||||
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
if (event.dataTransfer) event.dataTransfer.dropEffect = 'move';
|
||||||
dragOverTarget.value = targetItem.filename;
|
dragOverTarget.value = targetItem.filename; // 更新悬停目标
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDragLeaveRow = (targetItem: FileListItem) => {
|
const handleDragLeaveRow = (targetItem: FileListItem) => {
|
||||||
@@ -255,26 +272,18 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDropOnRow = (targetItem: FileListItem, event: DragEvent) => {
|
const handleDropOnRow = (targetItem: FileListItem, event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault(); // 确保阻止默认行为(例如导航)
|
||||||
// 检查是否是外部文件拖拽 (dataTransfer.files 存在)
|
event.stopPropagation(); // 阻止事件冒泡到容器的 handleDrop
|
||||||
const files = event.dataTransfer?.files;
|
|
||||||
if (files && files.length > 0) {
|
|
||||||
// 如果是外部文件拖拽,不阻止冒泡,让父容器的 handleDrop 处理上传
|
|
||||||
// console.log(`[DragDrop] External file drop detected on row, letting parent handle.`);
|
|
||||||
// 不需要清除 draggedItem.value,因为外部拖拽时它应该为 null
|
|
||||||
// dragOverTarget.value = null; // 清除悬停状态 (父容器 handleDrop 会处理)
|
|
||||||
return; // 让事件冒泡到父 div 的 handleDrop
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 以下是处理内部文件移动的逻辑 ---
|
// --- 处理内部文件移动的逻辑 ---
|
||||||
event.stopPropagation(); // 仅在处理内部移动时阻止冒泡
|
|
||||||
const sourceItem = draggedItem.value;
|
const sourceItem = draggedItem.value;
|
||||||
const currentDragOverTarget = dragOverTarget.value; // 保存当前目标,然后清除
|
const currentDragOverTarget = dragOverTarget.value; // 保存当前目标,然后清除
|
||||||
dragOverTarget.value = null; // 清除悬停状态
|
dragOverTarget.value = null; // 清除悬停状态
|
||||||
|
|
||||||
// 验证内部拖放操作的有效性
|
// 验证内部拖放操作的有效性
|
||||||
|
// 检查: 是否有拖拽项? 拖拽项不是 '..'? 目标项是文件夹或 '..'? 拖拽项不是目标项自身? 放置的目标确实是悬停的目标?
|
||||||
if (!sourceItem || sourceItem.filename === '..' || (targetItem.filename !== '..' && !targetItem.attrs.isDirectory) || sourceItem.filename === targetItem.filename || targetItem.filename !== currentDragOverTarget) {
|
if (!sourceItem || sourceItem.filename === '..' || (targetItem.filename !== '..' && !targetItem.attrs.isDirectory) || sourceItem.filename === targetItem.filename || targetItem.filename !== currentDragOverTarget) {
|
||||||
// console.log(`[DragDrop] Internal drop on row ignored: Invalid target, source, or drop occurred outside the intended target row. Source: ${sourceItem?.filename}, Target: ${targetItem.filename}, Drop Target: ${currentDragOverTarget}`);
|
console.log(`[DragDrop] Internal drop on row ignored: Invalid conditions. Source: ${sourceItem?.filename}, Target: ${targetItem.filename}, Drop Target: ${currentDragOverTarget}`);
|
||||||
if (sourceItem) draggedItem.value = null; // 清理拖拽状态
|
if (sourceItem) draggedItem.value = null; // 清理拖拽状态
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -359,14 +368,16 @@ export function useFileManagerDragAndDrop(options: UseFileManagerDragAndDropOpti
|
|||||||
|
|
||||||
// --- 返回状态和处理函数 ---
|
// --- 返回状态和处理函数 ---
|
||||||
return {
|
return {
|
||||||
isDraggingOver,
|
// isDraggingOver, // 不再导出
|
||||||
|
showExternalDropOverlay, // 新增导出
|
||||||
dragOverTarget,
|
dragOverTarget,
|
||||||
draggedItem, // 需要暴露以供 handleDragOverRow 等函数内部判断
|
draggedItem, // 需要暴露以供 handleDragOverRow 等函数内部判断
|
||||||
// --- 事件处理器 ---
|
// --- 事件处理器 ---
|
||||||
handleDragEnter,
|
handleDragEnter,
|
||||||
handleDragOver,
|
handleDragOver,
|
||||||
handleDragLeave,
|
handleDragLeave,
|
||||||
handleDrop,
|
handleDrop, // 容器的 drop (主要用于清理)
|
||||||
|
handleOverlayDrop, // 新增导出:蒙版的 drop
|
||||||
handleDragStart,
|
handleDragStart,
|
||||||
handleDragEnd,
|
handleDragEnd,
|
||||||
handleDragOverRow,
|
handleDragOverRow,
|
||||||
|
|||||||
Reference in New Issue
Block a user