@tutti-os/workspace-file-manager 0.0.196 → 0.0.198
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/dist/{chunk-KKKQGRC5.js → chunk-EI4ICYY4.js} +1 -35
- package/dist/chunk-EI4ICYY4.js.map +1 -0
- package/dist/{chunk-P4SNEQWG.js → chunk-TNFCNCZV.js} +14 -322
- package/dist/chunk-TNFCNCZV.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/{index-C3AgiOLN.d.ts → index-D0k_jjaw.d.ts} +0 -17
- package/dist/index.d.ts +69 -50
- package/dist/index.js +198 -829
- package/dist/index.js.map +1 -1
- package/dist/services/index.d.ts +3 -3
- package/dist/services/index.js +46 -6
- package/dist/services/index.js.map +1 -1
- package/dist/{workspaceFileManagerLocations-RmwpZYaa.d.ts → workspaceFileManagerLocations-BwRMCnUY.d.ts} +5 -77
- package/package.json +4 -4
- package/dist/chunk-KKKQGRC5.js.map +0 -1
- package/dist/chunk-P4SNEQWG.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -7,12 +7,10 @@ import {
|
|
|
7
7
|
formatWorkspaceFileBytes,
|
|
8
8
|
formatWorkspaceFileModifiedTime,
|
|
9
9
|
isWorkspaceApplicationBundle,
|
|
10
|
-
isWorkspaceFileBrowserOpenable,
|
|
11
10
|
isWorkspaceFileExternalLocation,
|
|
12
11
|
isWorkspaceFileRecentLocation,
|
|
13
12
|
normalizeWorkspaceFilePath,
|
|
14
13
|
readWorkspaceFileManagerArrangeMode,
|
|
15
|
-
resolveWorkspaceFileActivationTarget,
|
|
16
14
|
resolveWorkspaceFileEntryArrangeDateMs,
|
|
17
15
|
resolveWorkspaceFileEntryIconCacheKey,
|
|
18
16
|
resolveWorkspaceFileLocationDefaultId,
|
|
@@ -23,19 +21,19 @@ import {
|
|
|
23
21
|
splitWorkspaceFileName,
|
|
24
22
|
workspaceFileSearchEntryToEntry,
|
|
25
23
|
writeWorkspaceFileManagerArrangeMode
|
|
26
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-TNFCNCZV.js";
|
|
27
25
|
import {
|
|
28
26
|
createWorkspaceFileManagerI18nRuntime,
|
|
29
27
|
resolveRevealInFolderLabel,
|
|
30
28
|
workspaceFileManagerI18nNamespace,
|
|
31
29
|
workspaceFileManagerI18nResources
|
|
32
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-EI4ICYY4.js";
|
|
33
31
|
|
|
34
32
|
// src/ui/WorkspaceFileManager.tsx
|
|
35
33
|
import {
|
|
36
34
|
useCallback as useCallback6,
|
|
37
35
|
useEffect as useEffect7,
|
|
38
|
-
useLayoutEffect as
|
|
36
|
+
useLayoutEffect as useLayoutEffect5,
|
|
39
37
|
useMemo as useMemo3,
|
|
40
38
|
useRef as useRef7,
|
|
41
39
|
useState as useState8
|
|
@@ -43,25 +41,15 @@ import {
|
|
|
43
41
|
import { cn as cn7 } from "@tutti-os/ui-system";
|
|
44
42
|
|
|
45
43
|
// src/ui/WorkspaceFileManagerContextMenuContainer.tsx
|
|
46
|
-
import { useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
44
|
+
import { useEffect as useEffect2, useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
47
45
|
|
|
48
46
|
// src/ui/WorkspaceFileManagerContextMenu.tsx
|
|
49
47
|
import {
|
|
50
48
|
ArrowLeftIcon,
|
|
51
49
|
ArrowRightIcon,
|
|
52
|
-
CopyIcon,
|
|
53
|
-
DeleteIcon,
|
|
54
|
-
DownloadIcon,
|
|
55
|
-
EditIcon,
|
|
56
|
-
EyeIcon,
|
|
57
|
-
FileLinedIcon,
|
|
58
|
-
ImportLinedIcon as ImportIcon,
|
|
59
50
|
LaunchIcon,
|
|
60
|
-
LocateFolderIcon,
|
|
61
51
|
MenuSurface,
|
|
62
|
-
NewWorkspaceLinedIcon,
|
|
63
52
|
ViewportMenuSurface,
|
|
64
|
-
WebIcon,
|
|
65
53
|
cn
|
|
66
54
|
} from "@tutti-os/ui-system";
|
|
67
55
|
import {
|
|
@@ -153,47 +141,11 @@ function shouldShowOpenWithSectionDivider(input) {
|
|
|
153
141
|
// src/ui/WorkspaceFileManagerContextMenu.tsx
|
|
154
142
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
155
143
|
function WorkspaceFileManagerContextMenu({
|
|
156
|
-
busy,
|
|
157
|
-
copy,
|
|
158
144
|
contextMenu,
|
|
159
145
|
contextMenuRef,
|
|
160
|
-
|
|
146
|
+
items,
|
|
161
147
|
positionMode = "local",
|
|
162
|
-
|
|
163
|
-
showCopyPathAction,
|
|
164
|
-
showCreateDirectoryAction,
|
|
165
|
-
showCreateFileAction,
|
|
166
|
-
showDeleteAction,
|
|
167
|
-
showImportAction,
|
|
168
|
-
showExportAction,
|
|
169
|
-
showOpenInAppBrowserAction,
|
|
170
|
-
showOpenInDefaultBrowserAction,
|
|
171
|
-
showOpenInFileViewerAction,
|
|
172
|
-
showOpenAction,
|
|
173
|
-
showOpenWithAction,
|
|
174
|
-
showOpenWithOtherAction,
|
|
175
|
-
showRevealInFolderAction,
|
|
176
|
-
showRenameAction,
|
|
177
|
-
revealInFolderLabel,
|
|
178
|
-
openWithApplications,
|
|
179
|
-
openWithLoading,
|
|
180
|
-
resolveOpenWithApplicationIcon,
|
|
181
|
-
onClose,
|
|
182
|
-
onCreateDirectory,
|
|
183
|
-
onCreateFile,
|
|
184
|
-
onCopy,
|
|
185
|
-
onCopyPath,
|
|
186
|
-
onDelete,
|
|
187
|
-
onExport,
|
|
188
|
-
onOpen,
|
|
189
|
-
onOpenInAppBrowser,
|
|
190
|
-
onOpenInDefaultBrowser,
|
|
191
|
-
onOpenInFileViewer,
|
|
192
|
-
onOpenWithApplication,
|
|
193
|
-
onOpenWithOtherApplication,
|
|
194
|
-
onImport,
|
|
195
|
-
onRevealInFolder,
|
|
196
|
-
onRename
|
|
148
|
+
onClose
|
|
197
149
|
}) {
|
|
198
150
|
const [position, setPosition] = useState({
|
|
199
151
|
x: contextMenu?.x ?? 0,
|
|
@@ -231,145 +183,11 @@ function WorkspaceFileManagerContextMenu({
|
|
|
231
183
|
y: contextMenu.y
|
|
232
184
|
})
|
|
233
185
|
);
|
|
234
|
-
}, [
|
|
235
|
-
|
|
236
|
-
contextMenuRef,
|
|
237
|
-
openWithApplications.length,
|
|
238
|
-
openWithLoading,
|
|
239
|
-
positionMode,
|
|
240
|
-
showCopyAction,
|
|
241
|
-
showCopyPathAction,
|
|
242
|
-
showCreateDirectoryAction,
|
|
243
|
-
showCreateFileAction,
|
|
244
|
-
showExportAction,
|
|
245
|
-
showImportAction,
|
|
246
|
-
showOpenInAppBrowserAction,
|
|
247
|
-
showOpenInDefaultBrowserAction,
|
|
248
|
-
showOpenInFileViewerAction,
|
|
249
|
-
showOpenAction,
|
|
250
|
-
showOpenWithAction,
|
|
251
|
-
showOpenWithOtherAction,
|
|
252
|
-
showRevealInFolderAction,
|
|
253
|
-
showRenameAction
|
|
254
|
-
]);
|
|
255
|
-
if (!contextMenu) {
|
|
186
|
+
}, [contextMenu, contextMenuRef, items, positionMode]);
|
|
187
|
+
if (!contextMenu || items.length === 0) {
|
|
256
188
|
return null;
|
|
257
189
|
}
|
|
258
|
-
|
|
259
|
-
const isDirectory = entry?.kind === "directory";
|
|
260
|
-
const editItems = [];
|
|
261
|
-
const transferItems = [];
|
|
262
|
-
const dangerItems = [];
|
|
263
|
-
const createItems = [];
|
|
264
|
-
if (!entry || isDirectory) {
|
|
265
|
-
if (showCreateFileAction) {
|
|
266
|
-
createItems.push({
|
|
267
|
-
action: onCreateFile,
|
|
268
|
-
disabled: busy,
|
|
269
|
-
icon: /* @__PURE__ */ jsx(NewWorkspaceLinedIcon, { className: "size-4" }),
|
|
270
|
-
key: "create-file",
|
|
271
|
-
label: copy.t("createFileLabel")
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (showCreateDirectoryAction) {
|
|
275
|
-
createItems.push({
|
|
276
|
-
action: onCreateDirectory,
|
|
277
|
-
disabled: busy,
|
|
278
|
-
icon: /* @__PURE__ */ jsx(FileLinedIcon, { className: "size-4" }),
|
|
279
|
-
key: "create-directory",
|
|
280
|
-
label: copy.t("createDirectoryLabel")
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
if (entry) {
|
|
285
|
-
if (showRenameAction) {
|
|
286
|
-
editItems.push({
|
|
287
|
-
action: onRename,
|
|
288
|
-
disabled: busy,
|
|
289
|
-
icon: /* @__PURE__ */ jsx(EditIcon, { className: "size-4" }),
|
|
290
|
-
key: "rename",
|
|
291
|
-
label: copy.t("renameLabel")
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
if (showCopyAction) {
|
|
295
|
-
editItems.push({
|
|
296
|
-
action: onCopy,
|
|
297
|
-
disabled: busy,
|
|
298
|
-
icon: /* @__PURE__ */ jsx(CopyIcon, { className: "size-4" }),
|
|
299
|
-
key: "copy",
|
|
300
|
-
label: copy.t("copyLabel")
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
if (showCopyPathAction) {
|
|
304
|
-
editItems.push({
|
|
305
|
-
action: onCopyPath,
|
|
306
|
-
disabled: busy,
|
|
307
|
-
icon: /* @__PURE__ */ jsx(CopyIcon, { className: "size-4" }),
|
|
308
|
-
key: "copy-path",
|
|
309
|
-
label: copy.t("copyPathLabel")
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
if (showRevealInFolderAction) {
|
|
313
|
-
editItems.push({
|
|
314
|
-
action: onRevealInFolder,
|
|
315
|
-
disabled: busy,
|
|
316
|
-
icon: /* @__PURE__ */ jsx(LocateFolderIcon, { className: "size-4" }),
|
|
317
|
-
key: "reveal-in-folder",
|
|
318
|
-
label: revealInFolderLabel
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
if (isDirectory && showImportAction) {
|
|
322
|
-
transferItems.push({
|
|
323
|
-
action: onImport,
|
|
324
|
-
disabled: busy,
|
|
325
|
-
icon: /* @__PURE__ */ jsx(ImportIcon, { className: "size-4" }),
|
|
326
|
-
key: "import",
|
|
327
|
-
label: copy.t("importLabel")
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
if (showExportAction) {
|
|
331
|
-
transferItems.push({
|
|
332
|
-
action: onExport,
|
|
333
|
-
disabled: busy,
|
|
334
|
-
icon: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-4" }),
|
|
335
|
-
key: "export",
|
|
336
|
-
label: copy.t("downloadLabel")
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
if (showDeleteAction) {
|
|
340
|
-
dangerItems.push({
|
|
341
|
-
action: onDelete,
|
|
342
|
-
disabled: busy,
|
|
343
|
-
danger: true,
|
|
344
|
-
icon: /* @__PURE__ */ jsx(DeleteIcon, { className: "size-4" }),
|
|
345
|
-
key: "delete",
|
|
346
|
-
label: copy.t("deleteLabel")
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
} else {
|
|
350
|
-
if (showImportAction) {
|
|
351
|
-
transferItems.push({
|
|
352
|
-
action: onImport,
|
|
353
|
-
disabled: busy,
|
|
354
|
-
icon: /* @__PURE__ */ jsx(ImportIcon, { className: "size-4" }),
|
|
355
|
-
key: "import",
|
|
356
|
-
label: copy.t("importLabel")
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const menuGroups = entry ? [
|
|
361
|
-
{ items: createItems, key: "create" },
|
|
362
|
-
{ items: editItems, key: "edit" },
|
|
363
|
-
{ items: transferItems, key: "transfer" },
|
|
364
|
-
{ items: dangerItems, key: "danger" }
|
|
365
|
-
] : [
|
|
366
|
-
{ items: createItems, key: "create" },
|
|
367
|
-
{ items: transferItems, key: "transfer" }
|
|
368
|
-
];
|
|
369
|
-
const visibleMenuGroups = menuGroups.filter(
|
|
370
|
-
(group) => group.items.length > 0
|
|
371
|
-
);
|
|
372
|
-
return /* @__PURE__ */ jsxs(
|
|
190
|
+
return /* @__PURE__ */ jsx(
|
|
373
191
|
MenuSurface,
|
|
374
192
|
{
|
|
375
193
|
ref: contextMenuRef,
|
|
@@ -387,75 +205,38 @@ function WorkspaceFileManagerContextMenu({
|
|
|
387
205
|
onContextMenu: (event) => {
|
|
388
206
|
event.preventDefault();
|
|
389
207
|
},
|
|
390
|
-
children:
|
|
391
|
-
entry && showOpenAction ? /* @__PURE__ */ jsx(
|
|
392
|
-
ContextMenuActionButton,
|
|
393
|
-
{
|
|
394
|
-
disabled: busy,
|
|
395
|
-
icon: /* @__PURE__ */ jsx(EyeIcon, { className: "size-4" }),
|
|
396
|
-
label: copy.t("openLabel"),
|
|
397
|
-
onClick: () => {
|
|
398
|
-
onClose();
|
|
399
|
-
void onOpen();
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
) : null,
|
|
403
|
-
entry && showOpenWithAction ? /* @__PURE__ */ jsx(
|
|
404
|
-
OpenWithMenuItem,
|
|
405
|
-
{
|
|
406
|
-
applications: openWithApplications,
|
|
407
|
-
busy,
|
|
408
|
-
copy,
|
|
409
|
-
isLoading: openWithLoading,
|
|
410
|
-
openInAppBrowserIcon,
|
|
411
|
-
resolveOpenWithApplicationIcon,
|
|
412
|
-
showOpenInAppBrowser: showOpenInAppBrowserAction,
|
|
413
|
-
showOpenInDefaultBrowser: showOpenInDefaultBrowserAction,
|
|
414
|
-
showOpenInFileViewer: showOpenInFileViewerAction,
|
|
415
|
-
showOpenWithOther: showOpenWithOtherAction,
|
|
416
|
-
onClose,
|
|
417
|
-
onOpenInAppBrowser,
|
|
418
|
-
onOpenInDefaultBrowser,
|
|
419
|
-
onOpenInFileViewer,
|
|
420
|
-
onOpenWithApplication,
|
|
421
|
-
onOpenWithOtherApplication
|
|
422
|
-
}
|
|
423
|
-
) : null,
|
|
424
|
-
visibleMenuGroups.map((group, groupIndex) => /* @__PURE__ */ jsx(
|
|
425
|
-
ContextMenuActionGroup,
|
|
426
|
-
{
|
|
427
|
-
items: group.items,
|
|
428
|
-
showDivider: groupIndex > 0 || entry !== null && (showOpenAction || showOpenWithAction),
|
|
429
|
-
onClose
|
|
430
|
-
},
|
|
431
|
-
group.key
|
|
432
|
-
))
|
|
433
|
-
]
|
|
208
|
+
children: items.map((item) => /* @__PURE__ */ jsx(ContextMenuItemRenderer, { item, onClose }, item.id))
|
|
434
209
|
}
|
|
435
210
|
);
|
|
436
211
|
}
|
|
437
|
-
function
|
|
438
|
-
|
|
212
|
+
function ContextMenuItemRenderer({
|
|
213
|
+
item,
|
|
439
214
|
onClose,
|
|
440
|
-
|
|
215
|
+
activateOnPointerDown = false
|
|
441
216
|
}) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
{
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
217
|
+
switch (item.type) {
|
|
218
|
+
case "separator":
|
|
219
|
+
return /* @__PURE__ */ jsx(ContextMenuDivider, {});
|
|
220
|
+
case "submenu":
|
|
221
|
+
return /* @__PURE__ */ jsx(ContextMenuSubmenu, { item, onClose });
|
|
222
|
+
case "item":
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
ContextMenuActionButton,
|
|
225
|
+
{
|
|
226
|
+
activateOnPointerDown,
|
|
227
|
+
danger: item.danger,
|
|
228
|
+
disabled: item.disabled,
|
|
229
|
+
icon: item.icon ?? /* @__PURE__ */ jsx(LaunchIcon, { className: "size-4" }),
|
|
230
|
+
label: item.label,
|
|
231
|
+
onClick: () => {
|
|
232
|
+
onClose();
|
|
233
|
+
void item.onSelect();
|
|
234
|
+
}
|
|
454
235
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
236
|
+
);
|
|
237
|
+
default:
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
459
240
|
}
|
|
460
241
|
function ContextMenuActionButton({
|
|
461
242
|
activateOnPointerDown = false,
|
|
@@ -530,29 +311,18 @@ function ContextMenuActionButton({
|
|
|
530
311
|
function ContextMenuDivider() {
|
|
531
312
|
return /* @__PURE__ */ jsx("div", { className: "mx-2 my-0.5 h-px bg-[var(--border-1)]", role: "separator" });
|
|
532
313
|
}
|
|
533
|
-
function
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
copy,
|
|
537
|
-
isLoading,
|
|
538
|
-
openInAppBrowserIcon,
|
|
539
|
-
resolveOpenWithApplicationIcon,
|
|
540
|
-
showOpenInAppBrowser,
|
|
541
|
-
showOpenInDefaultBrowser,
|
|
542
|
-
showOpenInFileViewer,
|
|
543
|
-
showOpenWithOther,
|
|
544
|
-
onClose,
|
|
545
|
-
onOpenInAppBrowser,
|
|
546
|
-
onOpenInDefaultBrowser,
|
|
547
|
-
onOpenInFileViewer,
|
|
548
|
-
onOpenWithApplication,
|
|
549
|
-
onOpenWithOtherApplication
|
|
314
|
+
function ContextMenuSubmenu({
|
|
315
|
+
item,
|
|
316
|
+
onClose
|
|
550
317
|
}) {
|
|
551
318
|
const triggerRef = useRef(null);
|
|
552
319
|
const triggerButtonRef = useRef(null);
|
|
553
320
|
const submenuRef = useRef(null);
|
|
554
321
|
const focusSubmenuOnOpenRef = useRef(false);
|
|
555
322
|
const [open, setOpen] = useState(false);
|
|
323
|
+
const controlledChildren = item.children;
|
|
324
|
+
const [asyncChildren, setAsyncChildren] = useState(null);
|
|
325
|
+
const [asyncLoading, setAsyncLoading] = useState(false);
|
|
556
326
|
const [submenuPosition, setSubmenuPosition] = useState({
|
|
557
327
|
left: 0,
|
|
558
328
|
mode: "right",
|
|
@@ -560,21 +330,24 @@ function OpenWithMenuItem({
|
|
|
560
330
|
width: OPEN_WITH_SUBMENU_WIDTH_PX
|
|
561
331
|
});
|
|
562
332
|
const closeTimerRef = useRef(null);
|
|
563
|
-
const
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
showOpenInAppBrowser,
|
|
567
|
-
showOpenInFileViewer
|
|
568
|
-
});
|
|
333
|
+
const children = controlledChildren ?? asyncChildren ?? [];
|
|
334
|
+
const isLoading = Boolean(item.loading) || asyncLoading;
|
|
335
|
+
const childActionCount = countRenderableMenuActions(children);
|
|
569
336
|
const estimatedSubmenuHeight = estimateOpenWithSubmenuHeight({
|
|
570
|
-
applicationCount:
|
|
337
|
+
applicationCount: Math.max(0, childActionCount - 2),
|
|
571
338
|
isLoading,
|
|
572
|
-
showExternalSection,
|
|
573
|
-
showOpenInAppBrowser,
|
|
574
|
-
showOpenInDefaultBrowser,
|
|
575
|
-
showOpenInFileViewer,
|
|
576
|
-
showOpenWithOther
|
|
339
|
+
showExternalSection: childActionCount > 0 || isLoading,
|
|
340
|
+
showOpenInAppBrowser: false,
|
|
341
|
+
showOpenInDefaultBrowser: false,
|
|
342
|
+
showOpenInFileViewer: false,
|
|
343
|
+
showOpenWithOther: false
|
|
577
344
|
});
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
if (controlledChildren !== void 0) {
|
|
347
|
+
setAsyncChildren(null);
|
|
348
|
+
setAsyncLoading(false);
|
|
349
|
+
}
|
|
350
|
+
}, [controlledChildren]);
|
|
578
351
|
const cancelClose = useCallback(() => {
|
|
579
352
|
if (closeTimerRef.current !== null) {
|
|
580
353
|
window.clearTimeout(closeTimerRef.current);
|
|
@@ -588,11 +361,25 @@ function OpenWithMenuItem({
|
|
|
588
361
|
closeTimerRef.current = null;
|
|
589
362
|
}, 120);
|
|
590
363
|
}, [cancelClose]);
|
|
364
|
+
const ensureChildrenLoaded = useCallback(() => {
|
|
365
|
+
if (controlledChildren !== void 0 || asyncChildren !== null || !item.loadChildren || asyncLoading) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
setAsyncLoading(true);
|
|
369
|
+
void item.loadChildren().then((next) => {
|
|
370
|
+
setAsyncChildren(next);
|
|
371
|
+
}).catch(() => {
|
|
372
|
+
setAsyncChildren([]);
|
|
373
|
+
}).finally(() => {
|
|
374
|
+
setAsyncLoading(false);
|
|
375
|
+
});
|
|
376
|
+
}, [asyncChildren, asyncLoading, controlledChildren, item]);
|
|
591
377
|
const openSubmenu = useCallback(() => {
|
|
592
378
|
focusSubmenuOnOpenRef.current = false;
|
|
593
379
|
cancelClose();
|
|
380
|
+
ensureChildrenLoaded();
|
|
594
381
|
setOpen(true);
|
|
595
|
-
}, [cancelClose]);
|
|
382
|
+
}, [cancelClose, ensureChildrenLoaded]);
|
|
596
383
|
const closeSubmenuToTrigger = useCallback(() => {
|
|
597
384
|
cancelClose();
|
|
598
385
|
setOpen(false);
|
|
@@ -633,7 +420,7 @@ function OpenWithMenuItem({
|
|
|
633
420
|
return;
|
|
634
421
|
}
|
|
635
422
|
updateSubmenuPosition();
|
|
636
|
-
}, [open, updateSubmenuPosition]);
|
|
423
|
+
}, [open, updateSubmenuPosition, children.length, isLoading]);
|
|
637
424
|
useEffect(() => {
|
|
638
425
|
if (!open) {
|
|
639
426
|
return;
|
|
@@ -675,7 +462,7 @@ function OpenWithMenuItem({
|
|
|
675
462
|
"flex h-8 w-full items-center gap-2 rounded-md border-0 bg-transparent px-2 text-left text-[13px] text-[var(--text-primary)] transition-colors hover:bg-transparency-block disabled:cursor-default disabled:opacity-50",
|
|
676
463
|
open && "bg-transparency-block"
|
|
677
464
|
),
|
|
678
|
-
disabled:
|
|
465
|
+
disabled: item.disabled,
|
|
679
466
|
role: "menuitem",
|
|
680
467
|
type: "button",
|
|
681
468
|
onClick: (event) => {
|
|
@@ -684,6 +471,7 @@ function OpenWithMenuItem({
|
|
|
684
471
|
const next = !current;
|
|
685
472
|
if (next) {
|
|
686
473
|
cancelClose();
|
|
474
|
+
ensureChildrenLoaded();
|
|
687
475
|
} else {
|
|
688
476
|
focusSubmenuOnOpenRef.current = false;
|
|
689
477
|
}
|
|
@@ -698,11 +486,12 @@ function OpenWithMenuItem({
|
|
|
698
486
|
event.stopPropagation();
|
|
699
487
|
focusSubmenuOnOpenRef.current = true;
|
|
700
488
|
cancelClose();
|
|
489
|
+
ensureChildrenLoaded();
|
|
701
490
|
setOpen(true);
|
|
702
491
|
},
|
|
703
492
|
children: [
|
|
704
|
-
/* @__PURE__ */ jsx("span", { className: "grid size-4 flex-none place-items-center text-[var(--text-secondary)]", children: /* @__PURE__ */ jsx(LaunchIcon, { className: "size-4" }) }),
|
|
705
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children:
|
|
493
|
+
/* @__PURE__ */ jsx("span", { className: "grid size-4 flex-none place-items-center text-[var(--text-secondary)]", children: item.icon ?? /* @__PURE__ */ jsx(LaunchIcon, { className: "size-4" }) }),
|
|
494
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: item.label }),
|
|
706
495
|
/* @__PURE__ */ jsx(
|
|
707
496
|
"span",
|
|
708
497
|
{
|
|
@@ -718,7 +507,8 @@ function OpenWithMenuItem({
|
|
|
718
507
|
ViewportMenuSurface,
|
|
719
508
|
{
|
|
720
509
|
ref: submenuRef,
|
|
721
|
-
"aria-label":
|
|
510
|
+
"aria-label": item.label,
|
|
511
|
+
"data-workspace-file-manager-submenu": "",
|
|
722
512
|
"data-workspace-file-manager-submenu-mode": submenuPosition.mode,
|
|
723
513
|
open,
|
|
724
514
|
className: "max-h-[min(480px,calc(100vh-24px))] max-w-[calc(100vw-24px)] overflow-y-auto p-1",
|
|
@@ -748,22 +538,22 @@ function OpenWithMenuItem({
|
|
|
748
538
|
if (event.key !== "ArrowDown" && event.key !== "ArrowUp") {
|
|
749
539
|
return;
|
|
750
540
|
}
|
|
751
|
-
const
|
|
541
|
+
const buttons = Array.from(
|
|
752
542
|
event.currentTarget.querySelectorAll(
|
|
753
543
|
"button:not(:disabled)"
|
|
754
544
|
)
|
|
755
545
|
);
|
|
756
|
-
if (
|
|
546
|
+
if (buttons.length === 0) {
|
|
757
547
|
return;
|
|
758
548
|
}
|
|
759
549
|
event.preventDefault();
|
|
760
550
|
event.stopPropagation();
|
|
761
|
-
const currentIndex =
|
|
551
|
+
const currentIndex = buttons.indexOf(
|
|
762
552
|
document.activeElement
|
|
763
553
|
);
|
|
764
554
|
const offset = event.key === "ArrowDown" ? 1 : -1;
|
|
765
|
-
const nextIndex = currentIndex < 0 ? offset > 0 ? 0 :
|
|
766
|
-
|
|
555
|
+
const nextIndex = currentIndex < 0 ? offset > 0 ? 0 : buttons.length - 1 : (currentIndex + offset + buttons.length) % buttons.length;
|
|
556
|
+
buttons[nextIndex]?.focus();
|
|
767
557
|
},
|
|
768
558
|
children: [
|
|
769
559
|
submenuPosition.mode === "overlay" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -772,97 +562,22 @@ function OpenWithMenuItem({
|
|
|
772
562
|
{
|
|
773
563
|
activateOnPointerDown: true,
|
|
774
564
|
icon: /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "size-4" }),
|
|
775
|
-
label:
|
|
565
|
+
label: item.label,
|
|
776
566
|
onClick: closeSubmenuToTrigger
|
|
777
567
|
}
|
|
778
568
|
),
|
|
779
569
|
/* @__PURE__ */ jsx(ContextMenuDivider, {})
|
|
780
570
|
] }) : null,
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
activateOnPointerDown: true,
|
|
785
|
-
disabled: busy,
|
|
786
|
-
icon: /* @__PURE__ */ jsx(EyeIcon, { className: "size-4" }),
|
|
787
|
-
label: copy.t("openInFileViewerLabel"),
|
|
788
|
-
onClick: () => {
|
|
789
|
-
const openPromise = onOpenInFileViewer();
|
|
790
|
-
onClose();
|
|
791
|
-
void openPromise;
|
|
792
|
-
}
|
|
793
|
-
}
|
|
794
|
-
) : null,
|
|
795
|
-
showOpenInAppBrowser ? /* @__PURE__ */ jsx(
|
|
796
|
-
ContextMenuActionButton,
|
|
571
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-[11px] text-[var(--text-tertiary)]", children: item.loadingLabel ?? "\u2026" }) : null,
|
|
572
|
+
children.map((child) => /* @__PURE__ */ jsx(
|
|
573
|
+
ContextMenuItemRenderer,
|
|
797
574
|
{
|
|
798
575
|
activateOnPointerDown: true,
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
onClose();
|
|
805
|
-
void openPromise;
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
) : null,
|
|
809
|
-
showSectionDivider ? /* @__PURE__ */ jsx(ContextMenuDivider, {}) : null,
|
|
810
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-[11px] text-[var(--text-tertiary)]", children: copy.t("openWithLoadingLabel") }) : null,
|
|
811
|
-
applications.map((application) => {
|
|
812
|
-
const resolvedIcon = resolveOpenWithApplicationIcon?.(application);
|
|
813
|
-
return /* @__PURE__ */ jsx(
|
|
814
|
-
ContextMenuActionButton,
|
|
815
|
-
{
|
|
816
|
-
activateOnPointerDown: true,
|
|
817
|
-
disabled: busy,
|
|
818
|
-
icon: resolvedIcon ?? (application.iconDataUrl ? /* @__PURE__ */ jsx(
|
|
819
|
-
"img",
|
|
820
|
-
{
|
|
821
|
-
alt: "",
|
|
822
|
-
className: "size-4 rounded-[4px] object-contain",
|
|
823
|
-
src: application.iconDataUrl
|
|
824
|
-
}
|
|
825
|
-
) : /* @__PURE__ */ jsx(EyeIcon, { className: "size-4" })),
|
|
826
|
-
label: application.name,
|
|
827
|
-
onClick: () => {
|
|
828
|
-
const openPromise = onOpenWithApplication(
|
|
829
|
-
application.applicationPath
|
|
830
|
-
);
|
|
831
|
-
onClose();
|
|
832
|
-
void openPromise;
|
|
833
|
-
}
|
|
834
|
-
},
|
|
835
|
-
application.applicationPath
|
|
836
|
-
);
|
|
837
|
-
}),
|
|
838
|
-
showOpenInDefaultBrowser ? /* @__PURE__ */ jsx(
|
|
839
|
-
ContextMenuActionButton,
|
|
840
|
-
{
|
|
841
|
-
activateOnPointerDown: true,
|
|
842
|
-
disabled: busy,
|
|
843
|
-
icon: /* @__PURE__ */ jsx(WebIcon, { className: "size-4" }),
|
|
844
|
-
label: copy.t("openInDefaultBrowserLabel"),
|
|
845
|
-
onClick: () => {
|
|
846
|
-
const openPromise = onOpenInDefaultBrowser();
|
|
847
|
-
onClose();
|
|
848
|
-
void openPromise;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
) : null,
|
|
852
|
-
showOpenWithOther ? /* @__PURE__ */ jsx(
|
|
853
|
-
ContextMenuActionButton,
|
|
854
|
-
{
|
|
855
|
-
activateOnPointerDown: true,
|
|
856
|
-
disabled: busy,
|
|
857
|
-
icon: /* @__PURE__ */ jsx(LaunchIcon, { className: "size-4" }),
|
|
858
|
-
label: copy.t("openWithOtherLabel"),
|
|
859
|
-
onClick: () => {
|
|
860
|
-
const openPromise = onOpenWithOtherApplication();
|
|
861
|
-
onClose();
|
|
862
|
-
void openPromise;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
) : null
|
|
576
|
+
item: child,
|
|
577
|
+
onClose
|
|
578
|
+
},
|
|
579
|
+
child.id
|
|
580
|
+
))
|
|
866
581
|
]
|
|
867
582
|
}
|
|
868
583
|
)
|
|
@@ -870,6 +585,17 @@ function OpenWithMenuItem({
|
|
|
870
585
|
}
|
|
871
586
|
);
|
|
872
587
|
}
|
|
588
|
+
function countRenderableMenuActions(items) {
|
|
589
|
+
let count = 0;
|
|
590
|
+
for (const item of items) {
|
|
591
|
+
if (item.type === "item") {
|
|
592
|
+
count += 1;
|
|
593
|
+
} else if (item.type === "submenu") {
|
|
594
|
+
count += 1 + countRenderableMenuActions(item.children ?? []);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return count;
|
|
598
|
+
}
|
|
873
599
|
|
|
874
600
|
// src/ui/useWorkspaceFileManagerService.ts
|
|
875
601
|
import { useSnapshot } from "valtio";
|
|
@@ -877,21 +603,7 @@ import { useSnapshot } from "valtio";
|
|
|
877
603
|
// src/services/internal/workspaceFileManagerViewModel.ts
|
|
878
604
|
function resolveWorkspaceFileManagerRootViewState(input) {
|
|
879
605
|
const { state } = input;
|
|
880
|
-
const isRecentLocation = isWorkspaceFileRecentLocation(
|
|
881
|
-
findWorkspaceFileLocationById(
|
|
882
|
-
state.locationSections,
|
|
883
|
-
state.selectedLocationId
|
|
884
|
-
)
|
|
885
|
-
);
|
|
886
|
-
const isExternalLocation = isWorkspaceFileExternalLocation(
|
|
887
|
-
findWorkspaceFileLocationById(
|
|
888
|
-
state.locationSections,
|
|
889
|
-
state.selectedLocationId
|
|
890
|
-
)
|
|
891
|
-
);
|
|
892
|
-
const isSearchMode = state.searchQuery.trim().length > 0;
|
|
893
606
|
return {
|
|
894
|
-
canImportFromDrop: state.capabilities.canImportFromDrop && !isRecentLocation && !isExternalLocation && !isSearchMode,
|
|
895
607
|
currentDirectoryPath: state.currentDirectoryPath,
|
|
896
608
|
isBusy: state.busyAction !== null,
|
|
897
609
|
locationSections: state.locationSections,
|
|
@@ -918,9 +630,7 @@ function resolveWorkspaceFileManagerToolbarViewState(input) {
|
|
|
918
630
|
isLoading: state.isLoading,
|
|
919
631
|
isMutating: state.isMutating,
|
|
920
632
|
isSearching: state.isSearching,
|
|
921
|
-
searchQuery: state.searchQuery
|
|
922
|
-
isImporting: state.busyAction === "import",
|
|
923
|
-
showImportAction: state.capabilities.canImportFromPicker
|
|
633
|
+
searchQuery: state.searchQuery
|
|
924
634
|
};
|
|
925
635
|
}
|
|
926
636
|
function resolveWorkspaceFileManagerPanelsViewState(input) {
|
|
@@ -954,8 +664,7 @@ function resolveWorkspaceFileManagerPanelsViewState(input) {
|
|
|
954
664
|
searchError: state.searchError,
|
|
955
665
|
searchQuery: state.searchQuery,
|
|
956
666
|
selectedEntry: findSelectedEntry(state),
|
|
957
|
-
selectedPath: state.selectedPath
|
|
958
|
-
showDropOverlay: state.capabilities.canImportFromDrop && !isExternalLocation && state.dragDepth > 0 && state.busyAction === null
|
|
667
|
+
selectedPath: state.selectedPath
|
|
959
668
|
};
|
|
960
669
|
}
|
|
961
670
|
function resolveWorkspaceFileManagerDialogsViewState(input) {
|
|
@@ -966,7 +675,6 @@ function resolveWorkspaceFileManagerDialogsViewState(input) {
|
|
|
966
675
|
deleteDialogEntry: state.deleteDialog ? findEntry(state, state.deleteDialog.entryPath) : null,
|
|
967
676
|
isBusy: state.busyAction !== null,
|
|
968
677
|
isDeleting: state.busyAction === "delete",
|
|
969
|
-
isImporting: state.busyAction === "import",
|
|
970
678
|
isRenaming: state.busyAction === "rename",
|
|
971
679
|
isViewing: state.busyAction === "view",
|
|
972
680
|
unsupportedDialog: state.unsupportedDialog ? {
|
|
@@ -975,27 +683,12 @@ function resolveWorkspaceFileManagerDialogsViewState(input) {
|
|
|
975
683
|
kind: state.unsupportedDialog.kind,
|
|
976
684
|
message: state.unsupportedDialog.message,
|
|
977
685
|
title: state.unsupportedDialog.title
|
|
978
|
-
} : null
|
|
979
|
-
importConflictDialog: state.importConflictDialog
|
|
686
|
+
} : null
|
|
980
687
|
};
|
|
981
688
|
}
|
|
982
689
|
function resolveWorkspaceFileManagerContextMenuViewState(input) {
|
|
983
690
|
const { state } = input;
|
|
984
|
-
const isRecentLocation = isWorkspaceFileRecentLocation(
|
|
985
|
-
findWorkspaceFileLocationById(
|
|
986
|
-
state.locationSections,
|
|
987
|
-
state.selectedLocationId
|
|
988
|
-
)
|
|
989
|
-
);
|
|
990
|
-
const isExternalLocation = isWorkspaceFileExternalLocation(
|
|
991
|
-
findWorkspaceFileLocationById(
|
|
992
|
-
state.locationSections,
|
|
993
|
-
state.selectedLocationId
|
|
994
|
-
)
|
|
995
|
-
);
|
|
996
|
-
const isSearchMode = state.searchQuery.trim().length > 0;
|
|
997
691
|
const contextMenuEntry = state.contextMenu?.entryPath ? findEntry(state, state.contextMenu.entryPath) : null;
|
|
998
|
-
const isContextMenuFile = contextMenuEntry?.kind === "file";
|
|
999
692
|
return {
|
|
1000
693
|
contextMenu: state.contextMenu ? {
|
|
1001
694
|
entry: contextMenuEntry,
|
|
@@ -1005,21 +698,7 @@ function resolveWorkspaceFileManagerContextMenuViewState(input) {
|
|
|
1005
698
|
currentDirectoryPath: state.currentDirectoryPath,
|
|
1006
699
|
isBusy: state.busyAction !== null,
|
|
1007
700
|
isLoading: state.isLoading,
|
|
1008
|
-
isMutating: state.isMutating
|
|
1009
|
-
showCreateDirectoryAction: !isExternalLocation && !isRecentLocation && !isSearchMode && state.capabilities.canCreateDirectory,
|
|
1010
|
-
showCreateFileAction: !isExternalLocation && !isRecentLocation && !isSearchMode && state.capabilities.canCreateFile,
|
|
1011
|
-
showCopyAction: state.capabilities.canCopy,
|
|
1012
|
-
showDeleteAction: state.capabilities.canDelete && !isExternalLocation && !isRecentLocation && !isSearchMode,
|
|
1013
|
-
showExportAction: state.capabilities.canExport && !isExternalLocation,
|
|
1014
|
-
showImportAction: state.capabilities.canImportFromPicker && !isExternalLocation && !isRecentLocation && !isSearchMode,
|
|
1015
|
-
showMoveAction: state.capabilities.canMove && !isExternalLocation && !isRecentLocation && !isSearchMode,
|
|
1016
|
-
showOpenInAppBrowserAction: state.capabilities.canOpenInAppBrowser && !isExternalLocation,
|
|
1017
|
-
showOpenInDefaultBrowserAction: state.capabilities.canOpenInDefaultBrowser,
|
|
1018
|
-
showOpenInFileViewerAction: contextMenuEntry !== null && isContextMenuFile && resolveWorkspaceFileActivationTarget(contextMenuEntry) !== null,
|
|
1019
|
-
showOpenWithAction: state.capabilities.canOpenWith && isContextMenuFile,
|
|
1020
|
-
showOpenWithOtherAction: state.capabilities.canPickOtherOpenWithApplication && isContextMenuFile,
|
|
1021
|
-
showRevealInFolderAction: state.capabilities.canRevealInFolder && !isExternalLocation,
|
|
1022
|
-
showRenameAction: state.capabilities.canRename && !isExternalLocation && !isRecentLocation && !isSearchMode
|
|
701
|
+
isMutating: state.isMutating
|
|
1023
702
|
};
|
|
1024
703
|
}
|
|
1025
704
|
function findSelectedEntry(state) {
|
|
@@ -1081,198 +760,112 @@ function useWorkspaceFileManagerContextMenuView(session) {
|
|
|
1081
760
|
};
|
|
1082
761
|
}
|
|
1083
762
|
|
|
763
|
+
// src/ui/workspaceFileManagerContextMenuTypes.ts
|
|
764
|
+
function resolveWorkspaceFileManagerContextMenuTarget(input) {
|
|
765
|
+
if (!input.entry) {
|
|
766
|
+
return {
|
|
767
|
+
kind: "blank",
|
|
768
|
+
directoryPath: input.currentDirectoryPath
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
if (input.entry.kind === "directory") {
|
|
772
|
+
return {
|
|
773
|
+
kind: "directory",
|
|
774
|
+
directoryPath: input.currentDirectoryPath,
|
|
775
|
+
entry: input.entry
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
return {
|
|
779
|
+
kind: "file",
|
|
780
|
+
directoryPath: input.currentDirectoryPath,
|
|
781
|
+
entry: input.entry
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
|
|
1084
785
|
// src/ui/WorkspaceFileManagerContextMenuContainer.tsx
|
|
1085
786
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1086
787
|
function WorkspaceFileManagerContextMenuContainer({
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
onCopyEntry,
|
|
1090
|
-
onCopyPath,
|
|
1091
|
-
openInAppBrowserIcon,
|
|
1092
|
-
resolveOpenWithApplicationIcon,
|
|
1093
|
-
session,
|
|
1094
|
-
showInternalOpenWithActions
|
|
788
|
+
resolveContextMenu,
|
|
789
|
+
session
|
|
1095
790
|
}) {
|
|
1096
791
|
const contextMenuRef = useRef2(null);
|
|
1097
792
|
const { view } = useWorkspaceFileManagerContextMenuView(session);
|
|
1098
|
-
const [
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
if (!entry || !view.showOpenWithAction) {
|
|
1103
|
-
setOpenWithApplications([]);
|
|
1104
|
-
setOpenWithLoading(false);
|
|
793
|
+
const [items, setItems] = useState2([]);
|
|
794
|
+
useLayoutEffect2(() => {
|
|
795
|
+
if (!view.contextMenu) {
|
|
796
|
+
setItems([]);
|
|
1105
797
|
return;
|
|
1106
798
|
}
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
799
|
+
const request = buildContextMenuRequest({
|
|
800
|
+
session,
|
|
801
|
+
view
|
|
802
|
+
});
|
|
803
|
+
const resolved = resolveContextMenu(request);
|
|
804
|
+
if (!isPromiseLike(resolved)) {
|
|
805
|
+
setItems(resolved);
|
|
1111
806
|
return;
|
|
1112
807
|
}
|
|
1113
808
|
let cancelled = false;
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
return;
|
|
809
|
+
setItems([]);
|
|
810
|
+
void resolved.then((nextItems) => {
|
|
811
|
+
if (!cancelled) {
|
|
812
|
+
setItems(nextItems);
|
|
1119
813
|
}
|
|
1120
|
-
setOpenWithApplications(applications);
|
|
1121
|
-
setOpenWithLoading(false);
|
|
1122
|
-
}).catch(() => {
|
|
1123
|
-
if (cancelled) {
|
|
1124
|
-
return;
|
|
1125
|
-
}
|
|
1126
|
-
setOpenWithApplications([]);
|
|
1127
|
-
setOpenWithLoading(false);
|
|
1128
814
|
});
|
|
1129
815
|
return () => {
|
|
1130
816
|
cancelled = true;
|
|
1131
817
|
};
|
|
1132
|
-
}, [
|
|
818
|
+
}, [
|
|
819
|
+
resolveContextMenu,
|
|
820
|
+
session,
|
|
821
|
+
view.contextMenu,
|
|
822
|
+
view.currentDirectoryPath,
|
|
823
|
+
view.isBusy,
|
|
824
|
+
view.isLoading,
|
|
825
|
+
view.isMutating
|
|
826
|
+
]);
|
|
1133
827
|
useCloseContextMenuOnOutsideInteraction({
|
|
1134
828
|
contextMenuRef,
|
|
1135
829
|
isOpen: view.contextMenu !== null,
|
|
1136
830
|
session
|
|
1137
831
|
});
|
|
832
|
+
if (!view.contextMenu) {
|
|
833
|
+
return null;
|
|
834
|
+
}
|
|
1138
835
|
return /* @__PURE__ */ jsx2(
|
|
1139
836
|
WorkspaceFileManagerContextMenu,
|
|
1140
837
|
{
|
|
1141
|
-
|
|
1142
|
-
copy: i18n,
|
|
1143
|
-
contextMenu: view.contextMenu,
|
|
838
|
+
contextMenu: { x: view.contextMenu.x, y: view.contextMenu.y },
|
|
1144
839
|
contextMenuRef,
|
|
1145
|
-
|
|
1146
|
-
showCopyPathAction: true,
|
|
1147
|
-
showCreateDirectoryAction: view.contextMenu?.entry === null && view.showCreateDirectoryAction,
|
|
1148
|
-
showCreateFileAction: view.contextMenu?.entry === null && view.showCreateFileAction,
|
|
1149
|
-
showDeleteAction: view.showDeleteAction,
|
|
1150
|
-
showImportAction: view.showImportAction,
|
|
1151
|
-
showExportAction: view.showExportAction,
|
|
1152
|
-
showOpenInAppBrowserAction: showInternalOpenWithActions && view.showOpenInAppBrowserAction && !!view.contextMenu?.entry && isWorkspaceFileBrowserOpenable(view.contextMenu.entry),
|
|
1153
|
-
showOpenInDefaultBrowserAction: view.showOpenInDefaultBrowserAction && !!view.contextMenu?.entry && isWorkspaceFileBrowserOpenable(view.contextMenu.entry),
|
|
1154
|
-
showOpenInFileViewerAction: showInternalOpenWithActions && view.showOpenInFileViewerAction,
|
|
1155
|
-
showOpenAction: true,
|
|
1156
|
-
showOpenWithAction: view.showOpenWithAction,
|
|
1157
|
-
showOpenWithOtherAction: view.showOpenWithOtherAction,
|
|
1158
|
-
showRevealInFolderAction: view.showRevealInFolderAction,
|
|
1159
|
-
showRenameAction: view.showRenameAction,
|
|
1160
|
-
revealInFolderLabel: resolveRevealInFolderLabel(i18n, hostOs),
|
|
1161
|
-
openInAppBrowserIcon,
|
|
1162
|
-
openWithApplications,
|
|
1163
|
-
openWithLoading,
|
|
1164
|
-
resolveOpenWithApplicationIcon,
|
|
840
|
+
items,
|
|
1165
841
|
onClose: () => {
|
|
1166
842
|
session.closeContextMenu();
|
|
1167
|
-
},
|
|
1168
|
-
onCreateDirectory: () => {
|
|
1169
|
-
session.openCreateDirectoryDialog();
|
|
1170
|
-
},
|
|
1171
|
-
onCreateFile: () => {
|
|
1172
|
-
session.openCreateFileDialog();
|
|
1173
|
-
},
|
|
1174
|
-
onCopy: async () => {
|
|
1175
|
-
const entry = view.contextMenu?.entry;
|
|
1176
|
-
if (!entry) {
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
session.closeContextMenu();
|
|
1180
|
-
await session.copyToClipboard(entry);
|
|
1181
|
-
if (onCopyEntry) {
|
|
1182
|
-
await onCopyEntry();
|
|
1183
|
-
}
|
|
1184
|
-
},
|
|
1185
|
-
onCopyPath: async () => {
|
|
1186
|
-
const path = view.contextMenu?.entry?.path;
|
|
1187
|
-
if (!path) {
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
session.closeContextMenu();
|
|
1191
|
-
if (onCopyPath) {
|
|
1192
|
-
await onCopyPath(path);
|
|
1193
|
-
return;
|
|
1194
|
-
}
|
|
1195
|
-
await navigator.clipboard.writeText(path);
|
|
1196
|
-
},
|
|
1197
|
-
onDelete: () => {
|
|
1198
|
-
const entry = view.contextMenu?.entry;
|
|
1199
|
-
if (!entry) {
|
|
1200
|
-
return;
|
|
1201
|
-
}
|
|
1202
|
-
session.openDeleteDialog(entry);
|
|
1203
|
-
},
|
|
1204
|
-
onRename: () => {
|
|
1205
|
-
const entry = view.contextMenu?.entry;
|
|
1206
|
-
if (!entry) {
|
|
1207
|
-
return;
|
|
1208
|
-
}
|
|
1209
|
-
session.startInlineRename(entry);
|
|
1210
|
-
},
|
|
1211
|
-
onExport: async () => {
|
|
1212
|
-
const entry = view.contextMenu?.entry;
|
|
1213
|
-
if (!entry) {
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
await session.exportEntry(entry);
|
|
1217
|
-
},
|
|
1218
|
-
onOpen: async () => {
|
|
1219
|
-
const entry = view.contextMenu?.entry;
|
|
1220
|
-
if (!entry) {
|
|
1221
|
-
return;
|
|
1222
|
-
}
|
|
1223
|
-
await session.openEntry(entry);
|
|
1224
|
-
},
|
|
1225
|
-
onOpenInAppBrowser: async () => {
|
|
1226
|
-
const entry = view.contextMenu?.entry;
|
|
1227
|
-
if (!entry) {
|
|
1228
|
-
return;
|
|
1229
|
-
}
|
|
1230
|
-
await session.openFileInAppBrowser(entry);
|
|
1231
|
-
},
|
|
1232
|
-
onOpenInDefaultBrowser: async () => {
|
|
1233
|
-
const entry = view.contextMenu?.entry;
|
|
1234
|
-
if (!entry) {
|
|
1235
|
-
return;
|
|
1236
|
-
}
|
|
1237
|
-
await session.openFileInDefaultBrowser(entry);
|
|
1238
|
-
},
|
|
1239
|
-
onOpenInFileViewer: async () => {
|
|
1240
|
-
const entry = view.contextMenu?.entry;
|
|
1241
|
-
if (!entry) {
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
await session.openFileInFileViewer(entry);
|
|
1245
|
-
},
|
|
1246
|
-
onOpenWithApplication: async (applicationPath) => {
|
|
1247
|
-
const entry = view.contextMenu?.entry;
|
|
1248
|
-
if (!entry) {
|
|
1249
|
-
return;
|
|
1250
|
-
}
|
|
1251
|
-
await session.openFileWithApplication(entry, applicationPath);
|
|
1252
|
-
},
|
|
1253
|
-
onOpenWithOtherApplication: async () => {
|
|
1254
|
-
const entry = view.contextMenu?.entry;
|
|
1255
|
-
if (!entry) {
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
await session.openFileWithOtherApplication(entry);
|
|
1259
|
-
},
|
|
1260
|
-
onRevealInFolder: async () => {
|
|
1261
|
-
const entry = view.contextMenu?.entry;
|
|
1262
|
-
if (!entry) {
|
|
1263
|
-
return;
|
|
1264
|
-
}
|
|
1265
|
-
await session.revealEntry(entry);
|
|
1266
|
-
},
|
|
1267
|
-
onImport: async () => {
|
|
1268
|
-
session.closeContextMenu();
|
|
1269
|
-
await session.importFiles(
|
|
1270
|
-
view.contextMenu?.entry?.kind === "directory" ? view.contextMenu.entry.path : view.currentDirectoryPath
|
|
1271
|
-
);
|
|
1272
843
|
}
|
|
1273
844
|
}
|
|
1274
845
|
);
|
|
1275
846
|
}
|
|
847
|
+
function buildContextMenuRequest(input) {
|
|
848
|
+
const { session, view } = input;
|
|
849
|
+
const location = findWorkspaceFileLocationById(
|
|
850
|
+
session.store.locationSections,
|
|
851
|
+
session.store.selectedLocationId
|
|
852
|
+
);
|
|
853
|
+
return {
|
|
854
|
+
currentDirectoryPath: view.currentDirectoryPath,
|
|
855
|
+
isBusy: view.isBusy || view.isLoading || view.isMutating,
|
|
856
|
+
isExternalLocation: isWorkspaceFileExternalLocation(location),
|
|
857
|
+
isRecentLocation: isWorkspaceFileRecentLocation(location),
|
|
858
|
+
isSearchMode: session.store.searchQuery.trim().length > 0,
|
|
859
|
+
selectedLocationId: session.store.selectedLocationId,
|
|
860
|
+
target: resolveWorkspaceFileManagerContextMenuTarget({
|
|
861
|
+
currentDirectoryPath: view.currentDirectoryPath,
|
|
862
|
+
entry: view.contextMenu?.entry ?? null
|
|
863
|
+
})
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
function isPromiseLike(value) {
|
|
867
|
+
return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
|
|
868
|
+
}
|
|
1276
869
|
function useCloseContextMenuOnOutsideInteraction(input) {
|
|
1277
870
|
const { contextMenuRef, isOpen, session } = input;
|
|
1278
871
|
useEffect2(() => {
|
|
@@ -1417,8 +1010,8 @@ function WorkspaceFileManagerUnsupportedDialog({
|
|
|
1417
1010
|
if (!dialog) {
|
|
1418
1011
|
return null;
|
|
1419
1012
|
}
|
|
1420
|
-
const title = dialog.title ??
|
|
1421
|
-
const body = dialog.message ??
|
|
1013
|
+
const title = dialog.title ?? copy.t("unsupportedViewTitle");
|
|
1014
|
+
const body = dialog.message ?? copy.t("unsupportedViewBody", { name: dialog.entry?.name ?? "" });
|
|
1422
1015
|
const actions = dialog.actions?.filter((action) => action.kind !== "none") ?? [];
|
|
1423
1016
|
return /* @__PURE__ */ jsx3(
|
|
1424
1017
|
Dialog,
|
|
@@ -1481,122 +1074,6 @@ function WorkspaceFileManagerUnsupportedDialog({
|
|
|
1481
1074
|
}
|
|
1482
1075
|
);
|
|
1483
1076
|
}
|
|
1484
|
-
function WorkspaceFileManagerImportConflictDialog({
|
|
1485
|
-
busy,
|
|
1486
|
-
copy,
|
|
1487
|
-
dialog,
|
|
1488
|
-
onClose,
|
|
1489
|
-
onConfirm
|
|
1490
|
-
}) {
|
|
1491
|
-
if (!dialog) {
|
|
1492
|
-
return null;
|
|
1493
|
-
}
|
|
1494
|
-
const hasBlockedConflict = dialog.conflicts.some(
|
|
1495
|
-
(conflict) => conflict.conflictKind === "type_mismatch"
|
|
1496
|
-
);
|
|
1497
|
-
return /* @__PURE__ */ jsxs2(
|
|
1498
|
-
ConfirmationDialog,
|
|
1499
|
-
{
|
|
1500
|
-
cancelLabel: hasBlockedConflict ? copy.t("closeLabel") : copy.t("cancelLabel"),
|
|
1501
|
-
className: "max-w-lg",
|
|
1502
|
-
confirmBusy: busy,
|
|
1503
|
-
confirmLabel: hasBlockedConflict ? copy.t("closeLabel") : copy.t("importConflictReplaceLabel"),
|
|
1504
|
-
description: hasBlockedConflict ? copy.t("importTypeConflictDescription", {
|
|
1505
|
-
count: dialog.conflicts.length
|
|
1506
|
-
}) : copy.t("importConflictDescription", {
|
|
1507
|
-
count: dialog.conflicts.length
|
|
1508
|
-
}),
|
|
1509
|
-
hideConfirmButton: hasBlockedConflict,
|
|
1510
|
-
open: true,
|
|
1511
|
-
title: hasBlockedConflict ? copy.t("importTypeConflictTitle") : copy.t("importConflictTitle"),
|
|
1512
|
-
tone: hasBlockedConflict ? "default" : "destructive",
|
|
1513
|
-
onConfirm: hasBlockedConflict ? onClose : onConfirm,
|
|
1514
|
-
onOpenChange: (nextOpen) => {
|
|
1515
|
-
if (!nextOpen) {
|
|
1516
|
-
onClose();
|
|
1517
|
-
}
|
|
1518
|
-
},
|
|
1519
|
-
children: [
|
|
1520
|
-
/* @__PURE__ */ jsx3(ImportConflictSummary, { copy, dialog }),
|
|
1521
|
-
/* @__PURE__ */ jsx3("div", { className: "max-h-60 overflow-auto rounded-lg border border-[var(--border-1)] bg-transparency-block", children: /* @__PURE__ */ jsx3("div", { className: "divide-y divide-[var(--border-1)]", children: dialog.conflicts.map((conflict) => /* @__PURE__ */ jsxs2(
|
|
1522
|
-
"div",
|
|
1523
|
-
{
|
|
1524
|
-
className: "flex flex-col gap-1 px-4 py-3 text-[13px]",
|
|
1525
|
-
children: [
|
|
1526
|
-
/* @__PURE__ */ jsx3("span", { className: "font-medium text-[var(--text-primary)]", children: conflict.name }),
|
|
1527
|
-
/* @__PURE__ */ jsxs2("span", { className: "text-[11px] text-[var(--text-secondary)]", children: [
|
|
1528
|
-
copy.t("importConflictReviewLabel"),
|
|
1529
|
-
":",
|
|
1530
|
-
" ",
|
|
1531
|
-
conflict.destinationPath
|
|
1532
|
-
] })
|
|
1533
|
-
]
|
|
1534
|
-
},
|
|
1535
|
-
`${conflict.destinationPath}:${conflict.sourcePath}`
|
|
1536
|
-
)) }) })
|
|
1537
|
-
]
|
|
1538
|
-
}
|
|
1539
|
-
);
|
|
1540
|
-
}
|
|
1541
|
-
function ImportConflictSummary({
|
|
1542
|
-
copy,
|
|
1543
|
-
dialog
|
|
1544
|
-
}) {
|
|
1545
|
-
const summaryItems = [];
|
|
1546
|
-
const hasReasonBreakdown = dialog.summary?.reasonBreakdown?.some((reason) => reason.count > 0) ?? false;
|
|
1547
|
-
if (typeof dialog.summary?.selectedCount === "number" && dialog.summary.selectedCount > 0) {
|
|
1548
|
-
summaryItems.push(
|
|
1549
|
-
copy.t("importConflictSummarySelected", {
|
|
1550
|
-
count: dialog.summary.selectedCount
|
|
1551
|
-
})
|
|
1552
|
-
);
|
|
1553
|
-
}
|
|
1554
|
-
if (!hasReasonBreakdown && typeof dialog.summary?.filteredCount === "number" && dialog.summary.filteredCount > 0) {
|
|
1555
|
-
summaryItems.push(
|
|
1556
|
-
copy.t("importConflictSummaryFiltered", {
|
|
1557
|
-
count: dialog.summary.filteredCount
|
|
1558
|
-
})
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
if (!hasReasonBreakdown && typeof dialog.summary?.ignoredCount === "number" && dialog.summary.ignoredCount > 0) {
|
|
1562
|
-
summaryItems.push(
|
|
1563
|
-
copy.t("importConflictSummaryIgnored", {
|
|
1564
|
-
count: dialog.summary.ignoredCount
|
|
1565
|
-
})
|
|
1566
|
-
);
|
|
1567
|
-
}
|
|
1568
|
-
for (const reason of dialog.summary?.reasonBreakdown ?? []) {
|
|
1569
|
-
if (reason.count <= 0) {
|
|
1570
|
-
continue;
|
|
1571
|
-
}
|
|
1572
|
-
const copyKey = importSummaryReasonCopyKey(reason.reason);
|
|
1573
|
-
if (!copyKey) {
|
|
1574
|
-
continue;
|
|
1575
|
-
}
|
|
1576
|
-
summaryItems.push(copy.t(copyKey, { count: reason.count }));
|
|
1577
|
-
}
|
|
1578
|
-
if (summaryItems.length === 0) {
|
|
1579
|
-
return null;
|
|
1580
|
-
}
|
|
1581
|
-
return /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-2 text-[11px] text-[var(--text-secondary)]", children: summaryItems.map((item) => /* @__PURE__ */ jsx3(
|
|
1582
|
-
"span",
|
|
1583
|
-
{
|
|
1584
|
-
className: "rounded-md border border-[var(--border-1)] px-2 py-1",
|
|
1585
|
-
children: item
|
|
1586
|
-
},
|
|
1587
|
-
item
|
|
1588
|
-
)) });
|
|
1589
|
-
}
|
|
1590
|
-
function importSummaryReasonCopyKey(reason) {
|
|
1591
|
-
switch (reason) {
|
|
1592
|
-
case "ignored":
|
|
1593
|
-
return "importConflictSummaryReasonIgnored";
|
|
1594
|
-
case "symlink":
|
|
1595
|
-
return "importConflictSummaryReasonSymlink";
|
|
1596
|
-
case "system_metadata":
|
|
1597
|
-
return "importConflictSummaryReasonSystemMetadata";
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
1077
|
|
|
1601
1078
|
// src/ui/WorkspaceFileManagerPanels.tsx
|
|
1602
1079
|
import {
|
|
@@ -1613,7 +1090,7 @@ import { WorkspaceFilePreviewSurface as SharedWorkspaceFilePreviewSurface } from
|
|
|
1613
1090
|
import {
|
|
1614
1091
|
useCallback as useCallback2,
|
|
1615
1092
|
useEffect as useEffect4,
|
|
1616
|
-
useLayoutEffect as
|
|
1093
|
+
useLayoutEffect as useLayoutEffect4,
|
|
1617
1094
|
useMemo,
|
|
1618
1095
|
useRef as useRef5,
|
|
1619
1096
|
useState as useState3
|
|
@@ -1621,7 +1098,7 @@ import {
|
|
|
1621
1098
|
|
|
1622
1099
|
// src/ui/WorkspaceFileManagerIconGrid.tsx
|
|
1623
1100
|
import { cn as cn3 } from "@tutti-os/ui-system";
|
|
1624
|
-
import { useLayoutEffect as
|
|
1101
|
+
import { useLayoutEffect as useLayoutEffect3, useRef as useRef4 } from "react";
|
|
1625
1102
|
|
|
1626
1103
|
// src/ui/WorkspaceFileEntryIcon.tsx
|
|
1627
1104
|
import {
|
|
@@ -1986,7 +1463,7 @@ function WorkspaceFileManagerIconTile({
|
|
|
1986
1463
|
}) {
|
|
1987
1464
|
const buttonRef = useRef4(null);
|
|
1988
1465
|
const nameParts = splitWorkspaceFileName(entry.name);
|
|
1989
|
-
|
|
1466
|
+
useLayoutEffect3(() => {
|
|
1990
1467
|
if (!selected) {
|
|
1991
1468
|
return;
|
|
1992
1469
|
}
|
|
@@ -2088,7 +1565,7 @@ function IconTileRenameInput({
|
|
|
2088
1565
|
const nameParts = splitWorkspaceFileName(entry.name);
|
|
2089
1566
|
const hasFileExtension = nameParts.end.length > 0 && nameParts.end.startsWith(".");
|
|
2090
1567
|
const inputRef = useRef4(null);
|
|
2091
|
-
|
|
1568
|
+
useLayoutEffect3(() => {
|
|
2092
1569
|
const input = inputRef.current;
|
|
2093
1570
|
if (!input) {
|
|
2094
1571
|
return;
|
|
@@ -2266,7 +1743,6 @@ function WorkspaceFileManagerPanels({
|
|
|
2266
1743
|
selectedPath,
|
|
2267
1744
|
showPreviewPanel: showPreviewPanelEnabled = true,
|
|
2268
1745
|
state,
|
|
2269
|
-
showDropOverlay,
|
|
2270
1746
|
treeRows,
|
|
2271
1747
|
onBlankContextMenu,
|
|
2272
1748
|
onCancelInlineRename,
|
|
@@ -2517,7 +1993,7 @@ function WorkspaceFileManagerPanels({
|
|
|
2517
1993
|
containerWidth - workspaceFileManagerTableMinWidth
|
|
2518
1994
|
);
|
|
2519
1995
|
}, [rootRef]);
|
|
2520
|
-
|
|
1996
|
+
useLayoutEffect4(() => {
|
|
2521
1997
|
const element = rootRef.current;
|
|
2522
1998
|
if (!element || useStackedPreview || !showPreviewPanel) {
|
|
2523
1999
|
return;
|
|
@@ -2813,17 +2289,6 @@ function WorkspaceFileManagerPanels({
|
|
|
2813
2289
|
]
|
|
2814
2290
|
}
|
|
2815
2291
|
),
|
|
2816
|
-
/* @__PURE__ */ jsx6(
|
|
2817
|
-
"div",
|
|
2818
|
-
{
|
|
2819
|
-
"aria-hidden": "true",
|
|
2820
|
-
className: cn4(
|
|
2821
|
-
"pointer-events-none absolute inset-0 grid place-items-center rounded-[var(--workbench-window-radius,8px)] border border-dashed border-[var(--border-focus)] bg-[var(--accent-bg)] opacity-0 transition-opacity duration-150 ease-out",
|
|
2822
|
-
showDropOverlay && "opacity-100"
|
|
2823
|
-
),
|
|
2824
|
-
children: /* @__PURE__ */ jsx6("div", { className: "rounded-lg border border-[var(--border-1)] bg-[var(--background-fronted)] px-5 py-3 text-sm font-normal text-[var(--text-primary)] shadow-panel", children: copy.t("dropToImportLabel") })
|
|
2825
|
-
}
|
|
2826
|
-
),
|
|
2827
2292
|
moveDragPreview ? /* @__PURE__ */ jsx6(
|
|
2828
2293
|
MoveDragPreview,
|
|
2829
2294
|
{
|
|
@@ -2840,7 +2305,7 @@ function WorkspaceFileManagerPanels({
|
|
|
2840
2305
|
function useWorkspaceFileManagerStackedLayout(breakpoint) {
|
|
2841
2306
|
const rootRef = useRef5(null);
|
|
2842
2307
|
const [isStacked, setIsStacked] = useState3(false);
|
|
2843
|
-
|
|
2308
|
+
useLayoutEffect4(() => {
|
|
2844
2309
|
const element = rootRef.current;
|
|
2845
2310
|
if (!element) {
|
|
2846
2311
|
return;
|
|
@@ -2917,7 +2382,7 @@ function EntryRow({
|
|
|
2917
2382
|
}) {
|
|
2918
2383
|
const buttonRowRef = useRef5(null);
|
|
2919
2384
|
const divRowRef = useRef5(null);
|
|
2920
|
-
|
|
2385
|
+
useLayoutEffect4(() => {
|
|
2921
2386
|
if (!selected) {
|
|
2922
2387
|
return;
|
|
2923
2388
|
}
|
|
@@ -3209,7 +2674,7 @@ function EntryNameCell({
|
|
|
3209
2674
|
setName(entry.name);
|
|
3210
2675
|
skipBlurRef.current = false;
|
|
3211
2676
|
}, [entry.name, entry.path, isInlineRenaming]);
|
|
3212
|
-
|
|
2677
|
+
useLayoutEffect4(() => {
|
|
3213
2678
|
if (!isInlineRenaming) {
|
|
3214
2679
|
return;
|
|
3215
2680
|
}
|
|
@@ -3460,9 +2925,6 @@ function PreviewDetail({
|
|
|
3460
2925
|
function FeedbackState({ message }) {
|
|
3461
2926
|
return /* @__PURE__ */ jsx6("div", { className: "grid min-h-0 flex-1 place-items-center p-6 text-center text-sm text-[var(--text-tertiary)]", children: /* @__PURE__ */ jsx6("span", { className: "max-w-[34ch] [overflow-wrap:anywhere]", children: message }) });
|
|
3462
2927
|
}
|
|
3463
|
-
function hasFileDragPayload(dataTransfer) {
|
|
3464
|
-
return Array.from(dataTransfer.types).includes("Files");
|
|
3465
|
-
}
|
|
3466
2928
|
|
|
3467
2929
|
// src/ui/WorkspaceFileManagerToolbar.tsx
|
|
3468
2930
|
import {
|
|
@@ -4373,16 +3835,12 @@ function WorkspaceFileManager({
|
|
|
4373
3835
|
entryDragMode,
|
|
4374
3836
|
i18n,
|
|
4375
3837
|
onCopyEntry,
|
|
4376
|
-
onCopyPath,
|
|
4377
3838
|
onDirectoryExpanded,
|
|
4378
3839
|
onEntryDragStart,
|
|
4379
|
-
|
|
4380
|
-
resolveOpenWithApplicationIcon,
|
|
3840
|
+
resolveContextMenu,
|
|
4381
3841
|
resolveEntryIconUrl,
|
|
4382
3842
|
renderExternalLocationContent,
|
|
4383
|
-
hostOs = "linux",
|
|
4384
3843
|
session,
|
|
4385
|
-
showInternalOpenWithActions = true,
|
|
4386
3844
|
showPreviewPanel = true,
|
|
4387
3845
|
surface = "card"
|
|
4388
3846
|
}) {
|
|
@@ -4423,7 +3881,7 @@ function WorkspaceFileManager({
|
|
|
4423
3881
|
},
|
|
4424
3882
|
[sidebarContentMinWidth]
|
|
4425
3883
|
);
|
|
4426
|
-
|
|
3884
|
+
useLayoutEffect5(() => {
|
|
4427
3885
|
const element = rootRef.current;
|
|
4428
3886
|
if (!element || !hasLocationSidebar) {
|
|
4429
3887
|
return;
|
|
@@ -4600,27 +4058,6 @@ function WorkspaceFileManager({
|
|
|
4600
4058
|
selectedExternalLocation,
|
|
4601
4059
|
session
|
|
4602
4060
|
]);
|
|
4603
|
-
useEffect7(() => {
|
|
4604
|
-
function resetDropOverlay() {
|
|
4605
|
-
session.resetDragDepth();
|
|
4606
|
-
}
|
|
4607
|
-
function handleDocumentDragOver(event) {
|
|
4608
|
-
if (isPointInsideElement(rootRef.current, event.clientX, event.clientY)) {
|
|
4609
|
-
return;
|
|
4610
|
-
}
|
|
4611
|
-
session.resetDragDepth();
|
|
4612
|
-
}
|
|
4613
|
-
window.addEventListener("blur", resetDropOverlay);
|
|
4614
|
-
window.addEventListener("dragend", resetDropOverlay);
|
|
4615
|
-
window.addEventListener("drop", resetDropOverlay);
|
|
4616
|
-
document.addEventListener("dragover", handleDocumentDragOver, true);
|
|
4617
|
-
return () => {
|
|
4618
|
-
window.removeEventListener("blur", resetDropOverlay);
|
|
4619
|
-
window.removeEventListener("dragend", resetDropOverlay);
|
|
4620
|
-
window.removeEventListener("drop", resetDropOverlay);
|
|
4621
|
-
document.removeEventListener("dragover", handleDocumentDragOver, true);
|
|
4622
|
-
};
|
|
4623
|
-
}, [session]);
|
|
4624
4061
|
function openContextMenu(event, entry) {
|
|
4625
4062
|
event.preventDefault();
|
|
4626
4063
|
event.stopPropagation();
|
|
@@ -4646,43 +4083,6 @@ function WorkspaceFileManager({
|
|
|
4646
4083
|
y
|
|
4647
4084
|
});
|
|
4648
4085
|
}
|
|
4649
|
-
function handleDragEnter(event) {
|
|
4650
|
-
if (!rootView.canImportFromDrop || rootView.isBusy || !hasFileDragPayload(event.dataTransfer)) {
|
|
4651
|
-
return;
|
|
4652
|
-
}
|
|
4653
|
-
event.preventDefault();
|
|
4654
|
-
session.incrementDragDepth();
|
|
4655
|
-
}
|
|
4656
|
-
function handleDragOver(event) {
|
|
4657
|
-
if (!rootView.canImportFromDrop || rootView.isBusy || !hasFileDragPayload(event.dataTransfer)) {
|
|
4658
|
-
return;
|
|
4659
|
-
}
|
|
4660
|
-
event.preventDefault();
|
|
4661
|
-
event.dataTransfer.dropEffect = "copy";
|
|
4662
|
-
}
|
|
4663
|
-
function handleDragLeave(event) {
|
|
4664
|
-
if (!rootView.canImportFromDrop || !hasFileDragPayload(event.dataTransfer)) {
|
|
4665
|
-
return;
|
|
4666
|
-
}
|
|
4667
|
-
event.preventDefault();
|
|
4668
|
-
const nextTarget = event.relatedTarget;
|
|
4669
|
-
if (nextTarget instanceof Node && rootRef.current?.contains(nextTarget)) {
|
|
4670
|
-
return;
|
|
4671
|
-
}
|
|
4672
|
-
session.resetDragDepth();
|
|
4673
|
-
}
|
|
4674
|
-
function handleDrop(event) {
|
|
4675
|
-
if (!rootView.canImportFromDrop || rootView.isBusy || !hasFileDragPayload(event.dataTransfer)) {
|
|
4676
|
-
return;
|
|
4677
|
-
}
|
|
4678
|
-
event.preventDefault();
|
|
4679
|
-
event.stopPropagation();
|
|
4680
|
-
session.resetDragDepth();
|
|
4681
|
-
void session.importDroppedFiles(
|
|
4682
|
-
event.dataTransfer,
|
|
4683
|
-
rootView.currentDirectoryPath
|
|
4684
|
-
);
|
|
4685
|
-
}
|
|
4686
4086
|
return /* @__PURE__ */ jsxs8(
|
|
4687
4087
|
"section",
|
|
4688
4088
|
{
|
|
@@ -4693,10 +4093,6 @@ function WorkspaceFileManager({
|
|
|
4693
4093
|
),
|
|
4694
4094
|
"data-slot": "viewport-menu-boundary",
|
|
4695
4095
|
"data-workspace-file-manager": "",
|
|
4696
|
-
onDragEnter: handleDragEnter,
|
|
4697
|
-
onDragLeave: handleDragLeave,
|
|
4698
|
-
onDragOver: handleDragOver,
|
|
4699
|
-
onDrop: handleDrop,
|
|
4700
4096
|
ref: rootRef,
|
|
4701
4097
|
children: [
|
|
4702
4098
|
/* @__PURE__ */ jsx9(
|
|
@@ -4776,14 +4172,8 @@ function WorkspaceFileManager({
|
|
|
4776
4172
|
/* @__PURE__ */ jsx9(
|
|
4777
4173
|
WorkspaceFileManagerContextMenuContainer,
|
|
4778
4174
|
{
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
onCopyEntry,
|
|
4782
|
-
onCopyPath,
|
|
4783
|
-
openInAppBrowserIcon,
|
|
4784
|
-
resolveOpenWithApplicationIcon,
|
|
4785
|
-
session,
|
|
4786
|
-
showInternalOpenWithActions
|
|
4175
|
+
resolveContextMenu,
|
|
4176
|
+
session
|
|
4787
4177
|
}
|
|
4788
4178
|
)
|
|
4789
4179
|
] }) : null
|
|
@@ -4965,7 +4355,6 @@ function WorkspaceFileManagerPanelsContainer({
|
|
|
4965
4355
|
selectedEntry: view.selectedEntry,
|
|
4966
4356
|
selectedPath: view.selectedPath,
|
|
4967
4357
|
showPreviewPanel,
|
|
4968
|
-
showDropOverlay: view.showDropOverlay,
|
|
4969
4358
|
state: {
|
|
4970
4359
|
entries: displayedEntries,
|
|
4971
4360
|
error: view.isSearchMode ? view.searchError : state.error,
|
|
@@ -5044,20 +4433,6 @@ function WorkspaceFileManagerDialogsContainer({
|
|
|
5044
4433
|
}
|
|
5045
4434
|
}
|
|
5046
4435
|
),
|
|
5047
|
-
/* @__PURE__ */ jsx9(
|
|
5048
|
-
WorkspaceFileManagerImportConflictDialog,
|
|
5049
|
-
{
|
|
5050
|
-
busy: view.isImporting,
|
|
5051
|
-
copy: i18n,
|
|
5052
|
-
dialog: view.importConflictDialog,
|
|
5053
|
-
onClose: () => {
|
|
5054
|
-
session.closeImportConflictDialog();
|
|
5055
|
-
},
|
|
5056
|
-
onConfirm: () => {
|
|
5057
|
-
void session.confirmImportConflict();
|
|
5058
|
-
}
|
|
5059
|
-
}
|
|
5060
|
-
),
|
|
5061
4436
|
/* @__PURE__ */ jsx9(
|
|
5062
4437
|
WorkspaceFileManagerUnsupportedDialog,
|
|
5063
4438
|
{
|
|
@@ -5088,13 +4463,6 @@ function clampContextMenuCoordinate(coordinate, boundarySize, menuSize) {
|
|
|
5088
4463
|
const max = Math.max(8, boundarySize - menuSize - 8);
|
|
5089
4464
|
return Math.min(Math.max(coordinate, 8), max);
|
|
5090
4465
|
}
|
|
5091
|
-
function isPointInsideElement(element, clientX, clientY) {
|
|
5092
|
-
if (!element) {
|
|
5093
|
-
return false;
|
|
5094
|
-
}
|
|
5095
|
-
const bounds = element.getBoundingClientRect();
|
|
5096
|
-
return clientX >= bounds.left && clientX <= bounds.right && clientY >= bounds.top && clientY <= bounds.bottom;
|
|
5097
|
-
}
|
|
5098
4466
|
export {
|
|
5099
4467
|
WorkspaceFileEntryIcon,
|
|
5100
4468
|
WorkspaceFileManager,
|
|
@@ -5108,6 +4476,7 @@ export {
|
|
|
5108
4476
|
isWorkspaceFileRecentLocation,
|
|
5109
4477
|
resolveRevealInFolderLabel,
|
|
5110
4478
|
resolveWorkspaceFileLocationDefaultId,
|
|
4479
|
+
resolveWorkspaceFileManagerContextMenuTarget,
|
|
5111
4480
|
useWorkspaceFileEntryIconUrls,
|
|
5112
4481
|
workspaceFileManagerI18nNamespace,
|
|
5113
4482
|
workspaceFileManagerI18nResources
|