From 981f20625aaa5cc49321f0e06961478429db78f7 Mon Sep 17 00:00:00 2001 From: Baobhan Sith <80159437+Heavrnl@users.noreply.github.com> Date: Fri, 18 Apr 2025 09:38:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=99=A8=E5=8F=B3=E9=94=AE=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E5=AE=9A=E4=BD=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/FileManager.vue | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/packages/frontend/src/components/FileManager.vue b/packages/frontend/src/components/FileManager.vue index 7d9dd17..d6ef577 100644 --- a/packages/frontend/src/components/FileManager.vue +++ b/packages/frontend/src/components/FileManager.vue @@ -130,6 +130,7 @@ const isFetchingInitialPath = ref(false); const isEditingPath = ref(false); const pathInputRef = ref(null); const editablePath = ref(''); +const contextMenuRef = ref(null); // <-- Add ref for context menu element // --- Column Resizing State (Remains the same) --- const tableRef = ref(null); @@ -226,31 +227,49 @@ const showContextMenu = (event: MouseEvent, item?: FileListItem) => { contextMenuItems.value = menu; - // Calculate initial position - let posX = event.clientX; - let posY = event.clientY; + // Set initial position based on click event + contextMenuPosition.value = { x: event.clientX, y: event.clientY }; + contextMenuVisible.value = true; // Make menu visible so we can measure it - // Estimate menu dimensions - const estimatedMenuWidth = 180; - const estimatedMenuHeight = contextMenuItems.value.length * 35; // Estimate height based on items - - // Adjust position if menu would go off-screen - if (posX + estimatedMenuWidth > window.innerWidth) { - posX = window.innerWidth - estimatedMenuWidth - 5; - } - if (posY + estimatedMenuHeight > window.innerHeight) { - posY = window.innerHeight - estimatedMenuHeight - 5; - } - posX = Math.max(0, posX); - posY = Math.max(0, posY); - - contextMenuPosition.value = { x: posX, y: posY }; - contextMenuVisible.value = true; - - // Add global listener to hide menu + // Use nextTick to allow the DOM to update and the menu to render nextTick(() => { - document.removeEventListener('click', hideContextMenu, { capture: true }); - document.addEventListener('click', hideContextMenu, { capture: true, once: true }); + if (contextMenuRef.value && contextMenuVisible.value) { + const menuElement = contextMenuRef.value; + const menuRect = menuElement.getBoundingClientRect(); // Get actual dimensions and position + const menuWidth = menuRect.width; + const menuHeight = menuRect.height; + + let finalX = contextMenuPosition.value.x; + let finalY = contextMenuPosition.value.y; + + // Adjust horizontally if needed + if (finalX + menuWidth > window.innerWidth) { + finalX = window.innerWidth - menuWidth - 5; // Adjust left + } + + // Adjust vertically if needed (using actual height) + if (finalY + menuHeight > window.innerHeight) { + finalY = window.innerHeight - menuHeight - 5; // Adjust up + } + + // Ensure menu doesn't go off-screen top or left + finalX = Math.max(5, finalX); // Add small margin from left edge + finalY = Math.max(5, finalY); // Add small margin from top edge + + // Update the position state if adjustments were made + if (finalX !== contextMenuPosition.value.x || finalY !== contextMenuPosition.value.y) { + console.log(`[FileManager ${props.sessionId}] Adjusting context menu position: (${contextMenuPosition.value.x}, ${contextMenuPosition.value.y}) -> (${finalX}, ${finalY})`); + contextMenuPosition.value = { x: finalX, y: finalY }; + } + + // Add global listener to hide menu *after* positioning + document.removeEventListener('click', hideContextMenu, { capture: true }); + document.addEventListener('click', hideContextMenu, { capture: true, once: true }); + } else { + // Fallback listener if measurement fails + document.removeEventListener('click', hideContextMenu, { capture: true }); + document.addEventListener('click', hideContextMenu, { capture: true, once: true }); + } }); }; @@ -811,10 +830,11 @@ const cancelPathEdit = () => { -
+ @click.stop>