@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.
@@ -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 [-1];
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
- // TODO send to renderer worker
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, index, files) => {
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 handleDrop = async (state, x, y, files) => {
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
- switch (index) {
2773
- case -1:
2774
- return await handleDropRoot(state, files);
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 getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused) => {
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: mergeClassNames(Viewlet, Explorer, extraClass),
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 + ' ' + TreeItemActive : 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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",