@electerm/electerm-react 2.4.38 → 2.5.6

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.
@@ -3,6 +3,7 @@ window.refs = new Map()
3
3
  window.refsStatic = new Map()
4
4
  window.refsTransfers = new Map()
5
5
  window.refsTabs = new Map()
6
+ window.filesRef = new Map()
6
7
 
7
8
  class Ref {
8
9
  constructor (key) {
@@ -59,3 +60,4 @@ export const refs = new Ref('refs')
59
60
  export const refsTransfers = new Ref('refsTransfers')
60
61
  export const refsStatic = new Ref('refsStatic')
61
62
  export const refsTabs = new TabsRef('refsTabs')
63
+ export const filesRef = new Ref('filesRef')
@@ -37,12 +37,8 @@ import { pick } from 'lodash-es'
37
37
  import deepCopy from 'json-deep-copy'
38
38
  import './wrapper.styl'
39
39
 
40
- function setupGlobalMessageDismiss () {
41
- }
42
-
43
40
  export default auto(function Index (props) {
44
41
  useEffect(() => {
45
- setupGlobalMessageDismiss()
46
42
  const { store } = props
47
43
  window.addEventListener('resize', store.onResize)
48
44
  setTimeout(store.triggerResize, 200)
@@ -107,6 +103,7 @@ export default auto(function Index (props) {
107
103
  'not-mac': !isMac,
108
104
  'is-win': isWin,
109
105
  pinned,
106
+ 'not-win': !isWin,
110
107
  'qm-pinned': pinnedQuickCommandBar,
111
108
  'term-fullscreen': terminalFullScreen,
112
109
  'is-main': !isSecondInstance
@@ -36,11 +36,8 @@ import time from '../../common/time'
36
36
  import { filesize } from 'filesize'
37
37
  import { createTransferProps } from './transfer-common'
38
38
  import generate from '../../common/uid'
39
- import { refsStatic, refs } from '../common/ref'
39
+ import { refsStatic, refs, filesRef } from '../common/ref'
40
40
  import iconsMap from '../sys-menu/icons-map'
41
- import {
42
- Dropdown
43
- } from 'antd'
44
41
 
45
42
  const e = window.translate
46
43
 
@@ -63,6 +60,7 @@ export default class FileSection extends React.Component {
63
60
  }
64
61
 
65
62
  componentDidMount () {
63
+ filesRef.add(this.id, this)
66
64
  this.applyStyle()
67
65
  }
68
66
 
@@ -84,6 +82,7 @@ export default class FileSection extends React.Component {
84
82
  }
85
83
 
86
84
  clearRef = () => {
85
+ filesRef.remove(this.id)
87
86
  refs.remove(this.id)
88
87
  }
89
88
 
@@ -91,11 +90,11 @@ export default class FileSection extends React.Component {
91
90
  return refsStatic.get('text-editor')
92
91
  }
93
92
 
94
- handleDropdownOpenChange = (open) => {
95
- if (open) {
96
- this.forceUpdate()
97
- }
98
- }
93
+ // handleDropdownOpenChange = (open) => {
94
+ // if (open) {
95
+ // this.forceUpdate()
96
+ // }
97
+ // }
99
98
 
100
99
  applyStyle = () => {
101
100
  if (!this.domRef) {
@@ -447,20 +446,18 @@ export default class FileSection extends React.Component {
447
446
  const {
448
447
  id,
449
448
  type,
450
- isParent
449
+ isParent,
450
+ isEmpty
451
451
  } = file
452
- if (isParent) {
453
- return
452
+ if (isEmpty || isParent) {
453
+ return this.props.modifier({
454
+ selectedFiles: new Set()
455
+ })
454
456
  }
455
457
  this.props.modifier({
456
458
  lastClickedFile: file
457
459
  })
458
460
  this.onDragEnd(e)
459
- if (!id) {
460
- return this.props.modifier({
461
- selectedFiles: new Set()
462
- })
463
- }
464
461
  const selectedFilesOld = this.props.getSelectedFiles()
465
462
  const isSameSide = selectedFilesOld.length &&
466
463
  type === selectedFilesOld[0].type
@@ -519,7 +516,7 @@ export default class FileSection extends React.Component {
519
516
 
520
517
  handleBlur = () => {
521
518
  const file = copy(this.state.file)
522
- const { nameTemp, name, id, type } = this.state.file
519
+ const { nameTemp, name, type, id } = this.state.file
523
520
  if (name === nameTemp) {
524
521
  if (!id) {
525
522
  return this.cancelNew(type)
@@ -854,8 +851,8 @@ export default class FileSection extends React.Component {
854
851
  return this.props.renderDelConfirmTitle(files, true)
855
852
  }
856
853
 
857
- showModeEdit (type, id) {
858
- if (!id) {
854
+ showModeEdit (type, isRealFile) {
855
+ if (!isRealFile) {
859
856
  return false
860
857
  }
861
858
  if (type === typeMap.remote) {
@@ -865,6 +862,7 @@ export default class FileSection extends React.Component {
865
862
  }
866
863
 
867
864
  handleContextMenuCapture = (e) => {
865
+ this.props.setClickFileId(this.id)
868
866
  if (!this.isSelected(this.state.file.id)) {
869
867
  this.onClick(e)
870
868
  }
@@ -925,12 +923,13 @@ export default class FileSection extends React.Component {
925
923
  isDirectory,
926
924
  size,
927
925
  id,
926
+ isEmpty,
928
927
  isParent
929
928
  },
930
929
  selectedFiles,
931
930
  tab
932
931
  } = this.props
933
- const isRealFile = id && !isParent
932
+ const isRealFile = !isEmpty && !isParent
934
933
  const hasHost = !!tab.host
935
934
  const { enableSsh } = tab
936
935
  const isLocal = type === typeMap.local
@@ -1202,9 +1201,7 @@ export default class FileSection extends React.Component {
1202
1201
  const props = {
1203
1202
  className,
1204
1203
  draggable: draggable && !isParent,
1205
- onDoubleClick: this.transferOrEnterDirectory,
1206
1204
  ...pick(this, [
1207
- 'onClick',
1208
1205
  'onDrag',
1209
1206
  'onDragEnter',
1210
1207
  'onDragExit',
@@ -1216,33 +1213,22 @@ export default class FileSection extends React.Component {
1216
1213
  onDragStart: onDragStart || this.onDragStart,
1217
1214
  'data-id': id,
1218
1215
  id: this.id,
1219
- 'data-is-parent': isParent ? 'y' : 'n',
1220
1216
  'data-type': type,
1221
1217
  title: file.name
1222
1218
  }
1223
- const ddProps = {
1224
- menu: {
1225
- items: this.renderContextMenu(),
1226
- onClick: this.onContextMenu
1227
- },
1228
- trigger: ['contextMenu'],
1229
- onOpenChange: this.handleDropdownOpenChange
1230
- }
1231
1219
  return (
1232
- <Dropdown {...ddProps}>
1233
- <div
1234
- ref={this.domRef}
1235
- {...props}
1236
- onContextMenu={this.handleContextMenuCapture}
1237
- >
1238
- <div className='file-bg' />
1239
- <div className='file-props-div'>
1240
- {
1241
- properties.map(this.renderProp)
1242
- }
1243
- </div>
1220
+ <div
1221
+ ref={this.domRef}
1222
+ {...props}
1223
+ onContextMenu={this.handleContextMenuCapture}
1224
+ >
1225
+ <div className='file-bg' />
1226
+ <div className='file-props-div'>
1227
+ {
1228
+ properties.map(this.renderProp)
1229
+ }
1244
1230
  </div>
1245
- </Dropdown>
1231
+ </div>
1246
1232
  )
1247
1233
  }
1248
1234
  }
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import { Component } from 'react'
6
+ import { Dropdown } from 'antd'
6
7
  import classnames from 'classnames'
7
8
  import FileSection from './file-item'
8
9
  import PagedList from './paged-list'
@@ -11,6 +12,7 @@ import {
11
12
  CheckOutlined
12
13
  } from '@ant-design/icons'
13
14
  import IconHolder from '../sys-menu/icon-holder'
15
+ import { filesRef } from '../common/ref'
14
16
 
15
17
  const e = window.translate
16
18
 
@@ -168,57 +170,6 @@ export default class FileListTable extends Component {
168
170
  'left'
169
171
  ]
170
172
 
171
- // saveOldStyle = () => {
172
- // const { properties } = this.state
173
- // const ids = [
174
- // ...properties,
175
- // ...splitHandles
176
- // ]
177
- // const { type, id } = this.props
178
- // const parentWidth = document.querySelector(
179
- // `#id-${id} .tw-${type} .sftp-table`
180
- // ).clientWidth
181
- // this.oldStyles = ids.reduce((prev, { id, name }) => {
182
- // const sel = `.session-current .tw-${type} .sftp-file-table-header .shi-${name || id}`
183
- // return {
184
- // ...prev,
185
- // [name || id]: {
186
- // style: pick(
187
- // document.querySelector(sel)?.style || {},
188
- // this.positionProps
189
- // ),
190
- // parentWidth
191
- // }
192
- // }
193
- // }, {})
194
- // }
195
-
196
- // changePosition = (
197
- // dom,
198
- // xDiff,
199
- // type,
200
- // style
201
- // ) => {
202
- // const realWidth = style.width
203
- // const realLeft = style.left
204
- // if (type === 'prev') {
205
- // dom.forEach(d => {
206
- // d.style.width = (realWidth + xDiff) + 'px'
207
- // })
208
- // } else if (type === 'dom') {
209
- // dom.style.left = (realLeft + xDiff) + 'px'
210
- // } else {
211
- // dom.forEach(d => {
212
- // d.style.width = (realWidth - xDiff) + 'px'
213
- // d.style.left = (realLeft + xDiff) + 'px'
214
- // })
215
- // }
216
- // }
217
-
218
- // onDragEnd = () => {}
219
-
220
- // onDoubleClick = () => this.resetWidth()
221
-
222
173
  hasPager = () => {
223
174
  const {
224
175
  pageSize
@@ -230,36 +181,29 @@ export default class FileListTable extends Component {
230
181
  return len > pageSize
231
182
  }
232
183
 
233
- // rebuildStyle = (name) => {
234
- // let { style, parentWidth } = this.oldStyles[name]
235
- // style = copy(style)
236
- // const {
237
- // type,
238
- // id
239
- // } = this.props
240
- // const currentParentWidth = document.querySelector(
241
- // `#id-${id} .tw-${type} .sftp-table`
242
- // ).clientWidth
243
- // style.width = (parseFloat(style.width) * currentParentWidth / parentWidth) + 'px'
244
- // style.left = (parseFloat(style.left) * currentParentWidth / parentWidth) + 'px'
245
- // return style
246
- // }
247
-
248
184
  // reset
249
185
  resetWidth = () => {
250
186
  this.setState(this.initFromProps())
251
187
  }
252
188
 
189
+ setClickFileId = (id) => {
190
+ this.currentFileId = id
191
+ }
192
+
253
193
  renderItem = (item) => {
254
194
  const { type } = this.props
255
195
  const cls = item.isParent ? 'parent-file-item' : 'real-file-item'
256
196
  const key = item.id
197
+ const fileProps = {
198
+ ...this.props.getFileProps(item, type),
199
+ cls,
200
+ properties: this.state.properties,
201
+ setClickFileId: this.setClickFileId
202
+ }
257
203
  return (
258
204
  <FileSection
259
- {...this.props.getFileProps(item, type)}
205
+ {...fileProps}
260
206
  key={key}
261
- cls={cls}
262
- properties={this.state.properties}
263
207
  />
264
208
  )
265
209
  }
@@ -268,9 +212,59 @@ export default class FileListTable extends Component {
268
212
  this.onToggleProp(key)
269
213
  }
270
214
 
215
+ handleClick = (e) => {
216
+ const target = e.target.closest('[data-id]')
217
+ if (target) {
218
+ const id = target.getAttribute('data-id')
219
+ const refKey = 'file-' + id
220
+ const ref = filesRef.get(refKey)
221
+ if (ref) {
222
+ ref.onClick(e)
223
+ }
224
+ }
225
+ }
226
+
227
+ handleDoubleClick = (e) => {
228
+ const target = e.target.closest('[data-id]')
229
+ if (target) {
230
+ const id = target.getAttribute('data-id')
231
+ const ref = filesRef.get('file-' + id)
232
+ if (ref) {
233
+ ref.transferOrEnterDirectory(e)
234
+ }
235
+ }
236
+ }
237
+
238
+ getClickedFile = () => {
239
+ const refKey = this.currentFileId
240
+ return filesRef.get(refKey)
241
+ }
242
+
243
+ handleDropdownOpenChange = (open) => {
244
+ if (open) {
245
+ this.forceUpdate()
246
+ }
247
+ }
248
+
249
+ onContextMenuFile = ({ key }) => {
250
+ if (key !== 'more-submenu') {
251
+ const inst = this.getClickedFile()
252
+ if (inst) {
253
+ inst[key]()
254
+ }
255
+ }
256
+ }
257
+
258
+ renderContextMenuFile = () => {
259
+ const fileInst = this.getClickedFile()
260
+ return fileInst ? fileInst.renderContextMenu() : []
261
+ }
262
+
271
263
  renderParent = (type) => {
272
264
  const { parentItem } = this.props
273
- return parentItem ? this.renderItem(parentItem) : null
265
+ return parentItem
266
+ ? this.renderItem(parentItem)
267
+ : null
274
268
  }
275
269
 
276
270
  render () {
@@ -282,7 +276,9 @@ export default class FileListTable extends Component {
282
276
  style: {
283
277
  height: height - 42 - 30 - 32 - 90
284
278
  },
285
- draggable: false
279
+ draggable: false,
280
+ onClick: this.handleClick,
281
+ onDoubleClick: this.handleDoubleClick
286
282
  }
287
283
  const hasPager = this.hasPager()
288
284
  const cls = classnames(
@@ -291,21 +287,37 @@ export default class FileListTable extends Component {
291
287
  'sftp-has-pager': hasPager
292
288
  }
293
289
  )
294
-
290
+ const ddProps = {
291
+ menu: {
292
+ items: this.renderContextMenuFile(),
293
+ onClick: this.onContextMenuFile
294
+ },
295
+ trigger: ['contextMenu'],
296
+ onOpenChange: this.handleDropdownOpenChange
297
+ }
295
298
  return (
296
299
  <div className={cls}>
297
300
  {this.renderTableHeader()}
298
- <div
299
- {...props}
300
- >
301
- {this.props.renderEmptyFile(type)}
302
- {this.renderParent(type)}
303
- <PagedList
304
- list={fileList}
305
- renderItem={this.renderItem}
306
- hasPager={hasPager}
307
- />
308
- </div>
301
+ <Dropdown {...ddProps}>
302
+ <div
303
+ {...props}
304
+ >
305
+ {
306
+ this.props.renderEmptyFile(
307
+ type,
308
+ {
309
+ setClickFileId: this.setClickFileId
310
+ }
311
+ )
312
+ }
313
+ {this.renderParent(type)}
314
+ <PagedList
315
+ list={fileList}
316
+ renderItem={this.renderItem}
317
+ hasPager={hasPager}
318
+ />
319
+ </div>
320
+ </Dropdown>
309
321
  </div>
310
322
  )
311
323
  }
@@ -1054,29 +1054,45 @@ export default class Sftp extends Component {
1054
1054
  }
1055
1055
  }
1056
1056
 
1057
- renderEmptyFile = (type) => {
1057
+ renderEmptyFile = (type, extra = {}) => {
1058
+ const uniqueId = this.getPathUid(type, 'empty')
1058
1059
  const item = {
1059
1060
  type,
1060
1061
  name: '',
1061
- isDirectory: true
1062
+ isDirectory: true,
1063
+ id: uniqueId,
1064
+ isEmpty: true
1065
+ }
1066
+ const allProps = {
1067
+ ...this.getFileProps(item, type),
1068
+ ...extra,
1069
+ cls: 'virtual-file-unit',
1070
+ key: 'empty' + type,
1071
+ isEmpty: true,
1072
+ draggable: false,
1073
+ ref: ref => {
1074
+ this[type + 'Dom'] = ref
1075
+ }
1062
1076
  }
1063
1077
  return (
1064
1078
  <div
1065
1079
  className={`virtual-file virtual-file-${type}`}
1066
1080
  >
1067
1081
  <FileSection
1068
- {...this.getFileProps(item, type)}
1069
- ref={ref => {
1070
- this[type + 'Dom'] = ref
1071
- }}
1072
- draggable={false}
1073
- cls='virtual-file-unit'
1074
- key={'empty' + type}
1082
+ {...allProps}
1083
+ key={uniqueId}
1075
1084
  />
1076
1085
  </div>
1077
1086
  )
1078
1087
  }
1079
1088
 
1089
+ getPathUid = (type, type1) => {
1090
+ const currentPath = this.state[`${type}Path`]
1091
+ const parentPath = resolve(currentPath, '..')
1092
+ const { id } = this.props.tab
1093
+ return `${type1}-${parentPath}-${id}-${type}`
1094
+ }
1095
+
1080
1096
  renderParentItem = (type) => {
1081
1097
  const currentPath = this.state[`${type}Path`]
1082
1098
  const parentPath = resolve(currentPath, '..')
@@ -1085,8 +1101,7 @@ export default class Sftp extends Component {
1085
1101
  return null
1086
1102
  }
1087
1103
 
1088
- const { id } = this.props.tab
1089
- const uniqueId = `parent-${parentPath}-${id}-${type}`
1104
+ const uniqueId = this.getPathUid(type, 'parent')
1090
1105
 
1091
1106
  return {
1092
1107
  type,
@@ -13,7 +13,8 @@
13
13
  .item-list-unit:hover
14
14
  .list-item-remove
15
15
  display none !important
16
-
16
+ .sidebar-panel
17
+ top 36px
17
18
  .sidebar
18
19
  position absolute
19
20
  left 0
@@ -48,23 +48,37 @@ export default function AppDrag (props) {
48
48
  window.pre.runGlobalAsync('maximize')
49
49
  }
50
50
  }
51
+ if (!window.store.shouldSendWindowMove) {
52
+ useEffect(() => {
53
+ // Listen for mouseup at document level to catch mouseup outside window
54
+ document.addEventListener('mouseup', onMouseUp)
55
+ window.addEventListener('contextmenu', onMouseUp)
51
56
 
52
- useEffect(() => {
53
- // Listen for mouseup at document level to catch mouseup outside window
54
- document.addEventListener('mouseup', onMouseUp)
55
- window.addEventListener('contextmenu', onMouseUp)
56
-
57
- return () => {
58
- document.removeEventListener('mouseup', onMouseUp)
59
- window.removeEventListener('contextmenu', onMouseUp)
57
+ return () => {
58
+ document.removeEventListener('mouseup', onMouseUp)
59
+ window.removeEventListener('contextmenu', onMouseUp)
60
+ }
61
+ }, [])
62
+ }
63
+ const props0 = {
64
+ className: 'app-drag',
65
+ onDoubleClick
66
+ }
67
+ if (
68
+ window.store.shouldSendWindowMove
69
+ ) {
70
+ Object.assign(props0, {
71
+ onMouseDown,
72
+ onMouseUp
73
+ })
74
+ } else {
75
+ props0.style = {
76
+ WebkitAppRegion: 'drag'
60
77
  }
61
- }, [])
78
+ }
62
79
  return (
63
80
  <div
64
- className='app-drag'
65
- onMouseDown={onMouseDown}
66
- onMouseUp={onMouseUp}
67
- onDoubleClick={onDoubleClick}
81
+ {...props0}
68
82
  >
69
83
  {props.children}
70
84
  </div>
@@ -308,3 +308,11 @@
308
308
  text-overflow ellipsis
309
309
  white-space nowrap
310
310
 
311
+ .not-webapp.not-win
312
+ .tab
313
+ .tabs-add-btn
314
+ .window-control-box
315
+ .tab-close
316
+ .tab-reload
317
+ .tabs-extra
318
+ -webkit-app-region no-drag
@@ -12,13 +12,17 @@ export default Store => {
12
12
 
13
13
  Store.prototype.blur = function () {
14
14
  window.focused = false
15
- window.pre.runSync('windowMove', false)
15
+ if (window.store.shouldSendWindowMove) {
16
+ window.pre.runSync('windowMove', false)
17
+ }
16
18
  refs.get('term-' + window.store.activeTabId)?.term?.blur()
17
19
  }
18
20
 
19
21
  Store.prototype.onBlur = function () {
20
22
  window.focused = false
21
- window.pre.runSync('windowMove', false)
23
+ if (window.store.shouldSendWindowMove) {
24
+ window.pre.runSync('windowMove', false)
25
+ }
22
26
  }
23
27
 
24
28
  Store.prototype.selectall = function () {
@@ -36,7 +36,8 @@ import {
36
36
  settingMap,
37
37
  terminalSshConfigType,
38
38
  paneMap,
39
- staticNewItemTabs
39
+ staticNewItemTabs,
40
+ isWin
40
41
  } from '../common/constants'
41
42
  import getInitItem from '../common/init-setting-item'
42
43
  import createTitle from '../common/create-title'
@@ -89,6 +90,12 @@ class Store {
89
90
  return tab.props.tab
90
91
  }
91
92
 
93
+ get shouldSendWindowMove () {
94
+ return isWin &&
95
+ !window.et.isWebApp &&
96
+ !window.store.config.useSystemTitleBar
97
+ }
98
+
92
99
  get batchInputSelectedTabIds () {
93
100
  return Array.from(window.store._batchInputSelectedTabIds)
94
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "2.4.38",
3
+ "version": "2.5.6",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",