@electerm/electerm-react 1.37.66 → 1.37.78

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.
@@ -5,9 +5,7 @@
5
5
 
6
6
  body .ant-drawer .ant-drawer-content-wrapper
7
7
  left 43px
8
- // .setting-wrap-hide
9
- // width 0
10
- // border-left-width 0
8
+
11
9
  .close-setting-wrap
12
10
  position absolute
13
11
  left 20px
@@ -23,6 +23,10 @@ import {
23
23
  import copy from 'json-deep-copy'
24
24
  import FileSection from './file-item'
25
25
  import PagedList from './paged-list'
26
+ import {
27
+ DownOutlined,
28
+ UpOutlined
29
+ } from '@ant-design/icons'
26
30
 
27
31
  const { prefix } = window
28
32
  const e = prefix('sftp')
@@ -206,6 +210,9 @@ export default class FileListTable extends React.Component {
206
210
  onClick: this.onClickName
207
211
  }
208
212
  const text = e(name || '')
213
+ const directionIcon = isSorting
214
+ ? (sortDirection === 'asc' ? <DownOutlined /> : <UpOutlined />)
215
+ : null
209
216
  return (
210
217
  <div
211
218
  className={cls}
@@ -216,7 +223,7 @@ export default class FileListTable extends React.Component {
216
223
  {...props}
217
224
  title={text}
218
225
  >
219
- {text}
226
+ {directionIcon} {text}
220
227
  </div>
221
228
  )
222
229
  }
@@ -1,8 +1,5 @@
1
1
  @require '../../css/includes/theme-default'
2
- // .sftp-wrap
3
- // .ant-spin-container
4
- // .ant-spin-nested-loading
5
- // filter none
2
+
6
3
  .sftp-section
7
4
  position absolute
8
5
  .sftp-title-wrap
@@ -143,10 +140,6 @@
143
140
  border-right 1px solid main
144
141
  right 0 !important
145
142
  width auto !important
146
- &.desc
147
- background linear-gradient(to bottom, main-dark 0%,main-light 100%)
148
- &.asc
149
- background linear-gradient(to bottom, main-light 0%,main-dark 100%)
150
143
  .sftp-header-handle
151
144
  z-index 20
152
145
  cursor ew-resize
@@ -159,18 +152,6 @@
159
152
  &:hover
160
153
  ::-webkit-scrollbar
161
154
  width 12px
162
- // .sftp-table-content
163
- // overflow-x hidden
164
- // ::-webkit-scrollbar
165
- // width 7px
166
- // background alpha(main, .5)
167
-
168
- // ::-webkit-scrollbar-track
169
- // -webkit-box-shadow none
170
-
171
- // ::-webkit-scrollbar-thumb
172
- // background-color primary
173
- // outline none
174
155
  .sftp-item
175
156
  &.sftp-dragover
176
157
  .sftp-file-prop
@@ -202,13 +183,6 @@
202
183
  color text
203
184
 
204
185
  .file-list
205
- // &::-webkit-scrollbar
206
- // width 1em
207
- // background main
208
-
209
- // &::-webkit-scrollbar-track
210
- // -webkit-box-shadow inset 0 0 6px alpha(main, .1)
211
-
212
186
  ::-webkit-scrollbar-thumb
213
187
  background-color primary !important
214
188
 
@@ -39,14 +39,7 @@
39
39
  color primary
40
40
  .transports-count
41
41
  color text
42
- // .sftp-file
43
- // flex-grow 1
44
- // .sftp-file-percent
45
- // width 100px
46
- // .transfer-tag
47
- // width 200px
48
- // .transfer-control-icon
49
- // width 20px
42
+
50
43
  .flex-child + .flex-child
51
44
  margin-left 5px
52
45
  flex-grow 1
@@ -66,6 +66,7 @@ export default function transportAction (props) {
66
66
  ...update,
67
67
  finishTime,
68
68
  startTime: inst.current.startTime,
69
+ size: transfer.fromFile.size,
69
70
  speed: format(transfer.fromFile.size, inst.current.startTime),
70
71
  host: props.tab.host
71
72
  }
@@ -20,7 +20,8 @@ function buildConfig (config, filter = d => d) {
20
20
  [name]: {
21
21
  shortcut: c.readonly ? c[propName] : (shortcuts[name] || c[propName]),
22
22
  type,
23
- func
23
+ func,
24
+ readonly: c.readonly
24
25
  }
25
26
  }
26
27
  }, {})
@@ -54,6 +55,20 @@ export function shortcutExtend (Cls) {
54
55
  altKey,
55
56
  wheelDeltaY
56
57
  } = event
58
+ if (this.isTerm) {
59
+ const keymap = [
60
+ { key: 'Backspace', shiftKey: false, mapCode: 8 },
61
+ { key: 'Backspace', shiftKey: true, mapCode: 127 }
62
+ ]
63
+ if (event.type === 'keydown') {
64
+ for (const i in keymap) {
65
+ if (keymap[i].key === event.key && keymap[i].shiftKey === shiftKey) {
66
+ this.socket.send(String.fromCharCode(keymap[i].mapCode))
67
+ return false
68
+ }
69
+ }
70
+ }
71
+ }
57
72
  const codeName = event instanceof window.WheelEvent
58
73
  ? (wheelDeltaY > 0 ? 'mouseWheelUp' : 'mouseWheelDown')
59
74
  : code
@@ -77,8 +92,10 @@ export function shortcutExtend (Cls) {
77
92
  if (conf.shortcut.split(',').includes(r)) {
78
93
  if (this[funcName]) {
79
94
  return this[funcName](event)
80
- } else if (this.isTerm) {
95
+ } else if (this.isTerm && conf.readonly) {
81
96
  return true
97
+ } else {
98
+ return false
82
99
  }
83
100
  }
84
101
  }
@@ -65,16 +65,11 @@
65
65
  .btns
66
66
  background main-dark
67
67
  border-color primary
68
- // .ant-select-arrow
69
68
  .open-about-icon
70
69
  color text-dark
71
70
  &:hover
72
71
  color text-light
73
- // .ant-btn
74
- // .ant-select-selection
75
- // background transparent
76
- // color #aaa
77
- // border-color #555
72
+
78
73
  .drag-handle
79
74
  position absolute
80
75
  right 0
@@ -81,9 +81,9 @@ export default class TransferHistoryModal extends Component {
81
81
  sorter: sorterFactory('toPath')
82
82
  }, {
83
83
  title: f('size'),
84
- dataIndex: 'fromFile.size',
85
- key: 'fromFile.size',
86
- sorter: sorterFactory('fromFile.size'),
84
+ dataIndex: 'size',
85
+ key: 'size',
86
+ sorter: sorterFactory('size'),
87
87
  render: (v) => filesize(v || 0)
88
88
  }, {
89
89
  title: e('speed'),
@@ -10,7 +10,7 @@ import {
10
10
  CodeFilled,
11
11
  DownOutlined,
12
12
  LeftOutlined,
13
- PlusCircleOutlined,
13
+ PlusOutlined,
14
14
  RightOutlined,
15
15
  RightSquareFilled
16
16
  } from '@ant-design/icons'
@@ -187,7 +187,7 @@ export default class Tabs extends React.Component {
187
187
  <Popover
188
188
  content={this.renderMenus()}
189
189
  >
190
- <PlusCircleOutlined
190
+ <PlusOutlined
191
191
  title={e('openNewTerm')}
192
192
  className={cls}
193
193
  onClick={() => this.props.addTab()}
@@ -136,12 +136,6 @@
136
136
  z-index 20
137
137
  -webkit-app-region no-drag
138
138
 
139
- // .ant-btn
140
- // background #333
141
- // color #aaa
142
- // border-color: #333
143
- // &:hover
144
- // color #ccc
145
139
  .tabs-dd-icon
146
140
  color text
147
141
  font-size 12px
@@ -7,17 +7,13 @@ import postMessage from '../../common/post-msg'
7
7
  import clone from '../../common/to-simple-obj'
8
8
  import runIdle from '../../common/run-idle'
9
9
  import {
10
- CheckCircleOutlined,
11
10
  ReloadOutlined
12
11
  } from '@ant-design/icons'
13
12
  import {
14
13
  notification,
15
14
  Spin,
16
- Modal,
17
- Button,
18
- Checkbox
15
+ Button
19
16
  } from 'antd'
20
- import Input from '../common/input-auto-focus'
21
17
  import classnames from 'classnames'
22
18
  import './terminal.styl'
23
19
  import {
@@ -29,8 +25,7 @@ import {
29
25
  transferTypeMap,
30
26
  terminalActions,
31
27
  commonActions,
32
- rendererTypes,
33
- termInitId
28
+ rendererTypes
34
29
  } from '../../common/constants'
35
30
  import deepCopy from 'json-deep-copy'
36
31
  import { readClipboard, copy } from '../../common/clipboard'
@@ -38,7 +33,6 @@ import { FitAddon } from 'xterm-addon-fit'
38
33
  import AttachAddon from './attach-addon-custom'
39
34
  import { SearchAddon } from 'xterm-addon-search'
40
35
  import { WebLinksAddon } from 'xterm-addon-web-links'
41
- import { SerializeAddon } from 'xterm-addon-serialize'
42
36
  import { CanvasAddon } from 'xterm-addon-canvas'
43
37
  import { WebglAddon } from 'xterm-addon-webgl'
44
38
  import { LigaturesAddon } from 'xterm-addon-ligatures'
@@ -47,20 +41,16 @@ import { Zmodem, AddonZmodem } from './xterm-zmodem'
47
41
  import { Unicode11Addon } from 'xterm-addon-unicode11'
48
42
  import keyControlPressed from '../../common/key-control-pressed'
49
43
  import { Terminal } from 'xterm'
50
- import * as ls from '../../common/safe-local-storage'
51
44
  import NormalBuffer from './normal-buffer'
52
45
  import { createTerm, resizeTerm } from './terminal-apis'
53
- import createLsId from './build-ls-term-id'
54
46
  import { shortcutExtend, shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
55
47
  import { KeywordHighlighterAddon } from './highlight-addon.js'
48
+ import { SerializeAddon } from 'xterm-addon-serialize'
49
+ import strip from '@electerm/strip-ansi'
56
50
 
57
51
  const { prefix } = window
58
52
  const e = prefix('ssh')
59
53
  const m = prefix('menu')
60
- const f = prefix('form')
61
- const c = prefix('common')
62
- const authFailMsg = 'All configured authentication methods failed'
63
- const privateKeyMsg = 'no passphrase'
64
54
 
65
55
  const computePos = (e) => {
66
56
  return {
@@ -76,11 +66,8 @@ class Term extends Component {
76
66
  pid: '',
77
67
  id: props.id || 'id' + generate(),
78
68
  loading: false,
79
- promoteModalVisible: false,
80
- savePassword: false,
81
69
  saveTerminalLogToFile: !!this.props.config.saveTerminalLogToFile,
82
70
  addTimeStampToTermLog: !!this.props.config.addTimeStampToTermLog,
83
- tempPassword: '',
84
71
  passType: 'password',
85
72
  zmodemTransfer: null,
86
73
  lines: []
@@ -740,34 +727,17 @@ class Term extends Component {
740
727
  ]
741
728
  }
742
729
 
743
- loadState = term => {
744
- const uid = this.props.stateId || this.state.id
745
- if (uid === termInitId) {
746
- const id = createLsId(this.props.stateId || this.state.id)
747
- let str = ls.getItem(id)
748
- const after = '\r\n\r\n=======\r\nload from history\r\n=======\r\n\r\n'
749
- str = str.replace(/\s+=======\s+load from history\s+=======\s+/g, '\r\n').trim()
750
- if (str) {
751
- term.write(str + after)
752
- }
753
- }
754
- }
755
-
756
730
  notifyOnData = debounce(() => {
757
- const str = this.serializeAddon.serialize()
758
- const id = createLsId(this.state.id)
759
- ls.setItem(id, str)
760
731
  postMessage({
761
732
  action: 'terminal-receive-data',
762
733
  tabId: this.props.tab.id
763
734
  })
764
- }, 100)
735
+ }, 1000)
765
736
 
766
- onSocketData = () => {
767
- if (this.state.id === termInitId) {
768
- runIdle(this.notifyOnData)
769
- }
770
- }
737
+ // onSocketData = (a) => {
738
+ // console.log('onSocketData', a)
739
+ // runIdle(this.notifyOnData)
740
+ // }
771
741
 
772
742
  parse (rawText) {
773
743
  let result = ''
@@ -782,21 +752,33 @@ class Term extends Component {
782
752
  return result
783
753
  }
784
754
 
785
- onKey = ({ key }) => {
786
- if (key === '\x7F') {
787
- this.dataCache = this.dataCache.slice(0, -1)
788
- } else {
789
- this.dataCache += key
790
- }
755
+ // onKey = ({ key }) => {
756
+ // if (key === '\r') {
757
+ // this.getCmd()
758
+ // }
759
+ // }
760
+
761
+ getCmd = () => {
762
+ const str = this.serializeAddon.serialize()
763
+ const arr = strip(str).split(/ +/)
764
+ const len = arr.length
765
+ const last = arr[len - 1]
766
+ this.dataCache = last
791
767
  }
792
768
 
793
769
  onData = (d) => {
770
+ runIdle(this.notifyOnData)
794
771
  if (!d.includes('\r')) {
795
772
  delete this.userTypeExit
796
773
  } else {
797
- const data = this.parse(this.dataCache.trim())
774
+ this.getCmd()
775
+ const data = this.dataCache
798
776
  this.dataCache = ''
799
- if (data === 'exit') {
777
+ const exitCmds = [
778
+ 'exit',
779
+ 'logout'
780
+ ]
781
+ if (exitCmds.includes(data)) {
800
782
  this.userTypeExit = true
801
783
  this.timers.userTypeExit = setTimeout(() => {
802
784
  delete this.userTypeExit
@@ -841,11 +823,10 @@ class Term extends Component {
841
823
  // term.onLineFeed(this.onLineFeed)
842
824
  // term.onTitleChange(this.onTitleChange)
843
825
  term.onSelectionChange(this.onSelection)
844
- this.loadState(term)
845
826
  term.open(document.getElementById(id), true)
846
827
  this.loadRenderer(term, config)
847
828
  term.textarea.addEventListener('focus', this.setActive)
848
- term.onKey(this.onKey)
829
+ // term.onKey(this.onKey)
849
830
  // term.textarea.addEventListener('blur', this.onBlur)
850
831
 
851
832
  // term.on('keydown', this.handleEvent)
@@ -854,9 +835,9 @@ class Term extends Component {
854
835
  const ligtureAddon = new LigaturesAddon()
855
836
  this.searchAddon.onDidChangeResults(this.onSearchResultsChange)
856
837
  const unicode11Addon = new Unicode11Addon()
838
+ term.loadAddon(unicode11Addon)
857
839
  this.serializeAddon = new SerializeAddon()
858
840
  term.loadAddon(this.serializeAddon)
859
- term.loadAddon(unicode11Addon)
860
841
  term.loadAddon(ligtureAddon)
861
842
  // activate the new version
862
843
  term.unicode.activeVersion = '11'
@@ -1002,15 +983,7 @@ class Term extends Component {
1002
983
  let pid = await createTerm(opts)
1003
984
  .catch(err => {
1004
985
  const text = err.message
1005
- if (text.includes(authFailMsg)) {
1006
- this.setState(() => ({ passType: 'password' }))
1007
- return 'fail'
1008
- } else if (text.includes(privateKeyMsg)) {
1009
- this.setState(() => ({ passType: 'passphrase' }))
1010
- return 'fail-private'
1011
- } else {
1012
- handleErr({ message: text })
1013
- }
986
+ handleErr({ message: text })
1014
987
  })
1015
988
  pid = pid || ''
1016
989
  if (pid.includes('fail')) {
@@ -1051,7 +1024,7 @@ class Term extends Component {
1051
1024
  isWin && !this.isRemote()
1052
1025
  )
1053
1026
  term.loadAddon(this.attachAddon)
1054
- socket.addEventListener('message', this.onSocketData)
1027
+ // socket.addEventListener('message', this.onSocketData)
1055
1028
  this.runInitScript()
1056
1029
  term._initialized = true
1057
1030
  }
@@ -1159,75 +1132,11 @@ class Term extends Component {
1159
1132
  resizeTerm(this.pid, this.props.sessionId, cols, rows)
1160
1133
  }
1161
1134
 
1162
- promote = () => {
1163
- this.setState({
1164
- promoteModalVisible: true,
1165
- tempPassword: ''
1166
- })
1167
- }
1168
-
1169
1135
  handleCancel = () => {
1170
1136
  const { id } = this.props.tab
1171
1137
  this.props.delTab(id)
1172
1138
  }
1173
1139
 
1174
- handleToggleSavePass = () => {
1175
- this.setState({
1176
- savePassword: !this.state.savePassword
1177
- })
1178
- }
1179
-
1180
- renderPasswordForm = () => {
1181
- const { tempPassword, savePassword, promoteModalVisible } = this.state
1182
- const { type } = this.props.tab
1183
- return (
1184
- <div>
1185
- <Input
1186
- value={tempPassword}
1187
- type='password'
1188
- autofocustrigger={promoteModalVisible ? 1 : 2}
1189
- selectall='yes'
1190
- onChange={this.handleChangePass}
1191
- onPressEnter={this.handleClickConfirmPass}
1192
- />
1193
- {
1194
- type !== terminalSshConfigType
1195
- ? (
1196
- <div className='pd1t'>
1197
- <Checkbox
1198
- checked={savePassword}
1199
- onChange={this.handleToggleSavePass}
1200
- >{f('save')}
1201
- </Checkbox>
1202
- </div>
1203
- )
1204
- : null
1205
- }
1206
- </div>
1207
- )
1208
- }
1209
-
1210
- handleChangePass = e => {
1211
- this.setState({
1212
- tempPassword: e.target.value
1213
- })
1214
- }
1215
-
1216
- handleClickConfirmPass = () => {
1217
- const {
1218
- tempPassword,
1219
- passType
1220
- } = this.state
1221
- this.props.setSessionState(old => {
1222
- const sessionOptions = deepCopy(old.sessionOptions) || {}
1223
- sessionOptions[passType] = tempPassword
1224
- return { sessionOptions }
1225
- })
1226
- this.setState({
1227
- promoteModalVisible: false
1228
- }, this.remoteInit)
1229
- }
1230
-
1231
1140
  handleShowInfo = () => {
1232
1141
  const { id, sessionId, logName } = this.props
1233
1142
  const { pid } = this.state
@@ -1256,54 +1165,6 @@ class Term extends Component {
1256
1165
  // return result ? result[0].trim() : ''
1257
1166
  // }
1258
1167
 
1259
- renderPromoteModal = () => {
1260
- if (!this.isActiveTerminal()) {
1261
- return null
1262
- }
1263
- const {
1264
- passType = 'password'
1265
- } = this.state
1266
- const props = {
1267
- title: f(passType) + '?',
1268
- content: this.renderPasswordForm(),
1269
- onCancel: this.handleCancel,
1270
- show: this.state.promoteModalVisible,
1271
- footer: this.renderModalFooter(),
1272
- cancelText: c('cancel')
1273
- }
1274
- return (
1275
- <Modal
1276
- {...props}
1277
- >
1278
- {this.renderPasswordForm()}
1279
- </Modal>
1280
- )
1281
- }
1282
-
1283
- renderModalFooter = () => {
1284
- const disabled = !this.state.tempPassword
1285
- return (
1286
- <div className='alignright pd1'>
1287
- <Button
1288
- type='primary'
1289
- icon={<CheckCircleOutlined />}
1290
- disabled={disabled}
1291
- onClick={this.handleClickConfirmPass}
1292
- className='mg1r'
1293
- >
1294
- {c('ok')}
1295
- </Button>
1296
- <Button
1297
- type='dashed'
1298
- className='mg1r'
1299
- onClick={this.handleCancel}
1300
- >
1301
- {c('cancel')}
1302
- </Button>
1303
- </div>
1304
- )
1305
- }
1306
-
1307
1168
  switchEncoding = encode => {
1308
1169
  this.decode = new TextDecoder(encode)
1309
1170
  this.attachAddon.decoder = this.decode
@@ -1357,7 +1218,6 @@ class Term extends Component {
1357
1218
  <div
1358
1219
  {...prps1}
1359
1220
  >
1360
- {this.renderPromoteModal()}
1361
1221
  <div
1362
1222
  {...prps2}
1363
1223
  >
@@ -56,7 +56,7 @@ class TermSearch extends Component {
56
56
 
57
57
  toggleSearch = () => {
58
58
  this.props.store.toggleTerminalSearch()
59
- setTimeout(window.store.focus, 100)
59
+ setTimeout(window.store.focus, 200)
60
60
  }
61
61
 
62
62
  searchShortcut = (e) => {
@@ -86,7 +86,7 @@ class TermSearch extends Component {
86
86
 
87
87
  handleChange = e => {
88
88
  this.props.store.termSearch = e.target.value
89
- this.next()
89
+ this.prev()
90
90
  }
91
91
 
92
92
  close = () => {
@@ -5,39 +5,16 @@
5
5
  .loading-wrapper
6
6
  padding 30px
7
7
  z-index 100
8
- // .ant-spin
9
- // color #fff
10
- // background #000
11
- // .ant-spin-blur
12
- // opacity 0
13
8
  .term-search-box
14
9
  position absolute
15
10
  right 5px
16
11
  top 5px
17
12
  z-index 30
18
- // .term-sftp-box
19
- // .ant-tabs-bar
20
- // margin-bottom 0
21
- // .ant-tabs-tab
22
- // color #999
23
- // .ant-tabs-tab-active
24
- // color #fff
25
- // .ant-tabs-nav-wrap
26
- // background #333
13
+
27
14
  .terminal-control
28
15
  background main
29
16
  line-height 32px
30
17
  padding 0 10px
31
- // .fileManager
32
- // .terminal-control
33
- // background main-dark
34
- // .type-tab
35
- // color text
36
- // &:hover
37
- // &.active
38
- // color text-dark
39
- // &.active
40
- // border-bottom 1px solid text-dark
41
18
 
42
19
  .terms-box
43
20
  position relative
@@ -56,8 +33,6 @@
56
33
 
57
34
  #container
58
35
  .xterm-viewport
59
- // background-color transparent !important
60
- // background-image url("./images/electerm-watermark.")
61
36
  background-repeat no-repeat
62
37
  background-position 50% 50%
63
38
 
@@ -1,9 +1,5 @@
1
1
 
2
- // .ant-switch-handle::before
3
- // background #232340
4
- // .ant-spin-container
5
- // .ant-spin-nested-loading
6
- // filter none
2
+
7
3
  #container .ant-spin-blur
8
4
  opacity 1 !important
9
5
  .ant-tree-indent-unit
@@ -175,9 +175,11 @@ class Store {
175
175
  return {
176
176
  ...JSON.parse(window.store._termSearchOptions),
177
177
  decorations: {
178
+ activeMatchBorder: theme.yellow,
179
+ activeMatchBackground: theme.selectionBackground,
178
180
  activeMatchColorOverviewRuler: theme.selectionBackground,
179
181
  matchBackground: theme.background,
180
- matchOverviewRuler: theme.selectionBackground,
182
+ matchOverviewRuler: theme.yellow,
181
183
  matchBorder: getReverseColor(theme.background)
182
184
  }
183
185
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.37.66",
3
+ "version": "1.37.78",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",
File without changes