Skip to content

Commit 7740fbc

Browse files
committed
Refactor: Extract volume grouping and space display
1 parent 8522e71 commit 7740fbc

4 files changed

Lines changed: 281 additions & 240 deletions

File tree

apps/desktop/src/lib/file-explorer/navigation/CLAUDE.md

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Browser-style back/forward history, path resolution, paged keyboard shortcuts, a
44

55
## Key files
66

7-
| File | Purpose |
8-
| ---------------------------- | ------------------------------------------------ |
9-
| `navigation-history.ts` | Purely functional immutable history stack |
10-
| `path-navigation.ts` | Async path resolution with fallback chain |
11-
| `keyboard-shortcuts.ts` | Home/End/PageUp/PageDown handling for file lists |
12-
| `VolumeBreadcrumb.svelte` | Clickable volume label + grouped dropdown |
13-
| `navigation-history.test.ts` | Full unit test coverage of history functions |
14-
| `path-navigation.test.ts` | Unit tests for path resolution and timeouts |
15-
| `keyboard-shortcuts.test.ts` | Unit tests for shortcut calculations |
7+
| File | Purpose |
8+
| -------------------------------- | --------------------------------------------------------- |
9+
| `navigation-history.ts` | Purely functional immutable history stack |
10+
| `path-navigation.ts` | Async path resolution with fallback chain |
11+
| `keyboard-shortcuts.ts` | Home/End/PageUp/PageDown handling for file lists |
12+
| `VolumeBreadcrumb.svelte` | Clickable volume label + grouped dropdown |
13+
| `volume-grouping.ts` | Pure logic: group volumes by category, get volume icons |
14+
| `volume-space-manager.svelte.ts` | Reactive state machine for disk space fetch/retry/timeout |
15+
| `navigation-history.test.ts` | Full unit test coverage of history functions |
16+
| `path-navigation.test.ts` | Unit tests for path resolution and timeouts |
17+
| `keyboard-shortcuts.test.ts` | Unit tests for shortcut calculations |
1618

1719
## `navigation-history.ts`
1820

@@ -90,15 +92,8 @@ Brief PageUp/PageDown lands on the **bottom row** of the target column (TUI conv
9092

9193
## `VolumeBreadcrumb.svelte`
9294

93-
Clickable label that opens a grouped dropdown of all available volumes.
94-
95-
Volume groups (in display order):
96-
97-
1. Favorites — no checkmark shown even if current path is a favorite
98-
2. main_volume + attached_volume — merged into one group
99-
3. Cloud drives
100-
4. Mobile (MTP) devices
101-
5. Network — always includes a synthetic `'network'` entry (`smb://`) plus any mounted SMB shares
95+
Clickable label that opens a grouped dropdown of all available volumes. Volume grouping logic and disk-space retry state
96+
are extracted into `volume-grouping.ts` and `volume-space-manager.svelte.ts` respectively.
10297

10398
Props: `volumeId`, `currentPath`, `onVolumeChange?`.
10499

@@ -111,14 +106,30 @@ movement > 5px threshold exits keyboard mode.
111106
MTP volumes are refreshed with a 100ms delay after hotplug events (`mtp-device-detected`, `mtp-device-connected`,
112107
`mtp-device-removed`) to let `mtp-store`'s own event handler finish first.
113108

114-
### Timeout-aware UI
109+
Exported methods for parent components: `toggle()`, `open()`, `close()`, `getIsOpen()`, `handleKeyDown(e)`.
110+
111+
## `volume-grouping.ts`
112+
113+
Pure logic for organizing volumes into display groups. No reactive state.
114+
115+
`groupByCategory(vols, mtpVols)` — groups volumes by category in display order:
115116

116-
Both `listVolumes()` and `getVolumeSpace()` return `TimedOut<T>` wrappers. The component tracks timeout state and
117-
renders inline indicators (no toasts):
117+
1. Favorites — no checkmark shown even if current path is a favorite
118+
2. main_volume + attached_volume — merged into one group
119+
3. Cloud drives
120+
4. Mobile (MTP) devices — mapped from `MtpVolume[]`
121+
5. Network — always includes a synthetic `'network'` entry (`smb://`) plus any mounted SMB shares
122+
123+
`getIconForVolume(volume)` — returns the appropriate icon path for a volume based on its category.
124+
125+
## `volume-space-manager.svelte.ts`
126+
127+
Reactive state machine for fetching, retrying, and caching disk space info per volume. Created via
128+
`createVolumeSpaceManager()` (functional factory, no classes).
129+
130+
Both `listVolumes()` and `getVolumeSpace()` return `TimedOut<T>` wrappers. The manager tracks timeout state and exposes
131+
reactive sets for the component to render inline indicators (no toasts):
118132

119-
- **Volume list timeout** (`volumesTimedOut`): Shows a warning row at the bottom of the dropdown ("Some volumes may be
120-
missing") with a retry button that re-calls `listVolumes()`. The warning auto-clears on successful retry. The dropdown
121-
still opens with whatever partial data was returned.
122133
- **Volume space timeout** (`spaceTimedOutSet`): Three-state cycle with per-volume tracking:
123134
- **Idle**: Dashed-outline placeholder bar with "?" icon, "Unavailable" text, tooltip "Couldn't fetch disk space --
124135
click to retry". After a retry has been attempted, tooltip changes to "Still unavailable -- click to retry".
@@ -127,10 +138,11 @@ renders inline indicators (no toasts):
127138
- **Failed**: Brief shake animation (300ms), then returns to idle with "Still unavailable" tooltip.
128139
- **Auto-retry**: 5s after initial timeout, an automatic retry fires with full visual feedback (spinner + shake on
129140
failure). Tracked via `spaceAutoRetryingSet` for tooltip distinction.
130-
- All retry sets are cleared on volume mount/unmount events. Auto-retry timers are cleaned up on destroy.
141+
- All retry sets are cleared via `clearAll()` on volume mount/unmount events. Auto-retry timers are cleaned up via
142+
`destroy()`.
131143
- Reduced motion: spinner degrades to pulsing opacity, shake degrades to opacity flash.
132-
133-
Exported methods for parent components: `toggle()`, `open()`, `close()`, `getIsOpen()`, `handleKeyDown(e)`.
144+
- **Volume list timeout** (`volumesTimedOut`): Tracked in the component itself (not in the manager) since it controls
145+
the warning row at the bottom of the dropdown.
134146

135147
## Dependencies
136148

0 commit comments

Comments
 (0)