@lvce-editor/explorer-view 2.23.0 → 2.25.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.
@@ -894,6 +894,7 @@ const OpenInIntegratedTerminal = 'Open in integrated Terminal';
894
894
  const Paste = 'Paste';
895
895
  const RefreshExplorer = 'Refresh Explorer';
896
896
  const Rename = 'Rename';
897
+ const TypeAFileName = 'Type file name. Press Enter to confirm or Escape to cancel.'; // TODO use keybinding
897
898
  const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
898
899
 
899
900
  const newFile$1 = () => {
@@ -947,6 +948,9 @@ const openFolder$1 = () => {
947
948
  const fileOrFolderNameMustBeProvided = () => {
948
949
  return i18nString(FileOrFolderNameMustBeProvider);
949
950
  };
951
+ const typeAFileName = () => {
952
+ return i18nString(TypeAFileName);
953
+ };
950
954
 
951
955
  const List = 1;
952
956
  const Input$1 = 2;
@@ -985,6 +989,8 @@ const getPath = dirent => {
985
989
  return dirent.path;
986
990
  };
987
991
 
992
+ const DELTA_EDITING = 100;
993
+
988
994
  const BlockDevice = 1;
989
995
  const CharacterDevice = 2;
990
996
  const Directory = 3;
@@ -996,8 +1002,8 @@ const Symlink = 9;
996
1002
  const SymLinkFile = 10;
997
1003
  const SymLinkFolder = 11;
998
1004
  const Unknown = 12;
999
- const EditingFile = 13;
1000
- const EditingFolder = 14;
1005
+ const EditingFile = File + DELTA_EDITING;
1006
+ const EditingFolder = Directory + DELTA_EDITING;
1001
1007
 
1002
1008
  const RendererWorker = 1;
1003
1009
 
@@ -1015,12 +1021,20 @@ const invoke = (method, ...params) => {
1015
1021
  return rpc.invoke(method, ...params);
1016
1022
  };
1017
1023
 
1024
+ const getFileIcon = async name => {
1025
+ return invoke('IconTheme.getFileIcon', {
1026
+ name
1027
+ });
1028
+ };
1029
+
1030
+ const getFolderIcon = async name => {
1031
+ return invoke('IconTheme.getFolderIcon', {
1032
+ name
1033
+ });
1034
+ };
1035
+
1018
1036
  const requestFileIcons = async requests => {
1019
- const promises = requests.map(request => request.type === File ? invoke('IconTheme.getFileIcon', {
1020
- name: request.name
1021
- }) : invoke('IconTheme.getFolderIcon', {
1022
- name: request.name
1023
- }));
1037
+ const promises = requests.map(request => request.type === File ? getFileIcon(request.name) : getFolderIcon(request.name));
1024
1038
  return Promise.all(promises);
1025
1039
  };
1026
1040
 
@@ -1408,12 +1422,41 @@ const acceptEdit = async state => {
1408
1422
  }
1409
1423
  };
1410
1424
 
1425
+ const getNewDirentsForCancelRename = (items, editingIndex) => {
1426
+ const item = items[editingIndex];
1427
+ const newItems = [...items];
1428
+ newItems[editingIndex] = {
1429
+ ...item,
1430
+ type: item.type - DELTA_EDITING
1431
+ };
1432
+ return newItems;
1433
+ };
1434
+
1435
+ const isNormalItem = item => {
1436
+ return item.type !== EditingFile && item.type !== EditingFolder;
1437
+ };
1411
1438
  const cancelEdit = state => {
1412
1439
  const {
1413
- editingIndex
1440
+ editingIndex,
1441
+ editingType
1414
1442
  } = state;
1443
+ if (editingType === Rename$1) {
1444
+ const newItems = getNewDirentsForCancelRename(state.items, editingIndex);
1445
+ return {
1446
+ ...state,
1447
+ items: newItems,
1448
+ focusedIndex: editingIndex,
1449
+ focused: true,
1450
+ editingIndex: -1,
1451
+ editingValue: '',
1452
+ editingType: None$5,
1453
+ focus: List
1454
+ };
1455
+ }
1456
+ const filteredItems = state.items.filter(isNormalItem);
1415
1457
  return {
1416
1458
  ...state,
1459
+ items: filteredItems,
1417
1460
  focusedIndex: editingIndex,
1418
1461
  focused: true,
1419
1462
  editingIndex: -1,
@@ -1535,7 +1578,11 @@ const create2 = (uid, uri, x, y, width, height, args, parentUid, platform = 0) =
1535
1578
  platform,
1536
1579
  focus: 0,
1537
1580
  editingErrorMessage: '',
1538
- inputSource: 0
1581
+ inputSource: 0,
1582
+ editingSelection: {
1583
+ start: 0,
1584
+ end: 0
1585
+ }
1539
1586
  };
1540
1587
  set(uid, state, state);
1541
1588
  };
@@ -1572,7 +1619,11 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0) =>
1572
1619
  platform,
1573
1620
  focus: 0,
1574
1621
  editingErrorMessage: '',
1575
- inputSource: 0
1622
+ inputSource: 0,
1623
+ editingSelection: {
1624
+ start: 0,
1625
+ end: 0
1626
+ }
1576
1627
  };
1577
1628
  set(state.uid, state, state);
1578
1629
  return state;
@@ -1582,15 +1633,21 @@ const RenderItems = 4;
1582
1633
  const RenderFocus = 6;
1583
1634
  const RenderFocusContext = 7;
1584
1635
  const RenderValue = 8;
1636
+ const RenderSelection = 9;
1585
1637
 
1586
- const diffType$2 = RenderFocus;
1587
- const isEqual$3 = (oldState, newState) => {
1638
+ const diffType$3 = RenderFocus;
1639
+ const isEqual$4 = (oldState, newState) => {
1588
1640
  return oldState.focused === newState.focused && oldState.focus === newState.focus;
1589
1641
  };
1590
1642
 
1591
- const diffType$1 = RenderItems;
1643
+ const diffType$2 = RenderItems;
1644
+ const isEqual$3 = (oldState, newState) => {
1645
+ 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 && oldState.icons === newState.icons;
1646
+ };
1647
+
1648
+ const diffType$1 = RenderSelection;
1592
1649
  const isEqual$2 = (oldState, newState) => {
1593
- 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;
1650
+ return oldState.editingSelection.start === newState.editingSelection.start && oldState.editingSelection.end === newState.editingSelection.end;
1594
1651
  };
1595
1652
 
1596
1653
  const diffType = RenderValue;
@@ -1601,8 +1658,8 @@ const isEqual$1 = (oldState, newState) => {
1601
1658
  return oldState.focus === Input$1 && newState.focus === Input$1 && oldState.editingValue === newState.editingValue;
1602
1659
  };
1603
1660
 
1604
- const modules = [isEqual$2, isEqual$3, isEqual$3, isEqual$1];
1605
- const numbers = [diffType$1, diffType$2, RenderFocusContext, diffType];
1661
+ const modules = [isEqual$3, isEqual$4, isEqual$4, isEqual$1, isEqual$2];
1662
+ const numbers = [diffType$2, diffType$3, RenderFocusContext, diffType, diffType$1];
1606
1663
 
1607
1664
  const diff = (oldState, newState) => {
1608
1665
  const diffResult = [];
@@ -3580,7 +3637,7 @@ const getNewChildDirentsForNewDirent = async (items, depth, parentPath, direntTy
3580
3637
  const newDirent = {
3581
3638
  name: '',
3582
3639
  type: direntType,
3583
- path: '',
3640
+ path: parentPath,
3584
3641
  depth,
3585
3642
  selected: false,
3586
3643
  posInSet: updatedChildren.length + 1,
@@ -3591,7 +3648,20 @@ const getNewChildDirentsForNewDirent = async (items, depth, parentPath, direntTy
3591
3648
  return allChildDirents;
3592
3649
  };
3593
3650
 
3594
- const getNewDirentsForNewDirent = async (items, focusedIndex, type) => {
3651
+ const getNewDirentsForNewDirent = async (items, focusedIndex, type, root) => {
3652
+ if (items.length === 0 || focusedIndex === -1) {
3653
+ const newDirent = {
3654
+ name: '',
3655
+ type,
3656
+ path: root,
3657
+ depth: 0,
3658
+ selected: false,
3659
+ posInSet: 1,
3660
+ setSize: 1,
3661
+ icon: ''
3662
+ };
3663
+ return [...items, newDirent];
3664
+ }
3595
3665
  const focusedItem = items[focusedIndex];
3596
3666
  if (!focusedItem) {
3597
3667
  return items;
@@ -3632,10 +3702,11 @@ const newDirent = async (state, editingType) => {
3632
3702
  minLineY,
3633
3703
  height,
3634
3704
  itemHeight,
3635
- fileIconCache
3705
+ fileIconCache,
3706
+ root
3636
3707
  } = state;
3637
3708
  const direntType = getNewDirentType(editingType);
3638
- const newDirents = await getNewDirentsForNewDirent(items, focusedIndex, direntType);
3709
+ const newDirents = await getNewDirentsForNewDirent(items, focusedIndex, direntType, root);
3639
3710
  const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
3640
3711
  const visible = newDirents.slice(minLineY, maxLineY);
3641
3712
  const {
@@ -3649,6 +3720,7 @@ const newDirent = async (state, editingType) => {
3649
3720
  editingIndex,
3650
3721
  editingType,
3651
3722
  editingValue: '',
3723
+ focusedIndex: editingIndex,
3652
3724
  focus: Input$1,
3653
3725
  icons,
3654
3726
  fileIconCache: newFileIconCache,
@@ -3756,25 +3828,52 @@ const removeDirent = async state => {
3756
3828
  };
3757
3829
  };
3758
3830
 
3831
+ const getNewDirentsForRename = (items, focusedIndex) => {
3832
+ const item = items[focusedIndex];
3833
+ const newItems = [...items];
3834
+ const editingType = item.type === File ? EditingFile : EditingFolder;
3835
+ newItems[focusedIndex] = {
3836
+ ...item,
3837
+ type: editingType
3838
+ };
3839
+ return newItems;
3840
+ };
3841
+
3759
3842
  const User = 1;
3760
3843
  const Script = 2;
3761
3844
 
3762
3845
  const renameDirent = state => {
3763
3846
  const {
3764
3847
  focusedIndex,
3765
- items
3848
+ items,
3849
+ icons,
3850
+ minLineY
3766
3851
  } = state;
3852
+ if (items.length === 0) {
3853
+ return state;
3854
+ }
3767
3855
  const item = items[focusedIndex];
3856
+ const newItems = getNewDirentsForRename(items, focusedIndex);
3768
3857
  return {
3769
3858
  ...state,
3859
+ items: newItems,
3770
3860
  editingIndex: focusedIndex,
3771
3861
  editingType: Rename$1,
3772
3862
  editingValue: item.name,
3863
+ editingIcon: icons[focusedIndex - minLineY],
3864
+ editingSelection: {
3865
+ start: 0,
3866
+ end: item.name.length
3867
+ },
3773
3868
  focus: Input$1,
3774
3869
  inputSource: Script
3775
3870
  };
3776
3871
  };
3777
3872
 
3873
+ const renderEditingSelection = (oldState, newState) => {
3874
+ return ['Viewlet.setSelection', newState.editingSelection];
3875
+ };
3876
+
3778
3877
  const ExplorerInput = 'ExplorerInput';
3779
3878
 
3780
3879
  const renderFocus$1 = (oldState, newState) => {
@@ -3909,6 +4008,7 @@ const getClassName$2 = hasEditingError => {
3909
4008
  return InputBox;
3910
4009
  };
3911
4010
  const getInputDom = hasEditingError => {
4011
+ const ariaLabel = typeAFileName();
3912
4012
  return [{
3913
4013
  type: Input,
3914
4014
  className: getClassName$2(hasEditingError),
@@ -3916,7 +4016,11 @@ const getInputDom = hasEditingError => {
3916
4016
  onInput: HandleEditingInput,
3917
4017
  onBlur: HandleInputBlur,
3918
4018
  childCount: 0,
3919
- name: ExplorerInput
4019
+ name: ExplorerInput,
4020
+ autocorrect: 'off',
4021
+ autocapitalize: 'off',
4022
+ spellcheck: 'false',
4023
+ ariaLabel: ariaLabel
3920
4024
  }];
3921
4025
  };
3922
4026
 
@@ -4095,13 +4199,12 @@ const getClassName = (isSelected, isFocused) => {
4095
4199
  }
4096
4200
  return TreeItem;
4097
4201
  };
4098
- const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets) => {
4202
+ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editingIndex, editingType, editingValue, editingErrorMessage, icons, useChevrons, dropTargets, editingIcon) => {
4099
4203
  const visible = [];
4100
4204
  const indentFn = useChevrons ? getTreeItemIndentWithChevron : getTreeItemIndent;
4101
4205
  let iconIndex = 0;
4102
4206
  for (let i = minLineY; i < Math.min(maxLineY, items.length); i++) {
4103
4207
  const item = items[i];
4104
- const icon = icons[iconIndex++];
4105
4208
  const chevron = getChevronType(item.type, useChevrons);
4106
4209
  const indent = indentFn(item.depth, chevron);
4107
4210
  const isFocused = i === focusedIndex;
@@ -4110,12 +4213,17 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
4110
4213
  const className = getClassName(isSelected, isFocused);
4111
4214
  const expanded = getExpandedType(item.type);
4112
4215
  const ariaExpanded = ariaExpandedValues[expanded];
4113
-
4114
- // @ts-ignore
4216
+ const isEditing = i === editingIndex;
4217
+ let icon = icons[iconIndex++];
4218
+ if (isEditing) {
4219
+ icon = editingIcon;
4220
+ }
4115
4221
  visible.push({
4116
4222
  ...item,
4117
- isEditing: i === editingIndex,
4118
- hasEditingError: i === editingIndex && Boolean(editingErrorMessage),
4223
+ posInSet: item.posInSet ?? i + 1,
4224
+ setSize: item.setSize ?? items.length,
4225
+ isEditing: isEditing,
4226
+ hasEditingError: isEditing && Boolean(editingErrorMessage),
4119
4227
  icon,
4120
4228
  indent,
4121
4229
  ariaExpanded,
@@ -4124,29 +4232,11 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
4124
4232
  className
4125
4233
  });
4126
4234
  }
4127
- if (editingType !== None$5 && editingIndex === -1) {
4128
- visible.push({
4129
- depth: 3,
4130
- posInSet: 1,
4131
- setSize: 1,
4132
- icon: '',
4133
- name: 'new',
4134
- path: '/test/new',
4135
- isEditing: true,
4136
- hasEditingError: Boolean(editingErrorMessage),
4137
- indent: '',
4138
- ariaExpanded: undefined,
4139
- chevron: 0,
4140
- id: undefined,
4141
- className: TreeItem,
4142
- selected: false
4143
- });
4144
- }
4145
4235
  return visible;
4146
4236
  };
4147
4237
 
4148
4238
  const renderItems = (oldState, newState) => {
4149
- const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.editingErrorMessage, newState.icons, newState.useChevrons);
4239
+ const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.editingErrorMessage, newState.icons, newState.useChevrons, newState.dropTargets, newState.editingIcon);
4150
4240
  const isWide = newState.width > 450;
4151
4241
  const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused, newState.dropTargets);
4152
4242
  return ['Viewlet.setDom2', dom];
@@ -4172,6 +4262,8 @@ const getRenderer = diffType => {
4172
4262
  return renderFocus;
4173
4263
  case RenderValue:
4174
4264
  return renderValue;
4265
+ case RenderSelection:
4266
+ return renderEditingSelection;
4175
4267
  default:
4176
4268
  throw new Error('unknown renderer');
4177
4269
  }
@@ -4180,6 +4272,10 @@ const getRenderer = diffType => {
4180
4272
  const applyRender = (oldState, newState, diffResult) => {
4181
4273
  const commands = [];
4182
4274
  for (const item of diffResult) {
4275
+ if (item === RenderSelection) {
4276
+ // TODO support this in the future
4277
+ continue;
4278
+ }
4183
4279
  const fn = getRenderer(item);
4184
4280
  const result = fn(oldState, newState);
4185
4281
  if (result.length > 0) {
@@ -4647,21 +4743,34 @@ const terminate = () => {
4647
4743
  globalThis.close();
4648
4744
  };
4649
4745
 
4650
- const getEditingIcon = async (editingType, value) => {
4651
- if (editingType === File) {
4746
+ const getEditingIcon = async (editingType, value, direntType) => {
4747
+ if (editingType === CreateFile) {
4652
4748
  return invoke('IconTheme.getFileIcon', {
4653
4749
  name: value
4654
4750
  });
4655
4751
  }
4656
- if (editingType === Directory) {
4752
+ if (editingType === Rename$1) {
4753
+ if (direntType === File || direntType === EditingFile) {
4754
+ return invoke('IconTheme.getFileIcon', {
4755
+ name: value
4756
+ });
4757
+ }
4758
+ if (direntType === Directory || direntType === EditingFolder) {
4759
+ return invoke('IconTheme.getFolderIcon', {
4760
+ name: value
4761
+ });
4762
+ }
4763
+ }
4764
+ if (editingType === CreateFolder) {
4657
4765
  return invoke('IconTheme.getFolderIcon', {
4658
4766
  name: value
4659
4767
  });
4660
4768
  }
4661
4769
  return '';
4662
4770
  };
4771
+
4663
4772
  const updateEditingValue = async (state, value, inputSource = User) => {
4664
- const editingIcon = await getEditingIcon(state.editingType, value);
4773
+ const editingIcon = await getEditingIcon(state.editingType, value, state.items[state.editingIndex]?.type);
4665
4774
  return {
4666
4775
  ...state,
4667
4776
  editingValue: value,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "2.23.0",
3
+ "version": "2.25.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",