@lvce-editor/explorer-view 1.15.0 → 1.17.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 +229 -199
- package/package.json +1 -1
|
@@ -898,7 +898,7 @@ const compareDirent = (direntA, direntB) => {
|
|
|
898
898
|
return compareDirentType(direntA, direntB) || compareDirentName(direntA, direntB);
|
|
899
899
|
};
|
|
900
900
|
|
|
901
|
-
const getFileIcon
|
|
901
|
+
const getFileIcon = ({
|
|
902
902
|
name
|
|
903
903
|
}) => {
|
|
904
904
|
return '';
|
|
@@ -921,7 +921,7 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
|
|
|
921
921
|
...oldDirent,
|
|
922
922
|
name: newName,
|
|
923
923
|
path: oldDirent.path.slice(0, -oldDirent.name.length) + newName,
|
|
924
|
-
icon: getFileIcon
|
|
924
|
+
icon: getFileIcon({
|
|
925
925
|
name: newName
|
|
926
926
|
})
|
|
927
927
|
};
|
|
@@ -1005,7 +1005,7 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
|
|
|
1005
1005
|
};
|
|
1006
1006
|
};
|
|
1007
1007
|
|
|
1008
|
-
const None$
|
|
1008
|
+
const None$5 = 0;
|
|
1009
1009
|
const CreateFile = 1;
|
|
1010
1010
|
const CreateFolder = 2;
|
|
1011
1011
|
const Rename$1 = 3;
|
|
@@ -1155,7 +1155,7 @@ const acceptCreate = async (state, newDirentType, createFn) => {
|
|
|
1155
1155
|
items: newDirents,
|
|
1156
1156
|
editingIndex: -1,
|
|
1157
1157
|
focusedIndex: insertIndex + 1,
|
|
1158
|
-
editingType: None$
|
|
1158
|
+
editingType: None$5,
|
|
1159
1159
|
maxLineY: newMaxlineY
|
|
1160
1160
|
};
|
|
1161
1161
|
};
|
|
@@ -1189,7 +1189,7 @@ const acceptRename = async state => {
|
|
|
1189
1189
|
...state,
|
|
1190
1190
|
editingIndex: -1,
|
|
1191
1191
|
editingValue: '',
|
|
1192
|
-
editingType: None$
|
|
1192
|
+
editingType: None$5,
|
|
1193
1193
|
editingIcon: '',
|
|
1194
1194
|
focusedIndex,
|
|
1195
1195
|
focused: true
|
|
@@ -1221,7 +1221,7 @@ const cancelEdit = state => {
|
|
|
1221
1221
|
focused: true,
|
|
1222
1222
|
editingIndex: -1,
|
|
1223
1223
|
editingValue: '',
|
|
1224
|
-
editingType: None$
|
|
1224
|
+
editingType: None$5
|
|
1225
1225
|
};
|
|
1226
1226
|
};
|
|
1227
1227
|
|
|
@@ -1408,6 +1408,59 @@ const getExplorerMaxLineY = (minLineY, height, itemHeight, direntsLength) => {
|
|
|
1408
1408
|
return maxLineY;
|
|
1409
1409
|
};
|
|
1410
1410
|
|
|
1411
|
+
const getIconsCached = (dirents, fileIconCache) => {
|
|
1412
|
+
return dirents.map(dirent => fileIconCache[dirent.path]);
|
|
1413
|
+
};
|
|
1414
|
+
|
|
1415
|
+
const getMissingIconRequests = (dirents, fileIconCache) => {
|
|
1416
|
+
const missingRequests = [];
|
|
1417
|
+
for (const dirent of dirents) {
|
|
1418
|
+
if (!(dirent.path in fileIconCache)) {
|
|
1419
|
+
missingRequests.push({
|
|
1420
|
+
type: dirent.type,
|
|
1421
|
+
name: dirent.name,
|
|
1422
|
+
path: dirent.path
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return missingRequests;
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1429
|
+
const requestFileIcons = async requests => {
|
|
1430
|
+
const promises = requests.map(request => request.type === File ? invoke('IconTheme.getFileIcon', {
|
|
1431
|
+
name: request.name
|
|
1432
|
+
}) : invoke('IconTheme.getFolderIcon', {
|
|
1433
|
+
name: request.name
|
|
1434
|
+
}));
|
|
1435
|
+
return Promise.all(promises);
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
const updateIconCache = (iconCache, missingRequests, newIcons) => {
|
|
1439
|
+
if (missingRequests.length === 0) {
|
|
1440
|
+
return iconCache;
|
|
1441
|
+
}
|
|
1442
|
+
const newFileIconCache = {
|
|
1443
|
+
...iconCache
|
|
1444
|
+
};
|
|
1445
|
+
for (let i = 0; i < missingRequests.length; i++) {
|
|
1446
|
+
const request = missingRequests[i];
|
|
1447
|
+
const icon = newIcons[i];
|
|
1448
|
+
newFileIconCache[request.path] = icon;
|
|
1449
|
+
}
|
|
1450
|
+
return newFileIconCache;
|
|
1451
|
+
};
|
|
1452
|
+
|
|
1453
|
+
const getFileIcons = async (dirents, fileIconCache) => {
|
|
1454
|
+
const missingRequests = getMissingIconRequests(dirents, fileIconCache);
|
|
1455
|
+
const newIcons = await requestFileIcons(missingRequests);
|
|
1456
|
+
const newFileIconCache = updateIconCache(fileIconCache, missingRequests, newIcons);
|
|
1457
|
+
const icons = getIconsCached(dirents, newFileIconCache);
|
|
1458
|
+
return {
|
|
1459
|
+
icons,
|
|
1460
|
+
newFileIconCache
|
|
1461
|
+
};
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1411
1464
|
const expandAll = async state => {
|
|
1412
1465
|
const {
|
|
1413
1466
|
items,
|
|
@@ -1445,9 +1498,16 @@ const expandAll = async state => {
|
|
|
1445
1498
|
}
|
|
1446
1499
|
}
|
|
1447
1500
|
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
1501
|
+
const visible = newDirents.slice(minLineY, maxLineY);
|
|
1502
|
+
const {
|
|
1503
|
+
icons,
|
|
1504
|
+
newFileIconCache
|
|
1505
|
+
} = await getFileIcons(visible, state.fileIconCache);
|
|
1448
1506
|
return {
|
|
1449
1507
|
...state,
|
|
1450
1508
|
items: newDirents,
|
|
1509
|
+
icons,
|
|
1510
|
+
fileIconCache: newFileIconCache,
|
|
1451
1511
|
maxLineY
|
|
1452
1512
|
};
|
|
1453
1513
|
};
|
|
@@ -1740,20 +1800,24 @@ const getActions = root => {
|
|
|
1740
1800
|
}];
|
|
1741
1801
|
};
|
|
1742
1802
|
|
|
1743
|
-
const None$
|
|
1803
|
+
const None$4 = 'none';
|
|
1744
1804
|
const ToolBar = 'toolbar';
|
|
1745
1805
|
const Tree = 'tree';
|
|
1746
1806
|
const TreeItem$1 = 'treeitem';
|
|
1747
1807
|
|
|
1748
1808
|
const Actions = 'Actions';
|
|
1749
1809
|
const Button$1 = 'Button';
|
|
1810
|
+
const ButtonNarrow = 'ButtonNarrow';
|
|
1750
1811
|
const ButtonPrimary = 'ButtonPrimary';
|
|
1812
|
+
const ButtonWide = 'ButtonWide';
|
|
1751
1813
|
const Chevron = 'Chevron';
|
|
1752
1814
|
const Explorer$1 = 'Explorer';
|
|
1753
1815
|
const FileIcon = 'FileIcon';
|
|
1754
1816
|
const IconButton = 'IconButton';
|
|
1755
1817
|
const InputBox = 'InputBox';
|
|
1756
1818
|
const Label = 'Label';
|
|
1819
|
+
const MaskIconChevronDown = 'MaskIconChevronDown';
|
|
1820
|
+
const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
1757
1821
|
const TreeItem = 'TreeItem';
|
|
1758
1822
|
const TreeItemActive = 'TreeItemActive';
|
|
1759
1823
|
const Viewlet = 'Viewlet';
|
|
@@ -1764,6 +1828,7 @@ const HandleBlur = 'handleBlur';
|
|
|
1764
1828
|
const HandleClick = 'handleClick';
|
|
1765
1829
|
const handleClickOpenFolder$1 = 'handleClickOpenFolder';
|
|
1766
1830
|
const HandleContextMenu = 'handleContextMenu';
|
|
1831
|
+
const HandleEditingInput = 'handleEditingInput';
|
|
1767
1832
|
const HandleFocus = 'handleFocus';
|
|
1768
1833
|
const HandlePointerDown = 'handlePointerDown';
|
|
1769
1834
|
const HandleWheel = 'handleWheel';
|
|
@@ -1775,12 +1840,29 @@ const Text = 12;
|
|
|
1775
1840
|
const Img = 17;
|
|
1776
1841
|
const P = 50;
|
|
1777
1842
|
|
|
1843
|
+
const chevronDownVirtualDom = {
|
|
1844
|
+
type: Div,
|
|
1845
|
+
className: `${Chevron} ${MaskIconChevronDown}`,
|
|
1846
|
+
childCount: 0
|
|
1847
|
+
};
|
|
1848
|
+
|
|
1849
|
+
const chevronRightVirtualDom = {
|
|
1850
|
+
type: Div,
|
|
1851
|
+
className: `${Chevron} ${MaskIconChevronRight}`,
|
|
1852
|
+
childCount: 0
|
|
1853
|
+
};
|
|
1854
|
+
|
|
1855
|
+
const chevronDomNodes = [[], [chevronRightVirtualDom], [chevronDownVirtualDom]];
|
|
1856
|
+
const getChevronVirtualDom = chevronType => {
|
|
1857
|
+
return chevronDomNodes[chevronType];
|
|
1858
|
+
};
|
|
1859
|
+
|
|
1778
1860
|
const getFileIconVirtualDom = icon => {
|
|
1779
1861
|
return {
|
|
1780
1862
|
type: Img,
|
|
1781
1863
|
className: FileIcon,
|
|
1782
1864
|
src: icon,
|
|
1783
|
-
role: None$
|
|
1865
|
+
role: None$4,
|
|
1784
1866
|
childCount: 0
|
|
1785
1867
|
};
|
|
1786
1868
|
};
|
|
@@ -1795,76 +1877,26 @@ const text = data => {
|
|
|
1795
1877
|
};
|
|
1796
1878
|
};
|
|
1797
1879
|
|
|
1798
|
-
const
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
path,
|
|
1805
|
-
depth,
|
|
1806
|
-
isFocused,
|
|
1807
|
-
isEditing,
|
|
1808
|
-
indent
|
|
1809
|
-
} = item;
|
|
1810
|
-
|
|
1811
|
-
// TODO avoid mutation
|
|
1812
|
-
const dom = [];
|
|
1813
|
-
dom.push({
|
|
1814
|
-
type: Div,
|
|
1815
|
-
role: TreeItem$1,
|
|
1816
|
-
className: TreeItem,
|
|
1817
|
-
draggable: true,
|
|
1818
|
-
title: path,
|
|
1819
|
-
ariaPosInSet: posInSet,
|
|
1820
|
-
ariaSetSize: setSize,
|
|
1821
|
-
ariaLevel: depth,
|
|
1822
|
-
childCount: 2,
|
|
1823
|
-
paddingLeft: indent,
|
|
1824
|
-
ariaLabel: name,
|
|
1825
|
-
ariaDescription: ''
|
|
1826
|
-
}, getFileIconVirtualDom(icon));
|
|
1880
|
+
const label = {
|
|
1881
|
+
type: Div,
|
|
1882
|
+
className: Label,
|
|
1883
|
+
childCount: 1
|
|
1884
|
+
};
|
|
1885
|
+
const getInputOrLabelDom = (isEditing, name) => {
|
|
1827
1886
|
if (isEditing) {
|
|
1828
|
-
|
|
1887
|
+
return [{
|
|
1829
1888
|
type: Input,
|
|
1830
1889
|
className: InputBox,
|
|
1831
1890
|
id: 'ExplorerInput',
|
|
1832
|
-
onInput:
|
|
1891
|
+
onInput: HandleEditingInput,
|
|
1833
1892
|
childCount: 0,
|
|
1834
1893
|
name: ExplorerInput
|
|
1835
|
-
}
|
|
1836
|
-
} else {
|
|
1837
|
-
dom.push({
|
|
1838
|
-
type: Div,
|
|
1839
|
-
className: Label,
|
|
1840
|
-
childCount: 1
|
|
1841
|
-
}, text(name));
|
|
1894
|
+
}];
|
|
1842
1895
|
}
|
|
1843
|
-
|
|
1844
|
-
// @ts-ignore
|
|
1845
|
-
dom[0].id = 'TreeItemActive';
|
|
1846
|
-
// @ts-ignore
|
|
1847
|
-
dom[0].className += ' ' + TreeItemActive;
|
|
1848
|
-
}
|
|
1849
|
-
return dom;
|
|
1850
|
-
};
|
|
1851
|
-
|
|
1852
|
-
const getChevronDownVirtualDom = () => {
|
|
1853
|
-
return {
|
|
1854
|
-
type: Div,
|
|
1855
|
-
className: `${Chevron} MaskIconChevronDown`,
|
|
1856
|
-
childCount: 0
|
|
1857
|
-
};
|
|
1858
|
-
};
|
|
1859
|
-
const getChevronRightVirtualDom = () => {
|
|
1860
|
-
return {
|
|
1861
|
-
type: Div,
|
|
1862
|
-
className: `${Chevron} MaskIconChevronRight`,
|
|
1863
|
-
childCount: 0
|
|
1864
|
-
};
|
|
1896
|
+
return [label, text(name)];
|
|
1865
1897
|
};
|
|
1866
1898
|
|
|
1867
|
-
const
|
|
1899
|
+
const getExplorerItemVirtualDom = item => {
|
|
1868
1900
|
const {
|
|
1869
1901
|
posInSet,
|
|
1870
1902
|
setSize,
|
|
@@ -1872,76 +1904,33 @@ const getItemVirtualDomFolder = item => {
|
|
|
1872
1904
|
name,
|
|
1873
1905
|
path,
|
|
1874
1906
|
depth,
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1907
|
+
indent,
|
|
1908
|
+
chevron,
|
|
1909
|
+
id,
|
|
1910
|
+
className,
|
|
1911
|
+
isEditing,
|
|
1912
|
+
ariaExpanded
|
|
1879
1913
|
} = item;
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
switch (type) {
|
|
1883
|
-
// TODO decide on directory vs folder
|
|
1884
|
-
case Directory:
|
|
1885
|
-
ariaExpanded = 'false';
|
|
1886
|
-
chevron = getChevronRightVirtualDom();
|
|
1887
|
-
break;
|
|
1888
|
-
case DirectoryExpanding:
|
|
1889
|
-
ariaExpanded = 'true'; // TODO tree should be aria-busy then
|
|
1890
|
-
chevron = getChevronRightVirtualDom();
|
|
1891
|
-
break;
|
|
1892
|
-
case DirectoryExpanded:
|
|
1893
|
-
ariaExpanded = 'true';
|
|
1894
|
-
chevron = getChevronDownVirtualDom();
|
|
1895
|
-
break;
|
|
1896
|
-
}
|
|
1897
|
-
const dom = [];
|
|
1898
|
-
dom.push({
|
|
1914
|
+
const chevronDom = getChevronVirtualDom(chevron);
|
|
1915
|
+
const dom = [{
|
|
1899
1916
|
type: Div,
|
|
1900
1917
|
role: TreeItem$1,
|
|
1901
|
-
className
|
|
1918
|
+
className,
|
|
1902
1919
|
draggable: true,
|
|
1903
1920
|
title: path,
|
|
1904
1921
|
ariaPosInSet: posInSet,
|
|
1905
1922
|
ariaSetSize: setSize,
|
|
1906
1923
|
ariaLevel: depth,
|
|
1907
|
-
childCount: 2,
|
|
1924
|
+
childCount: 2 + chevronDom.length,
|
|
1908
1925
|
paddingLeft: indent,
|
|
1909
1926
|
ariaLabel: name,
|
|
1910
1927
|
ariaExpanded,
|
|
1911
|
-
ariaDescription: ''
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
// @ts-ignore
|
|
1915
|
-
dom[0].childCount++;
|
|
1916
|
-
// @ts-ignore
|
|
1917
|
-
dom.push(chevron);
|
|
1918
|
-
}
|
|
1919
|
-
dom.push(getFileIconVirtualDom(icon), {
|
|
1920
|
-
type: Div,
|
|
1921
|
-
className: Label,
|
|
1922
|
-
childCount: 1
|
|
1923
|
-
}, text(name));
|
|
1924
|
-
if (isFocused) {
|
|
1925
|
-
// @ts-ignore
|
|
1926
|
-
dom[0].id = 'TreeItemActive';
|
|
1927
|
-
}
|
|
1928
|
+
ariaDescription: '',
|
|
1929
|
+
id
|
|
1930
|
+
}, ...chevronDom, getFileIconVirtualDom(icon), ...getInputOrLabelDom(isEditing, name)];
|
|
1928
1931
|
return dom;
|
|
1929
1932
|
};
|
|
1930
1933
|
|
|
1931
|
-
const getExplorerItemVirtualDom = item => {
|
|
1932
|
-
const {
|
|
1933
|
-
type
|
|
1934
|
-
} = item;
|
|
1935
|
-
switch (type) {
|
|
1936
|
-
case Directory:
|
|
1937
|
-
case DirectoryExpanding:
|
|
1938
|
-
case DirectoryExpanded:
|
|
1939
|
-
return getItemVirtualDomFolder(item);
|
|
1940
|
-
default:
|
|
1941
|
-
return getItemVirtualDomFile(item);
|
|
1942
|
-
}
|
|
1943
|
-
};
|
|
1944
|
-
|
|
1945
1934
|
const mergeClassNames = (...classNames) => {
|
|
1946
1935
|
return classNames.filter(Boolean).join(' ');
|
|
1947
1936
|
};
|
|
@@ -1962,7 +1951,7 @@ const getExplorerWelcomeVirtualDom = isWide => {
|
|
|
1962
1951
|
childCount: 1
|
|
1963
1952
|
}, text(youHaveNotYetOpenedAFolder()), {
|
|
1964
1953
|
type: Button,
|
|
1965
|
-
className: mergeClassNames(Button$1, ButtonPrimary, isWide ?
|
|
1954
|
+
className: mergeClassNames(Button$1, ButtonPrimary, isWide ? ButtonWide : ButtonNarrow),
|
|
1966
1955
|
childCount: 1,
|
|
1967
1956
|
onClick: handleClickOpenFolder$1
|
|
1968
1957
|
}, text(openFolder$1())];
|
|
@@ -1972,9 +1961,7 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide) => {
|
|
|
1972
1961
|
if (!root) {
|
|
1973
1962
|
return getExplorerWelcomeVirtualDom(isWide);
|
|
1974
1963
|
}
|
|
1975
|
-
|
|
1976
|
-
const dom = [];
|
|
1977
|
-
dom.push({
|
|
1964
|
+
const dom = [{
|
|
1978
1965
|
type: Div,
|
|
1979
1966
|
className: mergeClassNames(Viewlet, Explorer$1),
|
|
1980
1967
|
tabIndex: 0,
|
|
@@ -1988,8 +1975,7 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide) => {
|
|
|
1988
1975
|
onPointerDown: HandlePointerDown,
|
|
1989
1976
|
onWheel: HandleWheel,
|
|
1990
1977
|
onClick: HandleClick
|
|
1991
|
-
});
|
|
1992
|
-
dom.push(...visibleItems.flatMap(getExplorerItemVirtualDom));
|
|
1978
|
+
}, ...visibleItems.flatMap(getExplorerItemVirtualDom)];
|
|
1993
1979
|
return dom;
|
|
1994
1980
|
};
|
|
1995
1981
|
|
|
@@ -2091,7 +2077,7 @@ const getKeyBindings = () => {
|
|
|
2091
2077
|
};
|
|
2092
2078
|
|
|
2093
2079
|
const Separator = 1;
|
|
2094
|
-
const None$
|
|
2080
|
+
const None$3 = 0;
|
|
2095
2081
|
const RestoreFocus = 6;
|
|
2096
2082
|
|
|
2097
2083
|
const menuEntrySeparator = {
|
|
@@ -2104,13 +2090,13 @@ const menuEntrySeparator = {
|
|
|
2104
2090
|
const menuEntryNewFile = {
|
|
2105
2091
|
id: 'newFile',
|
|
2106
2092
|
label: newFile$1(),
|
|
2107
|
-
flags: None$
|
|
2093
|
+
flags: None$3,
|
|
2108
2094
|
command: 'Explorer.newFile'
|
|
2109
2095
|
};
|
|
2110
2096
|
const menuEntryNewFolder = {
|
|
2111
2097
|
id: 'newFolder',
|
|
2112
2098
|
label: newFolder$1(),
|
|
2113
|
-
flags: None$
|
|
2099
|
+
flags: None$3,
|
|
2114
2100
|
command: 'Explorer.newFolder'
|
|
2115
2101
|
};
|
|
2116
2102
|
const menuEntryOpenContainingFolder = {
|
|
@@ -2122,7 +2108,7 @@ const menuEntryOpenContainingFolder = {
|
|
|
2122
2108
|
const menuEntryOpenInIntegratedTerminal = {
|
|
2123
2109
|
id: 'openInIntegratedTerminal',
|
|
2124
2110
|
label: openInIntegratedTerminal(),
|
|
2125
|
-
flags: None$
|
|
2111
|
+
flags: None$3,
|
|
2126
2112
|
command: /* TODO */-1
|
|
2127
2113
|
};
|
|
2128
2114
|
const menuEntryCut = {
|
|
@@ -2140,7 +2126,7 @@ const menuEntryCopy = {
|
|
|
2140
2126
|
const menuEntryPaste = {
|
|
2141
2127
|
id: 'paste',
|
|
2142
2128
|
label: paste(),
|
|
2143
|
-
flags: None$
|
|
2129
|
+
flags: None$3,
|
|
2144
2130
|
command: 'Explorer.handlePaste'
|
|
2145
2131
|
};
|
|
2146
2132
|
const menuEntryCopyPath = {
|
|
@@ -2158,13 +2144,13 @@ const menuEntryCopyRelativePath = {
|
|
|
2158
2144
|
const menuEntryRename = {
|
|
2159
2145
|
id: 'rename',
|
|
2160
2146
|
label: rename(),
|
|
2161
|
-
flags: None$
|
|
2147
|
+
flags: None$3,
|
|
2162
2148
|
command: 'Explorer.renameDirent'
|
|
2163
2149
|
};
|
|
2164
2150
|
const menuEntryDelete = {
|
|
2165
2151
|
id: 'delete',
|
|
2166
2152
|
label: deleteItem(),
|
|
2167
|
-
flags: None$
|
|
2153
|
+
flags: None$3,
|
|
2168
2154
|
command: 'Explorer.removeDirent'
|
|
2169
2155
|
};
|
|
2170
2156
|
const ALL_ENTRIES = [menuEntryNewFile, menuEntryNewFolder, menuEntryOpenContainingFolder, menuEntryOpenInIntegratedTerminal, menuEntrySeparator, menuEntryCut, menuEntryCopy, menuEntryPaste, menuEntrySeparator, menuEntryCopyPath, menuEntryCopyRelativePath, menuEntrySeparator, menuEntryRename, menuEntryDelete];
|
|
@@ -2205,51 +2191,98 @@ const getMenuEntries = state => {
|
|
|
2205
2191
|
}
|
|
2206
2192
|
};
|
|
2207
2193
|
|
|
2208
|
-
const
|
|
2194
|
+
const None$2 = 0;
|
|
2195
|
+
const Right = 1;
|
|
2196
|
+
const Down = 2;
|
|
2197
|
+
|
|
2198
|
+
const getChevronType = (type, useChevrons) => {
|
|
2199
|
+
if (!useChevrons) {
|
|
2200
|
+
return None$2;
|
|
2201
|
+
}
|
|
2202
|
+
switch (type) {
|
|
2203
|
+
case Directory:
|
|
2204
|
+
return Right;
|
|
2205
|
+
case DirectoryExpanded:
|
|
2206
|
+
case DirectoryExpanding:
|
|
2207
|
+
return Down;
|
|
2208
|
+
default:
|
|
2209
|
+
return None$2;
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
|
|
2213
|
+
const None$1 = 0;
|
|
2214
|
+
const Expanded = 1;
|
|
2215
|
+
const Collapsed = 2;
|
|
2216
|
+
|
|
2217
|
+
const getExpandedType = type => {
|
|
2218
|
+
switch (type) {
|
|
2219
|
+
case Directory:
|
|
2220
|
+
return Collapsed;
|
|
2221
|
+
case DirectoryExpanding:
|
|
2222
|
+
case DirectoryExpanded:
|
|
2223
|
+
return Expanded;
|
|
2224
|
+
default:
|
|
2225
|
+
return None$1;
|
|
2226
|
+
}
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
const defaultIndent$1 = 1;
|
|
2209
2230
|
const getTreeItemIndent = depth => {
|
|
2210
|
-
|
|
2211
|
-
return `${depth * defaultIndent}rem`;
|
|
2231
|
+
return `${depth * defaultIndent$1}rem`;
|
|
2212
2232
|
};
|
|
2213
2233
|
|
|
2234
|
+
// TODO make all of these variable configurable
|
|
2235
|
+
const defaultPaddingLeft = 4;
|
|
2236
|
+
const defaultIndent = 8;
|
|
2237
|
+
|
|
2238
|
+
// TODO make chevron size configurable
|
|
2239
|
+
const chevronSize = 22;
|
|
2240
|
+
const getTreeItemIndentWithChevron = (depth, chevron) => {
|
|
2241
|
+
// TODO use numeric value here, convert to string value in renderer process
|
|
2242
|
+
const extraSpace = chevron ? 0 : chevronSize;
|
|
2243
|
+
return `${depth * defaultIndent + extraSpace + defaultPaddingLeft}px`;
|
|
2244
|
+
};
|
|
2245
|
+
|
|
2246
|
+
const ariaExpandedValues = [undefined, 'true', 'false'];
|
|
2214
2247
|
const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons, useChevrons) => {
|
|
2215
2248
|
const visible = [];
|
|
2249
|
+
const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
|
|
2216
2250
|
let iconIndex = 0;
|
|
2217
2251
|
for (let i = minLineY; i < Math.min(maxLineY, items.length); i++) {
|
|
2218
2252
|
const item = items[i];
|
|
2219
2253
|
const icon = icons[iconIndex++];
|
|
2220
|
-
const
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
});
|
|
2238
|
-
}
|
|
2254
|
+
const chevron = getChevronType(item.type, useChevrons);
|
|
2255
|
+
const indent = indentFn(item.depth, chevron);
|
|
2256
|
+
const isFocused = i === focusedIndex;
|
|
2257
|
+
const id = isFocused ? 'TreeItemActive' : undefined;
|
|
2258
|
+
const className = isFocused ? TreeItem + ' ' + TreeItemActive : TreeItem;
|
|
2259
|
+
const expanded = getExpandedType(item.type);
|
|
2260
|
+
const ariaExpanded = ariaExpandedValues[expanded];
|
|
2261
|
+
visible.push({
|
|
2262
|
+
...item,
|
|
2263
|
+
isEditing: i === editingIndex,
|
|
2264
|
+
icon,
|
|
2265
|
+
indent,
|
|
2266
|
+
ariaExpanded,
|
|
2267
|
+
chevron,
|
|
2268
|
+
id,
|
|
2269
|
+
className
|
|
2270
|
+
});
|
|
2239
2271
|
}
|
|
2240
|
-
if (editingType !== None$
|
|
2272
|
+
if (editingType !== None$5 && editingIndex === -1) {
|
|
2241
2273
|
visible.push({
|
|
2242
2274
|
depth: 3,
|
|
2243
2275
|
posInSet: 1,
|
|
2244
2276
|
setSize: 1,
|
|
2245
2277
|
icon: '',
|
|
2246
|
-
isFocused: false,
|
|
2247
2278
|
name: 'new',
|
|
2248
2279
|
path: '/test/new',
|
|
2249
|
-
type: 2,
|
|
2250
2280
|
isEditing: true,
|
|
2251
|
-
|
|
2252
|
-
|
|
2281
|
+
indent: '',
|
|
2282
|
+
ariaExpanded: undefined,
|
|
2283
|
+
chevron: 0,
|
|
2284
|
+
id: undefined,
|
|
2285
|
+
className: TreeItem
|
|
2253
2286
|
});
|
|
2254
2287
|
}
|
|
2255
2288
|
return visible;
|
|
@@ -2261,7 +2294,7 @@ const handleBlur = state => {
|
|
|
2261
2294
|
const {
|
|
2262
2295
|
editingType
|
|
2263
2296
|
} = state;
|
|
2264
|
-
if (editingType !== None$
|
|
2297
|
+
if (editingType !== None$5) {
|
|
2265
2298
|
return state;
|
|
2266
2299
|
}
|
|
2267
2300
|
return {
|
|
@@ -2270,22 +2303,6 @@ const handleBlur = state => {
|
|
|
2270
2303
|
};
|
|
2271
2304
|
};
|
|
2272
2305
|
|
|
2273
|
-
const getFileIcon = dirent => {
|
|
2274
|
-
if (dirent.type === File) {
|
|
2275
|
-
return invoke('IconTheme.getFileIcon', {
|
|
2276
|
-
name: dirent.name
|
|
2277
|
-
});
|
|
2278
|
-
}
|
|
2279
|
-
return invoke('IconTheme.getFolderIcon', {
|
|
2280
|
-
name: dirent.name
|
|
2281
|
-
});
|
|
2282
|
-
};
|
|
2283
|
-
const getFileIcons = async dirents => {
|
|
2284
|
-
const promises = dirents.map(getFileIcon);
|
|
2285
|
-
const icons = await Promise.all(promises);
|
|
2286
|
-
return icons;
|
|
2287
|
-
};
|
|
2288
|
-
|
|
2289
2306
|
const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
2290
2307
|
dirent.type = DirectoryExpanding;
|
|
2291
2308
|
// TODO handle error
|
|
@@ -2312,11 +2329,15 @@ const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
|
2312
2329
|
// TODO when focused index has changed while expanding, don't update it
|
|
2313
2330
|
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
2314
2331
|
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2315
|
-
const
|
|
2332
|
+
const {
|
|
2333
|
+
icons,
|
|
2334
|
+
newFileIconCache
|
|
2335
|
+
} = await getFileIcons(parts, state.fileIconCache);
|
|
2316
2336
|
return {
|
|
2317
2337
|
...state,
|
|
2318
2338
|
items: newDirents,
|
|
2319
2339
|
icons,
|
|
2340
|
+
fileIconCache: newFileIconCache,
|
|
2320
2341
|
focusedIndex: newIndex,
|
|
2321
2342
|
focused: keepFocus,
|
|
2322
2343
|
maxLineY
|
|
@@ -2343,11 +2364,15 @@ const handleClickDirectoryExpanded$1 = async (state, dirent, index, keepFocus) =
|
|
|
2343
2364
|
const newMinLineY = newMaxLineY - visibleItems;
|
|
2344
2365
|
const deltaY = newMinLineY * itemHeight;
|
|
2345
2366
|
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2346
|
-
const
|
|
2367
|
+
const {
|
|
2368
|
+
icons,
|
|
2369
|
+
newFileIconCache
|
|
2370
|
+
} = await getFileIcons(parts, state.fileIconCache);
|
|
2347
2371
|
return {
|
|
2348
2372
|
...state,
|
|
2349
2373
|
items: newDirents,
|
|
2350
2374
|
icons,
|
|
2375
|
+
fileIconCache: newFileIconCache,
|
|
2351
2376
|
focusedIndex: index,
|
|
2352
2377
|
focused: keepFocus,
|
|
2353
2378
|
minLineY: newMinLineY,
|
|
@@ -2356,11 +2381,15 @@ const handleClickDirectoryExpanded$1 = async (state, dirent, index, keepFocus) =
|
|
|
2356
2381
|
};
|
|
2357
2382
|
}
|
|
2358
2383
|
const parts = newDirents.slice(state.minLineY, state.maxLineY);
|
|
2359
|
-
const
|
|
2384
|
+
const {
|
|
2385
|
+
icons,
|
|
2386
|
+
newFileIconCache
|
|
2387
|
+
} = await getFileIcons(parts, state.fileIconCache);
|
|
2360
2388
|
return {
|
|
2361
2389
|
...state,
|
|
2362
2390
|
items: newDirents,
|
|
2363
2391
|
icons,
|
|
2392
|
+
fileIconCache: newFileIconCache,
|
|
2364
2393
|
focusedIndex: index,
|
|
2365
2394
|
focused: keepFocus
|
|
2366
2395
|
};
|
|
@@ -3243,7 +3272,8 @@ const getSavedRoot$1 = (savedState, workspacePath) => {
|
|
|
3243
3272
|
return workspacePath;
|
|
3244
3273
|
};
|
|
3245
3274
|
const loadContent = async (state, savedState) => {
|
|
3246
|
-
const
|
|
3275
|
+
const useChevronsRaw = await invoke('Preferences.get', 'explorer.useChevrons');
|
|
3276
|
+
const useChevrons = Boolean(useChevronsRaw);
|
|
3247
3277
|
const workspacePath = await getWorkspacePath();
|
|
3248
3278
|
const root = getSavedRoot$1(savedState, workspacePath);
|
|
3249
3279
|
// TODO path separator could be restored from saved state
|
|
@@ -3263,12 +3293,16 @@ const loadContent = async (state, savedState) => {
|
|
|
3263
3293
|
deltaY = savedState.deltaY;
|
|
3264
3294
|
}
|
|
3265
3295
|
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, restoredDirents.length);
|
|
3266
|
-
const
|
|
3296
|
+
const {
|
|
3297
|
+
icons,
|
|
3298
|
+
newFileIconCache
|
|
3299
|
+
} = await getFileIcons(restoredDirents, Object.create(null));
|
|
3267
3300
|
return {
|
|
3268
3301
|
...state,
|
|
3269
3302
|
root,
|
|
3270
3303
|
items: restoredDirents,
|
|
3271
3304
|
icons,
|
|
3305
|
+
fileIconCache: newFileIconCache,
|
|
3272
3306
|
minLineY,
|
|
3273
3307
|
deltaY,
|
|
3274
3308
|
maxLineY,
|
|
@@ -3399,15 +3433,15 @@ const removeDirent = async state => {
|
|
|
3399
3433
|
indexToFocus = Math.max(state.focusedIndex - 1, 0);
|
|
3400
3434
|
}
|
|
3401
3435
|
const visible = newDirents.slice(state.minLineY, state.maxLineY);
|
|
3402
|
-
const
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
});
|
|
3436
|
+
const {
|
|
3437
|
+
icons,
|
|
3438
|
+
newFileIconCache
|
|
3439
|
+
} = await getFileIcons(visible, state.fileIconCache);
|
|
3406
3440
|
return {
|
|
3407
3441
|
...state,
|
|
3408
3442
|
items: newDirents,
|
|
3409
|
-
// @ts-ignore
|
|
3410
3443
|
icons,
|
|
3444
|
+
fileIconCache: newFileIconCache,
|
|
3411
3445
|
focusedIndex: indexToFocus
|
|
3412
3446
|
};
|
|
3413
3447
|
};
|
|
@@ -3432,11 +3466,7 @@ const renderItems = {
|
|
|
3432
3466
|
return JSON.stringify(oldState.items) === JSON.stringify(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;
|
|
3433
3467
|
},
|
|
3434
3468
|
apply(oldState, newState) {
|
|
3435
|
-
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue,
|
|
3436
|
-
// @ts-ignore
|
|
3437
|
-
newState.icons,
|
|
3438
|
-
// @ts-ignore
|
|
3439
|
-
newState.useChevrons);
|
|
3469
|
+
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.icons, newState.useChevrons);
|
|
3440
3470
|
const isWide = newState.width > 450;
|
|
3441
3471
|
const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide);
|
|
3442
3472
|
return ['Viewlet.setDom2', dom];
|
|
@@ -3486,7 +3516,7 @@ const getIconVirtualDom = (icon, type = Div) => {
|
|
|
3486
3516
|
return {
|
|
3487
3517
|
type,
|
|
3488
3518
|
className: `MaskIcon MaskIcon${icon}`,
|
|
3489
|
-
role: None$
|
|
3519
|
+
role: None$4,
|
|
3490
3520
|
childCount: 0
|
|
3491
3521
|
};
|
|
3492
3522
|
};
|
|
@@ -3831,7 +3861,7 @@ const setDeltaY = (state, deltaY) => {
|
|
|
3831
3861
|
};
|
|
3832
3862
|
|
|
3833
3863
|
const updateEditingValue = (state, value) => {
|
|
3834
|
-
const editingIcon = getFileIcon
|
|
3864
|
+
const editingIcon = getFileIcon({
|
|
3835
3865
|
name: value
|
|
3836
3866
|
});
|
|
3837
3867
|
return {
|