@electerm/electerm-react 1.37.92 → 1.37.96

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.
@@ -306,6 +306,7 @@ export const expandedKeysLsKey = 'expanded-keys'
306
306
  export const checkedKeysLsKey = 'checked-keys'
307
307
  export const quickCommandLabelsLsKey = 'quick-command-labels'
308
308
  export const localAddrBookmarkLsKey = 'local-addr-bookmark-keys'
309
+ export const dismissDelKeyTipLsKey = 'dismiss-del-key-tip'
309
310
  export const sshTunnelHelpLink = 'https://github.com/electerm/electerm/wiki/How-to-use-ssh-tunnel'
310
311
  export const batchOpHelpLink = 'https://github.com/electerm/electerm/wiki/batch-operation'
311
312
  export const proxyHelpLink = 'https://github.com/electerm/electerm/wiki/proxy-format'
@@ -33,6 +33,9 @@ export default function createTitle (res) {
33
33
 
34
34
  export function createTitleTag (obj) {
35
35
  const { color } = obj
36
+ if (!color) {
37
+ return null
38
+ }
36
39
  const styleTag = color
37
40
  ? { color }
38
41
  : {}
@@ -42,5 +42,6 @@ export default {
42
42
  hideSshConfig: false,
43
43
  addTimeStampToTermLog: false,
44
44
  sftpPathFollowSsh: false,
45
- keepaliveInterval: 0
45
+ keepaliveInterval: 0,
46
+ backspaceMode: '^?'
46
47
  }
@@ -10,7 +10,8 @@ import {
10
10
  CloseSquareFilled,
11
11
  SearchOutlined,
12
12
  FullscreenOutlined,
13
- PaperClipOutlined
13
+ PaperClipOutlined,
14
+ CloseOutlined
14
15
  } from '@ant-design/icons'
15
16
  import {
16
17
  Tooltip
@@ -84,6 +85,7 @@ export default class SessionWrapper extends Component {
84
85
  sessionOptions: null,
85
86
  sessionId: generate(),
86
87
  terminals: terminals.slice(0, 1),
88
+ delKeyPressed: false,
87
89
  showInfo: false,
88
90
  infoPanelProps: {}
89
91
  }
@@ -94,6 +96,31 @@ export default class SessionWrapper extends Component {
94
96
  // this.initEvent()
95
97
  }
96
98
 
99
+ componentWillUnmount () {
100
+ clearTimeout(this.backspaceKeyPressedTimer)
101
+ }
102
+
103
+ onDelKeyPressed = () => {
104
+ this.setState({
105
+ delKeyPressed: true
106
+ })
107
+ this.backspaceKeyPressedTimer = setTimeout(() => {
108
+ this.setState({
109
+ delKeyPressed: false
110
+ })
111
+ }, 5000)
112
+ }
113
+
114
+ handleChangeDelMode = (backspaceMode) => {
115
+ this.setState({
116
+ backspaceMode
117
+ })
118
+ }
119
+
120
+ handleDismissDelKeyTip = () => {
121
+ window.store.dismissDelKeyTip()
122
+ }
123
+
97
124
  setCwd = (cwd, tid) => {
98
125
  this.setState(old => {
99
126
  return {
@@ -330,7 +357,8 @@ export default class SessionWrapper extends Component {
330
357
  'handleShowInfo',
331
358
  'onChangePane',
332
359
  'hideInfoPanel',
333
- 'setCwd'
360
+ 'setCwd',
361
+ 'onDelKeyPressed'
334
362
  ]),
335
363
  ...this.computePosition(t.position / 10)
336
364
  }
@@ -420,6 +448,21 @@ export default class SessionWrapper extends Component {
420
448
  )
421
449
  }
422
450
 
451
+ renderDelTip = (isSsh) => {
452
+ if (!isSsh || this.props.hideDelKeyTip || !this.state.delKeyPressed) {
453
+ return null
454
+ }
455
+ return (
456
+ <div className='type-tab'>
457
+ <span className='mg1r'>Try <b>Shift + Backspace</b>?</span>
458
+ <CloseOutlined
459
+ onClick={this.handleDismissDelKeyTip}
460
+ className='pointer'
461
+ />
462
+ </div>
463
+ )
464
+ }
465
+
423
466
  renderControl = () => {
424
467
  const { splitDirection, terminals, sftpPathFollowSsh } = this.state
425
468
  const { props } = this
@@ -497,6 +540,9 @@ export default class SessionWrapper extends Component {
497
540
  )
498
541
  : null
499
542
  }
543
+ {
544
+ this.renderDelTip(pane === paneMap.terminal)
545
+ }
500
546
  {
501
547
  pane === paneMap.terminal
502
548
  ? (
@@ -340,6 +340,7 @@ class Sessions extends Component {
340
340
  currentTabId,
341
341
  tab: toSimpleObj(tab),
342
342
  ...pick(store, [
343
+ 'hideDelKeyTip',
343
344
  'fileOperation',
344
345
  'file',
345
346
  'height',
@@ -70,6 +70,9 @@ export default class SettingTerminal extends Component {
70
70
  })
71
71
  }
72
72
 
73
+ handleChangeDelMode = v => this.onChangeValue(v, 'backspaceMode')
74
+ handleChangeRenderType = v => this.onChangeValue(v, 'renderType')
75
+
73
76
  handleChangeFont = (values) => {
74
77
  this.onChangeValue(
75
78
  values.join(', '),
@@ -401,6 +404,7 @@ export default class SettingTerminal extends Component {
401
404
  }
402
405
  const {
403
406
  rendererType,
407
+ backspaceMode = '^?',
404
408
  keywords = [{ color: 'red' }]
405
409
  } = this.props.config
406
410
  const {
@@ -436,7 +440,7 @@ export default class SettingTerminal extends Component {
436
440
  <div className='pd2b'>
437
441
  <span className='inline-title mg1r'>{e('rendererType')}</span>
438
442
  <Select
439
- onChange={v => this.onChangeValue(v, 'rendererType')}
443
+ onChange={this.handleChangeRenderType}
440
444
  value={rendererType}
441
445
  popupMatchSelectWidth={false}
442
446
  >
@@ -501,6 +505,20 @@ export default class SettingTerminal extends Component {
501
505
  'ctrlOrMetaOpenTerminalLink'
502
506
  ].map(this.renderToggle)
503
507
  }
508
+ <div className='pd1b'>{e('terminalBackSpaceMode')}</div>
509
+ <Select
510
+ onChange={this.handleChangeDelMode}
511
+ value={backspaceMode}
512
+ popupMatchSelectWidth={false}
513
+ >
514
+ {
515
+ ['^?', '^H'].map(id => {
516
+ return (
517
+ <Option key={id} value={id}>{id}</Option>
518
+ )
519
+ })
520
+ }
521
+ </Select>
504
522
  {this.renderReset()}
505
523
  </div>
506
524
  )
@@ -13,33 +13,33 @@ class ShortcutControl extends React.PureComponent {
13
13
  window.addEventListener('mousewheel', this.handleKeyboardEvent.bind(this))
14
14
  }
15
15
 
16
- prevTabShortcut = (e) => {
16
+ prevTabShortcut = throttle((e) => {
17
17
  e.stopPropagation()
18
18
  window.store.clickPrevTab()
19
- }
19
+ }, 500)
20
20
 
21
- nextTabShortcut = (e) => {
21
+ nextTabShortcut = throttle((e) => {
22
22
  e.stopPropagation()
23
23
  window.store.clickNextTab()
24
- }
24
+ }, 500)
25
25
 
26
- newBookmarkShortcut = (e) => {
26
+ newBookmarkShortcut = throttle((e) => {
27
27
  e.stopPropagation()
28
28
  window.store.onNewSsh()
29
- }
29
+ }, 500)
30
30
 
31
- togglefullscreenShortcut = (e) => {
31
+ togglefullscreenShortcut = throttle((e) => {
32
32
  e.stopPropagation()
33
33
  const x = document.querySelector('.term-fullscreen-control') ||
34
34
  document.querySelector('.session-current .term-fullscreen-control1')
35
35
  x && x.click()
36
- }
36
+ }, 500)
37
37
 
38
- splitShortcut = (e) => {
38
+ splitShortcut = throttle((e) => {
39
39
  e.stopPropagation()
40
40
  const x = document.querySelector('.session-current .icon-split')
41
41
  x && x.click()
42
- }
42
+ }, 1000)
43
43
 
44
44
  zoominShortcut = throttle((e) => {
45
45
  e.stopPropagation()
@@ -3,7 +3,6 @@ import shortcutsDefaultsGen from './shortcuts-defaults.js'
3
3
  import {
4
4
  isMacJs
5
5
  } from '../../common/constants'
6
- import { throttle } from 'lodash-es'
7
6
 
8
7
  function buildConfig (config, filter = d => d) {
9
8
  const defs = shortcutsDefaultsGen().filter(filter)
@@ -46,7 +45,7 @@ function buildConfigForSearch (config) {
46
45
  }
47
46
 
48
47
  export function shortcutExtend (Cls) {
49
- Cls.prototype.handleKeyboardEvent = throttle(function (event) {
48
+ Cls.prototype.handleKeyboardEvent = function (event) {
50
49
  const {
51
50
  code,
52
51
  ctrlKey,
@@ -57,23 +56,13 @@ export function shortcutExtend (Cls) {
57
56
  type,
58
57
  key
59
58
  } = event
60
- if (key === 'Backspace' && this.isTerm && type === 'keydown') {
61
- const now = Date.now()
62
- if (!this.lastTimePressDel) {
63
- this.lastTimePressDel = now
64
- }
65
- const timer = now - this.lastTimePressDel
66
- const count = Math.ceil(timer / 800)
67
- let char = String.fromCharCode(
68
- shiftKey ? 127 : 8
69
- )
70
- char = new Array(count).fill(char).join('')
71
- this.socket.send(
72
- char
73
- )
59
+ if (this.isTerm && key === 'Backspace' && this.isTerm && type === 'keydown') {
60
+ this.props.onDelKeyPressed()
61
+ const delKey = this.props.config.backspaceMode === '^?' ? 8 : 127
62
+ const altDelDelKey = delKey === 8 ? 127 : 8
63
+ const char = String.fromCharCode(shiftKey ? delKey : altDelDelKey)
64
+ this.socket.send(char)
74
65
  return false
75
- } else if (key === 'Backspace' && this.isTerm && type === 'keyup') {
76
- delete this.lastTimePressDel
77
66
  }
78
67
  const codeName = event instanceof window.WheelEvent
79
68
  ? (wheelDeltaY > 0 ? 'mouseWheelUp' : 'mouseWheelDown')
@@ -105,7 +94,7 @@ export function shortcutExtend (Cls) {
105
94
  }
106
95
  }
107
96
  }
108
- }, 300)
97
+ }
109
98
  return Cls
110
99
  }
111
100
 
@@ -49,6 +49,7 @@ export default function AppDrag (props) {
49
49
  onMouseDown={onMouseDown}
50
50
  onMouseUp={onMouseUp}
51
51
  onDoubleClick={onDoubleClick}
52
+ onMouseLeave={onMouseUp}
52
53
  >
53
54
  {props.children}
54
55
  </div>
@@ -261,16 +261,6 @@ class Term extends Component {
261
261
  this.openNormalBuffer()
262
262
  }
263
263
 
264
- prevTabShortcut = throttle((e) => {
265
- e.stopPropagation()
266
- window.store.clickPrevTab()
267
- }, 300)
268
-
269
- nextTabShortcut = throttle((e) => {
270
- e.stopPropagation()
271
- window.store.clickNextTab()
272
- }, 300)
273
-
274
264
  handleEvent = (e) => {
275
265
  const {
276
266
  keyword,
@@ -748,11 +738,6 @@ class Term extends Component {
748
738
  })
749
739
  }, 1000)
750
740
 
751
- // onSocketData = (a) => {
752
- // console.log('onSocketData', a)
753
- // runIdle(this.notifyOnData)
754
- // }
755
-
756
741
  parse (rawText) {
757
742
  let result = ''
758
743
  const len = rawText.length
@@ -10,7 +10,8 @@ import {
10
10
  tabActions,
11
11
  modals,
12
12
  leftSidebarWidthKey,
13
- rightSidebarWidthKey
13
+ rightSidebarWidthKey,
14
+ dismissDelKeyTipLsKey
14
15
  } from '../common/constants'
15
16
  import * as ls from '../common/safe-local-storage'
16
17
 
@@ -150,4 +151,8 @@ export default Store => {
150
151
  ls.setItem(rightSidebarWidthKey, v)
151
152
  window.store.rightSidebarWidth = v
152
153
  }
154
+ Store.prototype.dismissDelKeyTip = function (v) {
155
+ ls.setItem(dismissDelKeyTipLsKey, 'y')
156
+ window.store.hideDelKeyTip = true
157
+ }
153
158
  }
@@ -17,7 +17,8 @@ import {
17
17
  checkedKeysLsKey,
18
18
  localAddrBookmarkLsKey,
19
19
  leftSidebarWidthKey,
20
- rightSidebarWidthKey
20
+ rightSidebarWidthKey,
21
+ dismissDelKeyTipLsKey
21
22
  } from '../common/constants'
22
23
  import { buildDefaultThemes, buildNewTheme } from '../common/terminal-theme'
23
24
  import * as ls from '../common/safe-local-storage'
@@ -185,6 +186,7 @@ export default () => {
185
186
  innerWidth: window.innerWidth,
186
187
  height: 500,
187
188
  isMaximized: window.pre.runSync('isMaximized'),
188
- terminalFullScreen: false
189
+ terminalFullScreen: false,
190
+ hideDelKeyTip: ls.getItem(dismissDelKeyTipLsKey) === 'y'
189
191
  }
190
192
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.37.92",
3
+ "version": "1.37.96",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",