|
1240 | 1240 | // Track the previous volumeId to detect MTP connection completion |
1241 | 1241 | let prevVolumeId = $state(volumeId) |
1242 | 1242 |
|
1243 | | - // Update path when initialPath prop changes (for persistence loading) |
1244 | | - // Skip for network views and device-only MTP views (not yet connected) |
1245 | | - // Use untrack for currentPath so this effect only fires when initialPath changes, |
1246 | | - // not when the user navigates (which changes currentPath before onPathChange is called) |
| 1243 | + // Reactive path loading — handles persistence restore AND MTP connection completion. |
| 1244 | + // One effect to avoid duplicate loadDirectory calls from overlapping triggers. |
1247 | 1245 | $effect(() => { |
1248 | 1246 | const newPath = initialPath // Track this |
1249 | | - const curPath = untrack(() => currentPath) // Don't track this |
1250 | | - // Load for local volumes and connected MTP views (not device-only) |
| 1247 | + const curPath = untrack(() => currentPath) // Don't track — user navigation changes this |
| 1248 | + const currentVolumeId = volumeId |
| 1249 | +
|
| 1250 | + // Case 1: MTP device just connected (device-only → storage-specific) |
| 1251 | + // This takes priority — the device just became browsable, always load. |
| 1252 | + const wasDeviceOnly = isMtpVolumeId(prevVolumeId) && !prevVolumeId.includes(':') |
| 1253 | + const isNowConnected = isMtpVolumeId(currentVolumeId) && currentVolumeId.includes(':') |
| 1254 | +
|
| 1255 | + if (wasDeviceOnly && isNowConnected) { |
| 1256 | + log.info('MTP volume connected, loading directory: {path}', { path: newPath }) |
| 1257 | + currentPath = newPath |
| 1258 | + void loadDirectory(newPath) |
| 1259 | + prevVolumeId = currentVolumeId |
| 1260 | + return // Don't also fire the initialPath branch |
| 1261 | + } |
| 1262 | +
|
| 1263 | + prevVolumeId = currentVolumeId |
| 1264 | +
|
| 1265 | + // Case 2: initialPath changed for a loadable view (local volumes, connected MTP) |
1251 | 1266 | if (!isNetworkView && !isMtpDeviceOnly && newPath !== curPath) { |
1252 | 1267 | log.debug( |
1253 | 1268 | '[FilePane] initialPath effect: triggering loadDirectory, paneId={paneId}, newPath={newPath}, curPath={curPath}', |
|
1256 | 1271 | currentPath = newPath |
1257 | 1272 | void loadDirectory(newPath) |
1258 | 1273 | } |
1259 | | - // For device-only MTP views, just update the path (auto-connect will handle switching to storage) |
| 1274 | +
|
| 1275 | + // Case 3: Device-only MTP — just sync path, don't load (auto-connect handles transition) |
1260 | 1276 | if (isMtpDeviceOnly && newPath !== curPath) { |
1261 | 1277 | log.debug('[FilePane] initialPath effect (MTP device-only): updating path only, paneId={paneId}', { |
1262 | 1278 | paneId, |
|
1265 | 1281 | } |
1266 | 1282 | }) |
1267 | 1283 |
|
1268 | | - // Detect when MTP volume transitions from device-only to connected (has storage ID) |
1269 | | - // This triggers loading after auto-connect completes |
1270 | | - $effect(() => { |
1271 | | - const wasDeviceOnly = isMtpVolumeId(prevVolumeId) && !prevVolumeId.includes(':') |
1272 | | - const isNowConnected = isMtpVolumeId(volumeId) && volumeId.includes(':') |
1273 | | -
|
1274 | | - if (wasDeviceOnly && isNowConnected) { |
1275 | | - log.info('MTP volume connected, loading directory: {path}', { path: initialPath }) |
1276 | | - log.debug( |
1277 | | - '[FilePane] MTP volume transition effect: triggering loadDirectory, paneId={paneId}, prevVolumeId={prevVolumeId}, volumeId={volumeId}, initialPath={initialPath}', |
1278 | | - { paneId, prevVolumeId, volumeId, initialPath }, |
1279 | | - ) |
1280 | | - currentPath = initialPath |
1281 | | - void loadDirectory(initialPath) |
1282 | | - } |
1283 | | -
|
1284 | | - prevVolumeId = volumeId |
1285 | | - }) |
1286 | | -
|
1287 | 1284 | // Update global menu context when cursor position or focus changes (debounced — only matters for right-click) |
1288 | 1285 | $effect(() => { |
1289 | 1286 | if (!isFocused) return |
|
0 commit comments