Skip to content

Commit 17efe8b

Browse files
committed
MTP: Fix duplicate directory listing on connect
- Merged two `$effect` blocks (`initialPath` change + MTP transition detection) into one with prioritized cases - When MTP transitions from device-only to connected, Case 1 fires and returns early, preventing the `initialPath` branch from also calling `loadDirectory` - Root cause: parent updates both `volumeId` and `initialPath` simultaneously, both effects saw their conditions met
1 parent 4a44d7d commit 17efe8b

1 file changed

Lines changed: 23 additions & 26 deletions

File tree

apps/desktop/src/lib/file-explorer/pane/FilePane.svelte

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,14 +1240,29 @@
12401240
// Track the previous volumeId to detect MTP connection completion
12411241
let prevVolumeId = $state(volumeId)
12421242
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.
12471245
$effect(() => {
12481246
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)
12511266
if (!isNetworkView && !isMtpDeviceOnly && newPath !== curPath) {
12521267
log.debug(
12531268
'[FilePane] initialPath effect: triggering loadDirectory, paneId={paneId}, newPath={newPath}, curPath={curPath}',
@@ -1256,7 +1271,8 @@
12561271
currentPath = newPath
12571272
void loadDirectory(newPath)
12581273
}
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)
12601276
if (isMtpDeviceOnly && newPath !== curPath) {
12611277
log.debug('[FilePane] initialPath effect (MTP device-only): updating path only, paneId={paneId}', {
12621278
paneId,
@@ -1265,25 +1281,6 @@
12651281
}
12661282
})
12671283
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-
12871284
// Update global menu context when cursor position or focus changes (debounced — only matters for right-click)
12881285
$effect(() => {
12891286
if (!isFocused) return

0 commit comments

Comments
 (0)