|
8 | 8 | type FileTree,
|
9 | 9 | type FileTreeNode,
|
10 | 10 | type FolderNode,
|
11 |
| - type OnChildrenChangeArgs, |
12 | 11 | type OnCircularReferenceArgs,
|
13 | 12 | type OnMoveArgs,
|
14 | 13 | type OnRemoveArgs,
|
|
47 | 46 | nodes.sort((a, b) => a.name.localeCompare(b.name));
|
48 | 47 | }
|
49 | 48 |
|
50 |
| - function onChildrenChange(args: OnChildrenChangeArgs) { |
51 |
| - if (args.operation === "insert") { |
52 |
| - sortByName(args.children); |
53 |
| - } |
54 |
| - } |
55 |
| -
|
56 |
| - function onResolveNameConflict(args: OnResolveNameConflictArgs) { |
| 49 | + function onResolveNameConflict({ operation, name }: OnResolveNameConflictArgs) { |
57 | 50 | let title: string;
|
58 |
| - switch (args.operation) { |
| 51 | + switch (operation) { |
59 | 52 | case "copy": {
|
60 | 53 | title = "Failed to copy items";
|
61 | 54 | break;
|
|
68 | 61 |
|
69 | 62 | return resolveConflictDialog!.show({
|
70 | 63 | title,
|
71 |
| - description: `An item named "${args.name}" already exists in this location. Do you want to skip it or cancel the operation entirely?`, |
| 64 | + description: `An item named "${name}" already exists in this location. Do you want to skip it or cancel the operation entirely?`, |
72 | 65 | });
|
73 | 66 | }
|
74 | 67 |
|
75 |
| - function onCircularReference(args: OnCircularReferenceArgs) { |
76 |
| - toast.error(`Cannot move "${args.source.node.name}" inside itself`); |
| 68 | + function onCircularReference({ source }: OnCircularReferenceArgs) { |
| 69 | + toast.error(`Cannot move "${source.node.name}" inside itself`); |
77 | 70 | }
|
78 | 71 |
|
79 |
| - function canRemove(args: OnRemoveArgs) { |
| 72 | + function canRemove({ removed }: OnRemoveArgs) { |
80 | 73 | return confirmRemoveDialog!.show({
|
81 |
| - title: `Are you sure you want to delete ${args.removed.length} item(s)?`, |
| 74 | + title: `Are you sure you want to delete ${removed.length} item(s)?`, |
82 | 75 | description: "They will be permanently deleted. This action cannot be undone.",
|
83 | 76 | });
|
84 | 77 | }
|
85 | 78 |
|
86 |
| - function onCopy(args: OnMoveArgs) { |
87 |
| - if (args.destination.type === "folder") { |
88 |
| - startBorderAnimation(args.destination.id); |
| 79 | + function onCopy({ destination }: OnMoveArgs) { |
| 80 | + sortByName(destination.children); |
| 81 | +
|
| 82 | + if (destination.type === "folder") { |
| 83 | + startBorderAnimation(destination.id); |
89 | 84 | }
|
90 | 85 | }
|
91 | 86 |
|
92 |
| - function onMove(args: OnMoveArgs) { |
93 |
| - if (args.destination.type === "folder") { |
94 |
| - startBorderAnimation(args.destination.id); |
| 87 | + function onMove({ destination }: OnMoveArgs) { |
| 88 | + sortByName(destination.children); |
| 89 | +
|
| 90 | + if (destination.type === "folder") { |
| 91 | + startBorderAnimation(destination.id); |
95 | 92 | }
|
96 | 93 | }
|
97 | 94 |
|
98 |
| - function onDrag(args: DragEventArgs) { |
99 |
| - dropDestination = args.destination; |
| 95 | + function onDrag({ destination }: DragEventArgs) { |
| 96 | + dropDestination = destination; |
100 | 97 | }
|
101 | 98 |
|
102 | 99 | function onDragLeave() {
|
103 | 100 | dropDestination = undefined;
|
104 | 101 | }
|
105 | 102 |
|
106 |
| - function onDrop(args: DragEventArgs) { |
| 103 | + function onDrop({ type, items, destination }: DragEventArgs) { |
107 | 104 | dropDestination = undefined;
|
108 | 105 |
|
109 |
| - if (args.type !== "external") { |
| 106 | + if (type !== "external") { |
110 | 107 | return;
|
111 | 108 | }
|
112 | 109 |
|
| 110 | + const uniqueNames = new Set(); |
| 111 | + for (const child of destination.children) { |
| 112 | + uniqueNames.add(child.name); |
| 113 | + } |
| 114 | +
|
113 | 115 | const files: Array<FileNode> = [];
|
114 |
| - for (const item of args.items) { |
| 116 | + for (const item of items) { |
115 | 117 | const file = item.getAsFile();
|
116 |
| - if (file !== null) { |
117 |
| - files.push( |
118 |
| - new FileNode({ |
119 |
| - id: crypto.randomUUID(), |
120 |
| - name: file.name, |
121 |
| - }), |
122 |
| - ); |
| 118 | + if (file === null) { |
| 119 | + continue; |
| 120 | + } |
| 121 | +
|
| 122 | + const fileName = file.name; |
| 123 | + if (uniqueNames.has(fileName)) { |
| 124 | + toast.error(`An item named "${fileName}" already exists in this location`); |
| 125 | + return; |
123 | 126 | }
|
| 127 | +
|
| 128 | + files.push( |
| 129 | + new FileNode({ |
| 130 | + id: crypto.randomUUID(), |
| 131 | + name: fileName, |
| 132 | + }), |
| 133 | + ); |
124 | 134 | }
|
125 | 135 |
|
126 |
| - const children = args.destination.children; |
127 |
| - children.push(...files); |
128 |
| - sortByName(children); |
| 136 | + destination.children.push(...files); |
| 137 | + sortByName(destination.children); |
| 138 | +
|
| 139 | + if (destination.type === "folder") { |
| 140 | + startBorderAnimation(destination.id); |
| 141 | + } |
129 | 142 | }
|
130 | 143 |
|
131 | 144 | function onExpand(item: TreeItemState) {
|
|
160 | 173 | <Tree
|
161 | 174 | {root}
|
162 | 175 | {expandedIds}
|
163 |
| - {onChildrenChange} |
164 | 176 | {onResolveNameConflict}
|
165 | 177 | {onCircularReference}
|
166 | 178 | {canRemove}
|
|
0 commit comments