@electerm/electerm-react 3.3.8 → 3.6.6
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 -5
- package/client/common/fs.js +84 -0
- package/client/common/ws.js +16 -5
- package/client/components/ai/ai-history.jsx +0 -6
- package/client/components/batch-op/batch-op-alert.jsx +6 -25
- package/client/components/batch-op/batch-op-editor.jsx +9 -5
- package/client/components/bookmark-form/common/fields.jsx +15 -0
- package/client/components/bookmark-form/config/rdp.js +5 -0
- package/client/components/main/upgrade.jsx +133 -104
- package/client/components/main/upgrade.styl +2 -2
- package/client/components/rdp/file-transfer.js +375 -0
- package/client/components/rdp/rdp-session.jsx +169 -76
- package/client/components/rdp/rdp.styl +27 -0
- package/client/components/sftp/address-bar.jsx +16 -2
- package/client/components/shortcuts/shortcut-control.jsx +9 -0
- package/client/components/shortcuts/shortcuts-defaults.js +5 -0
- package/client/components/sidebar/info-modal.jsx +7 -2
- package/client/components/ssh-config/load-ssh-configs.jsx +1 -1
- package/client/components/sys-menu/menu-btn.jsx +2 -1
- package/client/store/app-upgrade.js +2 -2
- package/package.json +1 -1
|
@@ -229,11 +229,6 @@ export const rendererTypes = {
|
|
|
229
229
|
canvas: 'canvas',
|
|
230
230
|
webGL: 'webGL'
|
|
231
231
|
}
|
|
232
|
-
export const mirrors = {
|
|
233
|
-
'download-electerm': 'download-electerm',
|
|
234
|
-
github: 'github',
|
|
235
|
-
sourceforge: 'sourceforge'
|
|
236
|
-
}
|
|
237
232
|
export const downloadUpgradeTimeout = 20000
|
|
238
233
|
export const expandedKeysLsKey = 'expanded-keys'
|
|
239
234
|
export const resolutionsLsKey = 'custom-resolution-key'
|
package/client/common/fs.js
CHANGED
|
@@ -16,6 +16,90 @@ const fs = fsFunctions.reduce((prev, func) => {
|
|
|
16
16
|
return prev
|
|
17
17
|
}, {})
|
|
18
18
|
|
|
19
|
+
// Encoding function
|
|
20
|
+
fs.encodeUint8Array = (uint8Array) => {
|
|
21
|
+
let str = ''
|
|
22
|
+
const len = uint8Array.byteLength
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < len; i++) {
|
|
25
|
+
str += String.fromCharCode(uint8Array[i])
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return btoa(str)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Decoding function
|
|
32
|
+
fs.decodeBase64String = (base64String) => {
|
|
33
|
+
const str = atob(base64String)
|
|
34
|
+
const len = str.length
|
|
35
|
+
|
|
36
|
+
const uint8Array = new Uint8Array(len)
|
|
37
|
+
|
|
38
|
+
for (let i = 0; i < len; i++) {
|
|
39
|
+
uint8Array[i] = str.charCodeAt(i)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return uint8Array
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Object.assign(fs, {
|
|
46
|
+
stat: (path, cb) => {
|
|
47
|
+
window.fs.statCustom(path)
|
|
48
|
+
.catch(err => cb(err))
|
|
49
|
+
.then(obj => {
|
|
50
|
+
obj.isDirectory = () => obj.isD
|
|
51
|
+
obj.isFile = () => obj.isF
|
|
52
|
+
cb(undefined, obj)
|
|
53
|
+
})
|
|
54
|
+
},
|
|
55
|
+
access: (...args) => {
|
|
56
|
+
const cb = args.pop()
|
|
57
|
+
window.fs.access(...args)
|
|
58
|
+
.then((data) => cb(undefined, data))
|
|
59
|
+
.catch((err) => cb(err))
|
|
60
|
+
},
|
|
61
|
+
open: (...args) => {
|
|
62
|
+
const cb = args.pop()
|
|
63
|
+
window.fs.openCustom(...args)
|
|
64
|
+
.then((data) => cb(undefined, data))
|
|
65
|
+
.catch((err) => cb(err))
|
|
66
|
+
},
|
|
67
|
+
read: (p1, arr, ...args) => {
|
|
68
|
+
const cb = args.pop()
|
|
69
|
+
window.fs.readCustom(
|
|
70
|
+
p1,
|
|
71
|
+
arr.length,
|
|
72
|
+
...args
|
|
73
|
+
)
|
|
74
|
+
.then((data) => {
|
|
75
|
+
const { n, newArr } = data
|
|
76
|
+
const newArr1 = window.fs.decodeBase64String(newArr)
|
|
77
|
+
cb(undefined, n, newArr1)
|
|
78
|
+
})
|
|
79
|
+
.catch(err => cb(err))
|
|
80
|
+
},
|
|
81
|
+
close: (fd, cb) => {
|
|
82
|
+
window.fs.closeCustom(fd)
|
|
83
|
+
.then((data) => cb(undefined, data))
|
|
84
|
+
.catch((err) => cb(err))
|
|
85
|
+
},
|
|
86
|
+
readdir: (p, cb) => {
|
|
87
|
+
window.fs.readdir(p)
|
|
88
|
+
.then((data) => cb(undefined, data))
|
|
89
|
+
.catch((err) => cb(err))
|
|
90
|
+
},
|
|
91
|
+
write: (p1, buf, cb) => {
|
|
92
|
+
window.fs.writeCustom(p1, window.fs.encodeUint8Array(buf))
|
|
93
|
+
.then((data) => cb(undefined, data))
|
|
94
|
+
.catch((err) => cb(err))
|
|
95
|
+
},
|
|
96
|
+
realpath: (p, cb) => {
|
|
97
|
+
window.fs.realpath(p)
|
|
98
|
+
.then((data) => cb(undefined, data))
|
|
99
|
+
.catch((err) => cb(err))
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
19
103
|
window.fs = fs
|
|
20
104
|
|
|
21
105
|
export default fs
|
package/client/common/ws.js
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import generate from './uid'
|
|
6
6
|
import wait from './wait'
|
|
7
|
-
import copy from 'json-deep-copy'
|
|
8
7
|
import { pick } from 'lodash-es'
|
|
9
8
|
|
|
10
9
|
const onces = {}
|
|
@@ -32,7 +31,13 @@ class Ws {
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
async once (func, id) {
|
|
34
|
+
const maxWait = 300
|
|
35
|
+
let waited = 0
|
|
35
36
|
while (this.closed) {
|
|
37
|
+
if (++waited >= maxWait) {
|
|
38
|
+
console.warn('ws once timeout waiting for reconnection', id)
|
|
39
|
+
return
|
|
40
|
+
}
|
|
36
41
|
await wait(100)
|
|
37
42
|
}
|
|
38
43
|
this.onceIds.push(id)
|
|
@@ -83,7 +88,7 @@ class Ws {
|
|
|
83
88
|
if (this.eid) {
|
|
84
89
|
delete persists[this.eid]
|
|
85
90
|
}
|
|
86
|
-
const ids =
|
|
91
|
+
const ids = [...this.onceIds]
|
|
87
92
|
ids.forEach(k => {
|
|
88
93
|
delete onces[k]
|
|
89
94
|
})
|
|
@@ -115,10 +120,16 @@ function onEvent (e) {
|
|
|
115
120
|
action,
|
|
116
121
|
persist
|
|
117
122
|
} = e.data
|
|
118
|
-
if (wss[id]) {
|
|
119
|
-
|
|
120
|
-
|
|
123
|
+
if (wss[id] && action === 'close') {
|
|
124
|
+
const ws = wss[id]
|
|
125
|
+
ws.onclose()
|
|
126
|
+
if (ws.persist) {
|
|
127
|
+
ws.closed = true
|
|
128
|
+
} else {
|
|
129
|
+
ws.clearOnces()
|
|
130
|
+
delete wss[id]
|
|
121
131
|
}
|
|
132
|
+
return
|
|
122
133
|
}
|
|
123
134
|
if (persists[id]) {
|
|
124
135
|
persists[id].resolve(data)
|
|
@@ -3,12 +3,10 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { useState, useEffect } from 'react'
|
|
5
5
|
import { Space } from 'antd'
|
|
6
|
-
import { HistoryOutlined } from '@ant-design/icons'
|
|
7
6
|
import { safeGetItemJSON, safeSetItemJSON } from '../../common/safe-local-storage'
|
|
8
7
|
import AiHistoryItem from './ai-history-item'
|
|
9
8
|
|
|
10
9
|
const MAX_HISTORY = 20
|
|
11
|
-
const e = window.translate
|
|
12
10
|
|
|
13
11
|
export function getHistory (storageKey) {
|
|
14
12
|
return safeGetItemJSON(storageKey, [])
|
|
@@ -81,10 +79,6 @@ export default function AiHistory (props) {
|
|
|
81
79
|
|
|
82
80
|
return (
|
|
83
81
|
<div className='ai-bookmark-history pd1b'>
|
|
84
|
-
<div className='pd1b text-muted'>
|
|
85
|
-
<HistoryOutlined className='mg1r' />
|
|
86
|
-
<span className='mg1r'>{e('history') || 'History'}:</span>
|
|
87
|
-
</div>
|
|
88
82
|
<Space size={[8, 8]} wrap>
|
|
89
83
|
{history.map((item, index) => {
|
|
90
84
|
const keyStr = typeof item === 'string' ? item : JSON.stringify(item)
|
|
@@ -1,34 +1,15 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { Alert
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Alert } from 'antd'
|
|
3
3
|
import ExternalLink from '../common/external-link'
|
|
4
4
|
|
|
5
5
|
const batchOpWikiLink = 'https://github.com/electerm/electerm/wiki/batch-operation'
|
|
6
6
|
|
|
7
7
|
export default function BatchOpAlert () {
|
|
8
|
-
const [expanded, setExpanded] = useState(false)
|
|
9
|
-
|
|
10
8
|
const description = (
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
</div>
|
|
16
|
-
{expanded && (
|
|
17
|
-
<div className='mg1t'>
|
|
18
|
-
<p><strong>connect</strong> params: <code>host, port, username, authType, password, privateKey, passphrase, certificate, profile, enableSftp, enableSsh, useSshAgent, sshAgent, term, encode, envLang, setEnv, startDirectoryRemote, startDirectoryLocal, proxy, x11, displayRaw, sshTunnels, connectionHoppings</code></p>
|
|
19
|
-
<p><strong>command</strong> params: <code>command</code></p>
|
|
20
|
-
<p><strong>sftp_upload</strong> params: <code>localPath, remotePath</code></p>
|
|
21
|
-
<p><strong>sftp_download</strong> params: <code>remotePath, localPath</code></p>
|
|
22
|
-
</div>
|
|
23
|
-
)}
|
|
24
|
-
<Button
|
|
25
|
-
size='small'
|
|
26
|
-
className='mg1y'
|
|
27
|
-
onClick={() => setExpanded(v => !v)}
|
|
28
|
-
>
|
|
29
|
-
{expanded ? 'Show less' : 'Show more'}
|
|
30
|
-
</Button>
|
|
31
|
-
</div>
|
|
9
|
+
<>
|
|
10
|
+
<p>Actions: <code>connect, command, sftp_upload, sftp_download</code></p>
|
|
11
|
+
<div><ExternalLink to={batchOpWikiLink}>{batchOpWikiLink}</ExternalLink></div>
|
|
12
|
+
</>
|
|
32
13
|
)
|
|
33
14
|
|
|
34
15
|
return (
|
|
@@ -15,7 +15,9 @@ import message from '../common/message'
|
|
|
15
15
|
import { refsStatic } from '../common/ref'
|
|
16
16
|
import generate from '../../common/uid'
|
|
17
17
|
import fs from '../../common/fs'
|
|
18
|
+
import { safeGetItem, safeSetItem } from '../../common/safe-local-storage'
|
|
18
19
|
|
|
20
|
+
const batchOpEditorKey = 'batch-op-editor-content'
|
|
19
21
|
const workflowExample = `[
|
|
20
22
|
{
|
|
21
23
|
"name": "Connect SSH",
|
|
@@ -80,11 +82,9 @@ const workflowExample = `[
|
|
|
80
82
|
]`
|
|
81
83
|
|
|
82
84
|
function getDefaultValue (widget) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
return ''
|
|
85
|
+
const saved = safeGetItem(batchOpEditorKey)
|
|
86
|
+
if (saved) return saved
|
|
87
|
+
return workflowExample
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
export default function BatchOpEditor ({ widget }) {
|
|
@@ -96,6 +96,10 @@ export default function BatchOpEditor ({ widget }) {
|
|
|
96
96
|
if (v) setValue(v)
|
|
97
97
|
}, [widget?.id])
|
|
98
98
|
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
safeSetItem(batchOpEditorKey, value)
|
|
101
|
+
}, [value])
|
|
102
|
+
|
|
99
103
|
const handleExecute = async () => {
|
|
100
104
|
if (!value || executing) return
|
|
101
105
|
setExecuting(true)
|
|
@@ -22,6 +22,7 @@ import SshHostSelector from './ssh-host-selector.jsx'
|
|
|
22
22
|
import SshAuthTypeSelector from './ssh-auth-type-selector.jsx'
|
|
23
23
|
import SshAuthSelector from './ssh-auth-selector.jsx'
|
|
24
24
|
import CategorySelect from './category-select.jsx'
|
|
25
|
+
import ExternalLink from '../../common/external-link.jsx'
|
|
25
26
|
const Fragment = React.Fragment
|
|
26
27
|
const FormItem = Form.Item
|
|
27
28
|
|
|
@@ -115,6 +116,20 @@ export function renderFormItem (item, formItemLayout, form, ctxProps, index) {
|
|
|
115
116
|
|
|
116
117
|
// Render complex/custom components directly (no extra wrapper component)
|
|
117
118
|
switch (type) {
|
|
119
|
+
case 'wiki':
|
|
120
|
+
return (
|
|
121
|
+
<Alert
|
|
122
|
+
key={name}
|
|
123
|
+
type='warning'
|
|
124
|
+
className='mg2b'
|
|
125
|
+
showIcon
|
|
126
|
+
description={
|
|
127
|
+
<>
|
|
128
|
+
<ExternalLink to={item.link}>{item.link}</ExternalLink>
|
|
129
|
+
</>
|
|
130
|
+
}
|
|
131
|
+
/>
|
|
132
|
+
)
|
|
118
133
|
case 'alert':
|
|
119
134
|
return <Alert key={name} {...item.props} />
|
|
120
135
|
case 'info':
|
|
@@ -21,6 +21,11 @@ const rdpConfig = {
|
|
|
21
21
|
key: 'auth',
|
|
22
22
|
label: e('auth'),
|
|
23
23
|
fields: [
|
|
24
|
+
{
|
|
25
|
+
type: 'wiki',
|
|
26
|
+
name: 'rdp-limitation-warning',
|
|
27
|
+
link: 'https://github.com/electerm/electerm/wiki/RDP-limitation'
|
|
28
|
+
},
|
|
24
29
|
commonFields.category,
|
|
25
30
|
commonFields.colorTitle,
|
|
26
31
|
{ type: 'input', name: 'host', label: () => e('host'), rules: [{ required: true, message: e('host') + ' required' }] },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PureComponent } from 'react'
|
|
2
2
|
import { CloseOutlined, MinusSquareOutlined, UpCircleOutlined } from '@ant-design/icons'
|
|
3
|
-
import { Button } from 'antd'
|
|
3
|
+
import { Button, Select, Space } from 'antd'
|
|
4
4
|
import { getLatestReleaseInfo, getLatestReleaseVersion } from '../../common/update-check'
|
|
5
5
|
import upgrade from '../../common/upgrade'
|
|
6
6
|
import compare from '../../common/version-compare'
|
|
@@ -9,8 +9,7 @@ import {
|
|
|
9
9
|
isMac,
|
|
10
10
|
isWin,
|
|
11
11
|
packInfo,
|
|
12
|
-
downloadUpgradeTimeout
|
|
13
|
-
mirrors
|
|
12
|
+
downloadUpgradeTimeout
|
|
14
13
|
} from '../../common/constants'
|
|
15
14
|
import { checkSkipSrc } from '../../common/check-skip-src'
|
|
16
15
|
import { debounce } from 'lodash-es'
|
|
@@ -18,6 +17,7 @@ import newTerm from '../../common/new-terminal'
|
|
|
18
17
|
import Markdown from '../common/markdown'
|
|
19
18
|
import downloadMirrors from '../../common/download-mirrors'
|
|
20
19
|
import { refsStatic } from '../common/ref'
|
|
20
|
+
import message from '../common/message'
|
|
21
21
|
import './upgrade.styl'
|
|
22
22
|
|
|
23
23
|
const e = window.translate
|
|
@@ -25,10 +25,15 @@ const {
|
|
|
25
25
|
homepage
|
|
26
26
|
} = packInfo
|
|
27
27
|
|
|
28
|
+
const downloadMirrorList = [
|
|
29
|
+
'github',
|
|
30
|
+
'gh-proxy',
|
|
31
|
+
'sourceforge'
|
|
32
|
+
]
|
|
33
|
+
|
|
28
34
|
export default class Upgrade extends PureComponent {
|
|
29
35
|
state = {
|
|
30
|
-
|
|
31
|
-
mirror: mirrors.github
|
|
36
|
+
mirror: downloadMirrorList[1]
|
|
32
37
|
}
|
|
33
38
|
|
|
34
39
|
downloadTimer = null
|
|
@@ -39,15 +44,23 @@ export default class Upgrade extends PureComponent {
|
|
|
39
44
|
}
|
|
40
45
|
this.id = 'upgrade'
|
|
41
46
|
refsStatic.add(this.id, this)
|
|
47
|
+
this.cleanupTimer = setInterval(() => {
|
|
48
|
+
const { noUpdateMessageExpires } = window.store.upgradeInfo
|
|
49
|
+
if (noUpdateMessageExpires && Date.now() > noUpdateMessageExpires) {
|
|
50
|
+
window.store.upgradeInfo.noUpdateMessage = ''
|
|
51
|
+
window.store.upgradeInfo.noUpdateMessageExpires = 0
|
|
52
|
+
}
|
|
53
|
+
}, 1000)
|
|
42
54
|
}
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
componentWillUnmount () {
|
|
57
|
+
if (this.cleanupTimer) {
|
|
58
|
+
clearInterval(this.cleanupTimer)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
appUpdateCheck = (isManual) => {
|
|
63
|
+
this.getLatestRelease(isManual)
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
changeProps = (update) => {
|
|
@@ -67,6 +80,12 @@ export default class Upgrade extends PureComponent {
|
|
|
67
80
|
window.store.upgradeInfo = {}
|
|
68
81
|
}
|
|
69
82
|
|
|
83
|
+
handleMirrorChange = (mirror) => {
|
|
84
|
+
this.setState({
|
|
85
|
+
mirror
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
70
89
|
onData = (upgradePercent) => {
|
|
71
90
|
clearTimeout(this.downloadTimer)
|
|
72
91
|
if (upgradePercent >= 100) {
|
|
@@ -93,17 +112,8 @@ export default class Upgrade extends PureComponent {
|
|
|
93
112
|
}
|
|
94
113
|
|
|
95
114
|
timeout = () => {
|
|
96
|
-
const { mirror } = this.state
|
|
97
115
|
this.cancel()
|
|
98
|
-
|
|
99
|
-
? this.doUpgrade
|
|
100
|
-
: undefined
|
|
101
|
-
const nextMirror = mirror === mirrors['download-electerm']
|
|
102
|
-
? mirrors.sourceforge
|
|
103
|
-
: mirrors['download-electerm']
|
|
104
|
-
this.setState({
|
|
105
|
-
mirror: nextMirror
|
|
106
|
-
}, next)
|
|
116
|
+
message.error('Download timeout, please try again')
|
|
107
117
|
}
|
|
108
118
|
|
|
109
119
|
onEnd = () => {
|
|
@@ -146,7 +156,7 @@ export default class Upgrade extends PureComponent {
|
|
|
146
156
|
this.handleClose()
|
|
147
157
|
}
|
|
148
158
|
|
|
149
|
-
getLatestRelease = async (
|
|
159
|
+
getLatestRelease = async (isManual = false) => {
|
|
150
160
|
const { installSrc } = this.props
|
|
151
161
|
if (checkSkipSrc(installSrc)) {
|
|
152
162
|
return
|
|
@@ -167,10 +177,19 @@ export default class Upgrade extends PureComponent {
|
|
|
167
177
|
const { skipVersion = 'v0.0.0' } = this.props
|
|
168
178
|
const currentVer = 'v' + window.et.version.split('-')[0]
|
|
169
179
|
const latestVer = releaseVer.tag_name
|
|
170
|
-
if (!
|
|
180
|
+
if (!isManual && compare(skipVersion, latestVer) >= 0) {
|
|
171
181
|
return
|
|
172
182
|
}
|
|
173
183
|
const shouldUpgrade = compare(currentVer, latestVer) < 0
|
|
184
|
+
if (!shouldUpgrade) {
|
|
185
|
+
if (isManual) {
|
|
186
|
+
this.changeProps({
|
|
187
|
+
noUpdateMessage: e('noNeed'),
|
|
188
|
+
noUpdateMessageExpires: Date.now() + 3000
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
return
|
|
192
|
+
}
|
|
174
193
|
const canAutoUpgrade = installSrc || isWin || isMac
|
|
175
194
|
let releaseInfo
|
|
176
195
|
if (canAutoUpgrade) {
|
|
@@ -208,28 +227,6 @@ export default class Upgrade extends PureComponent {
|
|
|
208
227
|
)
|
|
209
228
|
}
|
|
210
229
|
|
|
211
|
-
renderCanNotUpgrade = () => {
|
|
212
|
-
const {
|
|
213
|
-
showUpgradeModal
|
|
214
|
-
} = this.props.upgradeInfo
|
|
215
|
-
const cls = `animate upgrade-panel${showUpgradeModal ? '' : ' upgrade-panel-hide'}`
|
|
216
|
-
return (
|
|
217
|
-
<div className={cls}>
|
|
218
|
-
<div className='upgrade-panel-title fix'>
|
|
219
|
-
<span className='fleft'>
|
|
220
|
-
{e('noNeed')}
|
|
221
|
-
</span>
|
|
222
|
-
<span className='fright'>
|
|
223
|
-
<CloseOutlined className='pointer font16 close-upgrade-panel' onClick={this.handleClose} />
|
|
224
|
-
</span>
|
|
225
|
-
</div>
|
|
226
|
-
<div className='upgrade-panel-body'>
|
|
227
|
-
{e('noNeedDesc')}
|
|
228
|
-
</div>
|
|
229
|
-
</div>
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
230
|
renderChangeLog = () => {
|
|
234
231
|
const {
|
|
235
232
|
releaseInfo
|
|
@@ -261,38 +258,8 @@ export default class Upgrade extends PureComponent {
|
|
|
261
258
|
)
|
|
262
259
|
}
|
|
263
260
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
showCount
|
|
267
|
-
} = this.state
|
|
268
|
-
const { installSrc } = this.props
|
|
269
|
-
const {
|
|
270
|
-
remoteVersion,
|
|
271
|
-
upgrading,
|
|
272
|
-
checkingRemoteVersion,
|
|
273
|
-
showUpgradeModal,
|
|
274
|
-
upgradePercent,
|
|
275
|
-
shouldUpgrade,
|
|
276
|
-
releaseInfo,
|
|
277
|
-
error
|
|
278
|
-
} = this.props.upgradeInfo
|
|
279
|
-
if (error) {
|
|
280
|
-
return this.renderError(error)
|
|
281
|
-
}
|
|
282
|
-
if (!shouldUpgrade && showCount < 2) {
|
|
283
|
-
return null
|
|
284
|
-
}
|
|
285
|
-
if (!shouldUpgrade && showCount > 1) {
|
|
286
|
-
return this.renderCanNotUpgrade()
|
|
287
|
-
}
|
|
288
|
-
if (checkingRemoteVersion) {
|
|
289
|
-
return null
|
|
290
|
-
}
|
|
291
|
-
const cls = `animate upgrade-panel${showUpgradeModal ? '' : ' upgrade-panel-hide'}`
|
|
292
|
-
const func = upgrading
|
|
293
|
-
? this.cancel
|
|
294
|
-
: this.doUpgrade
|
|
295
|
-
const getLink = (
|
|
261
|
+
renderLinks = () => {
|
|
262
|
+
return (
|
|
296
263
|
<div>
|
|
297
264
|
<p>
|
|
298
265
|
{e('manuallyDownloadFrom')}:
|
|
@@ -307,7 +274,80 @@ export default class Upgrade extends PureComponent {
|
|
|
307
274
|
{this.renderChangeLog()}
|
|
308
275
|
</div>
|
|
309
276
|
)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
renderMirrorSelector = () => {
|
|
280
|
+
return (
|
|
281
|
+
<Select
|
|
282
|
+
value={this.state.mirror}
|
|
283
|
+
onChange={this.handleMirrorChange}
|
|
284
|
+
getPopupContainer={() => document.body}
|
|
285
|
+
size='small'
|
|
286
|
+
style={{ height: 32 }}
|
|
287
|
+
>
|
|
288
|
+
{downloadMirrorList.map((opt) => (
|
|
289
|
+
<Select.Option key={opt} value={opt}>{opt}</Select.Option>
|
|
290
|
+
))}
|
|
291
|
+
</Select>
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
renderUpgradeButton = () => {
|
|
296
|
+
const { upgrading, upgradePercent, checkingRemoteVersion } = this.props.upgradeInfo
|
|
297
|
+
if (upgrading) {
|
|
298
|
+
const percent = upgradePercent || 0
|
|
299
|
+
return (
|
|
300
|
+
<Button
|
|
301
|
+
type='primary'
|
|
302
|
+
icon={<UpCircleOutlined />}
|
|
303
|
+
loading={checkingRemoteVersion}
|
|
304
|
+
disabled={checkingRemoteVersion}
|
|
305
|
+
onClick={() => this.cancel()}
|
|
306
|
+
className='mg1b'
|
|
307
|
+
>
|
|
308
|
+
<span>{`${e('upgrading')}... ${percent}% ${e('cancel')}`}</span>
|
|
309
|
+
</Button>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
return (
|
|
313
|
+
<Space.Compact>
|
|
314
|
+
{this.renderMirrorSelector()}
|
|
315
|
+
<Button
|
|
316
|
+
type='primary'
|
|
317
|
+
icon={<UpCircleOutlined />}
|
|
318
|
+
loading={checkingRemoteVersion}
|
|
319
|
+
disabled={checkingRemoteVersion}
|
|
320
|
+
onClick={() => this.doUpgrade()}
|
|
321
|
+
className='mg1b'
|
|
322
|
+
>
|
|
323
|
+
{e('upgrade')}
|
|
324
|
+
</Button>
|
|
325
|
+
</Space.Compact>
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
renderUpgradeContent = () => {
|
|
330
|
+
const { installSrc } = this.props
|
|
310
331
|
const skip = checkSkipSrc(installSrc)
|
|
332
|
+
if (skip) {
|
|
333
|
+
return this.renderLinks()
|
|
334
|
+
}
|
|
335
|
+
return (
|
|
336
|
+
<div>
|
|
337
|
+
{this.renderUpgradeButton()}
|
|
338
|
+
{this.renderSkipVersion()}
|
|
339
|
+
<div className='pd1t'>
|
|
340
|
+
{this.renderLinks()}
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
renderUpgradePanel = () => {
|
|
347
|
+
const { remoteVersion, releaseInfo, showUpgradeModal } = this.props.upgradeInfo
|
|
348
|
+
const cls = showUpgradeModal
|
|
349
|
+
? 'animate upgrade-panel'
|
|
350
|
+
: 'animate upgrade-panel upgrade-panel-hide'
|
|
311
351
|
return (
|
|
312
352
|
<div className={cls}>
|
|
313
353
|
<div className='upgrade-panel-title fix'>
|
|
@@ -319,34 +359,23 @@ export default class Upgrade extends PureComponent {
|
|
|
319
359
|
</span>
|
|
320
360
|
</div>
|
|
321
361
|
<div className='upgrade-panel-body'>
|
|
322
|
-
{
|
|
323
|
-
!skip
|
|
324
|
-
? (
|
|
325
|
-
<div>
|
|
326
|
-
<Button
|
|
327
|
-
type='primary'
|
|
328
|
-
icon={<UpCircleOutlined />}
|
|
329
|
-
loading={checkingRemoteVersion}
|
|
330
|
-
disabled={checkingRemoteVersion}
|
|
331
|
-
onClick={func}
|
|
332
|
-
className='mg1b'
|
|
333
|
-
>
|
|
334
|
-
{
|
|
335
|
-
upgrading
|
|
336
|
-
? <span>{`${e('upgrading')}... ${upgradePercent || 0}% ${e('cancel')}`}</span>
|
|
337
|
-
: e('upgrade')
|
|
338
|
-
}
|
|
339
|
-
</Button>
|
|
340
|
-
{this.renderSkipVersion()}
|
|
341
|
-
<div className='pd1t'>
|
|
342
|
-
{getLink}
|
|
343
|
-
</div>
|
|
344
|
-
</div>
|
|
345
|
-
)
|
|
346
|
-
: getLink
|
|
347
|
-
}
|
|
362
|
+
{this.renderUpgradeContent()}
|
|
348
363
|
</div>
|
|
349
364
|
</div>
|
|
350
365
|
)
|
|
351
366
|
}
|
|
367
|
+
|
|
368
|
+
render () {
|
|
369
|
+
const { shouldUpgrade, checkingRemoteVersion, error } = this.props.upgradeInfo
|
|
370
|
+
if (error) {
|
|
371
|
+
return this.renderError(error)
|
|
372
|
+
}
|
|
373
|
+
if (!shouldUpgrade) {
|
|
374
|
+
return null
|
|
375
|
+
}
|
|
376
|
+
if (checkingRemoteVersion) {
|
|
377
|
+
return null
|
|
378
|
+
}
|
|
379
|
+
return this.renderUpgradePanel()
|
|
380
|
+
}
|
|
352
381
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
position fixed
|
|
3
3
|
right 10px
|
|
4
4
|
bottom 10px
|
|
5
|
-
z-index
|
|
5
|
+
z-index 888
|
|
6
6
|
background var(--main)
|
|
7
7
|
border-radius 5px
|
|
8
8
|
border 1px solid var(--main-darker)
|
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
.upgrade-panel-title
|
|
23
23
|
border-bottom 1px solid var(--main-darker)
|
|
24
24
|
.markdown-wrap
|
|
25
|
-
max-height
|
|
25
|
+
max-height 20vh
|
|
26
26
|
overflow-y auto
|