fix: sidebar refresh, context menu position, show-in-explorer for all items

Sidebar refresh:
- addFile/addFolder now use currentFolderId || selectedNode.id as parent
- startImport stores pendingImportParent; confirmImport uses it
- setNodeChildren also updates node.has_children for toggle arrow reactivity
- navigateToFolder expands the folder node in sidebar tree

Context menu position:
- FileTreeRow stores menuX/menuY from contextmenu event coords
- Menu uses position:fixed with cursor-relative left/top and window clamp

Show in explorer:
- Sidebar context menu uses file.showInExplorer label
- en.js: add file.showInExplorer key
This commit is contained in:
2026-06-03 04:46:42 +08:00
parent 3c9b9edf8c
commit cc3500c14f
6 changed files with 32 additions and 16 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -16,8 +16,8 @@
background: #13131f;
}
</style>
<script type="module" crossorigin src="/assets/main-BZ3I06Px.js"></script>
<link rel="stylesheet" crossorigin href="/assets/main-DsSP02cl.css">
<script type="module" crossorigin src="/assets/main-43Kzwqa7.js"></script>
<link rel="stylesheet" crossorigin href="/assets/main-D6qvckLy.css">
</head>
<body>
<div id="app"></div>
+19 -10
View File
@@ -73,6 +73,7 @@
let importSummary = null
let showImportDialog = false
let pendingImportPath = ''
let pendingImportParent = ''
let pendingImportMode = 'copy'
let treeItems = []
let expanded = {}
@@ -247,7 +248,6 @@
async function navigateToFolder(folderId) {
if (!selectedNode) return
// Get the folder node name for breadcrumbs
try {
const node = await wailsCall('GetNodeDetail', folderId)
if (node) {
@@ -257,6 +257,10 @@
folderStack = [...folderStack, { id: folderId, name: '...' }]
}
currentFolderId = folderId
expanded = { ...expanded, [folderId]: true }
const children = await wailsCall('ListWorkspaceChildren', folderId) || []
setNodeChildren(workspaceTree, folderId, children)
workspaceTree = [...workspaceTree]
await loadFolder(folderId)
}
@@ -681,6 +685,7 @@
for (const node of tree) {
if (node.id === nodeId) {
node.children = children
node.has_children = children.length > 0
return true
}
if (node.children && setNodeChildren(node.children, nodeId, children)) {
@@ -877,21 +882,24 @@
async function addFile() {
const path = await wailsCall('PickFile')
if (!path) return
await startImport(selectedNode.id, path)
const parentId = currentFolderId || selectedNode.id
await startImport(parentId, path)
}
async function addFolder() {
const path = await wailsCall('PickDirectory')
if (!path) return
await startImport(selectedNode.id, path)
const parentId = currentFolderId || selectedNode.id
await startImport(parentId, path)
}
async function startImport(nodeID, sourcePath) {
async function startImport(parentID, sourcePath) {
importing = true
try {
const summary = await wailsCall('PreviewImport', sourcePath)
importSummary = summary
pendingImportPath = sourcePath
pendingImportParent = parentID
showImportDialog = true
} catch (e) {
error = String(e)
@@ -901,17 +909,18 @@
async function confirmImport(mode) {
try {
const parentId = pendingImportParent || selectedNode.id
const result = mode === 'copy'
? await wailsCall('AddPathCopy', selectedNode.id, pendingImportPath)
: await wailsCall('AddPathLink', selectedNode.id, pendingImportPath)
? await wailsCall('AddPathCopy', parentId, pendingImportPath)
: await wailsCall('AddPathLink', parentId, pendingImportPath)
showImportDialog = false
importSummary = null
folderStack = []
currentFolderId = null
await Promise.all([
loadTabData(selectedNode.id),
loadFolder(selectedNode.id),
refreshParentNode(selectedNode.id),
loadTabData(parentId),
loadFolder(parentId),
refreshParentNode(parentId),
])
} catch (e) {
error = String(e)
@@ -1656,7 +1665,7 @@
{t('common.delete')}
</button>
<button class="context-menu-item" on:click={() => openNodeFolder(contextMenu.node)}>
{t('nav.openFolder')}
{t('file.showInExplorer')}
</button>
</div>
</div>
+6 -4
View File
@@ -16,6 +16,8 @@
const isFolder = item.type === 'folder'
const fileType = formatFileType(item)
let menuOpen = false
let menuX = 0
let menuY = 0
let clickTimer = null
function handleClick(e) {
@@ -107,6 +109,8 @@
function oncontextmenu(e) {
e.preventDefault()
menuX = Math.min(e.clientX, window.innerWidth - 240)
menuY = Math.min(e.clientY, window.innerHeight - 320)
menuOpen = true
}
</script>
@@ -189,7 +193,7 @@
{#if menuOpen}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="menu-backdrop" on:click|stopPropagation={closeMenu} role="presentation"></div>
<div class="menu" on:click|stopPropagation role="menu">
<div class="menu" style="left: {menuX}px; top: {menuY}px; position: fixed;" on:click|stopPropagation role="menu">
<button class="menu-item" on:click={handleOpen} role="menuitem">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
{t('common.open')}
@@ -347,9 +351,7 @@
}
.menu {
position: absolute;
right: 12px;
margin-top: 4px;
position: fixed;
background: #1a1a28;
border: 1px solid #2a2a3c;
border-radius: 8px;
+1
View File
@@ -74,6 +74,7 @@ export default {
'file.preview': 'Preview',
'file.openExternal': 'Open in external program',
'file.openFolder': 'Open folder',
'file.showInExplorer': 'Show in explorer',
'file.delete': 'Delete',
'file.pickSingle': 'Select file',
'file.pickDirectory': 'Select folder',