@electerm/electerm-react 2.7.9 → 2.8.7
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/pre.js +38 -11
- package/client/components/ai/ai-config.jsx +1 -1
- package/client/components/bookmark-form/common/run-scripts.jsx +1 -1
- package/client/components/bookmark-form/config/rdp.js +1 -0
- package/client/components/bookmark-form/config/vnc.js +5 -0
- package/client/components/common/remote-float-control.jsx +79 -0
- package/client/components/common/remote-float-control.styl +28 -0
- package/client/components/common/upload.jsx +75 -0
- package/client/components/layout/layout.jsx +2 -1
- package/client/components/main/main.jsx +3 -6
- package/client/components/main/term-fullscreen.styl +1 -10
- package/client/components/quick-commands/quick-commands-list-form.jsx +1 -2
- package/client/components/rdp/rdp-session.jsx +113 -4
- package/client/components/rdp/resolutions.js +6 -0
- package/client/components/session/session.jsx +4 -3
- package/client/components/session/session.styl +18 -5
- package/client/components/session/sessions.jsx +2 -1
- package/client/components/shortcuts/shortcut-control.jsx +5 -3
- package/client/components/shortcuts/shortcut-handler.js +4 -2
- package/client/components/tabs/workspace-save-modal.jsx +1 -1
- package/client/components/terminal/attach-addon-custom.js +13 -0
- package/client/components/terminal/event-emitter.js +27 -0
- package/client/components/terminal/terminal.jsx +10 -297
- package/client/components/terminal/zmodem-client.js +385 -0
- package/client/components/terminal-info/base.jsx +1 -1
- package/client/components/terminal-info/data-cols-parser.jsx +3 -2
- package/client/components/terminal-info/network.jsx +3 -2
- package/client/components/vnc/vnc-session.jsx +397 -52
- package/client/css/basic.styl +3 -0
- package/client/store/event.js +2 -2
- package/client/store/init-state.js +1 -1
- package/package.json +1 -1
- package/client/common/byte-format.js +0 -14
- package/client/components/main/term-fullscreen-control.jsx +0 -21
- package/client/components/terminal/xterm-zmodem.js +0 -55
|
@@ -184,9 +184,11 @@ class ShortcutControl extends React.PureComponent {
|
|
|
184
184
|
|
|
185
185
|
togglefullscreenShortcut = throttle((e) => {
|
|
186
186
|
e.stopPropagation()
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
if (window.store.fullscreen) {
|
|
188
|
+
window.store.toggleSessFullscreen(false)
|
|
189
|
+
} else {
|
|
190
|
+
window.store.toggleSessFullscreen(true)
|
|
191
|
+
}
|
|
190
192
|
}, 500)
|
|
191
193
|
|
|
192
194
|
zoominShortcut = throttle((e) => {
|
|
@@ -176,9 +176,11 @@ export function shortcutExtend (Cls) {
|
|
|
176
176
|
!altKey &&
|
|
177
177
|
!shiftKey &&
|
|
178
178
|
ctrlKey &&
|
|
179
|
-
this.
|
|
179
|
+
this.zmodemClient &&
|
|
180
|
+
this.zmodemClient.isActive
|
|
180
181
|
) {
|
|
181
|
-
this.
|
|
182
|
+
this.zmodemClient.cancel()
|
|
183
|
+
return false
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
let codeName
|
|
@@ -69,7 +69,7 @@ export default auto(function WorkspaceSaveModal ({ store }) {
|
|
|
69
69
|
width={400}
|
|
70
70
|
>
|
|
71
71
|
<div className='pd1y'>
|
|
72
|
-
<Space direction='vertical'
|
|
72
|
+
<Space direction='vertical' className='width-100'>
|
|
73
73
|
<Radio.Group
|
|
74
74
|
value={saveMode}
|
|
75
75
|
onChange={ev => setSaveMode(ev.target.value)}
|
|
@@ -107,6 +107,19 @@ export default class AttachAddonCustom extends AttachAddon {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
onMsg = (ev) => {
|
|
110
|
+
// Check if it's a JSON zmodem control message
|
|
111
|
+
if (typeof ev.data === 'string') {
|
|
112
|
+
try {
|
|
113
|
+
const msg = JSON.parse(ev.data)
|
|
114
|
+
if (msg.action === 'zmodem-event') {
|
|
115
|
+
// Let zmodem-client handle this, don't write to terminal
|
|
116
|
+
return
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {
|
|
119
|
+
// Not JSON, continue processing
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
// When in alternate screen mode (like vim, less, or TUI apps like Claude Code),
|
|
111
124
|
// bypass trzsz processing to avoid interference with the application's display
|
|
112
125
|
if (this.term?.buffer?.active?.type === 'alternate') {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default class EventEmitter {
|
|
2
|
+
constructor () {
|
|
3
|
+
this._events = {}
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
on (event, listener) {
|
|
7
|
+
if (!this._events[event]) {
|
|
8
|
+
this._events[event] = []
|
|
9
|
+
}
|
|
10
|
+
this._events[event].push(listener)
|
|
11
|
+
return this
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
off (event, listener) {
|
|
15
|
+
if (!this._events[event]) return this
|
|
16
|
+
this._events[event] = this._events[event].filter(l => l !== listener)
|
|
17
|
+
return this
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
emit (event, ...args) {
|
|
21
|
+
if (!this._events[event]) return false
|
|
22
|
+
this._events[event].forEach(listener => {
|
|
23
|
+
listener(...args)
|
|
24
|
+
})
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Component, createRef } from 'react'
|
|
2
2
|
import { handleErr } from '../../common/fetch.jsx'
|
|
3
|
-
import generate from '../../common/uid.js'
|
|
4
3
|
import { isEqual, pick, debounce, throttle } from 'lodash-es'
|
|
5
4
|
import clone from '../../common/to-simple-obj.js'
|
|
6
5
|
import resolve from '../../common/resolve.js'
|
|
@@ -22,10 +21,8 @@ import {
|
|
|
22
21
|
paneMap,
|
|
23
22
|
typeMap,
|
|
24
23
|
isWin,
|
|
25
|
-
transferTypeMap,
|
|
26
24
|
rendererTypes,
|
|
27
|
-
isMac
|
|
28
|
-
zmodemTransferPackSize
|
|
25
|
+
isMac
|
|
29
26
|
} from '../../common/constants.js'
|
|
30
27
|
import deepCopy from 'json-deep-copy'
|
|
31
28
|
import { readClipboardAsync, readClipboard, copy } from '../../common/clipboard.js'
|
|
@@ -37,7 +34,7 @@ import { CanvasAddon } from '@xterm/addon-canvas'
|
|
|
37
34
|
import { WebglAddon } from '@xterm/addon-webgl'
|
|
38
35
|
import { LigaturesAddon } from '@xterm/addon-ligatures'
|
|
39
36
|
import getProxy from '../../common/get-proxy.js'
|
|
40
|
-
import {
|
|
37
|
+
import { ZmodemClient } from './zmodem-client.js'
|
|
41
38
|
import { Unicode11Addon } from '@xterm/addon-unicode11'
|
|
42
39
|
import keyControlPressed from '../../common/key-control-pressed.js'
|
|
43
40
|
import { Terminal } from '@xterm/xterm'
|
|
@@ -45,22 +42,20 @@ import NormalBuffer from './normal-buffer.jsx'
|
|
|
45
42
|
import { createTerm, resizeTerm } from './terminal-apis.js'
|
|
46
43
|
import { shortcutExtend, shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
|
|
47
44
|
import { KeywordHighlighterAddon } from './highlight-addon.js'
|
|
48
|
-
import { getLocalFileInfo } from '../sftp/file-read.js'
|
|
49
45
|
import { getFilePath, isUnsafeFilename } from '../../common/file-drop-utils.js'
|
|
50
46
|
import { CommandTrackerAddon } from './command-tracker-addon.js'
|
|
51
47
|
import AIIcon from '../icons/ai-icon.jsx'
|
|
52
|
-
import { formatBytes } from '../../common/byte-format.js'
|
|
53
48
|
import {
|
|
54
49
|
getShellIntegrationCommand,
|
|
55
50
|
detectRemoteShell,
|
|
56
51
|
detectShellType
|
|
57
52
|
} from './shell.js'
|
|
58
|
-
import * as fs from './fs.js'
|
|
59
53
|
import iconsMap from '../sys-menu/icons-map.jsx'
|
|
60
54
|
import { refs, refsStatic } from '../common/ref.js'
|
|
61
55
|
import ExternalLink from '../common/external-link.jsx'
|
|
62
56
|
import createDefaultLogPath from '../../common/default-log-path.js'
|
|
63
57
|
import SearchResultBar from './terminal-search-bar'
|
|
58
|
+
import RemoteFloatControl from '../common/remote-float-control'
|
|
64
59
|
|
|
65
60
|
const e = window.translate
|
|
66
61
|
|
|
@@ -143,9 +138,6 @@ class Term extends Component {
|
|
|
143
138
|
if (window.store.activeTerminalId === this.props.tab.id) {
|
|
144
139
|
window.store.activeTerminalId = ''
|
|
145
140
|
}
|
|
146
|
-
if (this.zsession) {
|
|
147
|
-
this.onZmodemEnd()
|
|
148
|
-
}
|
|
149
141
|
this.term.parent = null
|
|
150
142
|
Object.keys(this.timers).forEach(k => {
|
|
151
143
|
clearTimeout(this.timers[k])
|
|
@@ -162,7 +154,7 @@ class Term extends Component {
|
|
|
162
154
|
}
|
|
163
155
|
this.attachAddon = null
|
|
164
156
|
this.fitAddon = null
|
|
165
|
-
this.
|
|
157
|
+
this.zmodemClient = null
|
|
166
158
|
this.searchAddon = null
|
|
167
159
|
this.fitAddon = null
|
|
168
160
|
this.cmdAddon = null
|
|
@@ -464,287 +456,6 @@ class Term extends Component {
|
|
|
464
456
|
}
|
|
465
457
|
}
|
|
466
458
|
|
|
467
|
-
onzmodemRetract = () => {
|
|
468
|
-
console.debug('zmodemRetract')
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
writeBanner = (type) => {
|
|
472
|
-
const border = '='.repeat(50)
|
|
473
|
-
this.term.write(`\r\n${border}\r\n`)
|
|
474
|
-
this.term.write('\x1b[33m\x1b[1mRecommend use trzsz instead: https://github.com/trzsz/trzsz\x1b[0m\r\n')
|
|
475
|
-
this.term.write(`${border}\r\n\r\n`)
|
|
476
|
-
this.term.write(`\x1b[32m\x1b[1mZMODEM::${type}::START\x1b[0m\r\n`)
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
onReceiveZmodemSession = async () => {
|
|
480
|
-
const savePath = await this.openSaveFolderSelect()
|
|
481
|
-
this.zsession.on('offer', this.onOfferReceive)
|
|
482
|
-
this.zsession.start()
|
|
483
|
-
this.term.write('\r\n\x1b[2A\r\n')
|
|
484
|
-
if (!savePath) {
|
|
485
|
-
return this.onZmodemEnd()
|
|
486
|
-
}
|
|
487
|
-
this.writeBanner('RECEIVE')
|
|
488
|
-
this.zmodemSavePath = savePath
|
|
489
|
-
return new Promise((resolve) => {
|
|
490
|
-
this.zsession.on('session_end', resolve)
|
|
491
|
-
})
|
|
492
|
-
.then(this.onZmodemEnd)
|
|
493
|
-
.catch(this.onZmodemCatch)
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
initZmodemDownload = async (name, size) => {
|
|
497
|
-
if (!this.zmodemSavePath) {
|
|
498
|
-
return
|
|
499
|
-
}
|
|
500
|
-
let pth = window.pre.resolve(
|
|
501
|
-
this.zmodemSavePath, name
|
|
502
|
-
)
|
|
503
|
-
const exist = await fs.exists(pth).catch(() => false)
|
|
504
|
-
if (exist) {
|
|
505
|
-
pth = pth + '.' + generate()
|
|
506
|
-
}
|
|
507
|
-
const fd = await fs.open(pth, 'w').catch(this.onZmodemEnd)
|
|
508
|
-
this.downloadFd = fd
|
|
509
|
-
this.downloadPath = pth
|
|
510
|
-
this.downloadCount = 0
|
|
511
|
-
this.zmodemStartTime = Date.now()
|
|
512
|
-
this.downloadSize = size
|
|
513
|
-
this.updateZmodemProgress(
|
|
514
|
-
0, pth, size, transferTypeMap.download
|
|
515
|
-
)
|
|
516
|
-
return fd
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
onOfferReceive = async (xfer) => {
|
|
520
|
-
const {
|
|
521
|
-
name,
|
|
522
|
-
size
|
|
523
|
-
} = xfer.get_details()
|
|
524
|
-
if (!this.downloadFd) {
|
|
525
|
-
await this.initZmodemDownload(name, size)
|
|
526
|
-
}
|
|
527
|
-
xfer.on('input', this.onZmodemDownload)
|
|
528
|
-
this.xfer = xfer
|
|
529
|
-
await xfer.accept()
|
|
530
|
-
.then(this.finishZmodemTransfer)
|
|
531
|
-
.catch(this.onZmodemEnd)
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
checkCache = async () => {
|
|
535
|
-
if (this.DownloadCache?.length > 0) {
|
|
536
|
-
return fs.write(this.downloadFd, new Uint8Array(this.DownloadCache))
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
onZmodemDownload = async payload => {
|
|
541
|
-
if (this.onCanceling || !this.downloadFd) {
|
|
542
|
-
return
|
|
543
|
-
}
|
|
544
|
-
// if (!this.DownloadCache) {
|
|
545
|
-
// this.DownloadCache = []
|
|
546
|
-
// }
|
|
547
|
-
// this.DownloadCache = this.DownloadCache.concat(payload)
|
|
548
|
-
// this.downloadCount += payload.length
|
|
549
|
-
// if (this.DownloadCache.length < zmodemTransferPackSize) {
|
|
550
|
-
// return this.updateZmodemProgress(
|
|
551
|
-
// this.downloadCount,
|
|
552
|
-
// this.downloadPath,
|
|
553
|
-
// this.downloadSize,
|
|
554
|
-
// transferTypeMap.download
|
|
555
|
-
// )
|
|
556
|
-
// }
|
|
557
|
-
// this.writeCache = this.DownloadCache
|
|
558
|
-
// this.DownloadCache = []
|
|
559
|
-
this.downloadCount += payload.length
|
|
560
|
-
await fs.write(this.downloadFd, new Uint8Array(payload))
|
|
561
|
-
this.updateZmodemProgress(
|
|
562
|
-
this.downloadCount,
|
|
563
|
-
this.downloadPath,
|
|
564
|
-
this.downloadSize,
|
|
565
|
-
transferTypeMap.download
|
|
566
|
-
)
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
updateZmodemProgress = throttle((start, name, size, type) => {
|
|
570
|
-
this.zmodemTransfer = {
|
|
571
|
-
type,
|
|
572
|
-
start,
|
|
573
|
-
name,
|
|
574
|
-
size
|
|
575
|
-
}
|
|
576
|
-
this.writeZmodemProgress()
|
|
577
|
-
}, 500)
|
|
578
|
-
|
|
579
|
-
finishZmodemTransfer = () => {
|
|
580
|
-
this.zmodemTransfer = {
|
|
581
|
-
...this.zmodemTransfer,
|
|
582
|
-
start: this.zmodemTransfer.size
|
|
583
|
-
}
|
|
584
|
-
this.writeZmodemProgress()
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
writeZmodemProgress = () => {
|
|
588
|
-
if (this.onCanceling) {
|
|
589
|
-
return
|
|
590
|
-
}
|
|
591
|
-
const {
|
|
592
|
-
size, start, name
|
|
593
|
-
} = this.zmodemTransfer
|
|
594
|
-
const speed = size > 0 ? formatBytes(start * 1000 / 1024 / (Date.now() - this.zmodemStartTime)) : 0
|
|
595
|
-
const percent = size > 0 ? Math.floor(start * 100 / size) : 100
|
|
596
|
-
const str = `\x1b[32m${name}\x1b[0m::${percent}%,${start}/${size},${speed}/s`
|
|
597
|
-
this.term.write('\r\n\x1b[2A' + str + '\n')
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
zmodemTransferFile = async (file, filesRemaining, sizeRemaining) => {
|
|
601
|
-
const offer = {
|
|
602
|
-
obj: file,
|
|
603
|
-
name: file.name,
|
|
604
|
-
size: file.size,
|
|
605
|
-
files_remaining: filesRemaining,
|
|
606
|
-
bytes_remaining: sizeRemaining
|
|
607
|
-
}
|
|
608
|
-
const xfer = await this.zsession.send_offer(offer)
|
|
609
|
-
if (!xfer) {
|
|
610
|
-
this.onZmodemEnd()
|
|
611
|
-
return window.store.onError(new Error('Transfer cancelled, maybe file already exists'))
|
|
612
|
-
}
|
|
613
|
-
this.zmodemStartTime = Date.now()
|
|
614
|
-
const fd = await fs.open(file.filePath, 'r')
|
|
615
|
-
let start = 0
|
|
616
|
-
const { size } = file
|
|
617
|
-
let inited = false
|
|
618
|
-
while (start < size || !inited) {
|
|
619
|
-
const rest = size - start
|
|
620
|
-
const len = rest > zmodemTransferPackSize ? zmodemTransferPackSize : rest
|
|
621
|
-
const buffer = new Uint8Array(len)
|
|
622
|
-
const newArr = await fs.read(fd, buffer, 0, len, null)
|
|
623
|
-
const n = newArr.length
|
|
624
|
-
await xfer.send(newArr)
|
|
625
|
-
start = start + n
|
|
626
|
-
inited = true
|
|
627
|
-
this.updateZmodemProgress(start, file.name, size, transferTypeMap.upload)
|
|
628
|
-
if (n < zmodemTransferPackSize || start >= file.size || this.onCanceling) {
|
|
629
|
-
break
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
await fs.close(fd)
|
|
633
|
-
this.finishZmodemTransfer()
|
|
634
|
-
await xfer.end()
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
openFileSelect = async () => {
|
|
638
|
-
const properties = [
|
|
639
|
-
'openFile',
|
|
640
|
-
'multiSelections',
|
|
641
|
-
'showHiddenFiles',
|
|
642
|
-
'noResolveAliases',
|
|
643
|
-
'treatPackageAsDirectory',
|
|
644
|
-
'dontAddToRecent'
|
|
645
|
-
]
|
|
646
|
-
const files = await window.api.openDialog({
|
|
647
|
-
title: 'Choose some files to send',
|
|
648
|
-
message: 'Choose some files to send',
|
|
649
|
-
properties
|
|
650
|
-
}).catch(() => false)
|
|
651
|
-
if (!files || !files.length) {
|
|
652
|
-
return this.onZmodemEnd()
|
|
653
|
-
}
|
|
654
|
-
const r = []
|
|
655
|
-
for (const filePath of files) {
|
|
656
|
-
const stat = await getLocalFileInfo(filePath)
|
|
657
|
-
r.push({ ...stat, filePath })
|
|
658
|
-
}
|
|
659
|
-
return r
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
openSaveFolderSelect = async () => {
|
|
663
|
-
const savePaths = await window.api.openDialog({
|
|
664
|
-
title: 'Choose a folder to save file(s)',
|
|
665
|
-
message: 'Choose a folder to save file(s)',
|
|
666
|
-
properties: [
|
|
667
|
-
'openDirectory',
|
|
668
|
-
'showHiddenFiles',
|
|
669
|
-
'createDirectory',
|
|
670
|
-
'noResolveAliases',
|
|
671
|
-
'treatPackageAsDirectory',
|
|
672
|
-
'dontAddToRecent'
|
|
673
|
-
]
|
|
674
|
-
}).catch(() => false)
|
|
675
|
-
if (!savePaths || !savePaths.length) {
|
|
676
|
-
return false
|
|
677
|
-
}
|
|
678
|
-
return savePaths[0]
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
beforeZmodemUpload = async (files) => {
|
|
682
|
-
if (!files || !files.length) {
|
|
683
|
-
return false
|
|
684
|
-
}
|
|
685
|
-
this.writeBanner('SEND')
|
|
686
|
-
let filesRemaining = files.length
|
|
687
|
-
let sizeRemaining = files.reduce((a, b) => a + b.size, 0)
|
|
688
|
-
for (const f of files) {
|
|
689
|
-
await this.zmodemTransferFile(f, filesRemaining, sizeRemaining)
|
|
690
|
-
filesRemaining = filesRemaining - 1
|
|
691
|
-
sizeRemaining = sizeRemaining - f.size
|
|
692
|
-
}
|
|
693
|
-
this.onZmodemEnd()
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
onSendZmodemSession = async () => {
|
|
697
|
-
this.term.write('\r\n\x1b[2A\n')
|
|
698
|
-
const files = await this.openFileSelect()
|
|
699
|
-
this.beforeZmodemUpload(files)
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
onZmodemEnd = async () => {
|
|
703
|
-
this.zmodemSavePath = null
|
|
704
|
-
this.onCanceling = true
|
|
705
|
-
if (this.downloadFd) {
|
|
706
|
-
await fs.close(this.downloadFd)
|
|
707
|
-
}
|
|
708
|
-
if (this.xfer && this.xfer.end) {
|
|
709
|
-
await this.xfer.end().catch(
|
|
710
|
-
console.error
|
|
711
|
-
)
|
|
712
|
-
}
|
|
713
|
-
this.xfer = null
|
|
714
|
-
if (this.zsession && this.zsession.close) {
|
|
715
|
-
await this.zsession.close().catch(
|
|
716
|
-
console.error
|
|
717
|
-
)
|
|
718
|
-
}
|
|
719
|
-
this.zsession = null
|
|
720
|
-
this.term.focus()
|
|
721
|
-
this.term.write('\r\n')
|
|
722
|
-
this.onZmodem = false
|
|
723
|
-
this.downloadFd = null
|
|
724
|
-
// delete this.downloadPath
|
|
725
|
-
// delete this.downloadCount
|
|
726
|
-
// delete this.downloadSize
|
|
727
|
-
this.DownloadCache = null
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
onZmodemCatch = (e) => {
|
|
731
|
-
window.store.onError(e)
|
|
732
|
-
this.onZmodemEnd()
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
onZmodemDetect = detection => {
|
|
736
|
-
this.onCanceling = false
|
|
737
|
-
this.term.blur()
|
|
738
|
-
this.onZmodem = true
|
|
739
|
-
const zsession = detection.confirm()
|
|
740
|
-
this.zsession = zsession
|
|
741
|
-
if (zsession.type === 'receive') {
|
|
742
|
-
this.onReceiveZmodemSession()
|
|
743
|
-
} else {
|
|
744
|
-
this.onSendZmodemSession()
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
|
|
748
459
|
onContextMenuInner = e => {
|
|
749
460
|
e.preventDefault()
|
|
750
461
|
if (this.state.loading) {
|
|
@@ -1423,10 +1134,9 @@ class Term extends Component {
|
|
|
1423
1134
|
}
|
|
1424
1135
|
term.loadAddon(new WebLinksAddon(this.webLinkHandler))
|
|
1425
1136
|
term.focus()
|
|
1426
|
-
this.
|
|
1137
|
+
this.zmodemClient = new ZmodemClient(this)
|
|
1138
|
+
this.zmodemClient.init(socket)
|
|
1427
1139
|
this.fitAddon.fit()
|
|
1428
|
-
term.loadAddon(this.zmodemAddon)
|
|
1429
|
-
term.zmodemAttach(this)
|
|
1430
1140
|
term.displayRaw = displayRaw
|
|
1431
1141
|
term.loadAddon(
|
|
1432
1142
|
new KeywordHighlighterAddon(keywords)
|
|
@@ -1583,7 +1293,7 @@ class Term extends Component {
|
|
|
1583
1293
|
|
|
1584
1294
|
render () {
|
|
1585
1295
|
const { loading } = this.state
|
|
1586
|
-
const { height, width, left, top } = this.props
|
|
1296
|
+
const { height, width, left, top, fullscreen } = this.props
|
|
1587
1297
|
const { id } = this.props.tab
|
|
1588
1298
|
const isActive = this.isActiveTerminal()
|
|
1589
1299
|
const cls = classnames(
|
|
@@ -1648,6 +1358,9 @@ class Term extends Component {
|
|
|
1648
1358
|
close={this.closeNormalBuffer}
|
|
1649
1359
|
/>
|
|
1650
1360
|
<SearchResultBar {...barProps} />
|
|
1361
|
+
<RemoteFloatControl
|
|
1362
|
+
isFullScreen={fullscreen}
|
|
1363
|
+
/>
|
|
1651
1364
|
<Spin className='loading-wrapper' spinning={loading} />
|
|
1652
1365
|
</div>
|
|
1653
1366
|
</Dropdown>
|