Skip to content

Commit 682d33a

Browse files
committed
Add Move (F6) frontend support
Generalize the Copy UI into a shared "transfer" abstraction that supports both Copy (F5) and Move (F6). The Rust backend already had full move support — this commit wires up the frontend. - Rename file-operations/copy/ → transfer/, parameterized by operation type - Rename copy-operations.ts → transfer-operations.ts with generalized interfaces - Enable F6 in FunctionKeyBar, wired through DualPaneExplorer - Move calls moveFiles(), refreshes both panes on completion - Add MTP move guard (not yet supported for cross-volume MTP) - Update tests and docs - Test manually
1 parent 1c75322 commit 682d33a

20 files changed

Lines changed: 796 additions & 370 deletions

apps/desktop/coverage-allowlist.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,15 @@
101101
"utils/confirm-dialog.ts": { "reason": "Thin wrapper over Tauri dialog API" },
102102
"updates/updater.svelte.ts": { "reason": "Depends on Tauri updater APIs" },
103103
"window-state.ts": { "reason": "Depends on Tauri window APIs" },
104-
"file-operations/copy/CopyDialog.svelte": { "reason": "UI modal, logic tested in copy-dialog-utils.test.ts" },
105-
"file-operations/copy/DirectionIndicator.svelte": {
106-
"reason": "Simple UI component, logic tested in copy-dialog-utils.test.ts"
104+
"file-operations/transfer/TransferDialog.svelte": {
105+
"reason": "UI modal, logic tested in transfer-dialog-utils.test.ts"
107106
},
108-
"file-operations/copy/CopyProgressDialog.svelte": { "reason": "UI dialog, depends on Tauri events" },
109-
"file-operations/copy/CopyErrorDialog.svelte": {
110-
"reason": "UI modal, logic tested in copy-error-messages.test.ts"
107+
"file-operations/transfer/DirectionIndicator.svelte": {
108+
"reason": "Simple UI component, logic tested in transfer-dialog-utils.test.ts"
109+
},
110+
"file-operations/transfer/TransferProgressDialog.svelte": { "reason": "UI dialog, depends on Tauri events" },
111+
"file-operations/transfer/TransferErrorDialog.svelte": {
112+
"reason": "UI modal, logic tested in transfer-error-messages.test.ts"
111113
}
112114
}
113115
}
Lines changed: 75 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,47 @@
11
<script lang="ts">
2-
import CopyDialog from '../../file-operations/copy/CopyDialog.svelte'
3-
import CopyProgressDialog from '../../file-operations/copy/CopyProgressDialog.svelte'
4-
import CopyErrorDialog from '../../file-operations/copy/CopyErrorDialog.svelte'
2+
import TransferDialog from '../../file-operations/transfer/TransferDialog.svelte'
3+
import TransferProgressDialog from '../../file-operations/transfer/TransferProgressDialog.svelte'
4+
import TransferErrorDialog from '../../file-operations/transfer/TransferErrorDialog.svelte'
55
import NewFolderDialog from '$lib/file-operations/mkdir/NewFolderDialog.svelte'
66
import AlertDialog from '$lib/ui/AlertDialog.svelte'
7-
import type { CopyDialogPropsData } from './copy-operations'
8-
import type { SortColumn, SortOrder, VolumeInfo, ConflictResolution, WriteOperationError } from '../types'
7+
import type { TransferDialogPropsData } from './transfer-operations'
8+
import type {
9+
TransferOperationType,
10+
SortColumn,
11+
SortOrder,
12+
VolumeInfo,
13+
ConflictResolution,
14+
WriteOperationError,
15+
} from '../types'
916
1017
const {
11-
showCopyDialog,
12-
copyDialogProps,
18+
showTransferDialog,
19+
transferDialogProps,
1320
volumes,
14-
showCopyProgressDialog,
15-
copyProgressProps,
21+
showTransferProgressDialog,
22+
transferProgressProps,
1623
showNewFolderDialog,
1724
newFolderDialogProps,
1825
showAlertDialog,
1926
alertDialogProps,
20-
showCopyErrorDialog,
21-
copyErrorProps,
22-
onCopyConfirm,
23-
onCopyCancel,
24-
onCopyComplete,
25-
onCopyCancelled,
26-
onCopyError,
27-
onCopyErrorClose,
27+
showTransferErrorDialog,
28+
transferErrorProps,
29+
onTransferConfirm,
30+
onTransferCancel,
31+
onTransferComplete,
32+
onTransferCancelled,
33+
onTransferError,
34+
onTransferErrorClose,
2835
onNewFolderCreated,
2936
onNewFolderCancel,
3037
onAlertClose,
3138
}: {
32-
showCopyDialog: boolean
33-
copyDialogProps: CopyDialogPropsData | null
39+
showTransferDialog: boolean
40+
transferDialogProps: TransferDialogPropsData | null
3441
volumes: VolumeInfo[]
35-
showCopyProgressDialog: boolean
36-
copyProgressProps: {
42+
showTransferProgressDialog: boolean
43+
transferProgressProps: {
44+
operationType: TransferOperationType
3745
sourcePaths: string[]
3846
sourceFolderPath: string
3947
destinationPath: string
@@ -55,59 +63,61 @@
5563
} | null
5664
showAlertDialog: boolean
5765
alertDialogProps: { title: string; message: string } | null
58-
showCopyErrorDialog: boolean
59-
copyErrorProps: { error: WriteOperationError } | null
60-
onCopyConfirm: (
66+
showTransferErrorDialog: boolean
67+
transferErrorProps: { operationType: TransferOperationType; error: WriteOperationError } | null
68+
onTransferConfirm: (
6169
destination: string,
6270
volumeId: string,
6371
previewId: string | null,
6472
conflictResolution: ConflictResolution,
6573
) => void
66-
onCopyCancel: () => void
67-
onCopyComplete: (filesProcessed: number, bytesProcessed: number) => void
68-
onCopyCancelled: (filesProcessed: number) => void
69-
onCopyError: (error: WriteOperationError) => void
70-
onCopyErrorClose: () => void
74+
onTransferCancel: () => void
75+
onTransferComplete: (filesProcessed: number, bytesProcessed: number) => void
76+
onTransferCancelled: (filesProcessed: number) => void
77+
onTransferError: (error: WriteOperationError) => void
78+
onTransferErrorClose: () => void
7179
onNewFolderCreated: (folderName: string) => void
7280
onNewFolderCancel: () => void
7381
onAlertClose: () => void
7482
} = $props()
7583
</script>
7684

77-
{#if showCopyDialog && copyDialogProps}
78-
<CopyDialog
79-
sourcePaths={copyDialogProps.sourcePaths}
80-
destinationPath={copyDialogProps.destinationPath}
81-
direction={copyDialogProps.direction}
85+
{#if showTransferDialog && transferDialogProps}
86+
<TransferDialog
87+
operationType={transferDialogProps.operationType}
88+
sourcePaths={transferDialogProps.sourcePaths}
89+
destinationPath={transferDialogProps.destinationPath}
90+
direction={transferDialogProps.direction}
8291
{volumes}
83-
currentVolumeId={copyDialogProps.currentVolumeId}
84-
fileCount={copyDialogProps.fileCount}
85-
folderCount={copyDialogProps.folderCount}
86-
sourceFolderPath={copyDialogProps.sourceFolderPath}
87-
sortColumn={copyDialogProps.sortColumn}
88-
sortOrder={copyDialogProps.sortOrder}
89-
sourceVolumeId={copyDialogProps.sourceVolumeId}
90-
destVolumeId={copyDialogProps.destVolumeId}
91-
onConfirm={onCopyConfirm}
92-
onCancel={onCopyCancel}
92+
currentVolumeId={transferDialogProps.currentVolumeId}
93+
fileCount={transferDialogProps.fileCount}
94+
folderCount={transferDialogProps.folderCount}
95+
sourceFolderPath={transferDialogProps.sourceFolderPath}
96+
sortColumn={transferDialogProps.sortColumn}
97+
sortOrder={transferDialogProps.sortOrder}
98+
sourceVolumeId={transferDialogProps.sourceVolumeId}
99+
destVolumeId={transferDialogProps.destVolumeId}
100+
onConfirm={onTransferConfirm}
101+
onCancel={onTransferCancel}
93102
/>
94103
{/if}
95104

96-
{#if showCopyProgressDialog && copyProgressProps}
97-
<CopyProgressDialog
98-
sourcePaths={copyProgressProps.sourcePaths}
99-
sourceFolderPath={copyProgressProps.sourceFolderPath}
100-
destinationPath={copyProgressProps.destinationPath}
101-
direction={copyProgressProps.direction}
102-
sortColumn={copyProgressProps.sortColumn}
103-
sortOrder={copyProgressProps.sortOrder}
104-
previewId={copyProgressProps.previewId}
105-
sourceVolumeId={copyProgressProps.sourceVolumeId}
106-
destVolumeId={copyProgressProps.destVolumeId}
107-
conflictResolution={copyProgressProps.conflictResolution}
108-
onComplete={onCopyComplete}
109-
onCancelled={onCopyCancelled}
110-
onError={onCopyError}
105+
{#if showTransferProgressDialog && transferProgressProps}
106+
<TransferProgressDialog
107+
operationType={transferProgressProps.operationType}
108+
sourcePaths={transferProgressProps.sourcePaths}
109+
sourceFolderPath={transferProgressProps.sourceFolderPath}
110+
destinationPath={transferProgressProps.destinationPath}
111+
direction={transferProgressProps.direction}
112+
sortColumn={transferProgressProps.sortColumn}
113+
sortOrder={transferProgressProps.sortOrder}
114+
previewId={transferProgressProps.previewId}
115+
sourceVolumeId={transferProgressProps.sourceVolumeId}
116+
destVolumeId={transferProgressProps.destVolumeId}
117+
conflictResolution={transferProgressProps.conflictResolution}
118+
onComplete={onTransferComplete}
119+
onCancelled={onTransferCancelled}
120+
onError={onTransferError}
111121
/>
112122
{/if}
113123

@@ -127,6 +137,10 @@
127137
<AlertDialog title={alertDialogProps.title} message={alertDialogProps.message} onClose={onAlertClose} />
128138
{/if}
129139

130-
{#if showCopyErrorDialog && copyErrorProps}
131-
<CopyErrorDialog error={copyErrorProps.error} onClose={onCopyErrorClose} />
140+
{#if showTransferErrorDialog && transferErrorProps}
141+
<TransferErrorDialog
142+
operationType={transferErrorProps.operationType}
143+
error={transferErrorProps.error}
144+
onClose={onTransferErrorClose}
145+
/>
132146
{/if}

0 commit comments

Comments
 (0)