@lvce-editor/explorer-view 1.20.0 → 1.22.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 +322 -335
- package/package.json +1 -2
|
@@ -779,12 +779,12 @@ const invokeAndTransfer = (ipc, method, ...params) => {
|
|
|
779
779
|
return invokeHelper(ipc, method, params, true);
|
|
780
780
|
};
|
|
781
781
|
|
|
782
|
-
const commands = Object.create(null);
|
|
782
|
+
const commands$1 = Object.create(null);
|
|
783
783
|
const register = commandMap => {
|
|
784
|
-
Object.assign(commands, commandMap);
|
|
784
|
+
Object.assign(commands$1, commandMap);
|
|
785
785
|
};
|
|
786
786
|
const getCommand = key => {
|
|
787
|
-
return commands[key];
|
|
787
|
+
return commands$1[key];
|
|
788
788
|
};
|
|
789
789
|
const execute = (command, ...args) => {
|
|
790
790
|
const fn = getCommand(command);
|
|
@@ -1100,9 +1100,7 @@ const acceptCreate = async (state, newDirentType, createFn) => {
|
|
|
1100
1100
|
return state;
|
|
1101
1101
|
}
|
|
1102
1102
|
const parentDirent = focusedIndex >= 0 ? state.items[focusedIndex] : {
|
|
1103
|
-
depth: 0
|
|
1104
|
-
path: state.root
|
|
1105
|
-
};
|
|
1103
|
+
depth: 0};
|
|
1106
1104
|
const depth = parentDirent.depth + 1;
|
|
1107
1105
|
const newDirent = {
|
|
1108
1106
|
path: absolutePath,
|
|
@@ -1334,6 +1332,43 @@ const create = (id, uri, x, y, width, height, args, parentUid) => {
|
|
|
1334
1332
|
return state;
|
|
1335
1333
|
};
|
|
1336
1334
|
|
|
1335
|
+
const RenderItems = 4;
|
|
1336
|
+
const RenderEditingIndex = 5;
|
|
1337
|
+
|
|
1338
|
+
const diffType$1 = RenderEditingIndex;
|
|
1339
|
+
const isEqual$2 = (oldState, newState) => {
|
|
1340
|
+
return oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType;
|
|
1341
|
+
};
|
|
1342
|
+
|
|
1343
|
+
const DiffEditingIndex = {
|
|
1344
|
+
__proto__: null,
|
|
1345
|
+
diffType: diffType$1,
|
|
1346
|
+
isEqual: isEqual$2
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
const diffType = RenderItems;
|
|
1350
|
+
const isEqual$1 = (oldState, newState) => {
|
|
1351
|
+
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;
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1354
|
+
const DiffItems = {
|
|
1355
|
+
__proto__: null,
|
|
1356
|
+
diffType,
|
|
1357
|
+
isEqual: isEqual$1
|
|
1358
|
+
};
|
|
1359
|
+
|
|
1360
|
+
const modules = [DiffItems, DiffEditingIndex];
|
|
1361
|
+
|
|
1362
|
+
const diff = (oldState, newState) => {
|
|
1363
|
+
const diffResult = [];
|
|
1364
|
+
for (const module of modules) {
|
|
1365
|
+
if (!module.isEqual(oldState, newState)) {
|
|
1366
|
+
diffResult.push(module.diffType);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
return diffResult;
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1337
1372
|
const isSymbolicLink = dirent => {
|
|
1338
1373
|
return dirent.type === Symlink;
|
|
1339
1374
|
};
|
|
@@ -1853,6 +1888,11 @@ const getActions = root => {
|
|
|
1853
1888
|
}];
|
|
1854
1889
|
};
|
|
1855
1890
|
|
|
1891
|
+
const commands = ['acceptEdit', 'cancelEdit', 'collapseAll', 'copyPath', 'copyRelativePath', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleCopy', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'refresh', 'relealItem', 'removeDirent', 'rename', 'renameDirent', 'revealItem', 'scrollDown', 'scrollUp', 'setDeltaY', 'updateEditingValue', 'updateIcons'];
|
|
1892
|
+
const getCommandIds = () => {
|
|
1893
|
+
return commands;
|
|
1894
|
+
};
|
|
1895
|
+
|
|
1856
1896
|
const None$4 = 'none';
|
|
1857
1897
|
const ToolBar = 'toolbar';
|
|
1858
1898
|
const Tree = 'tree';
|
|
@@ -1892,7 +1932,7 @@ const WelcomeMessage = 'WelcomeMessage';
|
|
|
1892
1932
|
|
|
1893
1933
|
const HandleBlur = 'handleBlur';
|
|
1894
1934
|
const HandleClick = 'handleClick';
|
|
1895
|
-
const
|
|
1935
|
+
const HandleClickOpenFolder = 'handleClickOpenFolder';
|
|
1896
1936
|
const HandleContextMenu = 'handleContextMenu';
|
|
1897
1937
|
const HandleEditingInput = 'handleEditingInput';
|
|
1898
1938
|
const HandleFocus = 'handleFocus';
|
|
@@ -2019,7 +2059,7 @@ const getExplorerWelcomeVirtualDom = isWide => {
|
|
|
2019
2059
|
type: Button,
|
|
2020
2060
|
className: mergeClassNames(Button$1, ButtonPrimary, isWide ? ButtonWide : ButtonNarrow),
|
|
2021
2061
|
childCount: 1,
|
|
2022
|
-
onClick:
|
|
2062
|
+
onClick: HandleClickOpenFolder
|
|
2023
2063
|
}, text(openFolder$1())];
|
|
2024
2064
|
};
|
|
2025
2065
|
|
|
@@ -2355,66 +2395,24 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
2355
2395
|
return visible;
|
|
2356
2396
|
};
|
|
2357
2397
|
|
|
2358
|
-
const
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
} = state;
|
|
2364
|
-
if (editingType !== None$5) {
|
|
2365
|
-
return state;
|
|
2398
|
+
const getParentStartIndex = (dirents, index) => {
|
|
2399
|
+
const dirent = dirents[index];
|
|
2400
|
+
let startIndex = index - 1;
|
|
2401
|
+
while (startIndex >= 0 && dirents[startIndex].depth >= dirent.depth) {
|
|
2402
|
+
startIndex--;
|
|
2366
2403
|
}
|
|
2367
|
-
return
|
|
2368
|
-
...state,
|
|
2369
|
-
focused: false
|
|
2370
|
-
};
|
|
2404
|
+
return startIndex;
|
|
2371
2405
|
};
|
|
2372
2406
|
|
|
2373
|
-
const
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
// TODO handle error
|
|
2377
|
-
const dirents = await getChildDirents(state.pathSeparator, dirent);
|
|
2378
|
-
const state2 = state;
|
|
2379
|
-
if (!state2) {
|
|
2380
|
-
return state;
|
|
2381
|
-
}
|
|
2382
|
-
// TODO use Viewlet.getState here and check if it exists
|
|
2383
|
-
const newIndex = state2.items.indexOf(dirent);
|
|
2384
|
-
// TODO if viewlet is disposed or root has changed, return
|
|
2385
|
-
if (newIndex === -1) {
|
|
2407
|
+
const focusParentFolder = state => {
|
|
2408
|
+
const parentStartIndex = getParentStartIndex(state.items, state.focusedIndex);
|
|
2409
|
+
if (parentStartIndex === -1) {
|
|
2386
2410
|
return state;
|
|
2387
2411
|
}
|
|
2388
|
-
|
|
2389
|
-
newDirents.splice(newIndex + 1, 0, ...dirents);
|
|
2390
|
-
// @ts-ignore
|
|
2391
|
-
dirent.type = DirectoryExpanded;
|
|
2392
|
-
// @ts-ignore
|
|
2393
|
-
dirent.icon = getIcon();
|
|
2394
|
-
const {
|
|
2395
|
-
height,
|
|
2396
|
-
itemHeight,
|
|
2397
|
-
minLineY
|
|
2398
|
-
} = state2;
|
|
2399
|
-
// TODO when focused index has changed while expanding, don't update it
|
|
2400
|
-
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
2401
|
-
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2402
|
-
const {
|
|
2403
|
-
icons,
|
|
2404
|
-
newFileIconCache
|
|
2405
|
-
} = await getFileIcons(parts, state.fileIconCache);
|
|
2406
|
-
return {
|
|
2407
|
-
...state,
|
|
2408
|
-
items: newDirents,
|
|
2409
|
-
icons,
|
|
2410
|
-
fileIconCache: newFileIconCache,
|
|
2411
|
-
focusedIndex: newIndex,
|
|
2412
|
-
focused: keepFocus,
|
|
2413
|
-
maxLineY
|
|
2414
|
-
};
|
|
2412
|
+
return focusIndex(state, parentStartIndex);
|
|
2415
2413
|
};
|
|
2416
2414
|
|
|
2417
|
-
const handleClickDirectoryExpanded
|
|
2415
|
+
const handleClickDirectoryExpanded = async (state, dirent, index, keepFocus) => {
|
|
2418
2416
|
const {
|
|
2419
2417
|
minLineY,
|
|
2420
2418
|
maxLineY,
|
|
@@ -2468,15 +2466,84 @@ const handleClickDirectoryExpanded$1 = async (state, dirent, index, keepFocus) =
|
|
|
2468
2466
|
};
|
|
2469
2467
|
};
|
|
2470
2468
|
|
|
2471
|
-
const
|
|
2469
|
+
const handleArrowLeft = state => {
|
|
2470
|
+
const {
|
|
2471
|
+
items,
|
|
2472
|
+
focusedIndex
|
|
2473
|
+
} = state;
|
|
2474
|
+
if (focusedIndex === -1) {
|
|
2475
|
+
return state;
|
|
2476
|
+
}
|
|
2477
|
+
const dirent = items[focusedIndex];
|
|
2478
|
+
switch (dirent.type) {
|
|
2479
|
+
case Directory:
|
|
2480
|
+
case File:
|
|
2481
|
+
case SymLinkFile:
|
|
2482
|
+
return focusParentFolder(state);
|
|
2483
|
+
case DirectoryExpanded:
|
|
2484
|
+
return handleClickDirectoryExpanded(state, dirent, focusedIndex, true);
|
|
2485
|
+
default:
|
|
2486
|
+
// TODO handle expanding directory and cancel file system call to read child dirents
|
|
2487
|
+
return state;
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
|
|
2491
|
+
const handleArrowRightDirectoryExpanded = (state, dirent) => {
|
|
2492
|
+
const {
|
|
2493
|
+
items,
|
|
2494
|
+
focusedIndex
|
|
2495
|
+
} = state;
|
|
2496
|
+
if (focusedIndex === items.length - 1) {
|
|
2497
|
+
return state;
|
|
2498
|
+
}
|
|
2499
|
+
const nextDirent = items[focusedIndex + 1];
|
|
2500
|
+
if (nextDirent.depth === dirent.depth + 1) {
|
|
2501
|
+
return focusIndex(state, focusedIndex + 1);
|
|
2502
|
+
}
|
|
2503
|
+
return state;
|
|
2504
|
+
};
|
|
2505
|
+
|
|
2506
|
+
const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
2472
2507
|
// @ts-ignore
|
|
2473
|
-
dirent.type =
|
|
2508
|
+
dirent.type = DirectoryExpanding;
|
|
2509
|
+
// TODO handle error
|
|
2510
|
+
const dirents = await getChildDirents(state.pathSeparator, dirent);
|
|
2511
|
+
const state2 = state;
|
|
2512
|
+
if (!state2) {
|
|
2513
|
+
return state;
|
|
2514
|
+
}
|
|
2515
|
+
// TODO use Viewlet.getState here and check if it exists
|
|
2516
|
+
const newIndex = state2.items.indexOf(dirent);
|
|
2517
|
+
// TODO if viewlet is disposed or root has changed, return
|
|
2518
|
+
if (newIndex === -1) {
|
|
2519
|
+
return state;
|
|
2520
|
+
}
|
|
2521
|
+
const newDirents = [...state2.items];
|
|
2522
|
+
newDirents.splice(newIndex + 1, 0, ...dirents);
|
|
2523
|
+
// @ts-ignore
|
|
2524
|
+
dirent.type = DirectoryExpanded;
|
|
2474
2525
|
// @ts-ignore
|
|
2475
2526
|
dirent.icon = getIcon();
|
|
2527
|
+
const {
|
|
2528
|
+
height,
|
|
2529
|
+
itemHeight,
|
|
2530
|
+
minLineY
|
|
2531
|
+
} = state2;
|
|
2532
|
+
// TODO when focused index has changed while expanding, don't update it
|
|
2533
|
+
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
2534
|
+
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2535
|
+
const {
|
|
2536
|
+
icons,
|
|
2537
|
+
newFileIconCache
|
|
2538
|
+
} = await getFileIcons(parts, state.fileIconCache);
|
|
2476
2539
|
return {
|
|
2477
2540
|
...state,
|
|
2478
|
-
|
|
2479
|
-
|
|
2541
|
+
items: newDirents,
|
|
2542
|
+
icons,
|
|
2543
|
+
fileIconCache: newFileIconCache,
|
|
2544
|
+
focusedIndex: newIndex,
|
|
2545
|
+
focused: keepFocus,
|
|
2546
|
+
maxLineY
|
|
2480
2547
|
};
|
|
2481
2548
|
};
|
|
2482
2549
|
|
|
@@ -2484,7 +2551,7 @@ const openUri = async (uri, focus) => {
|
|
|
2484
2551
|
await invoke(/* Main.openAbsolutePath */'Main.openUri', /* absolutePath */uri, /* focus */focus);
|
|
2485
2552
|
};
|
|
2486
2553
|
|
|
2487
|
-
const handleClickFile
|
|
2554
|
+
const handleClickFile = async (state, dirent, index, keepFocus = false) => {
|
|
2488
2555
|
await openUri(dirent.path, !keepFocus);
|
|
2489
2556
|
return {
|
|
2490
2557
|
...state,
|
|
@@ -2493,17 +2560,70 @@ const handleClickFile$1 = async (state, dirent, index, keepFocus = false) => {
|
|
|
2493
2560
|
};
|
|
2494
2561
|
};
|
|
2495
2562
|
|
|
2496
|
-
const handleClickSymLink
|
|
2563
|
+
const handleClickSymLink = async (state, dirent, index) => {
|
|
2497
2564
|
const realPath = await getRealPath(dirent.path);
|
|
2498
2565
|
const type = await stat(realPath);
|
|
2499
2566
|
switch (type) {
|
|
2500
2567
|
case File:
|
|
2501
|
-
return handleClickFile
|
|
2568
|
+
return handleClickFile(state, dirent, index);
|
|
2502
2569
|
default:
|
|
2503
2570
|
throw new Error(`unsupported file type ${type}`);
|
|
2504
2571
|
}
|
|
2505
2572
|
};
|
|
2506
2573
|
|
|
2574
|
+
const handleArrowRight = async state => {
|
|
2575
|
+
const {
|
|
2576
|
+
items,
|
|
2577
|
+
focusedIndex
|
|
2578
|
+
} = state;
|
|
2579
|
+
if (focusedIndex === -1) {
|
|
2580
|
+
return state;
|
|
2581
|
+
}
|
|
2582
|
+
const dirent = items[focusedIndex];
|
|
2583
|
+
switch (dirent.type) {
|
|
2584
|
+
case File:
|
|
2585
|
+
case SymLinkFile:
|
|
2586
|
+
return state;
|
|
2587
|
+
case Directory:
|
|
2588
|
+
case SymLinkFolder:
|
|
2589
|
+
// @ts-ignore
|
|
2590
|
+
return handleClickDirectory(state, dirent);
|
|
2591
|
+
case DirectoryExpanded:
|
|
2592
|
+
return handleArrowRightDirectoryExpanded(state, dirent);
|
|
2593
|
+
case Symlink:
|
|
2594
|
+
return handleClickSymLink(state, dirent, focusedIndex);
|
|
2595
|
+
default:
|
|
2596
|
+
throw new Error(`unsupported file type ${dirent.type}`);
|
|
2597
|
+
}
|
|
2598
|
+
};
|
|
2599
|
+
|
|
2600
|
+
const handleBlur = state => {
|
|
2601
|
+
// TODO when blur event occurs because of context menu, focused index should stay the same
|
|
2602
|
+
// but focus outline should be removed
|
|
2603
|
+
const {
|
|
2604
|
+
editingType
|
|
2605
|
+
} = state;
|
|
2606
|
+
if (editingType !== None$5) {
|
|
2607
|
+
return state;
|
|
2608
|
+
}
|
|
2609
|
+
return {
|
|
2610
|
+
...state,
|
|
2611
|
+
focused: false
|
|
2612
|
+
};
|
|
2613
|
+
};
|
|
2614
|
+
|
|
2615
|
+
const handleClickDirectoryExpanding = async (state, dirent, index, keepFocus) => {
|
|
2616
|
+
// @ts-ignore
|
|
2617
|
+
dirent.type = Directory;
|
|
2618
|
+
// @ts-ignore
|
|
2619
|
+
dirent.icon = getIcon();
|
|
2620
|
+
return {
|
|
2621
|
+
...state,
|
|
2622
|
+
focusedIndex: index,
|
|
2623
|
+
focused: keepFocus
|
|
2624
|
+
};
|
|
2625
|
+
};
|
|
2626
|
+
|
|
2507
2627
|
// TODO viewlet should only have create and refresh functions
|
|
2508
2628
|
// every thing else can be in a separate module <viewlet>.lazy.js
|
|
2509
2629
|
// and <viewlet>.ipc.js
|
|
@@ -2525,16 +2645,16 @@ const getClickFn = direntType => {
|
|
|
2525
2645
|
switch (direntType) {
|
|
2526
2646
|
case File:
|
|
2527
2647
|
case SymLinkFile:
|
|
2528
|
-
return handleClickFile
|
|
2648
|
+
return handleClickFile;
|
|
2529
2649
|
case Directory:
|
|
2530
2650
|
case SymLinkFolder:
|
|
2531
2651
|
return handleClickDirectory;
|
|
2532
2652
|
case DirectoryExpanding:
|
|
2533
2653
|
return handleClickDirectoryExpanding;
|
|
2534
2654
|
case DirectoryExpanded:
|
|
2535
|
-
return handleClickDirectoryExpanded
|
|
2655
|
+
return handleClickDirectoryExpanded;
|
|
2536
2656
|
case Symlink:
|
|
2537
|
-
return handleClickSymLink
|
|
2657
|
+
return handleClickSymLink;
|
|
2538
2658
|
case CharacterDevice:
|
|
2539
2659
|
throw new Error('Cannot open character device files');
|
|
2540
2660
|
case BlockDevice:
|
|
@@ -2546,34 +2666,6 @@ const getClickFn = direntType => {
|
|
|
2546
2666
|
}
|
|
2547
2667
|
};
|
|
2548
2668
|
|
|
2549
|
-
const getIndexFromPosition = (state, eventX, eventY) => {
|
|
2550
|
-
const {
|
|
2551
|
-
y,
|
|
2552
|
-
itemHeight,
|
|
2553
|
-
items
|
|
2554
|
-
} = state;
|
|
2555
|
-
const index = Math.floor((eventY - y) / itemHeight);
|
|
2556
|
-
if (index < 0) {
|
|
2557
|
-
return 0;
|
|
2558
|
-
}
|
|
2559
|
-
if (index >= items.length) {
|
|
2560
|
-
return -1;
|
|
2561
|
-
}
|
|
2562
|
-
return index;
|
|
2563
|
-
};
|
|
2564
|
-
|
|
2565
|
-
const getParentStartIndex = (dirents, index) => {
|
|
2566
|
-
const dirent = dirents[index];
|
|
2567
|
-
let startIndex = index - 1;
|
|
2568
|
-
while (startIndex >= 0 && dirents[startIndex].depth >= dirent.depth) {
|
|
2569
|
-
startIndex--;
|
|
2570
|
-
}
|
|
2571
|
-
return startIndex;
|
|
2572
|
-
};
|
|
2573
|
-
|
|
2574
|
-
const Keyboard = -1;
|
|
2575
|
-
const LeftClick = 0;
|
|
2576
|
-
|
|
2577
2669
|
// TODO viewlet should only have create and refresh functions
|
|
2578
2670
|
// every thing else can be in a separate module <viewlet>.lazy.js
|
|
2579
2671
|
// and <viewlet>.ipc.js
|
|
@@ -2584,81 +2676,11 @@ const LeftClick = 0;
|
|
|
2584
2676
|
// TODO instead of root string, there should be a root dirent
|
|
2585
2677
|
|
|
2586
2678
|
// TODO rename dirents to items, then can use virtual list component directly
|
|
2587
|
-
const setDeltaY$1 = (state, deltaY) => {
|
|
2588
|
-
const {
|
|
2589
|
-
itemHeight,
|
|
2590
|
-
height,
|
|
2591
|
-
items
|
|
2592
|
-
} = state;
|
|
2593
|
-
if (deltaY < 0) {
|
|
2594
|
-
deltaY = 0;
|
|
2595
|
-
} else if (deltaY > items.length * itemHeight - height) {
|
|
2596
|
-
deltaY = Math.max(items.length * itemHeight - height, 0);
|
|
2597
|
-
}
|
|
2598
|
-
if (state.deltaY === deltaY) {
|
|
2599
|
-
return state;
|
|
2600
|
-
}
|
|
2601
|
-
const minLineY = Math.round(deltaY / itemHeight);
|
|
2602
|
-
const maxLineY = minLineY + Math.round(height / itemHeight);
|
|
2603
|
-
return {
|
|
2604
|
-
...state,
|
|
2605
|
-
deltaY,
|
|
2606
|
-
minLineY,
|
|
2607
|
-
maxLineY
|
|
2608
|
-
};
|
|
2609
|
-
};
|
|
2610
|
-
const handleWheel = (state, deltaMode, deltaY) => {
|
|
2611
|
-
return setDeltaY$1(state, state.deltaY + deltaY);
|
|
2612
|
-
};
|
|
2613
2679
|
|
|
2614
2680
|
// TODO use posInSet and setSize properties to compute more effectively
|
|
2615
2681
|
|
|
2616
2682
|
// TODO much shared logic with newFolder
|
|
2617
2683
|
|
|
2618
|
-
const handleClickFile = async (state, dirent, index, keepFocus = false) => {
|
|
2619
|
-
// await Command.execute(/* Main.openAbsolutePath */ 'Main.openUri', /* absolutePath */ dirent.path, /* focus */ !keepFocus)
|
|
2620
|
-
return {
|
|
2621
|
-
...state,
|
|
2622
|
-
focusedIndex: index,
|
|
2623
|
-
focused: keepFocus
|
|
2624
|
-
};
|
|
2625
|
-
};
|
|
2626
|
-
const handleClickDirectoryExpanded = (state, dirent, index, keepFocus) => {
|
|
2627
|
-
const {
|
|
2628
|
-
minLineY,
|
|
2629
|
-
maxLineY,
|
|
2630
|
-
itemHeight
|
|
2631
|
-
} = state;
|
|
2632
|
-
dirent.type = Directory;
|
|
2633
|
-
dirent.icon = getIcon();
|
|
2634
|
-
const endIndex = getParentEndIndex(state.items, index);
|
|
2635
|
-
const removeCount = endIndex - index - 1;
|
|
2636
|
-
// TODO race conditions and side effects are everywhere
|
|
2637
|
-
const newDirents = [...state.items];
|
|
2638
|
-
newDirents.splice(index + 1, removeCount);
|
|
2639
|
-
const newTotal = newDirents.length;
|
|
2640
|
-
if (newTotal < maxLineY) {
|
|
2641
|
-
const visibleItems = Math.min(maxLineY - minLineY, newTotal);
|
|
2642
|
-
const newMaxLineY = Math.min(maxLineY, newTotal);
|
|
2643
|
-
const newMinLineY = newMaxLineY - visibleItems;
|
|
2644
|
-
const deltaY = newMinLineY * itemHeight;
|
|
2645
|
-
return {
|
|
2646
|
-
...state,
|
|
2647
|
-
items: newDirents,
|
|
2648
|
-
focusedIndex: index,
|
|
2649
|
-
focused: keepFocus,
|
|
2650
|
-
minLineY: newMinLineY,
|
|
2651
|
-
maxLineY: newMaxLineY,
|
|
2652
|
-
deltaY
|
|
2653
|
-
};
|
|
2654
|
-
}
|
|
2655
|
-
return {
|
|
2656
|
-
...state,
|
|
2657
|
-
items: newDirents,
|
|
2658
|
-
focusedIndex: index,
|
|
2659
|
-
focused: keepFocus
|
|
2660
|
-
};
|
|
2661
|
-
};
|
|
2662
2684
|
const handleClick = async (state, index, keepFocus = false) => {
|
|
2663
2685
|
const {
|
|
2664
2686
|
items,
|
|
@@ -2676,102 +2698,44 @@ const handleClick = async (state, index, keepFocus = false) => {
|
|
|
2676
2698
|
const clickFn = getClickFn(dirent.type);
|
|
2677
2699
|
return clickFn(state, dirent, actualIndex, keepFocus);
|
|
2678
2700
|
};
|
|
2679
|
-
const handleClickAt = (state, button, x, y) => {
|
|
2680
|
-
if (button !== LeftClick) {
|
|
2681
|
-
return state;
|
|
2682
|
-
}
|
|
2683
|
-
const index = getIndexFromPosition(state, x, y);
|
|
2684
|
-
return handleClick(state, index);
|
|
2685
|
-
};
|
|
2686
|
-
const handleClickCurrentButKeepFocus = state => {
|
|
2687
|
-
return handleClick(state, state.focusedIndex - state.minLineY, /* keepFocus */true);
|
|
2688
|
-
};
|
|
2689
2701
|
|
|
2690
2702
|
// export const handleBlur=()=>{}
|
|
2691
2703
|
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
default:
|
|
2699
|
-
throw new Error(`unsupported file type ${type}`);
|
|
2700
|
-
}
|
|
2701
|
-
};
|
|
2702
|
-
const handleArrowRightDirectoryExpanded = (state, dirent) => {
|
|
2703
|
-
const {
|
|
2704
|
-
items,
|
|
2705
|
-
focusedIndex
|
|
2706
|
-
} = state;
|
|
2707
|
-
if (focusedIndex === items.length - 1) {
|
|
2708
|
-
return state;
|
|
2709
|
-
}
|
|
2710
|
-
const nextDirent = items[focusedIndex + 1];
|
|
2711
|
-
if (nextDirent.depth === dirent.depth + 1) {
|
|
2712
|
-
return focusIndex(state, focusedIndex + 1);
|
|
2713
|
-
}
|
|
2714
|
-
return state;
|
|
2715
|
-
};
|
|
2716
|
-
const handleArrowRight = async state => {
|
|
2704
|
+
// TODO what happens when mouse leave and anther mouse enter event occur?
|
|
2705
|
+
// should update preview instead of closing and reopening
|
|
2706
|
+
|
|
2707
|
+
// TODO maybe just insert items into explorer and refresh whole explorer
|
|
2708
|
+
|
|
2709
|
+
const getIndexFromPosition = (state, eventX, eventY) => {
|
|
2717
2710
|
const {
|
|
2718
|
-
|
|
2719
|
-
|
|
2711
|
+
y,
|
|
2712
|
+
itemHeight,
|
|
2713
|
+
items
|
|
2720
2714
|
} = state;
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
const dirent = items[focusedIndex];
|
|
2725
|
-
switch (dirent.type) {
|
|
2726
|
-
case File:
|
|
2727
|
-
case SymLinkFile:
|
|
2728
|
-
return state;
|
|
2729
|
-
case Directory:
|
|
2730
|
-
case SymLinkFolder:
|
|
2731
|
-
// @ts-ignore
|
|
2732
|
-
return handleClickDirectory(state, dirent);
|
|
2733
|
-
case DirectoryExpanded:
|
|
2734
|
-
return handleArrowRightDirectoryExpanded(state, dirent);
|
|
2735
|
-
case Symlink:
|
|
2736
|
-
return handleClickSymLink(state, dirent, focusedIndex);
|
|
2737
|
-
default:
|
|
2738
|
-
throw new Error(`unsupported file type ${dirent.type}`);
|
|
2715
|
+
const index = Math.floor((eventY - y) / itemHeight);
|
|
2716
|
+
if (index < 0) {
|
|
2717
|
+
return 0;
|
|
2739
2718
|
}
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
const parentStartIndex = getParentStartIndex(state.items, state.focusedIndex);
|
|
2743
|
-
if (parentStartIndex === -1) {
|
|
2744
|
-
return state;
|
|
2719
|
+
if (index >= items.length) {
|
|
2720
|
+
return -1;
|
|
2745
2721
|
}
|
|
2746
|
-
return
|
|
2722
|
+
return index;
|
|
2747
2723
|
};
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
if (
|
|
2724
|
+
|
|
2725
|
+
const Keyboard = -1;
|
|
2726
|
+
const LeftClick = 0;
|
|
2727
|
+
|
|
2728
|
+
const handleClickAt = (state, button, x, y) => {
|
|
2729
|
+
if (button !== LeftClick) {
|
|
2754
2730
|
return state;
|
|
2755
2731
|
}
|
|
2756
|
-
const
|
|
2757
|
-
|
|
2758
|
-
case Directory:
|
|
2759
|
-
case File:
|
|
2760
|
-
case SymLinkFile:
|
|
2761
|
-
return focusParentFolder(state);
|
|
2762
|
-
case DirectoryExpanded:
|
|
2763
|
-
// @ts-ignore
|
|
2764
|
-
return handleClickDirectoryExpanded(state, dirent, focusedIndex);
|
|
2765
|
-
default:
|
|
2766
|
-
// TODO handle expanding directory and cancel file system call to read child dirents
|
|
2767
|
-
return state;
|
|
2768
|
-
}
|
|
2732
|
+
const index = getIndexFromPosition(state, x, y);
|
|
2733
|
+
return handleClick(state, index);
|
|
2769
2734
|
};
|
|
2770
2735
|
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
// TODO maybe just insert items into explorer and refresh whole explorer
|
|
2736
|
+
const handleClickCurrentButKeepFocus = state => {
|
|
2737
|
+
return handleClick(state, state.focusedIndex - state.minLineY, /* keepFocus */true);
|
|
2738
|
+
};
|
|
2775
2739
|
|
|
2776
2740
|
const openFolder = async () => {
|
|
2777
2741
|
// TODO
|
|
@@ -3239,6 +3203,34 @@ const handleUpload = async (state, dirents) => {
|
|
|
3239
3203
|
}
|
|
3240
3204
|
};
|
|
3241
3205
|
|
|
3206
|
+
const setDeltaY = (state, deltaY) => {
|
|
3207
|
+
const {
|
|
3208
|
+
itemHeight,
|
|
3209
|
+
height,
|
|
3210
|
+
items
|
|
3211
|
+
} = state;
|
|
3212
|
+
if (deltaY < 0) {
|
|
3213
|
+
deltaY = 0;
|
|
3214
|
+
} else if (deltaY > items.length * itemHeight - height) {
|
|
3215
|
+
deltaY = Math.max(items.length * itemHeight - height, 0);
|
|
3216
|
+
}
|
|
3217
|
+
if (state.deltaY === deltaY) {
|
|
3218
|
+
return state;
|
|
3219
|
+
}
|
|
3220
|
+
const minLineY = Math.round(deltaY / itemHeight);
|
|
3221
|
+
const maxLineY = minLineY + Math.round(height / itemHeight);
|
|
3222
|
+
return {
|
|
3223
|
+
...state,
|
|
3224
|
+
deltaY,
|
|
3225
|
+
minLineY,
|
|
3226
|
+
maxLineY
|
|
3227
|
+
};
|
|
3228
|
+
};
|
|
3229
|
+
|
|
3230
|
+
const handleWheel = (state, deltaMode, deltaY) => {
|
|
3231
|
+
return setDeltaY(state, state.deltaY + deltaY);
|
|
3232
|
+
};
|
|
3233
|
+
|
|
3242
3234
|
const getWorkspacePath = () => {
|
|
3243
3235
|
return invoke('Workspace.getPath');
|
|
3244
3236
|
};
|
|
@@ -3471,9 +3463,7 @@ const openContainingFolder = async state => {
|
|
|
3471
3463
|
const {
|
|
3472
3464
|
focusedIndex,
|
|
3473
3465
|
root,
|
|
3474
|
-
items
|
|
3475
|
-
pathSeparator
|
|
3476
|
-
} = state;
|
|
3466
|
+
items} = state;
|
|
3477
3467
|
const path = getContaingingFolder(root, items, focusedIndex);
|
|
3478
3468
|
await invoke('OpenNativeFolder.openNativeFolder', /* path */path);
|
|
3479
3469
|
return state;
|
|
@@ -3557,71 +3547,54 @@ const renameDirent = state => {
|
|
|
3557
3547
|
};
|
|
3558
3548
|
};
|
|
3559
3549
|
|
|
3560
|
-
const
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
return oldState.editingIndex === newState.editingIndex && oldState.editingType === newState.editingType;
|
|
3596
|
-
},
|
|
3597
|
-
apply(oldState, newState) {
|
|
3598
|
-
return ['focusInput', 'ExplorerInput'];
|
|
3599
|
-
}
|
|
3600
|
-
};
|
|
3601
|
-
const render = [renderItems, renderEditingIndex];
|
|
3550
|
+
const renderEditingIndex = (oldState, newState) => {
|
|
3551
|
+
return ['focusInput', 'ExplorerInput'];
|
|
3552
|
+
};
|
|
3553
|
+
|
|
3554
|
+
const renderItems = (oldState, newState) => {
|
|
3555
|
+
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.icons, newState.useChevrons);
|
|
3556
|
+
const isWide = newState.width > 450;
|
|
3557
|
+
const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused);
|
|
3558
|
+
return ['Viewlet.setDom2', dom];
|
|
3559
|
+
};
|
|
3560
|
+
|
|
3561
|
+
const getRenderer = diffType => {
|
|
3562
|
+
switch (diffType) {
|
|
3563
|
+
case RenderEditingIndex:
|
|
3564
|
+
return renderEditingIndex;
|
|
3565
|
+
case RenderItems:
|
|
3566
|
+
return renderItems;
|
|
3567
|
+
default:
|
|
3568
|
+
throw new Error('unknown renderer');
|
|
3569
|
+
}
|
|
3570
|
+
};
|
|
3571
|
+
|
|
3572
|
+
const applyRender = (oldState, newState, diffResult) => {
|
|
3573
|
+
const commands = [];
|
|
3574
|
+
for (const item of diffResult) {
|
|
3575
|
+
const fn = getRenderer(item);
|
|
3576
|
+
commands.push(fn(oldState, newState));
|
|
3577
|
+
}
|
|
3578
|
+
return commands;
|
|
3579
|
+
};
|
|
3580
|
+
|
|
3581
|
+
const renderInternal = (oldState, newState) => {
|
|
3582
|
+
const diffResult = diff(oldState, newState);
|
|
3583
|
+
return applyRender(oldState, newState, diffResult);
|
|
3584
|
+
};
|
|
3602
3585
|
const doRender = (uid, _) => {
|
|
3603
3586
|
if (typeof uid === 'number') {
|
|
3604
3587
|
const {
|
|
3605
3588
|
oldState,
|
|
3606
3589
|
newState
|
|
3607
3590
|
} = get(uid);
|
|
3608
|
-
const commands =
|
|
3609
|
-
for (const fn of render) {
|
|
3610
|
-
if (!fn.isEqual(oldState, newState)) {
|
|
3611
|
-
commands.push(fn.apply(oldState, newState));
|
|
3612
|
-
}
|
|
3613
|
-
}
|
|
3591
|
+
const commands = renderInternal(oldState, newState);
|
|
3614
3592
|
return commands;
|
|
3615
3593
|
}
|
|
3616
3594
|
// deprecated
|
|
3617
3595
|
const oldState = uid;
|
|
3618
3596
|
const newState = _;
|
|
3619
|
-
const commands =
|
|
3620
|
-
for (const fn of render) {
|
|
3621
|
-
if (!fn.isEqual(oldState, newState)) {
|
|
3622
|
-
commands.push(fn.apply(oldState, newState));
|
|
3623
|
-
}
|
|
3624
|
-
}
|
|
3597
|
+
const commands = renderInternal(oldState, newState);
|
|
3625
3598
|
return commands;
|
|
3626
3599
|
};
|
|
3627
3600
|
|
|
@@ -3673,6 +3646,41 @@ const renderActions = state => {
|
|
|
3673
3646
|
return dom;
|
|
3674
3647
|
};
|
|
3675
3648
|
|
|
3649
|
+
const renderEventListeners = () => {
|
|
3650
|
+
return [{
|
|
3651
|
+
name: HandleBlur,
|
|
3652
|
+
params: ['handleBlur']
|
|
3653
|
+
}, {
|
|
3654
|
+
name: HandleFocus,
|
|
3655
|
+
params: ['handleFocus', 'event.isTrusted', 'event.target.className']
|
|
3656
|
+
}, {
|
|
3657
|
+
name: HandleBlur,
|
|
3658
|
+
params: ['handleBlur']
|
|
3659
|
+
}, {
|
|
3660
|
+
name: HandleClick,
|
|
3661
|
+
params: ['event.button', 'event.clientX', 'event.clientY'],
|
|
3662
|
+
preventDefault: true
|
|
3663
|
+
}, {
|
|
3664
|
+
name: HandleClickOpenFolder,
|
|
3665
|
+
params: [],
|
|
3666
|
+
preventDefault: true
|
|
3667
|
+
}, {
|
|
3668
|
+
name: HandlePointerDown,
|
|
3669
|
+
params: ['event.button', 'event.clientX', 'event.clientY'],
|
|
3670
|
+
preventDefault: true
|
|
3671
|
+
}, {
|
|
3672
|
+
name: HandleEditingInput,
|
|
3673
|
+
params: ['event.target.value']
|
|
3674
|
+
}, {
|
|
3675
|
+
name: HandleContextMenu,
|
|
3676
|
+
params: ['event.button', 'event.clientX', 'event.clientY']
|
|
3677
|
+
}, {
|
|
3678
|
+
name: HandleWheel,
|
|
3679
|
+
params: ['event.deltaMode', 'event.deltaY'],
|
|
3680
|
+
passive: true
|
|
3681
|
+
}];
|
|
3682
|
+
};
|
|
3683
|
+
|
|
3676
3684
|
const getSavedRoot = (savedState, workspacePath) => {
|
|
3677
3685
|
return workspacePath;
|
|
3678
3686
|
};
|
|
@@ -3957,30 +3965,6 @@ const saveState = uid => {
|
|
|
3957
3965
|
};
|
|
3958
3966
|
};
|
|
3959
3967
|
|
|
3960
|
-
const setDeltaY = (state, deltaY) => {
|
|
3961
|
-
const {
|
|
3962
|
-
itemHeight,
|
|
3963
|
-
height,
|
|
3964
|
-
items
|
|
3965
|
-
} = state;
|
|
3966
|
-
if (deltaY < 0) {
|
|
3967
|
-
deltaY = 0;
|
|
3968
|
-
} else if (deltaY > items.length * itemHeight - height) {
|
|
3969
|
-
deltaY = Math.max(items.length * itemHeight - height, 0);
|
|
3970
|
-
}
|
|
3971
|
-
if (state.deltaY === deltaY) {
|
|
3972
|
-
return state;
|
|
3973
|
-
}
|
|
3974
|
-
const minLineY = Math.round(deltaY / itemHeight);
|
|
3975
|
-
const maxLineY = minLineY + Math.round(height / itemHeight);
|
|
3976
|
-
return {
|
|
3977
|
-
...state,
|
|
3978
|
-
deltaY,
|
|
3979
|
-
minLineY,
|
|
3980
|
-
maxLineY
|
|
3981
|
-
};
|
|
3982
|
-
};
|
|
3983
|
-
|
|
3984
3968
|
const terminate = () => {
|
|
3985
3969
|
globalThis.close();
|
|
3986
3970
|
};
|
|
@@ -4027,6 +4011,7 @@ const commandMap = {
|
|
|
4027
4011
|
'Explorer.focusNext': wrapCommand(focusNext),
|
|
4028
4012
|
'Explorer.focusPrevious': wrapCommand(focusPrevious),
|
|
4029
4013
|
'Explorer.getActions': wrapCommand(getActions),
|
|
4014
|
+
'Explorer.getCommandIds': getCommandIds,
|
|
4030
4015
|
'Explorer.getKeyBindings': wrapCommand(getKeyBindings),
|
|
4031
4016
|
'Explorer.getMenuEntries': wrapCommand(getMenuEntries),
|
|
4032
4017
|
'Explorer.getVirtualDom': wrapCommand(getExplorerVirtualDom),
|
|
@@ -4065,7 +4050,9 @@ const commandMap = {
|
|
|
4065
4050
|
'Explorer.create': create,
|
|
4066
4051
|
'Explorer.render': doRender,
|
|
4067
4052
|
'Explorer.renderActions': renderActions,
|
|
4068
|
-
'Explorer.saveState': saveState
|
|
4053
|
+
'Explorer.saveState': saveState,
|
|
4054
|
+
'Explorer.renderEventListeners': renderEventListeners,
|
|
4055
|
+
'Explorer.diff': diff
|
|
4069
4056
|
};
|
|
4070
4057
|
|
|
4071
4058
|
const listen = async () => {
|
package/package.json
CHANGED