|
2 | 2 | import { onMount, onDestroy } from 'svelte' |
3 | 3 | import FilePane from './FilePane.svelte' |
4 | 4 | import LoadingIcon from '../LoadingIcon.svelte' |
5 | | - import { loadAppStatus, saveAppStatus, type ViewMode } from '$lib/app-status-store' |
| 5 | + import { |
| 6 | + loadAppStatus, |
| 7 | + saveAppStatus, |
| 8 | + getLastUsedPathForVolume, |
| 9 | + saveLastUsedPathForVolume, |
| 10 | + type ViewMode, |
| 11 | + } from '$lib/app-status-store' |
6 | 12 | import { loadSettings, saveSettings, subscribeToSettingsChanges } from '$lib/settings-store' |
7 | 13 | import { |
8 | 14 | pathExists, |
9 | 15 | listen, |
10 | 16 | listVolumes, |
11 | 17 | getDefaultVolumeId, |
| 18 | + findContainingVolume, |
12 | 19 | DEFAULT_VOLUME_ID, |
13 | 20 | type UnlistenFn, |
14 | 21 | } from '$lib/tauri-commands' |
|
40 | 47 | function handleLeftPathChange(path: string) { |
41 | 48 | leftPath = path |
42 | 49 | void saveAppStatus({ leftPath: path }) |
| 50 | + void saveLastUsedPathForVolume(leftVolumeId, path) |
43 | 51 | // Re-focus to maintain keyboard handling after navigation |
44 | 52 | containerElement?.focus() |
45 | 53 | } |
46 | 54 |
|
47 | 55 | function handleRightPathChange(path: string) { |
48 | 56 | rightPath = path |
49 | 57 | void saveAppStatus({ rightPath: path }) |
| 58 | + void saveLastUsedPathForVolume(rightVolumeId, path) |
50 | 59 | // Re-focus to maintain keyboard handling after navigation |
51 | 60 | containerElement?.focus() |
52 | 61 | } |
53 | 62 |
|
54 | | - function handleLeftVolumeChange(volumeId: string, volumePath: string, targetPath: string) { |
| 63 | + async function handleLeftVolumeChange(volumeId: string, volumePath: string, targetPath: string) { |
| 64 | + // Save the current path for the old volume before switching |
| 65 | + void saveLastUsedPathForVolume(leftVolumeId, leftPath) |
| 66 | +
|
| 67 | + const pathToNavigate = await determineNavigationPath(volumeId, volumePath, targetPath) |
| 68 | +
|
55 | 69 | leftVolumeId = volumeId |
56 | | - leftPath = targetPath |
57 | | - void saveAppStatus({ leftVolumeId: volumeId, leftPath: targetPath }) |
| 70 | + leftPath = pathToNavigate |
| 71 | + void saveAppStatus({ leftVolumeId: volumeId, leftPath: pathToNavigate }) |
58 | 72 | } |
59 | 73 |
|
60 | | - function handleRightVolumeChange(volumeId: string, volumePath: string, targetPath: string) { |
| 74 | + async function handleRightVolumeChange(volumeId: string, volumePath: string, targetPath: string) { |
| 75 | + // Save the current path for the old volume before switching |
| 76 | + void saveLastUsedPathForVolume(rightVolumeId, rightPath) |
| 77 | +
|
| 78 | + const pathToNavigate = await determineNavigationPath(volumeId, volumePath, targetPath) |
| 79 | +
|
61 | 80 | rightVolumeId = volumeId |
62 | | - rightPath = targetPath |
63 | | - void saveAppStatus({ rightVolumeId: volumeId, rightPath: targetPath }) |
| 81 | + rightPath = pathToNavigate |
| 82 | + void saveAppStatus({ rightVolumeId: volumeId, rightPath: pathToNavigate }) |
| 83 | + } |
| 84 | +
|
| 85 | + /** |
| 86 | + * Determines which path to navigate to when switching volumes. |
| 87 | + * - If targetPath !== volumePath: user selected a favorite → go there directly |
| 88 | + * - Otherwise: look up last used path, or default to ~ for main volume, volume root for others |
| 89 | + */ |
| 90 | + async function determineNavigationPath(volumeId: string, volumePath: string, targetPath: string): Promise<string> { |
| 91 | + // User selected a favorite - go to the favorite's path directly |
| 92 | + if (targetPath !== volumePath) { |
| 93 | + return targetPath |
| 94 | + } |
| 95 | +
|
| 96 | + // Look up the last used path for this volume |
| 97 | + const lastUsedPath = await getLastUsedPathForVolume(volumeId) |
| 98 | + if (lastUsedPath && (await pathExists(lastUsedPath))) { |
| 99 | + return lastUsedPath |
| 100 | + } |
| 101 | +
|
| 102 | + // Default: ~ for main volume (root), volume path for others |
| 103 | + if (volumeId === DEFAULT_VOLUME_ID) { |
| 104 | + return '~' |
| 105 | + } |
| 106 | + return volumePath |
64 | 107 | } |
65 | 108 |
|
66 | 109 | function handleLeftFocus() { |
|
126 | 169 | leftViewMode = status.leftViewMode |
127 | 170 | rightViewMode = status.rightViewMode |
128 | 171 |
|
129 | | - // Validate persisted volume IDs exist, fallback to default if not |
| 172 | + // Determine the correct volume IDs by finding which volume contains each path |
| 173 | + // This is more reliable than trusting the stored volumeId, which may be stale |
130 | 174 | const defaultId = await getDefaultVolumeId() |
131 | | - leftVolumeId = volumes.some((v) => v.id === status.leftVolumeId) ? status.leftVolumeId : defaultId |
132 | | - rightVolumeId = volumes.some((v) => v.id === status.rightVolumeId) ? status.rightVolumeId : defaultId |
| 175 | + const [leftContaining, rightContaining] = await Promise.all([ |
| 176 | + findContainingVolume(status.leftPath), |
| 177 | + findContainingVolume(status.rightPath), |
| 178 | + ]) |
| 179 | + leftVolumeId = leftContaining?.id ?? defaultId |
| 180 | + rightVolumeId = rightContaining?.id ?? defaultId |
133 | 181 |
|
134 | 182 | initialized = true |
135 | 183 |
|
|
0 commit comments