@lvce-editor/explorer-view 2.6.0 → 2.8.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 +358 -296
- package/package.json +1 -1
|
@@ -901,6 +901,241 @@ const compareDirent = (direntA, direntB) => {
|
|
|
901
901
|
return compareDirentType(direntA, direntB) || compareDirentName(direntA, direntB);
|
|
902
902
|
};
|
|
903
903
|
|
|
904
|
+
const None$5 = 0;
|
|
905
|
+
const CreateFile = 1;
|
|
906
|
+
const CreateFolder = 2;
|
|
907
|
+
const Rename$1 = 3;
|
|
908
|
+
|
|
909
|
+
const emptyObject = {};
|
|
910
|
+
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
911
|
+
const i18nString = (key, placeholders = emptyObject) => {
|
|
912
|
+
if (placeholders === emptyObject) {
|
|
913
|
+
return key;
|
|
914
|
+
}
|
|
915
|
+
const replacer = (match, rest) => {
|
|
916
|
+
return placeholders[rest];
|
|
917
|
+
};
|
|
918
|
+
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
919
|
+
};
|
|
920
|
+
|
|
921
|
+
const CollapseAllFoldersInExplorer = 'Collapse All Folders in Explorer';
|
|
922
|
+
const Copy$1 = 'Copy';
|
|
923
|
+
const CopyPath = 'Copy Path';
|
|
924
|
+
const CopyRelativePath = 'Copy Relative Path';
|
|
925
|
+
const Cut$1 = 'Cut';
|
|
926
|
+
const Delete$1 = 'Delete';
|
|
927
|
+
const FileOrFolderNameMustBeProvider = 'A file or folder name must be provided.';
|
|
928
|
+
const FilesExplorer = 'Files Explorer';
|
|
929
|
+
const NewFile$1 = 'New File...';
|
|
930
|
+
const NewFolder$1 = 'New Folder...';
|
|
931
|
+
const OpenContainingFolder = 'Open Containing Folder';
|
|
932
|
+
const OpenFolder = 'Open folder';
|
|
933
|
+
const OpenInIntegratedTerminal = 'Open in integrated Terminal';
|
|
934
|
+
const Paste = 'Paste';
|
|
935
|
+
const RefreshExplorer = 'Refresh Explorer';
|
|
936
|
+
const Rename = 'Rename';
|
|
937
|
+
const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
|
|
938
|
+
|
|
939
|
+
const newFile$1 = () => {
|
|
940
|
+
return i18nString(NewFile$1);
|
|
941
|
+
};
|
|
942
|
+
const newFolder$1 = () => {
|
|
943
|
+
return i18nString(NewFolder$1);
|
|
944
|
+
};
|
|
945
|
+
const openContainingFolder$1 = () => {
|
|
946
|
+
return i18nString(OpenContainingFolder);
|
|
947
|
+
};
|
|
948
|
+
const openInIntegratedTerminal = () => {
|
|
949
|
+
return i18nString(OpenInIntegratedTerminal);
|
|
950
|
+
};
|
|
951
|
+
const cut = () => {
|
|
952
|
+
return i18nString(Cut$1);
|
|
953
|
+
};
|
|
954
|
+
const copy$1 = () => {
|
|
955
|
+
return i18nString(Copy$1);
|
|
956
|
+
};
|
|
957
|
+
const paste = () => {
|
|
958
|
+
return i18nString(Paste);
|
|
959
|
+
};
|
|
960
|
+
const copyPath$1 = () => {
|
|
961
|
+
return i18nString(CopyPath);
|
|
962
|
+
};
|
|
963
|
+
const copyRelativePath$1 = () => {
|
|
964
|
+
return i18nString(CopyRelativePath);
|
|
965
|
+
};
|
|
966
|
+
const rename$1 = () => {
|
|
967
|
+
return i18nString(Rename);
|
|
968
|
+
};
|
|
969
|
+
const deleteItem = () => {
|
|
970
|
+
return i18nString(Delete$1);
|
|
971
|
+
};
|
|
972
|
+
const refresh$1 = () => {
|
|
973
|
+
return i18nString(RefreshExplorer);
|
|
974
|
+
};
|
|
975
|
+
const collapseAll$1 = () => {
|
|
976
|
+
return i18nString(CollapseAllFoldersInExplorer);
|
|
977
|
+
};
|
|
978
|
+
const filesExplorer = () => {
|
|
979
|
+
return i18nString(FilesExplorer);
|
|
980
|
+
};
|
|
981
|
+
const youHaveNotYetOpenedAFolder = () => {
|
|
982
|
+
return i18nString(YouHaveNotYetOpenedAFolder);
|
|
983
|
+
};
|
|
984
|
+
const openFolder$1 = () => {
|
|
985
|
+
return i18nString(OpenFolder);
|
|
986
|
+
};
|
|
987
|
+
const fileOrFolderNameMustBeProvided = () => {
|
|
988
|
+
return i18nString(FileOrFolderNameMustBeProvider);
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
const getParentFolder = (dirents, index, root) => {
|
|
992
|
+
if (index < 0) {
|
|
993
|
+
return root;
|
|
994
|
+
}
|
|
995
|
+
return dirents[index].path;
|
|
996
|
+
};
|
|
997
|
+
const acceptCreate = async (state, newDirentType, createFn) => {
|
|
998
|
+
const {
|
|
999
|
+
focusedIndex,
|
|
1000
|
+
editingValue
|
|
1001
|
+
} = state;
|
|
1002
|
+
const newFileName = editingValue;
|
|
1003
|
+
if (!newFileName) {
|
|
1004
|
+
// TODO show error message that file name must not be empty
|
|
1005
|
+
// below input box
|
|
1006
|
+
// await ErrorHandling.showErrorDialog(new Error('file name must not be empty'))
|
|
1007
|
+
const editingErrorMessage = fileOrFolderNameMustBeProvided();
|
|
1008
|
+
return {
|
|
1009
|
+
...state,
|
|
1010
|
+
editingErrorMessage
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
const parentFolder = getParentFolder(state.items, focusedIndex, state.root);
|
|
1014
|
+
const absolutePath = [parentFolder, newFileName].join(state.pathSeparator);
|
|
1015
|
+
// TODO better handle error
|
|
1016
|
+
try {
|
|
1017
|
+
await createFn(absolutePath);
|
|
1018
|
+
} catch (error) {
|
|
1019
|
+
console.error(new VError(error, `Failed to create file`));
|
|
1020
|
+
// TODO display error
|
|
1021
|
+
return state;
|
|
1022
|
+
}
|
|
1023
|
+
const parentDirent = focusedIndex >= 0 ? state.items[focusedIndex] : {
|
|
1024
|
+
depth: 0};
|
|
1025
|
+
const depth = parentDirent.depth + 1;
|
|
1026
|
+
const newDirent = {
|
|
1027
|
+
path: absolutePath,
|
|
1028
|
+
posInSet: -1,
|
|
1029
|
+
setSize: 1,
|
|
1030
|
+
depth,
|
|
1031
|
+
name: newFileName,
|
|
1032
|
+
type: newDirentType,
|
|
1033
|
+
icon: ''
|
|
1034
|
+
};
|
|
1035
|
+
newDirent.icon = '';
|
|
1036
|
+
let insertIndex = state.focusedIndex;
|
|
1037
|
+
let deltaPosInSet = 0;
|
|
1038
|
+
let posInSet = 1;
|
|
1039
|
+
let setSize = 1;
|
|
1040
|
+
let i = Math.max(state.focusedIndex, -1) + 1;
|
|
1041
|
+
const {
|
|
1042
|
+
items
|
|
1043
|
+
} = state;
|
|
1044
|
+
// TODO update posinset and setsize of all affected dirents
|
|
1045
|
+
for (; i < items.length; i++) {
|
|
1046
|
+
const dirent = items[i];
|
|
1047
|
+
if (dirent.depth !== depth) {
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
const compareResult = compareDirent(dirent, newDirent);
|
|
1051
|
+
if (compareResult === 1) {
|
|
1052
|
+
insertIndex = i - 1;
|
|
1053
|
+
deltaPosInSet = 1 - 1;
|
|
1054
|
+
break;
|
|
1055
|
+
} else {
|
|
1056
|
+
// @ts-ignore
|
|
1057
|
+
posInSet = dirent.posInSet + 1;
|
|
1058
|
+
// @ts-ignore
|
|
1059
|
+
setSize = dirent.setSize + 1;
|
|
1060
|
+
// @ts-ignore
|
|
1061
|
+
insertIndex = i;
|
|
1062
|
+
}
|
|
1063
|
+
// @ts-ignore
|
|
1064
|
+
dirent.setSize++;
|
|
1065
|
+
// @ts-ignore
|
|
1066
|
+
dirent.posInSet += deltaPosInSet;
|
|
1067
|
+
}
|
|
1068
|
+
newDirent.setSize = setSize;
|
|
1069
|
+
newDirent.posInSet = posInSet;
|
|
1070
|
+
// @ts-ignore
|
|
1071
|
+
items.splice(insertIndex + 1, 0, newDirent);
|
|
1072
|
+
const newDirents = [...items];
|
|
1073
|
+
const newMaxlineY = Math.max(state.maxLineY, newDirents.length);
|
|
1074
|
+
return {
|
|
1075
|
+
...state,
|
|
1076
|
+
items: newDirents,
|
|
1077
|
+
editingIndex: -1,
|
|
1078
|
+
focusedIndex: insertIndex + 1,
|
|
1079
|
+
editingType: None$5,
|
|
1080
|
+
maxLineY: newMaxlineY
|
|
1081
|
+
};
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
const RendererWorker = 1;
|
|
1085
|
+
|
|
1086
|
+
const rpcs = Object.create(null);
|
|
1087
|
+
const set$1 = (id, rpc) => {
|
|
1088
|
+
rpcs[id] = rpc;
|
|
1089
|
+
};
|
|
1090
|
+
const get$1 = id => {
|
|
1091
|
+
return rpcs[id];
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1094
|
+
const invoke = (method, ...params) => {
|
|
1095
|
+
const rpc = get$1(RendererWorker);
|
|
1096
|
+
// @ts-ignore
|
|
1097
|
+
return rpc.invoke(method, ...params);
|
|
1098
|
+
};
|
|
1099
|
+
|
|
1100
|
+
const remove = async dirent => {
|
|
1101
|
+
return invoke('FileSystem.remove', dirent);
|
|
1102
|
+
};
|
|
1103
|
+
const readDirWithFileTypes = async uri => {
|
|
1104
|
+
return invoke('FileSystem.readDirWithFileTypes', uri);
|
|
1105
|
+
};
|
|
1106
|
+
const getPathSeparator$1 = async root => {
|
|
1107
|
+
return invoke('FileSystem.getPathSeparator', root);
|
|
1108
|
+
};
|
|
1109
|
+
const getRealPath = async path => {
|
|
1110
|
+
return invoke('FileSystem.getRealPath', path);
|
|
1111
|
+
};
|
|
1112
|
+
const stat = async dirent => {
|
|
1113
|
+
return invoke('FileSystem.stat', dirent);
|
|
1114
|
+
};
|
|
1115
|
+
const createFile = async uri => {
|
|
1116
|
+
return invoke('FileSystem.writeFile', uri, '');
|
|
1117
|
+
};
|
|
1118
|
+
const writeFile = async (uri, content) => {
|
|
1119
|
+
return invoke('FileSystem.writeFile', uri, content);
|
|
1120
|
+
};
|
|
1121
|
+
const mkdir = async uri => {
|
|
1122
|
+
return invoke('FileSystem.mkdir', uri);
|
|
1123
|
+
};
|
|
1124
|
+
const rename = async (oldUri, newUri) => {
|
|
1125
|
+
return invoke('FileSystem.rename', oldUri, newUri);
|
|
1126
|
+
};
|
|
1127
|
+
const copy = async (oldUri, newUri) => {
|
|
1128
|
+
return invoke('FileSystem.copy', oldUri, newUri);
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
const acceptCreateFile = async state => {
|
|
1132
|
+
return acceptCreate(state, File, createFile);
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
const acceptCreateFolder = async state => {
|
|
1136
|
+
return acceptCreate(state, Directory, mkdir);
|
|
1137
|
+
};
|
|
1138
|
+
|
|
904
1139
|
// TODO use posInSet and setSize properties to compute more effectively
|
|
905
1140
|
const computeExplorerRenamedDirent = (dirents, index, newName) => {
|
|
906
1141
|
let startIndex = index;
|
|
@@ -996,58 +1231,6 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
|
|
|
996
1231
|
};
|
|
997
1232
|
};
|
|
998
1233
|
|
|
999
|
-
const None$5 = 0;
|
|
1000
|
-
const CreateFile = 1;
|
|
1001
|
-
const CreateFolder = 2;
|
|
1002
|
-
const Rename$1 = 3;
|
|
1003
|
-
|
|
1004
|
-
const RendererWorker = 1;
|
|
1005
|
-
|
|
1006
|
-
const rpcs = Object.create(null);
|
|
1007
|
-
const set$1 = (id, rpc) => {
|
|
1008
|
-
rpcs[id] = rpc;
|
|
1009
|
-
};
|
|
1010
|
-
const get$1 = id => {
|
|
1011
|
-
return rpcs[id];
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
const invoke = (method, ...params) => {
|
|
1015
|
-
const rpc = get$1(RendererWorker);
|
|
1016
|
-
// @ts-ignore
|
|
1017
|
-
return rpc.invoke(method, ...params);
|
|
1018
|
-
};
|
|
1019
|
-
|
|
1020
|
-
const remove = async dirent => {
|
|
1021
|
-
return invoke('FileSystem.remove', dirent);
|
|
1022
|
-
};
|
|
1023
|
-
const readDirWithFileTypes = async uri => {
|
|
1024
|
-
return invoke('FileSystem.readDirWithFileTypes', uri);
|
|
1025
|
-
};
|
|
1026
|
-
const getPathSeparator$1 = async root => {
|
|
1027
|
-
return invoke('FileSystem.getPathSeparator', root);
|
|
1028
|
-
};
|
|
1029
|
-
const getRealPath = async path => {
|
|
1030
|
-
return invoke('FileSystem.getRealPath', path);
|
|
1031
|
-
};
|
|
1032
|
-
const stat = async dirent => {
|
|
1033
|
-
return invoke('FileSystem.stat', dirent);
|
|
1034
|
-
};
|
|
1035
|
-
const createFile = async uri => {
|
|
1036
|
-
return invoke('FileSystem.createFile', uri);
|
|
1037
|
-
};
|
|
1038
|
-
const writeFile = async (uri, content) => {
|
|
1039
|
-
return invoke('FileSystem.writeFile', uri, content);
|
|
1040
|
-
};
|
|
1041
|
-
const mkdir = async uri => {
|
|
1042
|
-
return invoke('FileSystem.mkdir', uri);
|
|
1043
|
-
};
|
|
1044
|
-
const rename$1 = async (oldUri, newUri) => {
|
|
1045
|
-
return invoke('FileSystem.rename', oldUri, newUri);
|
|
1046
|
-
};
|
|
1047
|
-
const copy$1 = async (oldUri, newUri) => {
|
|
1048
|
-
return invoke('FileSystem.copy', oldUri, newUri);
|
|
1049
|
-
};
|
|
1050
|
-
|
|
1051
1234
|
const dirname = (pathSeparator, path) => {
|
|
1052
1235
|
const index = path.lastIndexOf(pathSeparator);
|
|
1053
1236
|
if (index === -1) {
|
|
@@ -1062,93 +1245,6 @@ const getBaseName = (pathSeparator, path) => {
|
|
|
1062
1245
|
return path.slice(path.lastIndexOf(pathSeparator) + 1);
|
|
1063
1246
|
};
|
|
1064
1247
|
|
|
1065
|
-
const getParentFolder = (dirents, index, root) => {
|
|
1066
|
-
if (index < 0) {
|
|
1067
|
-
return root;
|
|
1068
|
-
}
|
|
1069
|
-
return dirents[index].path;
|
|
1070
|
-
};
|
|
1071
|
-
const acceptCreate = async (state, newDirentType, createFn) => {
|
|
1072
|
-
const {
|
|
1073
|
-
focusedIndex,
|
|
1074
|
-
editingValue
|
|
1075
|
-
} = state;
|
|
1076
|
-
const newFileName = editingValue;
|
|
1077
|
-
if (!newFileName) {
|
|
1078
|
-
// TODO show error message that file name must not be empty
|
|
1079
|
-
// below input box
|
|
1080
|
-
// await ErrorHandling.showErrorDialog(new Error('file name must not be empty'))
|
|
1081
|
-
return state;
|
|
1082
|
-
}
|
|
1083
|
-
const parentFolder = getParentFolder(state.items, focusedIndex, state.root);
|
|
1084
|
-
const absolutePath = [parentFolder, newFileName].join(state.pathSeparator);
|
|
1085
|
-
// TODO better handle error
|
|
1086
|
-
try {
|
|
1087
|
-
await createFn(absolutePath);
|
|
1088
|
-
} catch {
|
|
1089
|
-
// TODO display error
|
|
1090
|
-
return state;
|
|
1091
|
-
}
|
|
1092
|
-
const parentDirent = focusedIndex >= 0 ? state.items[focusedIndex] : {
|
|
1093
|
-
depth: 0};
|
|
1094
|
-
const depth = parentDirent.depth + 1;
|
|
1095
|
-
const newDirent = {
|
|
1096
|
-
path: absolutePath,
|
|
1097
|
-
posInSet: -1,
|
|
1098
|
-
setSize: 1,
|
|
1099
|
-
depth,
|
|
1100
|
-
name: newFileName,
|
|
1101
|
-
type: newDirentType,
|
|
1102
|
-
icon: ''
|
|
1103
|
-
};
|
|
1104
|
-
newDirent.icon = '';
|
|
1105
|
-
let insertIndex = state.focusedIndex;
|
|
1106
|
-
let deltaPosInSet = 0;
|
|
1107
|
-
let posInSet = 1;
|
|
1108
|
-
let setSize = 1;
|
|
1109
|
-
let i = Math.max(state.focusedIndex, -1) + 1;
|
|
1110
|
-
const {
|
|
1111
|
-
items
|
|
1112
|
-
} = state;
|
|
1113
|
-
// TODO update posinset and setsize of all affected dirents
|
|
1114
|
-
for (; i < items.length; i++) {
|
|
1115
|
-
const dirent = items[i];
|
|
1116
|
-
if (dirent.depth !== depth) {
|
|
1117
|
-
break;
|
|
1118
|
-
}
|
|
1119
|
-
const compareResult = compareDirent(dirent, newDirent);
|
|
1120
|
-
if (compareResult === 1) {
|
|
1121
|
-
insertIndex = i - 1;
|
|
1122
|
-
deltaPosInSet = 1 - 1;
|
|
1123
|
-
break;
|
|
1124
|
-
} else {
|
|
1125
|
-
// @ts-ignore
|
|
1126
|
-
posInSet = dirent.posInSet + 1;
|
|
1127
|
-
// @ts-ignore
|
|
1128
|
-
setSize = dirent.setSize + 1;
|
|
1129
|
-
// @ts-ignore
|
|
1130
|
-
insertIndex = i;
|
|
1131
|
-
}
|
|
1132
|
-
// @ts-ignore
|
|
1133
|
-
dirent.setSize++;
|
|
1134
|
-
// @ts-ignore
|
|
1135
|
-
dirent.posInSet += deltaPosInSet;
|
|
1136
|
-
}
|
|
1137
|
-
newDirent.setSize = setSize;
|
|
1138
|
-
newDirent.posInSet = posInSet;
|
|
1139
|
-
// @ts-ignore
|
|
1140
|
-
items.splice(insertIndex + 1, 0, newDirent);
|
|
1141
|
-
const newDirents = [...items];
|
|
1142
|
-
const newMaxlineY = Math.max(state.maxLineY, newDirents.length);
|
|
1143
|
-
return {
|
|
1144
|
-
...state,
|
|
1145
|
-
items: newDirents,
|
|
1146
|
-
editingIndex: -1,
|
|
1147
|
-
focusedIndex: insertIndex + 1,
|
|
1148
|
-
editingType: None$5,
|
|
1149
|
-
maxLineY: newMaxlineY
|
|
1150
|
-
};
|
|
1151
|
-
};
|
|
1152
1248
|
const acceptRename = async state => {
|
|
1153
1249
|
const {
|
|
1154
1250
|
editingIndex,
|
|
@@ -1162,7 +1258,7 @@ const acceptRename = async state => {
|
|
|
1162
1258
|
const oldAbsolutePath = renamedDirent.path;
|
|
1163
1259
|
const oldParentPath = dirname(pathSeparator, oldAbsolutePath);
|
|
1164
1260
|
const newAbsolutePath = [oldParentPath, editingValue].join(pathSeparator);
|
|
1165
|
-
await rename
|
|
1261
|
+
await rename(oldAbsolutePath, newAbsolutePath);
|
|
1166
1262
|
} catch {
|
|
1167
1263
|
// TODO
|
|
1168
1264
|
// await ErrorHandling.showErrorDialog(error)
|
|
@@ -1185,15 +1281,16 @@ const acceptRename = async state => {
|
|
|
1185
1281
|
focused: true
|
|
1186
1282
|
};
|
|
1187
1283
|
};
|
|
1284
|
+
|
|
1188
1285
|
const acceptEdit = async state => {
|
|
1189
1286
|
const {
|
|
1190
1287
|
editingType
|
|
1191
1288
|
} = state;
|
|
1192
1289
|
switch (editingType) {
|
|
1193
1290
|
case CreateFile:
|
|
1194
|
-
return
|
|
1291
|
+
return acceptCreateFile(state);
|
|
1195
1292
|
case CreateFolder:
|
|
1196
|
-
return
|
|
1293
|
+
return acceptCreateFolder(state);
|
|
1197
1294
|
case Rename$1:
|
|
1198
1295
|
return acceptRename(state);
|
|
1199
1296
|
default:
|
|
@@ -1229,7 +1326,7 @@ const toCollapsedDirent = dirent => {
|
|
|
1229
1326
|
return dirent;
|
|
1230
1327
|
};
|
|
1231
1328
|
|
|
1232
|
-
const collapseAll
|
|
1329
|
+
const collapseAll = state => {
|
|
1233
1330
|
const {
|
|
1234
1331
|
items
|
|
1235
1332
|
} = state;
|
|
@@ -1250,7 +1347,7 @@ const getFocusedDirent$1 = state => {
|
|
|
1250
1347
|
return dirent;
|
|
1251
1348
|
};
|
|
1252
1349
|
|
|
1253
|
-
const copyPath
|
|
1350
|
+
const copyPath = async state => {
|
|
1254
1351
|
// await Command.execute(RendererWorkerCommandType.ClipBoardWriteText, /* text */ path)
|
|
1255
1352
|
return state;
|
|
1256
1353
|
};
|
|
@@ -1265,7 +1362,7 @@ const writeNativeFiles = async (type, files) => {
|
|
|
1265
1362
|
return invoke('ClipBoard.writeNativeFiles', type, files);
|
|
1266
1363
|
};
|
|
1267
1364
|
|
|
1268
|
-
const copyRelativePath
|
|
1365
|
+
const copyRelativePath = async state => {
|
|
1269
1366
|
const dirent = getFocusedDirent$1(state);
|
|
1270
1367
|
const relativePath = dirent.path.slice(1);
|
|
1271
1368
|
// TODO handle error
|
|
@@ -1317,7 +1414,9 @@ const create2 = (uid, uri, x, y, width, height, args, parentUid, platform = 0) =
|
|
|
1317
1414
|
fileIconCache: Object.create(null),
|
|
1318
1415
|
useChevrons: false,
|
|
1319
1416
|
icons: [],
|
|
1320
|
-
platform
|
|
1417
|
+
platform,
|
|
1418
|
+
focus: 0,
|
|
1419
|
+
editingErrorMessage: ''
|
|
1321
1420
|
};
|
|
1322
1421
|
set(uid, state, state);
|
|
1323
1422
|
};
|
|
@@ -1351,7 +1450,9 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0) =>
|
|
|
1351
1450
|
fileIconCache: Object.create(null),
|
|
1352
1451
|
useChevrons: false,
|
|
1353
1452
|
icons: [],
|
|
1354
|
-
platform
|
|
1453
|
+
platform,
|
|
1454
|
+
focus: 0,
|
|
1455
|
+
editingErrorMessage: ''
|
|
1355
1456
|
};
|
|
1356
1457
|
set(state.uid, state, state);
|
|
1357
1458
|
return state;
|
|
@@ -1374,7 +1475,7 @@ const DiffEditingIndex = {
|
|
|
1374
1475
|
|
|
1375
1476
|
const diffType$1 = RenderFocus;
|
|
1376
1477
|
const isEqual$2 = (oldState, newState) => {
|
|
1377
|
-
return oldState.focused === newState.focused;
|
|
1478
|
+
return oldState.focused === newState.focused && oldState.focus === newState.focus;
|
|
1378
1479
|
};
|
|
1379
1480
|
|
|
1380
1481
|
const DiffFocus = {
|
|
@@ -1385,7 +1486,7 @@ const DiffFocus = {
|
|
|
1385
1486
|
|
|
1386
1487
|
const diffType = RenderItems;
|
|
1387
1488
|
const isEqual$1 = (oldState, newState) => {
|
|
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;
|
|
1489
|
+
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.editingErrorMessage === newState.editingErrorMessage && oldState.width === newState.width && oldState.focused === newState.focused && oldState.dropTargets === newState.dropTargets;
|
|
1389
1490
|
};
|
|
1390
1491
|
|
|
1391
1492
|
const DiffItems = {
|
|
@@ -1845,7 +1946,7 @@ const focusPrevious = state => {
|
|
|
1845
1946
|
}
|
|
1846
1947
|
};
|
|
1847
1948
|
|
|
1848
|
-
const commandIds = ['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', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'setDeltaY', 'updateEditingValue', 'updateIcons'];
|
|
1949
|
+
const commandIds = ['getMenuEntries2', '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', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'setDeltaY', 'updateEditingValue', 'updateIcons'];
|
|
1849
1950
|
|
|
1850
1951
|
const getCommandIds = () => {
|
|
1851
1952
|
return commandIds;
|
|
@@ -1860,7 +1961,7 @@ const LeftArrow = 13;
|
|
|
1860
1961
|
const UpArrow = 14;
|
|
1861
1962
|
const RightArrow = 15;
|
|
1862
1963
|
const DownArrow = 16;
|
|
1863
|
-
const Delete
|
|
1964
|
+
const Delete = 18;
|
|
1864
1965
|
const KeyC = 31;
|
|
1865
1966
|
const KeyV = 50;
|
|
1866
1967
|
const F2 = 58;
|
|
@@ -1930,7 +2031,7 @@ const getKeyBindings = () => {
|
|
|
1930
2031
|
command: 'Explorer.acceptEdit',
|
|
1931
2032
|
when: FocusExplorerEditBox
|
|
1932
2033
|
}, {
|
|
1933
|
-
key: Delete
|
|
2034
|
+
key: Delete,
|
|
1934
2035
|
command: 'Explorer.removeDirent',
|
|
1935
2036
|
when: FocusExplorer
|
|
1936
2037
|
}, {
|
|
@@ -1948,84 +2049,6 @@ const getKeyBindings = () => {
|
|
|
1948
2049
|
}];
|
|
1949
2050
|
};
|
|
1950
2051
|
|
|
1951
|
-
const emptyObject = {};
|
|
1952
|
-
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
1953
|
-
const i18nString = (key, placeholders = emptyObject) => {
|
|
1954
|
-
if (placeholders === emptyObject) {
|
|
1955
|
-
return key;
|
|
1956
|
-
}
|
|
1957
|
-
const replacer = (match, rest) => {
|
|
1958
|
-
return placeholders[rest];
|
|
1959
|
-
};
|
|
1960
|
-
return key.replaceAll(RE_PLACEHOLDER, replacer);
|
|
1961
|
-
};
|
|
1962
|
-
|
|
1963
|
-
const NewFile$1 = 'New File...';
|
|
1964
|
-
const NewFolder$1 = 'New Folder...';
|
|
1965
|
-
const OpenContainingFolder = 'Open Containing Folder';
|
|
1966
|
-
const OpenInIntegratedTerminal = 'Open in integrated Terminal';
|
|
1967
|
-
const Cut$1 = 'Cut';
|
|
1968
|
-
const Copy$1 = 'Copy';
|
|
1969
|
-
const Paste = 'Paste';
|
|
1970
|
-
const CopyPath = 'Copy Path';
|
|
1971
|
-
const CopyRelativePath = 'Copy Relative Path';
|
|
1972
|
-
const Rename = 'Rename';
|
|
1973
|
-
const Delete = 'Delete';
|
|
1974
|
-
const RefreshExplorer = 'Refresh Explorer';
|
|
1975
|
-
const CollapseAllFoldersInExplorer = 'Collapse All Folders in Explorer';
|
|
1976
|
-
const FilesExplorer = 'Files Explorer';
|
|
1977
|
-
const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
|
|
1978
|
-
const OpenFolder = 'Open folder';
|
|
1979
|
-
|
|
1980
|
-
const newFile$1 = () => {
|
|
1981
|
-
return i18nString(NewFile$1);
|
|
1982
|
-
};
|
|
1983
|
-
const newFolder$1 = () => {
|
|
1984
|
-
return i18nString(NewFolder$1);
|
|
1985
|
-
};
|
|
1986
|
-
const openContainingFolder$1 = () => {
|
|
1987
|
-
return i18nString(OpenContainingFolder);
|
|
1988
|
-
};
|
|
1989
|
-
const openInIntegratedTerminal = () => {
|
|
1990
|
-
return i18nString(OpenInIntegratedTerminal);
|
|
1991
|
-
};
|
|
1992
|
-
const cut = () => {
|
|
1993
|
-
return i18nString(Cut$1);
|
|
1994
|
-
};
|
|
1995
|
-
const copy = () => {
|
|
1996
|
-
return i18nString(Copy$1);
|
|
1997
|
-
};
|
|
1998
|
-
const paste = () => {
|
|
1999
|
-
return i18nString(Paste);
|
|
2000
|
-
};
|
|
2001
|
-
const copyPath = () => {
|
|
2002
|
-
return i18nString(CopyPath);
|
|
2003
|
-
};
|
|
2004
|
-
const copyRelativePath = () => {
|
|
2005
|
-
return i18nString(CopyRelativePath);
|
|
2006
|
-
};
|
|
2007
|
-
const rename = () => {
|
|
2008
|
-
return i18nString(Rename);
|
|
2009
|
-
};
|
|
2010
|
-
const deleteItem = () => {
|
|
2011
|
-
return i18nString(Delete);
|
|
2012
|
-
};
|
|
2013
|
-
const refresh$1 = () => {
|
|
2014
|
-
return i18nString(RefreshExplorer);
|
|
2015
|
-
};
|
|
2016
|
-
const collapseAll = () => {
|
|
2017
|
-
return i18nString(CollapseAllFoldersInExplorer);
|
|
2018
|
-
};
|
|
2019
|
-
const filesExplorer = () => {
|
|
2020
|
-
return i18nString(FilesExplorer);
|
|
2021
|
-
};
|
|
2022
|
-
const youHaveNotYetOpenedAFolder = () => {
|
|
2023
|
-
return i18nString(YouHaveNotYetOpenedAFolder);
|
|
2024
|
-
};
|
|
2025
|
-
const openFolder$1 = () => {
|
|
2026
|
-
return i18nString(OpenFolder);
|
|
2027
|
-
};
|
|
2028
|
-
|
|
2029
2052
|
const Separator = 1;
|
|
2030
2053
|
const None$4 = 0;
|
|
2031
2054
|
const RestoreFocus = 6;
|
|
@@ -2069,7 +2092,7 @@ const menuEntryCut = {
|
|
|
2069
2092
|
};
|
|
2070
2093
|
const menuEntryCopy = {
|
|
2071
2094
|
id: 'copy',
|
|
2072
|
-
label: copy(),
|
|
2095
|
+
label: copy$1(),
|
|
2073
2096
|
flags: RestoreFocus,
|
|
2074
2097
|
command: 'Explorer.handleCopy'
|
|
2075
2098
|
};
|
|
@@ -2081,19 +2104,19 @@ const menuEntryPaste = {
|
|
|
2081
2104
|
};
|
|
2082
2105
|
const menuEntryCopyPath = {
|
|
2083
2106
|
id: 'copyPath',
|
|
2084
|
-
label: copyPath(),
|
|
2107
|
+
label: copyPath$1(),
|
|
2085
2108
|
flags: RestoreFocus,
|
|
2086
2109
|
command: 'Explorer.copyPath'
|
|
2087
2110
|
};
|
|
2088
2111
|
const menuEntryCopyRelativePath = {
|
|
2089
2112
|
id: 'copyRelativePath',
|
|
2090
|
-
label: copyRelativePath(),
|
|
2113
|
+
label: copyRelativePath$1(),
|
|
2091
2114
|
flags: RestoreFocus,
|
|
2092
2115
|
command: 'Explorer.copyRelativePath'
|
|
2093
2116
|
};
|
|
2094
2117
|
const menuEntryRename = {
|
|
2095
2118
|
id: 'rename',
|
|
2096
|
-
label: rename(),
|
|
2119
|
+
label: rename$1(),
|
|
2097
2120
|
flags: None$4,
|
|
2098
2121
|
command: 'Explorer.renameDirent'
|
|
2099
2122
|
};
|
|
@@ -2141,6 +2164,13 @@ const getMenuEntries = state => {
|
|
|
2141
2164
|
}
|
|
2142
2165
|
};
|
|
2143
2166
|
|
|
2167
|
+
const getMenuEntries2 = uid => {
|
|
2168
|
+
const {
|
|
2169
|
+
newState
|
|
2170
|
+
} = get(uid);
|
|
2171
|
+
return getMenuEntries(newState);
|
|
2172
|
+
};
|
|
2173
|
+
|
|
2144
2174
|
const getParentStartIndex = (dirents, index) => {
|
|
2145
2175
|
const dirent = dirents[index];
|
|
2146
2176
|
let startIndex = index - 1;
|
|
@@ -2249,6 +2279,10 @@ const handleArrowRightDirectoryExpanded = (state, dirent) => {
|
|
|
2249
2279
|
return state;
|
|
2250
2280
|
};
|
|
2251
2281
|
|
|
2282
|
+
const setFocus = key => {
|
|
2283
|
+
return invoke('Focus.setFocus', key);
|
|
2284
|
+
};
|
|
2285
|
+
|
|
2252
2286
|
const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
2253
2287
|
// @ts-ignore
|
|
2254
2288
|
dirent.type = DirectoryExpanding;
|
|
@@ -2282,6 +2316,7 @@ const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
|
2282
2316
|
icons,
|
|
2283
2317
|
newFileIconCache
|
|
2284
2318
|
} = await getFileIcons(parts, state.fileIconCache);
|
|
2319
|
+
await setFocus(FocusExplorer);
|
|
2285
2320
|
return {
|
|
2286
2321
|
...state,
|
|
2287
2322
|
items: newDirents,
|
|
@@ -2486,6 +2521,10 @@ const handleClickAt = (state, button, x, y) => {
|
|
|
2486
2521
|
return handleClick(state, index);
|
|
2487
2522
|
};
|
|
2488
2523
|
|
|
2524
|
+
const handleClickCurrent = state => {
|
|
2525
|
+
return handleClick(state, state.focusedIndex - state.minLineY, /* keepFocus */false);
|
|
2526
|
+
};
|
|
2527
|
+
|
|
2489
2528
|
const handleClickCurrentButKeepFocus = state => {
|
|
2490
2529
|
return handleClick(state, state.focusedIndex - state.minLineY, /* keepFocus */true);
|
|
2491
2530
|
};
|
|
@@ -2551,7 +2590,7 @@ const handleCopy = async state => {
|
|
|
2551
2590
|
// TODO if not file is selected, what happens?
|
|
2552
2591
|
const dirent = getFocusedDirent$1(state);
|
|
2553
2592
|
if (!dirent) {
|
|
2554
|
-
console.
|
|
2593
|
+
console.error('[ViewletExplorer/handleCopy] no dirent selected');
|
|
2555
2594
|
return state;
|
|
2556
2595
|
}
|
|
2557
2596
|
const absolutePath = dirent.path;
|
|
@@ -2562,16 +2601,15 @@ const handleCopy = async state => {
|
|
|
2562
2601
|
};
|
|
2563
2602
|
|
|
2564
2603
|
const handleDragLeave = state => {
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
};
|
|
2604
|
+
return state;
|
|
2605
|
+
// const { dropTargets } = state
|
|
2606
|
+
// if (dropTargets.length === 0) {
|
|
2607
|
+
// return state
|
|
2608
|
+
// }
|
|
2609
|
+
// return {
|
|
2610
|
+
// ...state,
|
|
2611
|
+
// dropTargets: [],
|
|
2612
|
+
// }
|
|
2575
2613
|
};
|
|
2576
2614
|
|
|
2577
2615
|
const canBeDroppedInto = dirent => {
|
|
@@ -2672,7 +2710,7 @@ const applyOperation = operation => {
|
|
|
2672
2710
|
return mkdir(operation.path);
|
|
2673
2711
|
}
|
|
2674
2712
|
if (operation.type === 'copy') {
|
|
2675
|
-
return copy
|
|
2713
|
+
return copy(operation.from || '', operation.path);
|
|
2676
2714
|
}
|
|
2677
2715
|
return writeFile(operation.path, operation.text);
|
|
2678
2716
|
};
|
|
@@ -2707,7 +2745,9 @@ const isFileHandle = fileHandle => {
|
|
|
2707
2745
|
const createUploadTree = async (root, fileHandles) => {
|
|
2708
2746
|
const uploadTree = Object.create(null);
|
|
2709
2747
|
for (const fileHandle of fileHandles) {
|
|
2710
|
-
const
|
|
2748
|
+
const {
|
|
2749
|
+
name
|
|
2750
|
+
} = fileHandle;
|
|
2711
2751
|
if (isDirectoryHandle(fileHandle)) {
|
|
2712
2752
|
const children = await getChildHandles(fileHandle);
|
|
2713
2753
|
const childTree = await createUploadTree(name, children);
|
|
@@ -2795,7 +2835,9 @@ const getFileOperationsElectron = async (root, paths, fileHandles) => {
|
|
|
2795
2835
|
const operations = [];
|
|
2796
2836
|
for (let i = 0; i < paths.length; i++) {
|
|
2797
2837
|
const fileHandle = fileHandles[i];
|
|
2798
|
-
const
|
|
2838
|
+
const {
|
|
2839
|
+
name
|
|
2840
|
+
} = fileHandle;
|
|
2799
2841
|
const path = paths[i];
|
|
2800
2842
|
operations.push({
|
|
2801
2843
|
type: 'copy',
|
|
@@ -2807,22 +2849,8 @@ const getFileOperationsElectron = async (root, paths, fileHandles) => {
|
|
|
2807
2849
|
return operations;
|
|
2808
2850
|
};
|
|
2809
2851
|
|
|
2810
|
-
const getFilePathElectron = async file => {
|
|
2811
|
-
return invoke('FileSystemHandle.getFilePathElectron', file);
|
|
2812
|
-
};
|
|
2813
|
-
|
|
2814
|
-
const getFilepath = async file => {
|
|
2815
|
-
return getFilePathElectron(file);
|
|
2816
|
-
};
|
|
2817
|
-
const getFilePaths = async files => {
|
|
2818
|
-
const promises = files.map(getFilepath);
|
|
2819
|
-
const paths = await Promise.all(promises);
|
|
2820
|
-
return paths;
|
|
2821
|
-
};
|
|
2822
|
-
|
|
2823
2852
|
// TODO copy files in parallel
|
|
2824
|
-
const copyFilesElectron = async (root, pathSeparator, fileHandles, files) => {
|
|
2825
|
-
const paths = await getFilePaths(files);
|
|
2853
|
+
const copyFilesElectron = async (root, pathSeparator, fileHandles, files, paths) => {
|
|
2826
2854
|
const operations = await getFileOperationsElectron(root, paths, fileHandles);
|
|
2827
2855
|
await applyFileOperations(operations);
|
|
2828
2856
|
};
|
|
@@ -2838,13 +2866,13 @@ const getMergedDirents$1 = async (root, pathSeparator, dirents) => {
|
|
|
2838
2866
|
const mergedDirents = mergeDirents(dirents, childDirents);
|
|
2839
2867
|
return mergedDirents;
|
|
2840
2868
|
};
|
|
2841
|
-
const handleDrop$1 = async (state, fileHandles, files) => {
|
|
2869
|
+
const handleDrop$1 = async (state, fileHandles, files, paths) => {
|
|
2842
2870
|
const {
|
|
2843
2871
|
root,
|
|
2844
2872
|
pathSeparator,
|
|
2845
2873
|
items
|
|
2846
2874
|
} = state;
|
|
2847
|
-
await copyFilesElectron(root, pathSeparator, fileHandles, files);
|
|
2875
|
+
await copyFilesElectron(root, pathSeparator, fileHandles, files, paths);
|
|
2848
2876
|
const mergedDirents = await getMergedDirents$1(root, pathSeparator, items);
|
|
2849
2877
|
return {
|
|
2850
2878
|
...state,
|
|
@@ -2861,10 +2889,10 @@ const getModule = isElectron => {
|
|
|
2861
2889
|
}
|
|
2862
2890
|
return handleDrop$2;
|
|
2863
2891
|
};
|
|
2864
|
-
const handleDropRoot = async (state, fileHandles, files) => {
|
|
2892
|
+
const handleDropRoot = async (state, fileHandles, files, paths) => {
|
|
2865
2893
|
const isElectron = state.platform === Electron;
|
|
2866
2894
|
const fn = getModule(isElectron);
|
|
2867
|
-
return fn(state, fileHandles, files);
|
|
2895
|
+
return fn(state, fileHandles, files, paths);
|
|
2868
2896
|
};
|
|
2869
2897
|
|
|
2870
2898
|
const getEndIndex = (items, index, dirent) => {
|
|
@@ -2884,7 +2912,7 @@ const getMergedDirents = (items, index, dirent, childDirents) => {
|
|
|
2884
2912
|
}, ...childDirents, ...items.slice(endIndex)];
|
|
2885
2913
|
return mergedDirents;
|
|
2886
2914
|
};
|
|
2887
|
-
const handleDropIntoFolder = async (state, dirent, index, fileHandles, files) => {
|
|
2915
|
+
const handleDropIntoFolder = async (state, dirent, index, fileHandles, files, paths) => {
|
|
2888
2916
|
const {
|
|
2889
2917
|
pathSeparator,
|
|
2890
2918
|
items
|
|
@@ -2895,7 +2923,7 @@ const handleDropIntoFolder = async (state, dirent, index, fileHandles, files) =>
|
|
|
2895
2923
|
const baseName = file.name;
|
|
2896
2924
|
const to = dirent.path + pathSeparator + baseName;
|
|
2897
2925
|
// @ts-ignore
|
|
2898
|
-
await copy
|
|
2926
|
+
await copy(file, to);
|
|
2899
2927
|
}
|
|
2900
2928
|
const childDirents = await getChildDirents(pathSeparator, dirent);
|
|
2901
2929
|
const mergedDirents = getMergedDirents(items, index, dirent, childDirents);
|
|
@@ -2906,18 +2934,18 @@ const handleDropIntoFolder = async (state, dirent, index, fileHandles, files) =>
|
|
|
2906
2934
|
dropTargets: []
|
|
2907
2935
|
};
|
|
2908
2936
|
};
|
|
2909
|
-
const handleDropIntoFile = (state, dirent, index, fileHandles, files) => {
|
|
2937
|
+
const handleDropIntoFile = (state, dirent, index, fileHandles, files, paths) => {
|
|
2910
2938
|
const {
|
|
2911
2939
|
items
|
|
2912
2940
|
} = state;
|
|
2913
2941
|
const parentIndex = getParentStartIndex(items, index);
|
|
2914
2942
|
if (parentIndex === -1) {
|
|
2915
|
-
return handleDropRoot(state, fileHandles, files);
|
|
2943
|
+
return handleDropRoot(state, fileHandles, files, paths);
|
|
2916
2944
|
}
|
|
2917
2945
|
// @ts-ignore
|
|
2918
2946
|
return handleDropIndex(parentIndex);
|
|
2919
2947
|
};
|
|
2920
|
-
const handleDropIndex = async (state, fileHandles, files, index) => {
|
|
2948
|
+
const handleDropIndex = async (state, fileHandles, files, paths, index) => {
|
|
2921
2949
|
const {
|
|
2922
2950
|
items
|
|
2923
2951
|
} = state;
|
|
@@ -2930,7 +2958,7 @@ const handleDropIndex = async (state, fileHandles, files, index) => {
|
|
|
2930
2958
|
case DirectoryExpanded:
|
|
2931
2959
|
return handleDropIntoFolder(state, dirent, index, fileHandles);
|
|
2932
2960
|
case File:
|
|
2933
|
-
return handleDropIntoFile(state, dirent, index, fileHandles, files);
|
|
2961
|
+
return handleDropIntoFile(state, dirent, index, fileHandles, files, paths);
|
|
2934
2962
|
default:
|
|
2935
2963
|
return state;
|
|
2936
2964
|
}
|
|
@@ -2950,24 +2978,37 @@ const getFileHandles = async fileIds => {
|
|
|
2950
2978
|
return files;
|
|
2951
2979
|
};
|
|
2952
2980
|
|
|
2981
|
+
const getFilePathElectron = async file => {
|
|
2982
|
+
return invoke('FileSystemHandle.getFilePathElectron', file);
|
|
2983
|
+
};
|
|
2984
|
+
|
|
2985
|
+
const getFilepath = async file => {
|
|
2986
|
+
return getFilePathElectron(file);
|
|
2987
|
+
};
|
|
2988
|
+
const getFilePaths = async (files, platform) => {
|
|
2989
|
+
if (platform !== Electron) {
|
|
2990
|
+
return files.map(file => '');
|
|
2991
|
+
}
|
|
2992
|
+
const promises = files.map(getFilepath);
|
|
2993
|
+
const paths = await Promise.all(promises);
|
|
2994
|
+
return paths;
|
|
2995
|
+
};
|
|
2996
|
+
|
|
2953
2997
|
const handleDrop = async (state, x, y, fileIds, fileList) => {
|
|
2954
2998
|
try {
|
|
2955
2999
|
// @ts-ignore
|
|
2956
3000
|
const files = [...fileList];
|
|
2957
3001
|
const fileHandles = await getFileHandles(fileIds);
|
|
3002
|
+
const paths = await getFilePaths(files, state.platform);
|
|
2958
3003
|
const index = getIndexFromPosition(state, x, y);
|
|
2959
3004
|
const fn = getDropHandler(index);
|
|
2960
|
-
const result = await fn(state, fileHandles, files, index);
|
|
3005
|
+
const result = await fn(state, fileHandles, files, paths, index);
|
|
2961
3006
|
return result;
|
|
2962
3007
|
} catch (error) {
|
|
2963
3008
|
throw new VError(error, 'Failed to drop files');
|
|
2964
3009
|
}
|
|
2965
3010
|
};
|
|
2966
3011
|
|
|
2967
|
-
const setFocus = key => {
|
|
2968
|
-
return invoke('Focus.setFocus', key);
|
|
2969
|
-
};
|
|
2970
|
-
|
|
2971
3012
|
const handleFocus = async state => {
|
|
2972
3013
|
await setFocus(FocusExplorer);
|
|
2973
3014
|
return state;
|
|
@@ -3035,7 +3076,7 @@ const handlePasteCopy = async (state, nativeFiles) => {
|
|
|
3035
3076
|
for (const source of nativeFiles.files) {
|
|
3036
3077
|
// @ts-ignore
|
|
3037
3078
|
const target = join(state.pathSeperator, state.root, getBaseName(state.pathSeparator, source));
|
|
3038
|
-
await copy
|
|
3079
|
+
await copy(source, target);
|
|
3039
3080
|
}
|
|
3040
3081
|
// TODO only update folder at which level it changed
|
|
3041
3082
|
return updateRoot(state);
|
|
@@ -3044,13 +3085,13 @@ const handlePasteCopy = async (state, nativeFiles) => {
|
|
|
3044
3085
|
const handlePasteCut = async (state, nativeFiles) => {
|
|
3045
3086
|
for (const source of nativeFiles.files) {
|
|
3046
3087
|
const target = `${state.root}${state.pathSeparator}${getBaseName(state.pathSeparator, source)}`;
|
|
3047
|
-
await rename
|
|
3088
|
+
await rename(source, target);
|
|
3048
3089
|
}
|
|
3049
3090
|
return state;
|
|
3050
3091
|
};
|
|
3051
3092
|
|
|
3052
3093
|
const handlePasteNone = async (state, nativeFiles) => {
|
|
3053
|
-
console.
|
|
3094
|
+
console.error('[ViewletExplorer/handlePaste] no paths detected');
|
|
3054
3095
|
return state;
|
|
3055
3096
|
};
|
|
3056
3097
|
|
|
@@ -3354,6 +3395,8 @@ const handleWorkspaceChange = async state => {
|
|
|
3354
3395
|
return newState;
|
|
3355
3396
|
};
|
|
3356
3397
|
|
|
3398
|
+
const Input$1 = 2;
|
|
3399
|
+
|
|
3357
3400
|
const ExplorerEditBox = FocusExplorerEditBox;
|
|
3358
3401
|
|
|
3359
3402
|
const newDirent = async (state, editingType) => {
|
|
@@ -3376,7 +3419,8 @@ const newDirent = async (state, editingType) => {
|
|
|
3376
3419
|
...state,
|
|
3377
3420
|
editingIndex: focusedIndex,
|
|
3378
3421
|
editingType,
|
|
3379
|
-
editingValue: ''
|
|
3422
|
+
editingValue: '',
|
|
3423
|
+
focus: Input$1
|
|
3380
3424
|
};
|
|
3381
3425
|
};
|
|
3382
3426
|
|
|
@@ -3491,7 +3535,12 @@ const renderEditingIndex = (oldState, newState) => {
|
|
|
3491
3535
|
return ['focusInput', 'ExplorerInput'];
|
|
3492
3536
|
};
|
|
3493
3537
|
|
|
3538
|
+
const ExplorerInput = 'ExplorerInput';
|
|
3539
|
+
|
|
3494
3540
|
const renderFocus = (oldState, newState) => {
|
|
3541
|
+
if (newState.focus === Input$1) {
|
|
3542
|
+
return ['Viewlet.focusElementByName', ExplorerInput];
|
|
3543
|
+
}
|
|
3495
3544
|
// TODO
|
|
3496
3545
|
// 1. when focused, focus the outer list element
|
|
3497
3546
|
// 2. when focused, set focus context in renderer worker
|
|
@@ -3509,13 +3558,14 @@ const ButtonNarrow = 'ButtonNarrow';
|
|
|
3509
3558
|
const ButtonPrimary = 'ButtonPrimary';
|
|
3510
3559
|
const ButtonWide = 'ButtonWide';
|
|
3511
3560
|
const Chevron = 'Chevron';
|
|
3512
|
-
const Explorer = 'Explorer';
|
|
3513
3561
|
const Empty = '';
|
|
3562
|
+
const Explorer = 'Explorer';
|
|
3514
3563
|
const ExplorerDropTarget = 'DropTarget';
|
|
3515
3564
|
const FileIcon = 'FileIcon';
|
|
3516
3565
|
const FocusOutline = 'FocusOutline';
|
|
3517
3566
|
const IconButton = 'IconButton';
|
|
3518
3567
|
const InputBox = 'InputBox';
|
|
3568
|
+
const InputValidationError = 'InputValidationError';
|
|
3519
3569
|
const Label = 'Label';
|
|
3520
3570
|
const MaskIconChevronDown = 'MaskIconChevronDown';
|
|
3521
3571
|
const MaskIconChevronRight = 'MaskIconChevronRight';
|
|
@@ -3594,18 +3644,22 @@ const getFileIconVirtualDom = icon => {
|
|
|
3594
3644
|
};
|
|
3595
3645
|
};
|
|
3596
3646
|
|
|
3597
|
-
const ExplorerInput = 'ExplorerInput';
|
|
3598
|
-
|
|
3599
3647
|
const label = {
|
|
3600
3648
|
type: Div,
|
|
3601
3649
|
className: Label,
|
|
3602
3650
|
childCount: 1
|
|
3603
3651
|
};
|
|
3604
|
-
const
|
|
3652
|
+
const getClassName$1 = hasEditingError => {
|
|
3653
|
+
if (hasEditingError) {
|
|
3654
|
+
return mergeClassNames(InputBox, InputValidationError);
|
|
3655
|
+
}
|
|
3656
|
+
return InputBox;
|
|
3657
|
+
};
|
|
3658
|
+
const getInputOrLabelDom = (isEditing, hasEditingError, name) => {
|
|
3605
3659
|
if (isEditing) {
|
|
3606
3660
|
return [{
|
|
3607
3661
|
type: Input,
|
|
3608
|
-
className:
|
|
3662
|
+
className: getClassName$1(hasEditingError),
|
|
3609
3663
|
id: 'ExplorerInput',
|
|
3610
3664
|
onInput: HandleEditingInput,
|
|
3611
3665
|
childCount: 0,
|
|
@@ -3628,7 +3682,8 @@ const getExplorerItemVirtualDom = item => {
|
|
|
3628
3682
|
id,
|
|
3629
3683
|
className,
|
|
3630
3684
|
isEditing,
|
|
3631
|
-
ariaExpanded
|
|
3685
|
+
ariaExpanded,
|
|
3686
|
+
hasEditingError
|
|
3632
3687
|
} = item;
|
|
3633
3688
|
const chevronDom = getChevronVirtualDom(chevron);
|
|
3634
3689
|
const dom = [{
|
|
@@ -3646,7 +3701,7 @@ const getExplorerItemVirtualDom = item => {
|
|
|
3646
3701
|
ariaExpanded,
|
|
3647
3702
|
ariaDescription: '',
|
|
3648
3703
|
id
|
|
3649
|
-
}, ...chevronDom, getFileIconVirtualDom(icon), ...getInputOrLabelDom(isEditing, name)];
|
|
3704
|
+
}, ...chevronDom, getFileIconVirtualDom(icon), ...getInputOrLabelDom(isEditing, hasEditingError, name)];
|
|
3650
3705
|
return dom;
|
|
3651
3706
|
};
|
|
3652
3707
|
|
|
@@ -3762,7 +3817,7 @@ const getTreeItemIndentWithChevron = (depth, chevron) => {
|
|
|
3762
3817
|
};
|
|
3763
3818
|
|
|
3764
3819
|
const ariaExpandedValues = [undefined, 'true', 'false'];
|
|
3765
|
-
const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, icons, useChevrons, dropTargets) => {
|
|
3820
|
+
const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets) => {
|
|
3766
3821
|
const visible = [];
|
|
3767
3822
|
const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
|
|
3768
3823
|
let iconIndex = 0;
|
|
@@ -3779,6 +3834,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
3779
3834
|
visible.push({
|
|
3780
3835
|
...item,
|
|
3781
3836
|
isEditing: i === editingIndex,
|
|
3837
|
+
hasEditingError: i === editingIndex && Boolean(editingErrorMessage),
|
|
3782
3838
|
icon,
|
|
3783
3839
|
indent,
|
|
3784
3840
|
ariaExpanded,
|
|
@@ -3796,6 +3852,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
3796
3852
|
name: 'new',
|
|
3797
3853
|
path: '/test/new',
|
|
3798
3854
|
isEditing: true,
|
|
3855
|
+
hasEditingError: Boolean(editingErrorMessage),
|
|
3799
3856
|
indent: '',
|
|
3800
3857
|
ariaExpanded: undefined,
|
|
3801
3858
|
chevron: 0,
|
|
@@ -3807,7 +3864,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
3807
3864
|
};
|
|
3808
3865
|
|
|
3809
3866
|
const renderItems = (oldState, newState) => {
|
|
3810
|
-
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.icons, newState.useChevrons);
|
|
3867
|
+
const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.editingErrorMessage, newState.icons, newState.useChevrons);
|
|
3811
3868
|
const isWide = newState.width > 450;
|
|
3812
3869
|
const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused, newState.dropTargets);
|
|
3813
3870
|
return ['Viewlet.setDom2', dom];
|
|
@@ -3876,7 +3933,7 @@ const getActions = root => {
|
|
|
3876
3933
|
command: 'refresh'
|
|
3877
3934
|
}, {
|
|
3878
3935
|
type: Button,
|
|
3879
|
-
id: collapseAll(),
|
|
3936
|
+
id: collapseAll$1(),
|
|
3880
3937
|
icon: CollapseAll,
|
|
3881
3938
|
command: 'collapseAll'
|
|
3882
3939
|
}];
|
|
@@ -4249,7 +4306,9 @@ const isExpandedDirectory = dirent => {
|
|
|
4249
4306
|
const saveState = uid => {
|
|
4250
4307
|
number(uid);
|
|
4251
4308
|
const value = get(uid);
|
|
4252
|
-
const
|
|
4309
|
+
const {
|
|
4310
|
+
newState
|
|
4311
|
+
} = value;
|
|
4253
4312
|
const {
|
|
4254
4313
|
items,
|
|
4255
4314
|
root,
|
|
@@ -4296,11 +4355,12 @@ const wrapCommand = fn => {
|
|
|
4296
4355
|
};
|
|
4297
4356
|
|
|
4298
4357
|
const commandMap = {
|
|
4358
|
+
'Explorer.getMenuEntries2': getMenuEntries2,
|
|
4299
4359
|
'Explorer.acceptEdit': wrapCommand(acceptEdit),
|
|
4300
4360
|
'Explorer.cancelEdit': wrapCommand(cancelEdit),
|
|
4301
|
-
'Explorer.collapseAll': wrapCommand(collapseAll
|
|
4302
|
-
'Explorer.copyPath': wrapCommand(copyPath
|
|
4303
|
-
'Explorer.copyRelativePath': wrapCommand(copyRelativePath
|
|
4361
|
+
'Explorer.collapseAll': wrapCommand(collapseAll),
|
|
4362
|
+
'Explorer.copyPath': wrapCommand(copyPath),
|
|
4363
|
+
'Explorer.copyRelativePath': wrapCommand(copyRelativePath),
|
|
4304
4364
|
'Explorer.expandAll': wrapCommand(expandAll),
|
|
4305
4365
|
'Explorer.expandRecursively': wrapCommand(expandRecursively),
|
|
4306
4366
|
'Explorer.focusFirst': wrapCommand(focusFirst),
|
|
@@ -4314,9 +4374,11 @@ const commandMap = {
|
|
|
4314
4374
|
'Explorer.handleBlur': wrapCommand(handleBlur),
|
|
4315
4375
|
'Explorer.handleClick': wrapCommand(handleClick),
|
|
4316
4376
|
'Explorer.handleClickAt': wrapCommand(handleClickAt),
|
|
4377
|
+
'Explorer.handleClickCurrent': wrapCommand(handleClickCurrent),
|
|
4317
4378
|
'Explorer.handleClickCurrentButKeepFocus': wrapCommand(handleClickCurrentButKeepFocus),
|
|
4318
4379
|
'Explorer.handleClickOpenFolder': wrapCommand(handleClickOpenFolder),
|
|
4319
4380
|
'Explorer.handleContextMenu': wrapCommand(handleContextMenu),
|
|
4381
|
+
'Explorer.handleContextMenuKeyboard': wrapCommand(handleContextMenuKeyboard),
|
|
4320
4382
|
'Explorer.handleCopy': wrapCommand(handleCopy),
|
|
4321
4383
|
'Explorer.handleDragLeave': wrapCommand(handleDragLeave),
|
|
4322
4384
|
'Explorer.handleDragOver': wrapCommand(handleDragOver),
|