@lvce-editor/explorer-view 2.2.0 → 2.4.0
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/dist/explorerViewWorkerMain.js +109 -24
- package/package.json +1 -1
|
@@ -1013,6 +1013,7 @@ const get$1 = id => {
|
|
|
1013
1013
|
|
|
1014
1014
|
const invoke = (method, ...params) => {
|
|
1015
1015
|
const rpc = get$1(RendererWorker);
|
|
1016
|
+
// @ts-ignore
|
|
1016
1017
|
return rpc.invoke(method, ...params);
|
|
1017
1018
|
};
|
|
1018
1019
|
|
|
@@ -1384,7 +1385,7 @@ const DiffFocus = {
|
|
|
1384
1385
|
|
|
1385
1386
|
const diffType = RenderItems;
|
|
1386
1387
|
const isEqual$1 = (oldState, newState) => {
|
|
1387
|
-
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex && oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType && oldState.editingValue === newState.editingValue && oldState.width === newState.width && oldState.focused === newState.focused;
|
|
1388
|
+
return oldState.items === newState.items && oldState.minLineY === newState.minLineY && oldState.maxLineY === newState.maxLineY && oldState.focusedIndex === newState.focusedIndex && oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType && oldState.editingValue === newState.editingValue && oldState.width === newState.width && oldState.focused === newState.focused && oldState.dropTargets === newState.dropTargets;
|
|
1388
1389
|
};
|
|
1389
1390
|
|
|
1390
1391
|
const DiffItems = {
|
|
@@ -1795,6 +1796,13 @@ const focusFirst = state => {
|
|
|
1795
1796
|
const lastIndex = array => {
|
|
1796
1797
|
return array.length - 1;
|
|
1797
1798
|
};
|
|
1799
|
+
const fromAsync = async asyncIterable => {
|
|
1800
|
+
const children = [];
|
|
1801
|
+
for await (const value of asyncIterable) {
|
|
1802
|
+
children.push(value);
|
|
1803
|
+
}
|
|
1804
|
+
return children;
|
|
1805
|
+
};
|
|
1798
1806
|
|
|
1799
1807
|
const focusLast = state => {
|
|
1800
1808
|
const {
|
|
@@ -2567,13 +2575,15 @@ const canBeDroppedInto = dirent => {
|
|
|
2567
2575
|
}
|
|
2568
2576
|
};
|
|
2569
2577
|
|
|
2578
|
+
const dropTargetFull = [-1];
|
|
2579
|
+
|
|
2570
2580
|
const getNewDropTargets = (state, x, y) => {
|
|
2571
2581
|
const {
|
|
2572
2582
|
items
|
|
2573
2583
|
} = state;
|
|
2574
2584
|
const index = getIndexFromPosition(state, x, y);
|
|
2575
2585
|
if (index === -1) {
|
|
2576
|
-
return
|
|
2586
|
+
return dropTargetFull;
|
|
2577
2587
|
}
|
|
2578
2588
|
const item = items[index];
|
|
2579
2589
|
if (!canBeDroppedInto(item)) {
|
|
@@ -2614,8 +2624,55 @@ const handleDragOver = (state, x, y) => {
|
|
|
2614
2624
|
};
|
|
2615
2625
|
};
|
|
2616
2626
|
|
|
2627
|
+
const getChildHandles = async fileHandle => {
|
|
2628
|
+
// @ts-ignore
|
|
2629
|
+
const values = fileHandle.values();
|
|
2630
|
+
const children = await fromAsync(values);
|
|
2631
|
+
return children;
|
|
2632
|
+
};
|
|
2633
|
+
|
|
2634
|
+
const getFileHandleText = async fileHandle => {
|
|
2635
|
+
const file = await fileHandle.getFile();
|
|
2636
|
+
const text = await file.text();
|
|
2637
|
+
return text;
|
|
2638
|
+
};
|
|
2639
|
+
|
|
2640
|
+
const isDirectoryHandle = fileHandle => {
|
|
2641
|
+
return fileHandle.kind === 'directory';
|
|
2642
|
+
};
|
|
2643
|
+
|
|
2644
|
+
const isFileHandle = fileHandle => {
|
|
2645
|
+
return fileHandle.kind === 'file';
|
|
2646
|
+
};
|
|
2647
|
+
|
|
2648
|
+
const createUploadTree = async (root, fileHandles) => {
|
|
2649
|
+
const uploadTree = Object.create(null);
|
|
2650
|
+
for (const fileHandle of fileHandles) {
|
|
2651
|
+
const name = fileHandle.name;
|
|
2652
|
+
if (isDirectoryHandle(fileHandle)) {
|
|
2653
|
+
const children = await getChildHandles(fileHandle);
|
|
2654
|
+
const childTree = await createUploadTree(name, children);
|
|
2655
|
+
uploadTree[name] = childTree;
|
|
2656
|
+
} else if (isFileHandle(fileHandle)) {
|
|
2657
|
+
const text = await getFileHandleText(fileHandle);
|
|
2658
|
+
uploadTree[name] = text;
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
return uploadTree;
|
|
2662
|
+
};
|
|
2663
|
+
|
|
2617
2664
|
const uploadFileSystemHandles = async (root, pathSeparator, fileSystemHandles) => {
|
|
2618
|
-
|
|
2665
|
+
const uploadTree = await createUploadTree(root, fileSystemHandles);
|
|
2666
|
+
console.log({
|
|
2667
|
+
uploadTree
|
|
2668
|
+
});
|
|
2669
|
+
|
|
2670
|
+
// TODO
|
|
2671
|
+
// 1. in electron, use webutils.getPathForFile to see if a path is available
|
|
2672
|
+
// 2. else, walk all files and folders recursively and upload all of them (if there are many, show a progress bar)
|
|
2673
|
+
|
|
2674
|
+
// TODO send file system operations to renderer worker
|
|
2675
|
+
return true;
|
|
2619
2676
|
};
|
|
2620
2677
|
|
|
2621
2678
|
const mergeDirents$2 = (oldDirents, newDirents) => {
|
|
@@ -2635,7 +2692,7 @@ const handleDrop$2 = async (state, files) => {
|
|
|
2635
2692
|
pathSeparator,
|
|
2636
2693
|
items
|
|
2637
2694
|
} = state;
|
|
2638
|
-
const handled = await uploadFileSystemHandles();
|
|
2695
|
+
const handled = await uploadFileSystemHandles(root, pathSeparator, files);
|
|
2639
2696
|
if (handled) {
|
|
2640
2697
|
return state;
|
|
2641
2698
|
}
|
|
@@ -2721,10 +2778,12 @@ const handleDropIntoFolder = async (state, dirent, index, files) => {
|
|
|
2721
2778
|
pathSeparator,
|
|
2722
2779
|
items
|
|
2723
2780
|
} = state;
|
|
2781
|
+
// @ts-ignore
|
|
2724
2782
|
for (const file of files) {
|
|
2725
2783
|
// TODO path basename
|
|
2726
|
-
const baseName = file;
|
|
2784
|
+
const baseName = file.name;
|
|
2727
2785
|
const to = dirent.path + pathSeparator + baseName;
|
|
2786
|
+
// @ts-ignore
|
|
2728
2787
|
await copy$1(file, to);
|
|
2729
2788
|
}
|
|
2730
2789
|
const childDirents = await getChildDirents(pathSeparator, dirent);
|
|
@@ -2747,7 +2806,7 @@ const handleDropIntoFile = (state, dirent, index, files) => {
|
|
|
2747
2806
|
// @ts-ignore
|
|
2748
2807
|
return handleDropIndex(parentIndex);
|
|
2749
2808
|
};
|
|
2750
|
-
const handleDropIndex = async (state,
|
|
2809
|
+
const handleDropIndex = async (state, files, index) => {
|
|
2751
2810
|
const {
|
|
2752
2811
|
items
|
|
2753
2812
|
} = state;
|
|
@@ -2766,15 +2825,27 @@ const handleDropIndex = async (state, index, files) => {
|
|
|
2766
2825
|
}
|
|
2767
2826
|
};
|
|
2768
2827
|
|
|
2769
|
-
const
|
|
2828
|
+
const getDropHandler = index => {
|
|
2829
|
+
switch (index) {
|
|
2830
|
+
case -1:
|
|
2831
|
+
return handleDropRoot;
|
|
2832
|
+
default:
|
|
2833
|
+
return handleDropIndex;
|
|
2834
|
+
}
|
|
2835
|
+
};
|
|
2836
|
+
|
|
2837
|
+
const getFileHandles = async fileIds => {
|
|
2838
|
+
const files = await invoke('FileSystemHandle.getFileHandles', fileIds);
|
|
2839
|
+
return files;
|
|
2840
|
+
};
|
|
2841
|
+
|
|
2842
|
+
const handleDrop = async (state, x, y, fileIds) => {
|
|
2770
2843
|
try {
|
|
2844
|
+
const files = await getFileHandles(fileIds);
|
|
2771
2845
|
const index = getIndexFromPosition(state, x, y);
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
default:
|
|
2776
|
-
return await handleDropIndex(state, index, files);
|
|
2777
|
-
}
|
|
2846
|
+
const fn = getDropHandler(index);
|
|
2847
|
+
const result = await fn(state, files, index);
|
|
2848
|
+
return result;
|
|
2778
2849
|
} catch (error) {
|
|
2779
2850
|
throw new VError(error, 'Failed to drop files');
|
|
2780
2851
|
}
|
|
@@ -3345,6 +3416,8 @@ const ButtonPrimary = 'ButtonPrimary';
|
|
|
3345
3416
|
const ButtonWide = 'ButtonWide';
|
|
3346
3417
|
const Chevron = 'Chevron';
|
|
3347
3418
|
const Explorer = 'Explorer';
|
|
3419
|
+
const Empty = '';
|
|
3420
|
+
const ExplorerDropTarget = 'DropTarget';
|
|
3348
3421
|
const FileIcon = 'FileIcon';
|
|
3349
3422
|
const FocusOutline = 'FocusOutline';
|
|
3350
3423
|
const IconButton = 'IconButton';
|
|
@@ -3379,6 +3452,7 @@ const HandleListFocus = 'handleListFocus';
|
|
|
3379
3452
|
const HandlePointerDown = 'handlePointerDown';
|
|
3380
3453
|
const HandleWheel = 'handleWheel';
|
|
3381
3454
|
const HandleDragOver = 'handleDragOver';
|
|
3455
|
+
const HandleDrop = 'handleDrop';
|
|
3382
3456
|
|
|
3383
3457
|
const mergeClassNames = (...classNames) => {
|
|
3384
3458
|
return classNames.filter(Boolean).join(' ');
|
|
@@ -3509,26 +3583,32 @@ const getActiveDescendant = focusedIndex => {
|
|
|
3509
3583
|
}
|
|
3510
3584
|
return undefined;
|
|
3511
3585
|
};
|
|
3512
|
-
const
|
|
3586
|
+
const getClassName = (focused, focusedIndex, dropTarget) => {
|
|
3587
|
+
const extraClass1 = focused && focusedIndex === -1 ? FocusOutline : Empty;
|
|
3588
|
+
const extraClass2 = dropTarget === dropTargetFull ? ExplorerDropTarget : Empty;
|
|
3589
|
+
const className = mergeClassNames(Viewlet, Explorer, extraClass1, extraClass2);
|
|
3590
|
+
return className;
|
|
3591
|
+
};
|
|
3592
|
+
const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused, dropTargets) => {
|
|
3513
3593
|
if (!root) {
|
|
3514
3594
|
return getExplorerWelcomeVirtualDom(isWide);
|
|
3515
3595
|
}
|
|
3516
|
-
const extraClass = focused && focusedIndex === -1 ? FocusOutline : '';
|
|
3517
3596
|
const dom = [{
|
|
3518
3597
|
type: Div,
|
|
3519
|
-
className:
|
|
3598
|
+
className: getClassName(focused, focusedIndex, dropTargets),
|
|
3520
3599
|
tabIndex: 0,
|
|
3521
3600
|
role: Tree,
|
|
3522
3601
|
ariaLabel: filesExplorer(),
|
|
3523
3602
|
childCount: visibleItems.length,
|
|
3524
3603
|
ariaActiveDescendant: getActiveDescendant(focusedIndex),
|
|
3525
|
-
onFocus: HandleListFocus,
|
|
3526
3604
|
onBlur: HandleListBlur,
|
|
3605
|
+
onClick: HandleClick,
|
|
3527
3606
|
onContextMenu: HandleContextMenu,
|
|
3607
|
+
onDragOver: HandleDragOver,
|
|
3608
|
+
onDrop: HandleDrop,
|
|
3609
|
+
onFocus: HandleListFocus,
|
|
3528
3610
|
onPointerDown: HandlePointerDown,
|
|
3529
|
-
onWheel: HandleWheel
|
|
3530
|
-
onClick: HandleClick,
|
|
3531
|
-
onDragOver: HandleDragOver
|
|
3611
|
+
onWheel: HandleWheel
|
|
3532
3612
|
}, ...visibleItems.flatMap(getExplorerItemVirtualDom)];
|
|
3533
3613
|
return dom;
|
|
3534
3614
|
};
|
|
@@ -3586,7 +3666,7 @@ const getTreeItemIndentWithChevron = (depth, chevron) => {
|
|
|
3586
3666
|
};
|
|
3587
3667
|
|
|
3588
3668
|
const ariaExpandedValues = [undefined, 'true', 'false'];
|
|
3589
|
-
const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons, useChevrons) => {
|
|
3669
|
+
const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons, useChevrons, dropTargets) => {
|
|
3590
3670
|
const visible = [];
|
|
3591
3671
|
const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
|
|
3592
3672
|
let iconIndex = 0;
|
|
@@ -3597,7 +3677,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
3597
3677
|
const indent = indentFn(item.depth, chevron);
|
|
3598
3678
|
const isFocused = i === focusedIndex;
|
|
3599
3679
|
const id = isFocused ? 'TreeItemActive' : undefined;
|
|
3600
|
-
const className = isFocused ? TreeItem
|
|
3680
|
+
const className = isFocused ? mergeClassNames(TreeItem, TreeItemActive) : TreeItem;
|
|
3601
3681
|
const expanded = getExpandedType(item.type);
|
|
3602
3682
|
const ariaExpanded = ariaExpandedValues[expanded];
|
|
3603
3683
|
visible.push({
|
|
@@ -3633,7 +3713,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
3633
3713
|
const renderItems = (oldState, newState) => {
|
|
3634
3714
|
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.icons, newState.useChevrons);
|
|
3635
3715
|
const isWide = newState.width > 450;
|
|
3636
|
-
const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused);
|
|
3716
|
+
const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused, newState.dropTargets);
|
|
3637
3717
|
return ['Viewlet.setDom2', dom];
|
|
3638
3718
|
};
|
|
3639
3719
|
|
|
@@ -3792,7 +3872,12 @@ const renderEventListeners = () => {
|
|
|
3792
3872
|
passive: true
|
|
3793
3873
|
}, {
|
|
3794
3874
|
name: HandleDragOver,
|
|
3795
|
-
params: ['handleDragOver', 'event.clientX', 'event.clientY']
|
|
3875
|
+
params: ['handleDragOver', 'event.clientX', 'event.clientY'],
|
|
3876
|
+
preventDefault: true
|
|
3877
|
+
}, {
|
|
3878
|
+
name: HandleDrop,
|
|
3879
|
+
params: ['handleDrop', 'event.clientX', 'event.clientY', 'event.dataTransfer.files2'],
|
|
3880
|
+
preventDefault: true
|
|
3796
3881
|
}];
|
|
3797
3882
|
};
|
|
3798
3883
|
|