@electerm/electerm-react 1.38.65 → 1.38.80
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 +6 -3
- package/client/common/create-title.jsx +9 -1
- package/client/common/sftp.js +3 -0
- package/client/components/batch-op/batch-op.jsx +1 -6
- package/client/components/bookmark-form/bookmark-form.styl +3 -1
- package/client/components/bookmark-form/index.jsx +12 -8
- package/client/components/bookmark-form/render-ssh-tunnel.jsx +210 -88
- package/client/components/bookmark-form/ssh-form-ui.jsx +1 -1
- package/client/components/bookmark-form/web-form-ui.jsx +96 -0
- package/client/components/bookmark-form/web-form.jsx +16 -0
- package/client/components/main/main.jsx +14 -0
- package/client/components/quick-commands/qm.styl +1 -1
- package/client/components/session/session.styl +4 -1
- package/client/components/session/sessions.jsx +16 -2
- package/client/components/session/web-session.jsx +20 -0
- package/client/components/sftp/{confirm-modal.jsx → confirm-modal-store.jsx} +81 -50
- package/client/components/sftp/file-item.jsx +2 -0
- package/client/components/sftp/sftp-entry.jsx +27 -37
- package/client/components/sftp/transfer-conflict-store.jsx +291 -0
- package/client/components/sftp/transport-action-store.jsx +430 -0
- package/client/components/sftp/transports-action-store.jsx +102 -0
- package/client/components/sftp/transports-ui-store.jsx +30 -0
- package/client/components/sidebar/transfer-list-control.jsx +5 -14
- package/client/components/sidebar/transport-ui.jsx +2 -12
- package/client/components/tabs/tab.jsx +43 -2
- package/client/components/tabs/tabs.styl +1 -1
- package/client/components/terminal/index.jsx +14 -1
- package/client/components/terminal/terminal-interactive.jsx +15 -0
- package/client/components/terminal-info/disk.jsx +9 -0
- package/client/entry/worker.js +5 -1
- package/client/store/index.js +16 -1
- package/client/store/init-state.js +2 -3
- package/client/store/sync.js +5 -2
- package/client/store/tab.js +1 -1
- package/client/store/transfer-list.js +55 -2
- package/client/store/watch.js +0 -8
- package/package.json +1 -1
- package/client/components/sftp/transfer-conflict.jsx +0 -323
- package/client/components/sftp/transport-action.jsx +0 -412
- package/client/components/sftp/transport-entry.jsx +0 -108
- package/client/components/sftp/transport-types.js +0 -8
- package/client/components/sftp/transports-action.jsx +0 -111
- package/client/components/sftp/transports-ui.jsx +0 -93
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pass transfer list from props
|
|
3
|
+
* when list changes, do transfer and other op
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Component } from '../common/react-subx'
|
|
7
|
+
import Transports from './transports-ui-store'
|
|
8
|
+
import { maxTransport } from '../../common/constants'
|
|
9
|
+
|
|
10
|
+
export default class TransportsActionStore extends Component {
|
|
11
|
+
componentDidMount () {
|
|
12
|
+
this.control()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
componentDidUpdate (prevProps) {
|
|
16
|
+
if (
|
|
17
|
+
prevProps._fileTransfers !== this.props._fileTransfers
|
|
18
|
+
) {
|
|
19
|
+
this.control()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
control = async () => {
|
|
24
|
+
const { store } = this.props
|
|
25
|
+
let {
|
|
26
|
+
fileTransfers
|
|
27
|
+
} = store
|
|
28
|
+
|
|
29
|
+
fileTransfers = fileTransfers.map(t => {
|
|
30
|
+
const {
|
|
31
|
+
typeTo,
|
|
32
|
+
typeFrom,
|
|
33
|
+
fromFile,
|
|
34
|
+
inited
|
|
35
|
+
} = t
|
|
36
|
+
const ready = !!fromFile
|
|
37
|
+
if (typeTo === typeFrom && ready && !inited) {
|
|
38
|
+
t.inited = true
|
|
39
|
+
}
|
|
40
|
+
return t
|
|
41
|
+
})
|
|
42
|
+
// if (pauseAllTransfer) {
|
|
43
|
+
// return store.setFileTransfers(fileTransfers)
|
|
44
|
+
// }
|
|
45
|
+
let count = fileTransfers.filter(t => {
|
|
46
|
+
const {
|
|
47
|
+
typeTo,
|
|
48
|
+
typeFrom,
|
|
49
|
+
inited
|
|
50
|
+
} = t
|
|
51
|
+
return typeTo !== typeFrom && inited
|
|
52
|
+
}).length
|
|
53
|
+
if (count >= maxTransport) {
|
|
54
|
+
return store.setFileTransfers(fileTransfers)
|
|
55
|
+
}
|
|
56
|
+
const len = fileTransfers.length
|
|
57
|
+
const ids = []
|
|
58
|
+
for (let i = 0; i < len; i++) {
|
|
59
|
+
const tr = fileTransfers[i]
|
|
60
|
+
const {
|
|
61
|
+
typeTo,
|
|
62
|
+
typeFrom,
|
|
63
|
+
inited,
|
|
64
|
+
fromFile,
|
|
65
|
+
error,
|
|
66
|
+
id,
|
|
67
|
+
action
|
|
68
|
+
} = tr
|
|
69
|
+
if (!error) {
|
|
70
|
+
ids.push(id)
|
|
71
|
+
}
|
|
72
|
+
const isTransfer = typeTo !== typeFrom
|
|
73
|
+
const ready = (
|
|
74
|
+
action && fromFile
|
|
75
|
+
)
|
|
76
|
+
if (
|
|
77
|
+
!ready ||
|
|
78
|
+
inited ||
|
|
79
|
+
!isTransfer
|
|
80
|
+
) {
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
// if (isTransfer && tr.fromFile.isDirectory) {
|
|
84
|
+
// i = len
|
|
85
|
+
// continue
|
|
86
|
+
// }
|
|
87
|
+
if (
|
|
88
|
+
fromFile && count < maxTransport
|
|
89
|
+
) {
|
|
90
|
+
count++
|
|
91
|
+
tr.inited = true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
store.setFileTransfers(fileTransfers)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
render () {
|
|
98
|
+
return (
|
|
99
|
+
<Transports {...this.props} />
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transporter UI component
|
|
3
|
+
*/
|
|
4
|
+
import { Component } from '../common/react-subx'
|
|
5
|
+
import Transport from './transport-action-store'
|
|
6
|
+
|
|
7
|
+
export default class TransportsUI extends Component {
|
|
8
|
+
render () {
|
|
9
|
+
const { store } = this.props
|
|
10
|
+
const {
|
|
11
|
+
fileTransfers
|
|
12
|
+
} = store
|
|
13
|
+
if (!fileTransfers.length) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
return fileTransfers.map((t, i) => {
|
|
17
|
+
const { id } = t
|
|
18
|
+
return (
|
|
19
|
+
<Transport
|
|
20
|
+
{...this.props}
|
|
21
|
+
transfer={t}
|
|
22
|
+
inited={t.inited}
|
|
23
|
+
cancel={t.cancel}
|
|
24
|
+
pause={t.pausing}
|
|
25
|
+
key={id + ':tr:' + i}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -8,10 +8,6 @@ import {
|
|
|
8
8
|
PauseCircleOutlined
|
|
9
9
|
} from '@ant-design/icons'
|
|
10
10
|
import { get } from 'lodash-es'
|
|
11
|
-
import {
|
|
12
|
-
transportTypes
|
|
13
|
-
} from '../sftp/transport-types'
|
|
14
|
-
import postMessage from '../../common/post-msg'
|
|
15
11
|
|
|
16
12
|
const { Option } = Select
|
|
17
13
|
|
|
@@ -28,21 +24,16 @@ export default class TransferModalUI extends Component {
|
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
handlePauseOrResumeAll = () => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
id: this.state.filter
|
|
34
|
-
})
|
|
27
|
+
const { store } = window
|
|
28
|
+
store.pauseAllTransfer ? store.resumeAll() : store.pauseAll()
|
|
35
29
|
}
|
|
36
30
|
|
|
37
31
|
handleCancelAll = () => {
|
|
38
|
-
|
|
39
|
-
action: transportTypes.cancelAll,
|
|
40
|
-
id: this.state.filter
|
|
41
|
-
})
|
|
32
|
+
window.store.cancelAll()
|
|
42
33
|
}
|
|
43
34
|
|
|
44
35
|
getGroups = () => {
|
|
45
|
-
const fileTransfers = this.props.store.
|
|
36
|
+
const fileTransfers = this.props.store.fileTransfers
|
|
46
37
|
const tree = fileTransfers.reduce((p, k) => {
|
|
47
38
|
const {
|
|
48
39
|
id,
|
|
@@ -79,7 +70,7 @@ export default class TransferModalUI extends Component {
|
|
|
79
70
|
const {
|
|
80
71
|
filter
|
|
81
72
|
} = this.state
|
|
82
|
-
const fileTransfers = this.props.store.
|
|
73
|
+
const fileTransfers = this.props.store.fileTransfers
|
|
83
74
|
return filter === 'all'
|
|
84
75
|
? fileTransfers
|
|
85
76
|
: fileTransfers.filter(d => d.sessionId === filter)
|
|
@@ -8,10 +8,6 @@ import {
|
|
|
8
8
|
PlayCircleOutlined,
|
|
9
9
|
PauseCircleOutlined
|
|
10
10
|
} from '@ant-design/icons'
|
|
11
|
-
import {
|
|
12
|
-
transportTypes
|
|
13
|
-
} from '../sftp/transport-types'
|
|
14
|
-
import postMessage from '../../common/post-msg'
|
|
15
11
|
import './transfer.styl'
|
|
16
12
|
|
|
17
13
|
const { prefix } = window
|
|
@@ -35,16 +31,10 @@ export default function Transporter (props) {
|
|
|
35
31
|
id
|
|
36
32
|
} = props.transfer
|
|
37
33
|
function cancel () {
|
|
38
|
-
|
|
39
|
-
action: transportTypes.cancelTransport,
|
|
40
|
-
id
|
|
41
|
-
})
|
|
34
|
+
window.store.cancelTransfer(id)
|
|
42
35
|
}
|
|
43
36
|
function handlePauseOrResume () {
|
|
44
|
-
|
|
45
|
-
action: transportTypes.pauseOrResumeTransfer,
|
|
46
|
-
id
|
|
47
|
-
})
|
|
37
|
+
window.store.toggleTransfer(id)
|
|
48
38
|
}
|
|
49
39
|
const isTransfer = typeTo !== typeFrom
|
|
50
40
|
const Icon = !pausing ? PauseCircleOutlined : PlayCircleOutlined
|
|
@@ -26,6 +26,7 @@ import { shortcutDescExtend } from '../shortcuts/shortcut-handler.js'
|
|
|
26
26
|
const { prefix } = window
|
|
27
27
|
const e = prefix('tabs')
|
|
28
28
|
const m = prefix('menu')
|
|
29
|
+
const s = prefix('sftp')
|
|
29
30
|
const onDragCls = 'ondrag-tab'
|
|
30
31
|
const onDragOverCls = 'dragover-tab'
|
|
31
32
|
|
|
@@ -346,6 +347,36 @@ class Tab extends Component {
|
|
|
346
347
|
)
|
|
347
348
|
}
|
|
348
349
|
|
|
350
|
+
// sshTunnelResults is a array of { sshTunnel, error? }, sshTunnel is a object has props of sshTunnelLocalPort, sshTunnelRemoteHost, sshTunnelRemotePort, sshTunnel, sshTunnelLocalHost, should build sshTunnel string from sshTunnel object, when error exist, this string should start with "error:", return title and sshTunnelResults list in react element.
|
|
351
|
+
renderTitle = (sshTunnelResults, title) => {
|
|
352
|
+
const list = sshTunnelResults.map(({ sshTunnel: obj, error }, i) => {
|
|
353
|
+
const {
|
|
354
|
+
sshTunnelLocalPort,
|
|
355
|
+
sshTunnelRemoteHost = '127.0.0.1',
|
|
356
|
+
sshTunnelRemotePort,
|
|
357
|
+
sshTunnel,
|
|
358
|
+
sshTunnelLocalHost = '127.0.0.1',
|
|
359
|
+
name
|
|
360
|
+
} = obj
|
|
361
|
+
let tunnel = sshTunnel === 'forwardRemoteToLocal'
|
|
362
|
+
? `-> ${s('remote')}:${sshTunnelRemoteHost}:${sshTunnelRemotePort} -> ${sshTunnelLocalHost}:${sshTunnelLocalPort}`
|
|
363
|
+
: `-> ${s('local')}:${sshTunnelLocalHost}:${sshTunnelLocalPort} -> ${sshTunnelRemoteHost}:${sshTunnelRemotePort}`
|
|
364
|
+
if (error) {
|
|
365
|
+
tunnel = `error: ${tunnel}`
|
|
366
|
+
}
|
|
367
|
+
if (name) {
|
|
368
|
+
tunnel = `[${name}] ${tunnel}`
|
|
369
|
+
}
|
|
370
|
+
return <div key={tunnel}>{tunnel}</div>
|
|
371
|
+
})
|
|
372
|
+
return (
|
|
373
|
+
<div>
|
|
374
|
+
<div>${title}</div>
|
|
375
|
+
{list}
|
|
376
|
+
</div>
|
|
377
|
+
)
|
|
378
|
+
}
|
|
379
|
+
|
|
349
380
|
renderCloseIcon () {
|
|
350
381
|
return (
|
|
351
382
|
<span className='tab-close pointer'>
|
|
@@ -360,7 +391,13 @@ class Tab extends Component {
|
|
|
360
391
|
} = this.props
|
|
361
392
|
const { isLast } = this.props
|
|
362
393
|
const { tab, terminalOnData } = this.state
|
|
363
|
-
const {
|
|
394
|
+
const {
|
|
395
|
+
id,
|
|
396
|
+
isEditting,
|
|
397
|
+
status,
|
|
398
|
+
isTransporting,
|
|
399
|
+
sshTunnelResults
|
|
400
|
+
} = tab
|
|
364
401
|
const active = id === currentTabId
|
|
365
402
|
const cls = classnames(
|
|
366
403
|
`tab-${id}`,
|
|
@@ -378,6 +415,10 @@ class Tab extends Component {
|
|
|
378
415
|
}
|
|
379
416
|
)
|
|
380
417
|
const title = createName(tab)
|
|
418
|
+
let tooltipTitle = title
|
|
419
|
+
if (sshTunnelResults) {
|
|
420
|
+
tooltipTitle = this.renderTitle(sshTunnelResults, title)
|
|
421
|
+
}
|
|
381
422
|
if (isEditting) {
|
|
382
423
|
return this.renderEditting(tab, cls)
|
|
383
424
|
}
|
|
@@ -387,7 +428,7 @@ class Tab extends Component {
|
|
|
387
428
|
: {}
|
|
388
429
|
return (
|
|
389
430
|
<Tooltip
|
|
390
|
-
title={
|
|
431
|
+
title={tooltipTitle}
|
|
391
432
|
placement='top'
|
|
392
433
|
>
|
|
393
434
|
<div
|
|
@@ -138,9 +138,13 @@ class Term extends Component {
|
|
|
138
138
|
clearTimeout(this.timers[k])
|
|
139
139
|
})
|
|
140
140
|
this.onClose = true
|
|
141
|
-
|
|
141
|
+
if (this.socket) {
|
|
142
|
+
this.socket.close()
|
|
143
|
+
delete this.socket
|
|
144
|
+
}
|
|
142
145
|
if (this.term) {
|
|
143
146
|
this.term.dispose()
|
|
147
|
+
delete this.term
|
|
144
148
|
}
|
|
145
149
|
window.removeEventListener(
|
|
146
150
|
'resize',
|
|
@@ -149,6 +153,13 @@ class Term extends Component {
|
|
|
149
153
|
window.removeEventListener('message', this.handleEvent)
|
|
150
154
|
this.dom.removeEventListener('contextmenu', this.onContextMenu)
|
|
151
155
|
window.removeEventListener('message', this.onContextAction)
|
|
156
|
+
delete this.dom
|
|
157
|
+
delete this.attachAddon
|
|
158
|
+
delete this.fitAddon
|
|
159
|
+
delete this.zmodemAddon
|
|
160
|
+
delete this.searchAddon
|
|
161
|
+
delete this.serializeAddon
|
|
162
|
+
delete this.fitAddon
|
|
152
163
|
}
|
|
153
164
|
|
|
154
165
|
terminalConfigProps = [
|
|
@@ -1110,6 +1121,7 @@ class Term extends Component {
|
|
|
1110
1121
|
]),
|
|
1111
1122
|
sessionId,
|
|
1112
1123
|
tabId: id,
|
|
1124
|
+
srcTabId: tab.id,
|
|
1113
1125
|
terminalIndex,
|
|
1114
1126
|
termType,
|
|
1115
1127
|
readyTimeout: config.sshReadyTimeout,
|
|
@@ -1225,6 +1237,7 @@ class Term extends Component {
|
|
|
1225
1237
|
this.socketCloseWarning = notification.warning({
|
|
1226
1238
|
key,
|
|
1227
1239
|
message: e('socketCloseTip'),
|
|
1240
|
+
duration: 30,
|
|
1228
1241
|
description: (
|
|
1229
1242
|
<div className='pd2y'>
|
|
1230
1243
|
<Button
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import { useEffect, useState } from 'react'
|
|
6
6
|
import { Modal, Form, Button } from 'antd'
|
|
7
7
|
import InputAutoFocus from '../common/input-auto-focus'
|
|
8
|
+
import { tabActions } from '../../common/constants'
|
|
8
9
|
import wait from '../../common/wait'
|
|
10
|
+
import postMsg from '../../common/post-msg'
|
|
9
11
|
|
|
10
12
|
const { prefix } = window
|
|
11
13
|
const e = prefix('sftp')
|
|
@@ -16,6 +18,13 @@ export default function TermInteractive () {
|
|
|
16
18
|
const [trigger] = useState(0)
|
|
17
19
|
const [opts, setter] = useState(null)
|
|
18
20
|
const [form] = Form.useForm()
|
|
21
|
+
function updateTab (data) {
|
|
22
|
+
postMsg({
|
|
23
|
+
action: tabActions.updateTabs,
|
|
24
|
+
id: data.tabId,
|
|
25
|
+
update: data.update
|
|
26
|
+
})
|
|
27
|
+
}
|
|
19
28
|
function onMsg (e) {
|
|
20
29
|
if (
|
|
21
30
|
e &&
|
|
@@ -24,6 +33,12 @@ export default function TermInteractive () {
|
|
|
24
33
|
e.data.includes('session-interactive')
|
|
25
34
|
) {
|
|
26
35
|
setter(JSON.parse(e.data))
|
|
36
|
+
} else if (
|
|
37
|
+
e &&
|
|
38
|
+
e.data &&
|
|
39
|
+
e.data.includes('ssh-tunnel-result')
|
|
40
|
+
) {
|
|
41
|
+
updateTab(JSON.parse(e.data))
|
|
27
42
|
}
|
|
28
43
|
}
|
|
29
44
|
function clear () {
|
|
@@ -13,6 +13,15 @@ export default function TerminalInfoDisk (props) {
|
|
|
13
13
|
return null
|
|
14
14
|
}
|
|
15
15
|
const col = colsParser(disks[0])
|
|
16
|
+
disks.sort((a, b) => {
|
|
17
|
+
if (a.filesystem.startsWith('/') && !b.filesystem.startsWith('/')) {
|
|
18
|
+
return -1
|
|
19
|
+
}
|
|
20
|
+
if (!a.filesystem.startsWith('/') && b.filesystem.startsWith('/')) {
|
|
21
|
+
return 1
|
|
22
|
+
}
|
|
23
|
+
return 0
|
|
24
|
+
})
|
|
16
25
|
const ps = {
|
|
17
26
|
rowKey: (rec) => `${rec.mount}_${rec.filesystem}`,
|
|
18
27
|
dataSource: disks,
|
package/client/entry/worker.js
CHANGED
|
@@ -16,7 +16,11 @@ function createWs (
|
|
|
16
16
|
const wsUrl = `ws://${host}:${port}/${type}/${id}?sessionId=${sessionId}&sftpId=${sftpId}&token=${tokenElecterm}`
|
|
17
17
|
const ws = new WebSocket(wsUrl)
|
|
18
18
|
ws.s = msg => {
|
|
19
|
-
|
|
19
|
+
try {
|
|
20
|
+
ws.send(JSON.stringify(msg))
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error('ws send error', e)
|
|
23
|
+
}
|
|
20
24
|
}
|
|
21
25
|
ws.id = id
|
|
22
26
|
ws.once = (callack, id) => {
|
package/client/store/index.js
CHANGED
|
@@ -63,7 +63,18 @@ function expandShorthandColor (color) {
|
|
|
63
63
|
if (color.length === 4) {
|
|
64
64
|
return '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
if (color.length === 7) {
|
|
67
|
+
return color
|
|
68
|
+
}
|
|
69
|
+
if (color.length < 7) {
|
|
70
|
+
return expandShorthandColor(color + 'f')
|
|
71
|
+
}
|
|
72
|
+
if (color.length > 7) {
|
|
73
|
+
return expandShorthandColor(color.slice(0, 7))
|
|
74
|
+
}
|
|
75
|
+
if (!/^#[A-Fa-f0-9]{6}$/.test(color)) {
|
|
76
|
+
return '#141314'
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
function isColorDark (_color) {
|
|
@@ -233,6 +244,10 @@ class Store {
|
|
|
233
244
|
return JSON.parse(window.store._upgradeInfo)
|
|
234
245
|
}
|
|
235
246
|
|
|
247
|
+
get transferToConfirm () {
|
|
248
|
+
return JSON.parse(window.store._transferToConfirm)
|
|
249
|
+
}
|
|
250
|
+
|
|
236
251
|
get settingItem () {
|
|
237
252
|
return JSON.parse(window.store._settingItem)
|
|
238
253
|
}
|
|
@@ -92,9 +92,11 @@ export default () => {
|
|
|
92
92
|
|
|
93
93
|
// sftp
|
|
94
94
|
fileOperation: fileOperationsMap.cp, // cp or mv
|
|
95
|
+
pauseAllTransfer: false,
|
|
95
96
|
transferTab: 'transfer',
|
|
96
97
|
_transferHistory: '[]',
|
|
97
98
|
_fileTransfers: '[]',
|
|
99
|
+
_transferToConfirm: '{}',
|
|
98
100
|
_sftpSortSetting: ls.getItem(sftpDefaultSortSettingKey) || JSON.stringify({
|
|
99
101
|
local: {
|
|
100
102
|
prop: 'modifyTime',
|
|
@@ -169,9 +171,6 @@ export default () => {
|
|
|
169
171
|
_serials: '[]',
|
|
170
172
|
loaddingSerials: false,
|
|
171
173
|
|
|
172
|
-
// transfer list
|
|
173
|
-
transports: [],
|
|
174
|
-
|
|
175
174
|
_sshConfigItems: '[]',
|
|
176
175
|
|
|
177
176
|
appPath: '',
|
package/client/store/sync.js
CHANGED
|
@@ -12,6 +12,7 @@ import fetch from '../common/fetch-from-server'
|
|
|
12
12
|
import download from '../common/download'
|
|
13
13
|
import { fixBookmarks } from '../common/db-fix'
|
|
14
14
|
import dayjs from 'dayjs'
|
|
15
|
+
import parseJsonSafe from '../common/parse-json-safe'
|
|
15
16
|
|
|
16
17
|
const names = without(dbNames, settingMap.history)
|
|
17
18
|
const {
|
|
@@ -262,10 +263,12 @@ export default (Store) => {
|
|
|
262
263
|
})
|
|
263
264
|
store.setItems(n, arr)
|
|
264
265
|
}
|
|
265
|
-
const userConfig =
|
|
266
|
+
const userConfig = parseJsonSafe(
|
|
266
267
|
get(gist, 'files["userConfig.json"].content')
|
|
267
268
|
)
|
|
268
|
-
|
|
269
|
+
if (userConfig && userConfig.theme) {
|
|
270
|
+
store.setTheme(userConfig.theme)
|
|
271
|
+
}
|
|
269
272
|
const up = {
|
|
270
273
|
[type + 'LastSyncTime']: Date.now()
|
|
271
274
|
}
|
package/client/store/tab.js
CHANGED
|
@@ -11,7 +11,7 @@ import postMsg from '../common/post-msg'
|
|
|
11
11
|
export default Store => {
|
|
12
12
|
Store.prototype.updateTabsStatus = function () {
|
|
13
13
|
const tabIds = uniq(
|
|
14
|
-
window.store.
|
|
14
|
+
window.store.fileTransfers.map(d => d.tabId)
|
|
15
15
|
)
|
|
16
16
|
postMsg({
|
|
17
17
|
action: tabActions.updateTabsStatus,
|
|
@@ -4,10 +4,9 @@ export default Store => {
|
|
|
4
4
|
window.store.transferTab = tab
|
|
5
5
|
}
|
|
6
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
7
|
Store.prototype.setTransfers = function (list, _sessId) {
|
|
9
8
|
const { store } = window
|
|
10
|
-
let oldList = store.
|
|
9
|
+
let oldList = store.fileTransfers
|
|
11
10
|
const sessId = _sessId || list[0].sessionId
|
|
12
11
|
const arr2 = oldList.filter(t => {
|
|
13
12
|
return t.sessionId === sessId
|
|
@@ -48,4 +47,58 @@ export default Store => {
|
|
|
48
47
|
Store.prototype.addTransfers = function (objs) {
|
|
49
48
|
return window.store.addItems(objs, 'fileTransfers')
|
|
50
49
|
}
|
|
50
|
+
Store.prototype.setFileTransfers = function (objs) {
|
|
51
|
+
return window.store.setState('fileTransfers', objs)
|
|
52
|
+
}
|
|
53
|
+
Store.prototype.addTransferList = function (objs) {
|
|
54
|
+
const { store } = window
|
|
55
|
+
store.setFileTransfers([
|
|
56
|
+
...store.fileTransfers,
|
|
57
|
+
...objs
|
|
58
|
+
])
|
|
59
|
+
}
|
|
60
|
+
Store.prototype.toggleTransfer = function (itemId) {
|
|
61
|
+
const { store } = window
|
|
62
|
+
const { fileTransfers } = store
|
|
63
|
+
const index = findIndex(fileTransfers, t => t.id === itemId)
|
|
64
|
+
if (index < 0) {
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
fileTransfers[index].pausing = !fileTransfers[index].pausing
|
|
68
|
+
store.setFileTransfers(fileTransfers)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Store.prototype.pauseAll = function () {
|
|
72
|
+
const { store } = window
|
|
73
|
+
store.pauseAllTransfer = true
|
|
74
|
+
store.setFileTransfers(store.fileTransfers.map(t => {
|
|
75
|
+
t.pausing = true
|
|
76
|
+
return t
|
|
77
|
+
}))
|
|
78
|
+
}
|
|
79
|
+
Store.prototype.resumeAll = function () {
|
|
80
|
+
const { store } = window
|
|
81
|
+
store.pauseAllTransfer = false
|
|
82
|
+
store.setFileTransfers(store.fileTransfers.map(t => {
|
|
83
|
+
t.pausing = false
|
|
84
|
+
return t
|
|
85
|
+
}))
|
|
86
|
+
}
|
|
87
|
+
Store.prototype.cancelAll = function () {
|
|
88
|
+
const { store } = window
|
|
89
|
+
store.setFileTransfers(store.fileTransfers.map(t => {
|
|
90
|
+
t.cancel = true
|
|
91
|
+
return t
|
|
92
|
+
}))
|
|
93
|
+
}
|
|
94
|
+
Store.prototype.cancelTransfer = function (itemId) {
|
|
95
|
+
const { store } = window
|
|
96
|
+
const { fileTransfers } = store
|
|
97
|
+
const index = findIndex(fileTransfers, t => t.id === itemId)
|
|
98
|
+
if (index < 0) {
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
fileTransfers[index].cancel = true
|
|
102
|
+
store.setFileTransfers(fileTransfers)
|
|
103
|
+
}
|
|
51
104
|
}
|
package/client/store/watch.js
CHANGED
|
@@ -33,14 +33,6 @@ export default store => {
|
|
|
33
33
|
// return store.menuOpened
|
|
34
34
|
// })
|
|
35
35
|
|
|
36
|
-
// autoRun(store, () => {
|
|
37
|
-
// const v = store.getItems('tabs').map(t => {
|
|
38
|
-
// delete t.isTransporting
|
|
39
|
-
// return t
|
|
40
|
-
// })
|
|
41
|
-
// update('sessions', v)
|
|
42
|
-
// return store._tabs
|
|
43
|
-
// }, func => debounce(func, 100))
|
|
44
36
|
for (const name of dbNamesForWatch) {
|
|
45
37
|
autoRun(store, async () => {
|
|
46
38
|
await update(
|