The relaunch restore checked the saved browser directory with
os.ReadDir on the UI thread before the first frame (bounded to 2 s in
the previous commit). The check was unnecessary: Run dispatches a
background index load of Browser.CurrentPath immediately, and that load
IS the readability probe. So:
- main.go no longer does any pre-first-frame directory read;
BeginBrowserRestore is called unconditionally for browser sessions.
- BrowserManager gains a one-shot initial-load fallback
(SetLoadFallback): when the startup load fails (dir deleted by a sync,
or unreadable by the app — /storage/emulated is 0750 media_rw), the
manager reverts to the armed fallback (the startup directory) and
loads it, instead of resetting to a blank browser. Any successful
index disarms it, so later failures keep the History-recovery path.
- Logic stores its start path and arms the fallback from
BeginBrowserRestore.
Verified on device with seeded sessions pointing at a deleted dir and
at unreadable /storage/emulated: both fall back to the startup dir in
~20 ms, first frame renders, list populated. New manager test
TestHandleResult_InitialLoadFailureFallsBack.
Navigating into an unreadable directory failed cleanly in the header
(handleError reverts CurrentPath to the previous path) but left the
list empty forever: the recovery re-read of the previous directory
found it unchanged, so handleBuildIndexSuccess took the no-change
fast path — which assumes the view already shows that content — while
the failed navigation's navigateToDirectory reset had just wiped
TotalEntries/Pages. No frame was emitted and the browser sat on a
correct header over a dead list (seen on device tapping ".." into
/storage/emulated, which is media_rw:media_rw 0750; only
/storage/emulated/0 is app-exposed).
The fast path now requires a live view (TotalEntries != 0); a
torn-down view always takes the full rebuild, restoring the rows.
Regression test TestHandleResult_NavigationFailureRecoveryReloads
(red without the fix, green with it); verified on emulator and phone.
The browser list was cached: files added/removed/renamed, or whose mtime
changed, did not show up (and did not re-sort) until the user navigated
away and back in. In particular, opening a file and returning showed a
stale list — a new file created elsewhere only appeared after navigating
up and back down.
The browser now re-reads the current directory while it is on screen:
- A short (~1 s) timer re-reads the visible directory so external changes
(including inbound syncs) appear live, re-sorted in the current sort
mode. A landing re-index repopulates the visible+prefetch pages
synchronously (no flicker), preserves the scroll offset, and re-filters
an active search without a scroll jump.
- Returning to the browser from the editor triggers one immediate re-read
so the list is current the moment you land back.
- Bounded to one read per directory: a refresh while a read of the same
directory is in flight coalesces, and a stale result for a directory the
user has since left is dropped rather than clobbering the current view.
- A failed background refresh keeps the last good view (the next tick
retries); a failed navigation still recovers to the previous directory.
- Change detection: a refresh that finds the directory unchanged rebuilds
nothing and emits no frame, preserving the event-driven emission
contract (TestNoFramesWhileIdle_Browser) while the browser idles.
Verified on-device: external add while sitting in the browser appears and
re-sorts to the top within ~1 s; an external add+remove made while in the
editor is reflected immediately on return; an external delete drops the
row within ~1 s.
Drop the log.Printf/fmt.Printf traces that fired on every config/input/
click/scroll/open/worker-result during IME and tap debugging. These were
noise (and some were commented out). Error, limit, and recovery logs are
kept; the default-off profiler and gated IME debug remain untouched.
When directory navigation fails (e.g., permission denied on Android),
the browser now restores the previous path instead of staying in a
broken empty state. NavigateTo saves the current path to History, and
handleError restores it and re-builds the index for the previous
directory when a BuildIndexTask fails.
- Initialize browser path to the actual startup directory instead of '/'
- Improve '..' navigation to be relative to the filesystem root
- Fix path duplication issues by avoiding redundant absolute path joining
- Define pool.FileSystem interface in internal/io/pool/filesystem.go
- Move DirEntry interface to internal/io/pool/types/types.go to break
the pool <-> mock import cycle
- Implement real.FileSystem with atomic writes (temp file + os.Rename)
- Update mock.FileSystem to satisfy pool.FileSystem interface
- Update worker pool tasks to accept pool.FileSystem interface
- Update main.go to use RealFileSystem by default, with -root flag
- Update all browser/editor/test references to types.DirEntry