@electerm/electerm-react 1.50.66 → 1.51.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.
- package/client/common/constants.js +0 -13
- package/client/common/is-color-dark.js +33 -0
- package/client/components/footer/batch-input.jsx +3 -2
- package/client/components/layout/layout-item.jsx +1 -23
- package/client/components/layout/layout.jsx +55 -19
- package/client/components/layout/layouts.jsx +2 -10
- package/client/components/layout/pixed.js +9 -0
- package/client/components/main/css-overwrite.jsx +2 -2
- package/client/components/quick-commands/quick-commands-select.jsx +1 -1
- package/client/components/session/session.jsx +100 -22
- package/client/components/session/session.styl +9 -5
- package/client/components/session/sessions.jsx +45 -451
- package/client/components/setting-panel/setting-modal.jsx +2 -1
- package/client/components/sftp/sftp-entry.jsx +1 -1
- package/client/components/shortcuts/shortcut-control.jsx +18 -6
- package/client/components/sidebar/info-modal.jsx +8 -1
- package/client/components/sidebar/side-panel.jsx +1 -1
- package/client/components/tabs/index.jsx +70 -9
- package/client/components/tabs/on-tab-drop.js +25 -0
- package/client/components/tabs/tab.jsx +67 -119
- package/client/components/tabs/tabs.styl +12 -1
- package/client/components/terminal/index.jsx +11 -6
- package/client/components/terminal/terminal-interactive.jsx +1 -7
- package/client/components/terminal/terminal.styl +1 -2
- package/client/components/theme/theme-form.jsx +1 -1
- package/client/components/theme/theme-list-item.jsx +148 -0
- package/client/components/theme/theme-list.jsx +18 -72
- package/client/store/common.js +0 -7
- package/client/store/index.js +5 -39
- package/client/store/init-state.js +1 -1
- package/client/store/tab.js +338 -86
- package/client/store/watch.js +1 -6
- package/package.json +1 -1
|
@@ -1,416 +1,74 @@
|
|
|
1
1
|
import { Component } from 'react'
|
|
2
2
|
import Session from './session.jsx'
|
|
3
|
-
|
|
4
|
-
import {
|
|
3
|
+
|
|
4
|
+
import { pick } from 'lodash-es'
|
|
5
5
|
import classNames from 'classnames'
|
|
6
|
-
import generate from '../../common/id-with-stamp'
|
|
7
|
-
import copy from 'json-deep-copy'
|
|
8
|
-
import Tabs from '../tabs/index.jsx'
|
|
9
6
|
import {
|
|
10
|
-
tabActions,
|
|
11
|
-
paneMap,
|
|
12
|
-
statusMap,
|
|
13
|
-
terminalWebType,
|
|
14
7
|
termControlHeight
|
|
15
8
|
} from '../../common/constants.js'
|
|
16
|
-
import
|
|
17
|
-
import LogoElem from '../common/logo-elem.jsx'
|
|
18
|
-
import { Button } from 'antd'
|
|
19
|
-
import toSimpleObj from '../../common/to-simple-obj.js'
|
|
20
|
-
import { shortcutExtend } from '../shortcuts/shortcut-handler.js'
|
|
21
|
-
import deepEqual from 'fast-deep-equal'
|
|
22
|
-
|
|
23
|
-
const e = window.translate
|
|
24
|
-
|
|
25
|
-
class Sessions extends Component {
|
|
26
|
-
constructor (props) {
|
|
27
|
-
super(props)
|
|
28
|
-
this.state = {
|
|
29
|
-
tabs: copy(props.tabs || []),
|
|
30
|
-
currentTabId: props.currentTabId
|
|
31
|
-
}
|
|
32
|
-
this.bindHandleKeyboardEvent = this.handleKeyboardEvent.bind(this)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
componentDidMount () {
|
|
36
|
-
this.watch()
|
|
37
|
-
this.initShortcuts()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
componentDidUpdate (prevProps) {
|
|
41
|
-
if (
|
|
42
|
-
this.props.tabs &&
|
|
43
|
-
!deepEqual(prevProps.tabs, this.props.tabs)
|
|
44
|
-
) {
|
|
45
|
-
this.updateTabs(this.props.tabs)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
componentWillUnmount () {
|
|
50
|
-
window.removeEventListener('message', this.onEvent)
|
|
51
|
-
window.removeEventListener('keydown', this.bindHandleKeyboardEvent)
|
|
52
|
-
this.timer && clearTimeout(this.timer)
|
|
53
|
-
this.timer = null
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
updateTabs = (propTabs) => {
|
|
57
|
-
const update = {
|
|
58
|
-
tabs: copy(propTabs)
|
|
59
|
-
}
|
|
60
|
-
const currentTab = propTabs.find(t => t.id === this.state.currentTabId)
|
|
61
|
-
if (!currentTab) {
|
|
62
|
-
update.currentTabId = propTabs[0]?.id
|
|
63
|
-
}
|
|
64
|
-
this.setState(update)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
initShortcuts () {
|
|
68
|
-
window.addEventListener('keydown', this.bindHandleKeyboardEvent)
|
|
69
|
-
}
|
|
9
|
+
import pixed from '../layout/pixed'
|
|
70
10
|
|
|
71
|
-
|
|
72
|
-
|
|
11
|
+
export default class Sessions extends Component {
|
|
12
|
+
// Function to reload a tab using store.reloadTab
|
|
13
|
+
reloadTab = (tab) => {
|
|
14
|
+
window.store.reloadTab(tab.id)
|
|
73
15
|
}
|
|
74
16
|
|
|
75
|
-
|
|
76
|
-
if (this.notCurrentTab()) {
|
|
77
|
-
return
|
|
78
|
-
}
|
|
79
|
-
e.stopPropagation()
|
|
80
|
-
this.delTab(
|
|
81
|
-
this.state.currentTabId
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
reloadCurrentTabShortcut = (e) => {
|
|
86
|
-
if (this.notCurrentTab()) {
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
e.stopPropagation()
|
|
90
|
-
this.reloadTab(
|
|
91
|
-
this.getCurrentTab()
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
cloneToNextLayoutShortcut = (e) => {
|
|
96
|
-
if (this.notCurrentTab()) {
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
e.stopPropagation()
|
|
100
|
-
window.store.cloneToNextLayout()
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
watch = () => {
|
|
104
|
-
window.addEventListener('message', this.onEvent)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
updateStoreTabs = (tabs) => {
|
|
108
|
-
window.store.updateStoreTabs(tabs, this.props.batch)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
updateStoreCurrentTabId = id => {
|
|
112
|
-
if (id) {
|
|
113
|
-
window.store.storeAssign({
|
|
114
|
-
currentTabId: id,
|
|
115
|
-
[id + this.props.batch]: id
|
|
116
|
-
})
|
|
117
|
-
this.setState({
|
|
118
|
-
currentTabId: id
|
|
119
|
-
})
|
|
120
|
-
} else {
|
|
121
|
-
document.querySelector('.tab.active')?.click()
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
getCurrentTab = () => {
|
|
126
|
-
const {
|
|
127
|
-
currentTabId,
|
|
128
|
-
tabs
|
|
129
|
-
} = this.state
|
|
130
|
-
return tabs.find(t => t.id === currentTabId)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
editTab = (id, update) => {
|
|
134
|
-
this.setState((oldState) => {
|
|
135
|
-
const tabs = copy(oldState.tabs)
|
|
136
|
-
const tab = tabs.find(t => t.id === id)
|
|
137
|
-
if (tab) {
|
|
138
|
-
Object.assign(tab, update)
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
tabs
|
|
142
|
-
}
|
|
143
|
-
}, () => {
|
|
144
|
-
this.updateStoreTabs(this.state.tabs)
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
addTab = (_tab, _index, callback) => {
|
|
149
|
-
this.setState((oldState) => {
|
|
150
|
-
const tabs = copy(oldState.tabs)
|
|
151
|
-
const index = typeof _index === 'undefined'
|
|
152
|
-
? tabs.length
|
|
153
|
-
: _index
|
|
154
|
-
let tab = _tab
|
|
155
|
-
if (!tab) {
|
|
156
|
-
tab = newTerm()
|
|
157
|
-
} else {
|
|
158
|
-
updateCount(tab)
|
|
159
|
-
}
|
|
160
|
-
tab.batch = this.props.batch
|
|
161
|
-
tabs.splice(index, 0, tab)
|
|
162
|
-
return {
|
|
163
|
-
currentTabId: tab.id,
|
|
164
|
-
tabs
|
|
165
|
-
}
|
|
166
|
-
}, () => {
|
|
167
|
-
this.updateStoreTabs(this.state.tabs)
|
|
168
|
-
this.updateStoreCurrentTabId(this.state.currentTabId)
|
|
169
|
-
if (callback) {
|
|
170
|
-
callback()
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// After
|
|
17
|
+
// Function to delete tab using store.delTab
|
|
176
18
|
delTab = (id) => {
|
|
177
|
-
|
|
178
|
-
const tabs = copy(oldState.tabs)
|
|
179
|
-
const { currentTabId } = oldState
|
|
180
|
-
const up = {}
|
|
181
|
-
if (currentTabId === id) {
|
|
182
|
-
let i = findIndex(tabs, t => {
|
|
183
|
-
return t.id === id
|
|
184
|
-
})
|
|
185
|
-
i = i ? i - 1 : i + 1
|
|
186
|
-
const next = tabs[i] || {}
|
|
187
|
-
up.currentTabId = next.id || ''
|
|
188
|
-
}
|
|
189
|
-
up.tabs = tabs.filter(t => {
|
|
190
|
-
return t.id !== id
|
|
191
|
-
})
|
|
192
|
-
return up
|
|
193
|
-
}, () => {
|
|
194
|
-
this.updateStoreTabs(this.state.tabs)
|
|
195
|
-
if (this.state.currentTabId !== id) {
|
|
196
|
-
this.updateStoreCurrentTabId(this.state.currentTabId)
|
|
197
|
-
}
|
|
198
|
-
})
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
initFirstTab = () => {
|
|
202
|
-
const tab = newTerm()
|
|
203
|
-
const { batch } = this.props
|
|
204
|
-
tab.batch = batch
|
|
205
|
-
this.addTab(tab)
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
handleClick = () => {
|
|
209
|
-
window.store.currentTabId = this.state.currentTabId
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
reloadTab = (tabToReload) => {
|
|
213
|
-
const tab = copy(
|
|
214
|
-
tabToReload
|
|
215
|
-
)
|
|
216
|
-
tab.pane = paneMap.terminal
|
|
217
|
-
const { id } = tab
|
|
218
|
-
const { tabs } = this.state
|
|
219
|
-
tab.id = generate()
|
|
220
|
-
tab.status = statusMap.processing
|
|
221
|
-
const index = findIndex(tabs, t => t.id === id)
|
|
222
|
-
this.addTab(tab, index, () => {
|
|
223
|
-
this.delTab(id)
|
|
224
|
-
this.onChangeTabId(tab.id)
|
|
225
|
-
})
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
onDuplicateTab = (tabToDup) => {
|
|
229
|
-
const defaultStatus = statusMap.processing
|
|
230
|
-
let tab = copy(tabToDup)
|
|
231
|
-
updateCount(tab)
|
|
232
|
-
const tabs = copy(this.state.tabs)
|
|
233
|
-
const index = findIndex(
|
|
234
|
-
tabs,
|
|
235
|
-
d => d.id === tab.id
|
|
236
|
-
)
|
|
237
|
-
tab = {
|
|
238
|
-
...tab,
|
|
239
|
-
status: defaultStatus,
|
|
240
|
-
id: generate(),
|
|
241
|
-
isTransporting: undefined
|
|
242
|
-
}
|
|
243
|
-
tab.pane = paneMap.terminal
|
|
244
|
-
this.addTab(tab, index + 1)
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
onChangeTabId = id => {
|
|
248
|
-
const matchedTab = this.state.tabs.find(t => t.id === id)
|
|
249
|
-
if (!matchedTab) {
|
|
250
|
-
return
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Batch the updates
|
|
254
|
-
this.setState({
|
|
255
|
-
currentTabId: id
|
|
256
|
-
}, () => {
|
|
257
|
-
this.updateStoreCurrentTabId(id)
|
|
258
|
-
this.timer = setTimeout(window.store.triggerResize, 500)
|
|
259
|
-
this.postChange()
|
|
260
|
-
})
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
setTabs = tabs => {
|
|
264
|
-
this.setState({
|
|
265
|
-
tabs
|
|
266
|
-
})
|
|
267
|
-
this.updateStoreTabs(tabs)
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
setOffline = () => {
|
|
271
|
-
this.setState(oldState => {
|
|
272
|
-
const tabs = copy(oldState.tabs)
|
|
273
|
-
.map(t => {
|
|
274
|
-
return {
|
|
275
|
-
...t,
|
|
276
|
-
status: t.host ? statusMap.error : t.status
|
|
277
|
-
}
|
|
278
|
-
})
|
|
279
|
-
this.updateStoreTabs(tabs)
|
|
280
|
-
return {
|
|
281
|
-
tabs
|
|
282
|
-
}
|
|
283
|
-
})
|
|
19
|
+
window.store.delTab(id)
|
|
284
20
|
}
|
|
285
21
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
...d,
|
|
291
|
-
isTransporting: tabIds.includes(d.id)
|
|
292
|
-
}
|
|
293
|
-
})
|
|
294
|
-
this.updateStoreTabs(tabs)
|
|
295
|
-
return {
|
|
296
|
-
tabs
|
|
297
|
-
}
|
|
298
|
-
})
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
onEvent = e => {
|
|
302
|
-
const {
|
|
303
|
-
currentTabId,
|
|
304
|
-
action,
|
|
305
|
-
id,
|
|
306
|
-
update,
|
|
307
|
-
tab,
|
|
308
|
-
index,
|
|
309
|
-
batch,
|
|
310
|
-
tabIds
|
|
311
|
-
} = e.data || {}
|
|
312
|
-
if (
|
|
313
|
-
action === tabActions.changeCurrentTabId &&
|
|
314
|
-
currentTabId &&
|
|
315
|
-
currentTabId !== this.state.currentTabId
|
|
316
|
-
) {
|
|
317
|
-
this.onChangeTabId(currentTabId)
|
|
318
|
-
} else if (action === tabActions.updateTabs) {
|
|
319
|
-
this.editTab(id, update)
|
|
320
|
-
} else if (action === tabActions.addTab && (batch ?? tab.batch) === this.props.batch) {
|
|
321
|
-
this.addTab(tab, index)
|
|
322
|
-
} else if (action === tabActions.initFirstTab) {
|
|
323
|
-
this.initFirstTab()
|
|
324
|
-
} else if (action === tabActions.delTab) {
|
|
325
|
-
this.delTab(id)
|
|
326
|
-
} else if (action === tabActions.setAllTabOffline) {
|
|
327
|
-
this.setOffline()
|
|
328
|
-
} else if (action === tabActions.updateTabsStatus) {
|
|
329
|
-
this.updateTabsStatus(tabIds)
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
postChange = () => {
|
|
334
|
-
window.store.currentLayoutBatch = this.props.batch
|
|
335
|
-
window.store.triggerResize()
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
handleNewTab = () => {
|
|
339
|
-
this.initFirstTab()
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
handleNewSsh = () => {
|
|
343
|
-
window.store.onNewSsh()
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
renderNoSession = () => {
|
|
347
|
-
const props = {
|
|
348
|
-
style: {
|
|
349
|
-
height: this.props.height + 'px'
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return (
|
|
353
|
-
<div className='no-sessions electerm-logo-bg' {...props}>
|
|
354
|
-
<Button
|
|
355
|
-
onClick={this.handleNewTab}
|
|
356
|
-
size='large'
|
|
357
|
-
className='mg1r mg1b add-new-tab-btn'
|
|
358
|
-
>
|
|
359
|
-
{e('newTab')}
|
|
360
|
-
</Button>
|
|
361
|
-
<Button
|
|
362
|
-
onClick={this.handleNewSsh}
|
|
363
|
-
size='large'
|
|
364
|
-
className='mg1r mg1b'
|
|
365
|
-
>
|
|
366
|
-
{e('newBookmark')}
|
|
367
|
-
</Button>
|
|
368
|
-
<div className='pd3'>
|
|
369
|
-
<LogoElem />
|
|
370
|
-
</div>
|
|
371
|
-
</div>
|
|
372
|
-
)
|
|
22
|
+
// Function to edit tab properties using store.editItem
|
|
23
|
+
editTab = (id, update) => {
|
|
24
|
+
window.store.updateTab(id, update)
|
|
373
25
|
}
|
|
374
26
|
|
|
375
|
-
computeHeight = () => {
|
|
27
|
+
computeHeight = (height) => {
|
|
376
28
|
const {
|
|
377
29
|
tabsHeight
|
|
378
30
|
} = this.props
|
|
379
|
-
return
|
|
31
|
+
return height -
|
|
380
32
|
tabsHeight -
|
|
381
33
|
termControlHeight
|
|
382
34
|
}
|
|
383
35
|
|
|
36
|
+
computeSessionStyle = (batch) => {
|
|
37
|
+
const style = this.props.styles[batch]
|
|
38
|
+
return pixed(style)
|
|
39
|
+
}
|
|
40
|
+
|
|
384
41
|
renderSessions () {
|
|
385
42
|
const {
|
|
386
|
-
config,
|
|
387
|
-
|
|
388
|
-
const {
|
|
43
|
+
config,
|
|
44
|
+
tabs,
|
|
389
45
|
currentTabId,
|
|
390
|
-
|
|
391
|
-
} = this.
|
|
392
|
-
if (!tabs || !tabs.length) {
|
|
393
|
-
return this.renderNoSession()
|
|
394
|
-
}
|
|
46
|
+
sizes
|
|
47
|
+
} = this.props
|
|
395
48
|
return tabs.map((tab) => {
|
|
396
|
-
const { id,
|
|
49
|
+
const { id, batch } = tab
|
|
50
|
+
const { height, width } = sizes[batch]
|
|
51
|
+
const currentBatchTabId = this.props['currentTabId' + batch]
|
|
397
52
|
const cls = classNames(
|
|
398
53
|
`session-wrap session-${id}`,
|
|
399
54
|
{
|
|
400
|
-
'session-current': id === currentTabId
|
|
55
|
+
'session-current': id === currentTabId,
|
|
56
|
+
'session-batch-active': id === currentBatchTabId
|
|
401
57
|
}
|
|
402
58
|
)
|
|
59
|
+
const sessionWrapProps = {
|
|
60
|
+
style: this.computeSessionStyle(batch),
|
|
61
|
+
className: cls
|
|
62
|
+
}
|
|
403
63
|
const sessProps = {
|
|
404
64
|
currentTabId,
|
|
405
|
-
tab
|
|
65
|
+
tab,
|
|
406
66
|
width,
|
|
407
67
|
height,
|
|
408
68
|
...pick(this.props, [
|
|
409
|
-
'batch',
|
|
410
69
|
'resolutions',
|
|
411
70
|
'hideDelKeyTip',
|
|
412
71
|
'fileOperation',
|
|
413
|
-
'file',
|
|
414
72
|
'pinnedQuickCommandBar',
|
|
415
73
|
'tabsHeight',
|
|
416
74
|
'appPath',
|
|
@@ -420,34 +78,15 @@ class Sessions extends Component {
|
|
|
420
78
|
]),
|
|
421
79
|
config,
|
|
422
80
|
...pick(this, [
|
|
423
|
-
'onChangeTabId',
|
|
424
|
-
'onDuplicateTab',
|
|
425
81
|
'reloadTab',
|
|
426
82
|
'computeHeight',
|
|
427
83
|
'delTab',
|
|
428
|
-
'addTab',
|
|
429
84
|
'editTab'
|
|
430
|
-
])
|
|
431
|
-
|
|
432
|
-
if (type === terminalWebType) {
|
|
433
|
-
const webProps = {
|
|
434
|
-
tab,
|
|
435
|
-
width,
|
|
436
|
-
height: this.computeHeight(),
|
|
437
|
-
...pick(this, [
|
|
438
|
-
'reloadTab'
|
|
439
|
-
])
|
|
440
|
-
}
|
|
441
|
-
return (
|
|
442
|
-
<div className={cls} key={id}>
|
|
443
|
-
<WebSession
|
|
444
|
-
{...webProps}
|
|
445
|
-
/>
|
|
446
|
-
</div>
|
|
447
|
-
)
|
|
85
|
+
]),
|
|
86
|
+
currentBatchTabId
|
|
448
87
|
}
|
|
449
88
|
return (
|
|
450
|
-
<div
|
|
89
|
+
<div {...sessionWrapProps} key={id}>
|
|
451
90
|
<Session
|
|
452
91
|
{...sessProps}
|
|
453
92
|
/>
|
|
@@ -456,66 +95,21 @@ class Sessions extends Component {
|
|
|
456
95
|
})
|
|
457
96
|
}
|
|
458
97
|
|
|
459
|
-
|
|
460
|
-
const {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
} = this.props
|
|
468
|
-
const {
|
|
469
|
-
tabs,
|
|
470
|
-
currentTabId
|
|
471
|
-
} = this.state
|
|
472
|
-
const tabsProps = {
|
|
473
|
-
batch,
|
|
474
|
-
currentTabId,
|
|
475
|
-
config,
|
|
476
|
-
width,
|
|
477
|
-
height,
|
|
478
|
-
layout,
|
|
479
|
-
isMaximized,
|
|
480
|
-
tabs,
|
|
481
|
-
...pick(this, [
|
|
482
|
-
'setTabs',
|
|
483
|
-
'onChangeTabId',
|
|
484
|
-
'onDuplicateTab',
|
|
485
|
-
'reloadTab',
|
|
486
|
-
'delTab',
|
|
487
|
-
'addTab',
|
|
488
|
-
'editTab'
|
|
489
|
-
])
|
|
98
|
+
render () {
|
|
99
|
+
const { layoutStyle, tabs } = this.props
|
|
100
|
+
if (!tabs || !tabs.length) {
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
const sessProps = {
|
|
104
|
+
style: layoutStyle,
|
|
105
|
+
className: 'sessions'
|
|
490
106
|
}
|
|
491
|
-
return (
|
|
492
|
-
<Tabs
|
|
493
|
-
key={'main-tabs' + batch}
|
|
494
|
-
{...tabsProps}
|
|
495
|
-
/>
|
|
496
|
-
)
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
renderSessionsWrap = () => {
|
|
500
107
|
return (
|
|
501
108
|
<div
|
|
502
|
-
|
|
503
|
-
key='main-sess'
|
|
504
|
-
onClick={this.handleClick}
|
|
109
|
+
{...sessProps}
|
|
505
110
|
>
|
|
506
111
|
{this.renderSessions()}
|
|
507
112
|
</div>
|
|
508
113
|
)
|
|
509
114
|
}
|
|
510
|
-
|
|
511
|
-
render () {
|
|
512
|
-
return (
|
|
513
|
-
<div>
|
|
514
|
-
{this.renderTabs()}
|
|
515
|
-
{this.renderSessionsWrap()}
|
|
516
|
-
</div>
|
|
517
|
-
)
|
|
518
|
-
}
|
|
519
115
|
}
|
|
520
|
-
|
|
521
|
-
export default shortcutExtend(Sessions)
|
|
@@ -105,7 +105,8 @@ export default auto(function SettingModalWrap (props) {
|
|
|
105
105
|
items,
|
|
106
106
|
onChange: store.handleChangeSettingTab,
|
|
107
107
|
destroyInactiveTabPane: true,
|
|
108
|
-
className: 'setting-tabs'
|
|
108
|
+
className: 'setting-tabs',
|
|
109
|
+
type: 'card'
|
|
109
110
|
}
|
|
110
111
|
return (
|
|
111
112
|
<div>
|
|
@@ -212,7 +212,7 @@ export default class Sftp extends Component {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
isActive () {
|
|
215
|
-
return this.props.enableSftp && this.props.
|
|
215
|
+
return this.props.enableSftp && this.props.currentBatchTabId === this.props.tab.id &&
|
|
216
216
|
this.props.pane === paneMap.fileManager
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -13,6 +13,24 @@ class ShortcutControl extends React.PureComponent {
|
|
|
13
13
|
window.addEventListener('mousewheel', this.handleKeyboardEvent.bind(this))
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
closeCurrentTabShortcut = throttle((e) => {
|
|
17
|
+
e.stopPropagation()
|
|
18
|
+
const { currentTabId } = window.store
|
|
19
|
+
if (currentTabId) {
|
|
20
|
+
window.store.delTab(currentTabId)
|
|
21
|
+
}
|
|
22
|
+
}, 500)
|
|
23
|
+
|
|
24
|
+
reloadCurrentTabShortcut = throttle((e) => {
|
|
25
|
+
e.stopPropagation()
|
|
26
|
+
window.store.reloadTab()
|
|
27
|
+
}, 500)
|
|
28
|
+
|
|
29
|
+
cloneToNextLayoutShortcut = throttle((e) => {
|
|
30
|
+
e.stopPropagation()
|
|
31
|
+
window.store.cloneToNextLayout()
|
|
32
|
+
}, 500)
|
|
33
|
+
|
|
16
34
|
prevTabShortcut = throttle((e) => {
|
|
17
35
|
e.stopPropagation()
|
|
18
36
|
window.store.clickPrevTab()
|
|
@@ -35,12 +53,6 @@ class ShortcutControl extends React.PureComponent {
|
|
|
35
53
|
x && x.click()
|
|
36
54
|
}, 500)
|
|
37
55
|
|
|
38
|
-
splitShortcut = throttle((e) => {
|
|
39
|
-
e.stopPropagation()
|
|
40
|
-
const x = document.querySelector('.session-current .icon-split')
|
|
41
|
-
x && x.click()
|
|
42
|
-
}, 1000)
|
|
43
|
-
|
|
44
56
|
zoominShortcut = throttle((e) => {
|
|
45
57
|
e.stopPropagation()
|
|
46
58
|
window.store.zoom(0.25, true)
|
|
@@ -9,7 +9,8 @@ import {
|
|
|
9
9
|
InfoCircleOutlined,
|
|
10
10
|
AlignLeftOutlined,
|
|
11
11
|
BugOutlined,
|
|
12
|
-
HeartOutlined
|
|
12
|
+
HeartOutlined,
|
|
13
|
+
JavaScriptOutlined
|
|
13
14
|
} from '@ant-design/icons'
|
|
14
15
|
import { Modal, Tabs, Button } from 'antd'
|
|
15
16
|
import Link from '../common/external-link'
|
|
@@ -174,6 +175,12 @@ export default memo(function InfoModal (props) {
|
|
|
174
175
|
{sponsorLink}
|
|
175
176
|
</Link>
|
|
176
177
|
</p>
|
|
178
|
+
<p className='mg1b'>
|
|
179
|
+
<JavaScriptOutlined /> <b className='mg1r'>Powered by</b>
|
|
180
|
+
<Link to='https://github.com/tylerlong/manate'>
|
|
181
|
+
manate
|
|
182
|
+
</Link>
|
|
183
|
+
</p>
|
|
177
184
|
{renderCheckUpdate()}
|
|
178
185
|
</div>
|
|
179
186
|
)
|