feat(browse): double-click a folder to navigate into it
Single-click still expands the folder inline; double-click swaps the view's root onto the folder. In server mode it loads the folder's URL (zddc-server returns a fresh browse instance scoped there); in FS-API mode it re-roots state.rootHandle onto the folder's handle and re- enumerates. Files and zips are unchanged — files have a single-click preview, zips have inline JSZip expansion. Help panel updated to document the new behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0ad47561ed
commit
562b105550
2 changed files with 52 additions and 0 deletions
|
|
@ -202,6 +202,54 @@
|
||||||
// Browser handles target=_blank natively for middle
|
// Browser handles target=_blank natively for middle
|
||||||
// click; don't preventDefault, just don't intercept.
|
// click; don't preventDefault, just don't intercept.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Double-click on a folder → "navigate into" it. Distinct
|
||||||
|
// from single-click (which expands inline) so users keep
|
||||||
|
// both UX models. Server mode jumps to the folder URL —
|
||||||
|
// zddc-server returns a fresh browse instance scoped to
|
||||||
|
// that directory. FS-API mode swaps state.rootHandle to
|
||||||
|
// the folder's handle and re-loads, so the user sees
|
||||||
|
// only that subtree at the root level.
|
||||||
|
//
|
||||||
|
// Files: dblclick is left alone — the single-click preview
|
||||||
|
// is already a "look at this file" action; a separate
|
||||||
|
// navigate-into doesn't apply.
|
||||||
|
// ZIPs: skipped too — they're inspected via inline
|
||||||
|
// expansion (JSZip), not navigated into.
|
||||||
|
tbody.addEventListener('dblclick', function (e) {
|
||||||
|
var row = e.target.closest('tr.tree-row');
|
||||||
|
if (!row) return;
|
||||||
|
if (row.dataset.isdir !== 'true') return;
|
||||||
|
var id = parseInt(row.dataset.id, 10);
|
||||||
|
var node = state.nodes.get(id);
|
||||||
|
if (!node) return;
|
||||||
|
e.preventDefault();
|
||||||
|
navigateIntoFolder(node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function navigateIntoFolder(node) {
|
||||||
|
if (state.source === 'server') {
|
||||||
|
var url = window.app.modules.tree.pathFor(node);
|
||||||
|
if (!url.endsWith('/')) url += '/';
|
||||||
|
window.location.assign(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.source === 'fs') {
|
||||||
|
if (!node.handle || node.handle.kind !== 'directory') return;
|
||||||
|
state.rootHandle = node.handle;
|
||||||
|
state.currentPath = node.handle.name + '/';
|
||||||
|
var raw;
|
||||||
|
try {
|
||||||
|
raw = await loader.fetchFsChildren(node.handle);
|
||||||
|
} catch (e) {
|
||||||
|
statusError('Failed to enter ' + node.name + ': ' + e.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tree.setRoot(raw);
|
||||||
|
tree.render();
|
||||||
|
statusInfo('Entered ' + node.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,10 @@
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Click a folder</dt>
|
<dt>Click a folder</dt>
|
||||||
<dd>Toggle expand/collapse on that folder.</dd>
|
<dd>Toggle expand/collapse on that folder.</dd>
|
||||||
|
<dt>Double-click a folder</dt>
|
||||||
|
<dd>Navigate into the folder — it becomes the new root of the
|
||||||
|
view. Server mode loads the folder's URL; local mode re-roots
|
||||||
|
onto that folder's handle.</dd>
|
||||||
<dt>Shift-click a folder</dt>
|
<dt>Shift-click a folder</dt>
|
||||||
<dd>Recursive expand or collapse — applies to the whole subtree.</dd>
|
<dd>Recursive expand or collapse — applies to the whole subtree.</dd>
|
||||||
<dt>Click a file</dt>
|
<dt>Click a file</dt>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue