Make browser back button step up one Library folder instead of exiting

Drilling into a Library folder only ever swapped #library-groups's
contents via fetch, never touching browser history - so back had
nothing of the app's own to step through once you were a few folders
deep, and fell straight through to exiting the app instead of going up
a level.

Push a history entry per drill-down and breadcrumb jump, and restore
libraryTrail/re-fetch that level on popstate, so back now un-drills
one folder at a time and only reaches the app's actual exit once
you're back at the library root.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 20:55:44 -04:00
co-authored by Claude Sonnet 5
parent 68639a2b5b
commit 255361ca6e
+22
View File
@@ -1133,8 +1133,27 @@
if (!libraryCard) return; if (!libraryCard) return;
libraryTrail = []; libraryTrail = [];
fetchLibraryLevel(null); fetchLibraryLevel(null);
history.replaceState({ libraryTrail: [], path: null }, '');
} }
// Drilling into a folder only ever swapped #library-groups's
// contents - no history entry, no URL change - so the back
// button/gesture had nothing of ours to step back through once
// you were a few folders deep, and fell straight through to
// exiting the app instead of going up one level. Pushing a state
// per level (and restoring it on popstate, below) makes back
// step back up the library trail one folder at a time instead.
function pushLibraryState() {
history.pushState({ libraryTrail: libraryTrail.slice(), path: libraryTrail.length ? libraryTrail[libraryTrail.length - 1].path : null }, '');
}
window.addEventListener('popstate', function(event) {
const state = event.state;
if (!state || !document.getElementById('library-card')) return;
libraryTrail = state.libraryTrail || [];
fetchLibraryLevel(state.path || null);
});
function fetchLibraryLevel(path) { function fetchLibraryLevel(path) {
searchActive = false; searchActive = false;
const searchInput = document.getElementById('library-search-input'); const searchInput = document.getElementById('library-search-input');
@@ -1176,11 +1195,13 @@
if (index < 0) { if (index < 0) {
libraryTrail = []; libraryTrail = [];
fetchLibraryLevel(null); fetchLibraryLevel(null);
pushLibraryState();
return; return;
} }
const target = libraryTrail[index]; const target = libraryTrail[index];
libraryTrail = libraryTrail.slice(0, index + 1); libraryTrail = libraryTrail.slice(0, index + 1);
fetchLibraryLevel(target.path); fetchLibraryLevel(target.path);
pushLibraryState();
} }
function renderLibraryLevel(data) { function renderLibraryLevel(data) {
@@ -1202,6 +1223,7 @@
function enterLibraryDir(path, name) { function enterLibraryDir(path, name) {
libraryTrail.push({ name: name, path: path }); libraryTrail.push({ name: name, path: path });
fetchLibraryLevel(path); fetchLibraryLevel(path);
pushLibraryState();
} }
// A few shimmering placeholder rows for in-flight fetches, instead // A few shimmering placeholder rows for in-flight fetches, instead