diff --git a/docker/frontend/src/Library.tsx b/docker/frontend/src/Library.tsx
index a2dcec7..5861543 100644
--- a/docker/frontend/src/Library.tsx
+++ b/docker/frontend/src/Library.tsx
@@ -10,6 +10,7 @@ import {
canBrowseFolders,
clearLibraryCache,
ensurePermission,
+ findFolderRelationship,
getPhoto,
getPhotoThumbs,
HEAD_BYTES,
@@ -659,16 +660,54 @@ export function Library() {
try {
const folder = await pickFolder();
if (!folder) return;
- setFolders((prev) => [...prev.filter((f) => f.name !== folder.name), folder].sort((a, b) => a.name.localeCompare(b.name)));
- setReady((prev) => new Set(prev).add(folder.name));
- setNode(folder.name);
- await scan(folder);
+
+ const relInfo = await findFolderRelationship(folder.handle, folders);
+
+ if (relInfo.type === 'subfolder') {
+ const { parent, relPath } = relInfo;
+ const subNodeKey = `${parent.name}/${relPath}`;
+ const parts = relPath.split('/');
+
+ setExpanded((prev) => {
+ const next = new Set(prev);
+ let curr = parent.name;
+ next.add(curr);
+ for (let i = 0; i < parts.length; i++) {
+ curr = `${curr}/${parts[i]}`;
+ next.add(curr);
+ }
+ return next;
+ });
+
+ setDirs((prev) => {
+ if (prev.some((d) => d.id === subNodeKey)) return prev;
+ return [...prev, { id: subNodeKey, folder: parent.name, rel: relPath }];
+ });
+
+ setNode(subNodeKey);
+ await scan(parent, false, relPath + '/');
+ } else if (relInfo.type === 'parent') {
+ const { child } = relInfo;
+ const nextFolders = [...folders.filter((f) => f.name !== child.name), folder].sort((a, b) =>
+ a.name.localeCompare(b.name)
+ );
+ setFolders(nextFolders);
+ setReady((prev) => new Set(prev).add(folder.name));
+ setNode(folder.name);
+ await scan(folder);
+ } else {
+ setFolders((prev) =>
+ [...prev.filter((f) => f.name !== folder.name), folder].sort((a, b) => a.name.localeCompare(b.name))
+ );
+ setReady((prev) => new Set(prev).add(folder.name));
+ setNode(folder.name);
+ await scan(folder);
+ }
} catch (err) {
- // Closing the picker is a "not now", not a failure worth a line of text.
if (err instanceof DOMException && err.name === 'AbortError') return;
setNote(t('lib.failed'));
}
- }, [scan, t]);
+ }, [folders, scan, t]);
const reconnect = useCallback(
async (folder: LibraryFolder) => {
@@ -1107,7 +1146,7 @@ export function Library() {
same row and ellipsises — the catalogue is the content, this bar
is furniture. */}
-