@electerm/electerm-react 1.38.43 → 1.38.60

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.
@@ -74,7 +74,6 @@ export const authTypeMap = buildConst([
74
74
  'privateKey'
75
75
  ])
76
76
 
77
- export const maxTransferHistory = 100
78
77
  export const footerHeight = 36
79
78
  export const quickCommandBoxHeight = 180
80
79
  export const isWin = typeof window.et.isWin === 'undefined' ? window.pre.isWin : window.et.isWin
@@ -140,6 +139,7 @@ export const sidebarPinnedKey = 'sidebar-pinned'
140
139
  export const leftSidebarWidthKey = 'left-sidebar-width'
141
140
  export const rightSidebarWidthKey = 'right-sidebar-width'
142
141
  export const sftpDefaultSortSettingKey = 'sftp-default-sort'
142
+ export const qmSortByFrequencyKey = 'qm-sort-by-frequency'
143
143
  // https://github.com/tinkertrain/panda-syntax-vscode/blob/master/themes/workbench.yaml
144
144
  export const defaultTheme = {
145
145
  id: 'default',
@@ -14,6 +14,9 @@ export const initWsCommon = async () => {
14
14
  return
15
15
  }
16
16
  const ws = await initWs('common', id, undefined, undefined, true)
17
+ if (!ws) {
18
+ return
19
+ }
17
20
  window.et.wsOpened = true
18
21
  ws.onclose = () => {
19
22
  window.et.wsOpened = false
@@ -19,6 +19,12 @@ export default class QuickCommandsItem extends PureComponent {
19
19
 
20
20
  render () {
21
21
  const { name, id, nameMatch, labelMatch } = this.props.item
22
+ const {
23
+ draggable,
24
+ handleDragOver,
25
+ handleDragStart,
26
+ handleDrop
27
+ } = this.props
22
28
  const cls = classNames('qm-item mg1r mg1b', {
23
29
  'name-match': nameMatch,
24
30
  'label-match': labelMatch
@@ -28,6 +34,11 @@ export default class QuickCommandsItem extends PureComponent {
28
34
  key={id}
29
35
  className={cls}
30
36
  onClick={this.handleSelect}
37
+ data-id={id}
38
+ draggable={draggable}
39
+ onDragOver={handleDragOver}
40
+ onDragStart={handleDragStart}
41
+ onDrop={handleDrop}
31
42
  >
32
43
  {name}
33
44
  </Button>
@@ -7,7 +7,6 @@ import { isWin, quickCommandLabelsLsKey } from '../../common/constants'
7
7
  import { find, sortBy } from 'lodash-es'
8
8
  import { Button, Input, Select, Space } from 'antd'
9
9
  import * as ls from '../../common/safe-local-storage'
10
- import copy from 'json-deep-copy'
11
10
  import generate from '../../common/uid'
12
11
  import CmdItem from './quick-command-item'
13
12
  import delay from '../../common/wait'
@@ -110,6 +109,35 @@ export default class QuickCommandsFooterBox extends Component {
110
109
  return c.includes(vv) || m.includes(vv)
111
110
  }
112
111
 
112
+ onDragOver = e => {
113
+ e.preventDefault()
114
+ }
115
+
116
+ onDragStart = e => {
117
+ e.dataTransfer.setData('idDragged', e.target.getAttribute('data-id'))
118
+ }
119
+
120
+ // sort quick commands array when drop, so that the dragged item will be placed at the right position, e.target.getAttribute('data-id') would target item id, e.dataTransfer.getData('idDragged') would target dragged item id, then set window.store.quickCommands use window.store.setItems
121
+ onDrop = e => {
122
+ e.preventDefault()
123
+ const { store } = window
124
+ const { quickCommands } = store
125
+ const idDragged = e.dataTransfer.getData('idDragged')
126
+ const idDrop = e.target.getAttribute('data-id')
127
+ const idDraggedIndex = quickCommands.findIndex(
128
+ ({ id }) => id === idDragged
129
+ )
130
+ const targetIndex = quickCommands.findIndex(
131
+ ({ id }) => id === idDrop
132
+ )
133
+ if (idDraggedIndex < targetIndex) {
134
+ quickCommands.splice(targetIndex, 0, quickCommands.splice(idDraggedIndex, 1)[0])
135
+ } else {
136
+ quickCommands.splice(targetIndex + 1, 0, quickCommands.splice(idDraggedIndex, 1)[0])
137
+ }
138
+ store.setItems('quickCommands', quickCommands)
139
+ }
140
+
113
141
  renderNoCmd = () => {
114
142
  return (
115
143
  <div className='pd1'>
@@ -124,11 +152,18 @@ export default class QuickCommandsFooterBox extends Component {
124
152
  }
125
153
 
126
154
  renderItem = (item) => {
155
+ const {
156
+ qmSortByFrequency
157
+ } = this.props.store
127
158
  return (
128
159
  <CmdItem
129
160
  item={item}
130
161
  key={item.id}
131
162
  onSelect={this.handleSelect}
163
+ draggable={!qmSortByFrequency}
164
+ handleDragOver={this.onDragOver}
165
+ handleDragStart={this.onDragStart}
166
+ handleDrop={this.onDrop}
132
167
  />
133
168
  )
134
169
  }
@@ -144,32 +179,33 @@ export default class QuickCommandsFooterBox extends Component {
144
179
  )
145
180
  }
146
181
 
147
- sortArray (array, keyword, labels) {
148
- return sortBy(array, [
149
- // First, sort by the keyword match
182
+ sortArray (array, keyword, labels, qmSortByFrequency) {
183
+ const sorters = [
150
184
  (obj) => !(keyword && obj.name.toLowerCase().includes(keyword)),
151
- // Then, sort by the label match
152
- (obj) => !labels.some((label) => obj.labels.includes(label)),
153
- // Finally, sort by the clickCount
154
- (obj) => -(obj.clickCount || 0)
155
- ])
185
+ (obj) => !labels.some((label) => obj.labels.includes(label))
186
+ ]
187
+ if (qmSortByFrequency) {
188
+ sorters.push((obj) => -(obj.clickCount || 0))
189
+ }
190
+ return sortBy(array, sorters)
156
191
  }
157
192
 
158
193
  render () {
159
194
  const {
160
195
  openQuickCommandBar,
161
- pinnedQuickCommandBar
196
+ pinnedQuickCommandBar,
197
+ qmSortByFrequency
162
198
  } = this.props.store
163
199
  if (!openQuickCommandBar && !pinnedQuickCommandBar) {
164
200
  return null
165
201
  }
166
- const all = copy(this.props.store.currentQuickCommands)
202
+ const all = this.props.store.currentQuickCommands
167
203
  if (!all.length) {
168
204
  return this.renderNoCmd()
169
205
  }
170
206
  const keyword = this.state.keyword.toLowerCase()
171
207
  const { labels } = this.state
172
- const filtered = this.sortArray(all, keyword, labels)
208
+ const filtered = this.sortArray(all, keyword, labels, qmSortByFrequency)
173
209
  .map(d => {
174
210
  return {
175
211
  ...d,
@@ -195,6 +231,7 @@ export default class QuickCommandsFooterBox extends Component {
195
231
  { 'fil-label': !!this.state.labels.length },
196
232
  { 'fil-keyword': !!keyword }
197
233
  )
234
+ const type = qmSortByFrequency ? 'primary' : 'default'
198
235
  return (
199
236
  <div
200
237
  className='qm-wrap-tooltip'
@@ -219,6 +256,13 @@ export default class QuickCommandsFooterBox extends Component {
219
256
  this.renderTag
220
257
  )}
221
258
  </Select>
259
+ <Button
260
+ className='mg1l iblock'
261
+ type={type}
262
+ onClick={this.props.store.handleSortByFrequency}
263
+ >
264
+ {e('sortByFrequency')}
265
+ </Button>
222
266
  </span>
223
267
  <span className='fright'>
224
268
  <Space.Compact>
@@ -33,6 +33,35 @@ export default class QuickCommandsList extends List {
33
33
  return this.props.store.quickCommandTags
34
34
  }
35
35
 
36
+ handleDragOver = e => {
37
+ e.preventDefault()
38
+ }
39
+
40
+ handleDragStart = e => {
41
+ e.dataTransfer.setData('idDragged', e.target.getAttribute('data-id'))
42
+ }
43
+
44
+ // adjust window.store.quickCommands array order when drop, so that the dragged item will be placed at the right position, e.target.getAttribute('data-id') would target item id, e.dataTransfer.getData('idDragged') would target dragged item id
45
+ handleDrop = e => {
46
+ e.preventDefault()
47
+ const { store } = window
48
+ const { quickCommands } = store
49
+ const idDragged = e.dataTransfer.getData('idDragged')
50
+ const idDrop = e.target.getAttribute('data-id')
51
+ const idDraggedIndex = quickCommands.findIndex(
52
+ ({ id }) => id === idDragged
53
+ )
54
+ const targetIndex = quickCommands.findIndex(
55
+ ({ id }) => id === idDrop
56
+ )
57
+ if (idDraggedIndex < targetIndex) {
58
+ quickCommands.splice(targetIndex, 0, quickCommands.splice(idDraggedIndex, 1)[0])
59
+ } else {
60
+ quickCommands.splice(targetIndex + 1, 0, quickCommands.splice(idDraggedIndex, 1)[0])
61
+ }
62
+ store.setItems('quickCommands', quickCommands)
63
+ }
64
+
36
65
  renderItem = (item, i) => {
37
66
  if (!item) {
38
67
  return null
@@ -55,6 +84,11 @@ export default class QuickCommandsList extends List {
55
84
  key={i + id}
56
85
  className={cls}
57
86
  onClick={() => this.onClickItem(item)}
87
+ data-id={id}
88
+ draggable
89
+ onDragOver={this.handleDragOver}
90
+ onDragStart={this.handleDragStart}
91
+ onDrop={this.handleDrop}
58
92
  >
59
93
  <div className='elli pd1y pd2x' title={name}>
60
94
  {
@@ -26,15 +26,54 @@ export default class AddrBookmarkItem extends Component {
26
26
  )
27
27
  }
28
28
 
29
+ handleDragOver = e => {
30
+ e.preventDefault()
31
+ }
32
+
33
+ handleDragStart = e => {
34
+ e.dataTransfer.setData('idDragged', e.target.getAttribute('data-id'))
35
+ }
36
+
37
+ handleDrop = e => {
38
+ e.preventDefault()
39
+ const { store } = window
40
+ const [host, idDragged] = e.dataTransfer.getData('idDragged').split('#')
41
+ const idDrop = e.target.getAttribute('data-id').split('#')[1]
42
+ const addressBookmarks = host
43
+ ? store.addressBookmarks
44
+ : store.addressBookmarksLocal
45
+ const dataName = host
46
+ ? 'addressBookmarks'
47
+ : 'addressBookmarksLocal'
48
+ const idDraggedIndex = addressBookmarks.findIndex(
49
+ ({ id }) => id === idDragged
50
+ )
51
+ const targetIndex = addressBookmarks.findIndex(
52
+ ({ id }) => id === idDrop
53
+ )
54
+ if (idDraggedIndex < targetIndex) {
55
+ addressBookmarks.splice(targetIndex, 0, addressBookmarks.splice(idDraggedIndex, 1)[0])
56
+ } else {
57
+ addressBookmarks.splice(targetIndex + 1, 0, addressBookmarks.splice(idDraggedIndex, 1)[0])
58
+ }
59
+ store.setItems(dataName, addressBookmarks)
60
+ }
61
+
29
62
  render () {
30
63
  const {
31
64
  item
32
65
  } = this.props
66
+ const id = `${item.host}#${item.id}`
33
67
  return (
34
68
  <div
35
69
  key={item.id}
36
70
  className='sftp-history-item addr-bookmark-item'
37
71
  onClick={this.handleClick}
72
+ data-id={id}
73
+ draggable
74
+ onDragOver={this.handleDragOver}
75
+ onDragStart={this.handleDragStart}
76
+ onDrop={this.handleDrop}
38
77
  >
39
78
  {item.addr}
40
79
  <CloseCircleOutlined
@@ -55,7 +55,9 @@ export default class AddrBookmark extends Component {
55
55
  })
56
56
  : null
57
57
  const content = (
58
- <div>
58
+ <div
59
+ className='addr-bookmark-list'
60
+ >
59
61
  {inner}
60
62
  </div>
61
63
  )
@@ -21,7 +21,7 @@ import eq from 'fast-deep-equal'
21
21
  import { createTransferProps } from './transfer-common'
22
22
 
23
23
  export default (props) => {
24
- const { transferList } = props
24
+ const { transferList, sessionId } = props
25
25
  const delta = useDelta(transferList)
26
26
  const currentId = useRef('')
27
27
  const timer = useRef(null)
@@ -105,7 +105,7 @@ export default (props) => {
105
105
  } else if (action === 'skipAll') {
106
106
  transferList.splice(index, 1)
107
107
  }
108
- window.store.setTransfers(transferList)
108
+ window.store.setTransfers(transferList, sessionId)
109
109
  return {
110
110
  transferList
111
111
  }
@@ -126,7 +126,7 @@ export default (props) => {
126
126
  if (index >= 0) {
127
127
  transferList.splice(index, 1)
128
128
  }
129
- window.store.setTransfers(transferList)
129
+ window.store.setTransfers(transferList, sessionId)
130
130
  return {
131
131
  transferList
132
132
  }
@@ -175,7 +175,7 @@ export default (props) => {
175
175
  }
176
176
  Object.assign(transferList[index], up)
177
177
  }
178
- window.store.setTransfers(transferList)
178
+ window.store.setTransfers(transferList, sessionId)
179
179
  return {
180
180
  transferList
181
181
  }
@@ -211,7 +211,7 @@ export default (props) => {
211
211
  if (transferList[index]) {
212
212
  transferList[index].expanded = true
213
213
  }
214
- window.store.setTransfers(transferList)
214
+ window.store.setTransfers(transferList, sessionId)
215
215
  return {
216
216
  transferList
217
217
  }
@@ -43,7 +43,7 @@ export default function transportAction (props) {
43
43
  const transferList = copy(old.transferList)
44
44
  const index = findIndex(transferList, t => t.id === transfer.id)
45
45
  transferList.splice(index, 1, ...insts)
46
- window.store.setTransfers(transferList)
46
+ window.store.setTransfers(transferList, transfer.sessionId)
47
47
  return {
48
48
  transferList
49
49
  }
@@ -111,7 +111,7 @@ export default function transportAction (props) {
111
111
  const transferList = oldTrans.filter(t => {
112
112
  return t.id !== id
113
113
  })
114
- window.store.setTransfers(transferList)
114
+ window.store.setTransfers(transferList, transfer.sessionId)
115
115
  return {
116
116
  transferList
117
117
  }
@@ -11,7 +11,7 @@ import eq from 'fast-deep-equal'
11
11
  import { isUndefined } from 'lodash-es'
12
12
 
13
13
  export default (props) => {
14
- const { transferList, pauseAll } = props
14
+ const { transferList, pauseAll, sessionId } = props
15
15
  const delta = useDelta(transferList)
16
16
  const pauseControl = useDelta(pauseAll)
17
17
  async function control () {
@@ -31,7 +31,7 @@ export default (props) => {
31
31
  return t
32
32
  })
33
33
  if (old.pauseAll) {
34
- window.store.setTransfers(transferList)
34
+ window.store.setTransfers(transferList, sessionId)
35
35
  return {
36
36
  transferList
37
37
  }
@@ -45,7 +45,7 @@ export default (props) => {
45
45
  return typeTo !== typeFrom && inited
46
46
  }).length
47
47
  if (count >= maxTransport) {
48
- window.store.setTransfers(transferList)
48
+ window.store.setTransfers(transferList, sessionId)
49
49
  return {
50
50
  transferList
51
51
  }
@@ -93,7 +93,7 @@ export default (props) => {
93
93
  tr.inited = true
94
94
  }
95
95
  }
96
- window.store.setTransfers(transferList)
96
+ window.store.setTransfers(transferList, sessionId)
97
97
  return {
98
98
  transferList
99
99
  }
@@ -18,7 +18,8 @@ import {
18
18
  localAddrBookmarkLsKey,
19
19
  leftSidebarWidthKey,
20
20
  rightSidebarWidthKey,
21
- dismissDelKeyTipLsKey
21
+ dismissDelKeyTipLsKey,
22
+ qmSortByFrequencyKey
22
23
  } from '../common/constants'
23
24
  import { buildDefaultThemes, buildNewTheme } from '../common/terminal-theme'
24
25
  import * as ls from '../common/safe-local-storage'
@@ -141,6 +142,7 @@ export default () => {
141
142
  quickCommandId: '',
142
143
  openQuickCommandBar: false,
143
144
  pinnedQuickCommandBar: false,
145
+ qmSortByFrequency: ls.getItem(qmSortByFrequencyKey) === 'yes',
144
146
 
145
147
  // sidebar
146
148
  openedSideBar: ls.getItem(openedSidebarKey),
@@ -4,9 +4,11 @@
4
4
 
5
5
  import {
6
6
  settingMap,
7
+ qmSortByFrequencyKey,
7
8
  terminalActions
8
9
  } from '../common/constants'
9
10
  import postMessage from '../common/post-msg'
11
+ import * as ls from '../common/safe-local-storage'
10
12
 
11
13
  export default Store => {
12
14
  Store.prototype.setQuickCommands = function (list) {
@@ -36,4 +38,13 @@ export default Store => {
36
38
  activeSplitId: activeTerminalId
37
39
  })
38
40
  }
41
+
42
+ Store.prototype.setQmSortByFrequency = function (v) {
43
+ window.store.qmSortByFrequency = v
44
+ ls.setItem(qmSortByFrequencyKey, v ? 'yes' : 'no')
45
+ }
46
+
47
+ Store.prototype.handleSortByFrequency = function () {
48
+ window.store.setQmSortByFrequency(!window.store.qmSortByFrequency)
49
+ }
39
50
  }
@@ -162,18 +162,24 @@ export default (Store) => {
162
162
  const pass = store.getSyncPassword(type)
163
163
  const objs = {}
164
164
  for (const n of names) {
165
- let str = JSON.stringify(store.getItems(n))
165
+ let str = store.getItems(n)
166
+ const order = await getData(`${n}:order`)
167
+ if (order && order.length) {
168
+ str.sort((a, b) => {
169
+ const ai = findIndex(order, r => r === a.id)
170
+ const bi = findIndex(order, r => r === b.id)
171
+ return ai - bi
172
+ })
173
+ }
174
+ str = JSON.stringify(str)
166
175
  if (n === settingMap.bookmarks && pass) {
167
176
  str = await window.pre.runGlobalAsync('encryptAsync', str, pass)
168
177
  }
169
178
  objs[`${n}.json`] = {
170
179
  content: str
171
180
  }
172
- const order = await getData(`${n}:order`)
173
- if (order && order.length) {
174
- objs[`${n}.order.json`] = {
175
- content: JSON.stringify(order)
176
- }
181
+ objs[`${n}.order.json`] = {
182
+ content: 'empty'
177
183
  }
178
184
  }
179
185
  const res = await fetchData(type, 'update', [gistId, {
@@ -315,11 +321,19 @@ export default (Store) => {
315
321
  update('lastDataUpdateTime', store.lastDataUpdateTime)
316
322
  }, 1000)
317
323
 
318
- Store.prototype.handleExportAllData = function () {
324
+ Store.prototype.handleExportAllData = async function () {
319
325
  const { store } = window
320
326
  const objs = {}
321
327
  for (const n of names) {
322
328
  objs[n] = store.getItems(n)
329
+ const order = await getData(`${n}:order`)
330
+ if (order && order.length) {
331
+ objs[n].sort((a, b) => {
332
+ const ai = findIndex(order, r => r === a.id)
333
+ const bi = findIndex(order, r => r === b.id)
334
+ return ai - bi
335
+ })
336
+ }
323
337
  }
324
338
  objs.config = pick(store.config, [
325
339
  'theme',
@@ -2,10 +2,6 @@
2
2
  * transfer history related functions
3
3
  */
4
4
 
5
- import {
6
- maxTransferHistory
7
- } from '../common/constants'
8
-
9
5
  export default Store => {
10
6
  Store.prototype.clearTransferHistory = function () {
11
7
  window.store.setItems('transferHistory', [])
@@ -21,7 +17,7 @@ export default Store => {
21
17
  transferHistory.unshift(item)
22
18
  store.setItems(
23
19
  'transferHistory',
24
- transferHistory.slice(0, maxTransferHistory)
20
+ transferHistory
25
21
  )
26
22
  }
27
23
  }
@@ -1,9 +1,40 @@
1
+ import { findIndex } from 'lodash-es'
1
2
  export default Store => {
2
3
  Store.prototype.handleTransferTab = function (tab) {
3
4
  window.store.transferTab = tab
4
5
  }
5
- Store.prototype.setTransfers = function (list) {
6
- return window.store.setItems('fileTransfers', list)
6
+
7
+ // should update any item with same id in oldList from list array, should add any new item from list array to oldList, should remove any item with same id and sessionId in oldList but not in list array
8
+ Store.prototype.setTransfers = function (list, _sessId) {
9
+ const { store } = window
10
+ let oldList = store.getTransfers()
11
+ const sessId = _sessId || list[0].sessionId
12
+ const arr2 = oldList.filter(t => {
13
+ return t.sessionId === sessId
14
+ })
15
+ const idsToRm = arr2.reduce((prev, curr) => {
16
+ if (!list.find(l => l.id === curr.id)) {
17
+ prev.push(curr.id)
18
+ }
19
+ return prev
20
+ }, [])
21
+ if (idsToRm.length) {
22
+ oldList = oldList.filter(t => {
23
+ return !idsToRm.includes(t.id)
24
+ })
25
+ }
26
+ for (const ntm of list) {
27
+ const index = findIndex(oldList, t => {
28
+ return t.id === ntm.id
29
+ })
30
+ if (index >= 0) {
31
+ oldList[index] = ntm
32
+ continue
33
+ } else {
34
+ oldList.unshift(ntm)
35
+ }
36
+ }
37
+ store.setItems('fileTransfers', oldList)
7
38
  }
8
39
  Store.prototype.getTransfers = function () {
9
40
  return window.store.getItems('fileTransfers')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.38.43",
3
+ "version": "1.38.60",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",