@electerm/electerm-react 1.50.59 → 1.50.66
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/components/batch-op/batch-op.jsx +3 -3
- package/client/components/bookmark-form/render-connection-hopping.jsx +9 -0
- package/client/components/bookmark-form/ssh-form.jsx +3 -0
- package/client/components/bookmark-form/web-form-ui.jsx +11 -2
- package/client/components/footer/batch-input.jsx +96 -20
- package/client/components/footer/batch-item.jsx +33 -0
- package/client/components/footer/footer-entry.jsx +10 -6
- package/client/components/footer/tab-select.jsx +65 -0
- package/client/components/layout/layout.jsx +1 -2
- package/client/components/session/sessions.jsx +1 -0
- package/client/components/terminal/highlight-addon.js +3 -1
- package/client/components/terminal/index.jsx +9 -18
- package/client/components/terminal-info/resource.jsx +9 -0
- package/client/components/web/web-session.jsx +16 -5
- package/client/store/watch.js +13 -13
- package/package.json +1 -1
|
@@ -236,7 +236,7 @@ export default class BatchOp extends PureComponent {
|
|
|
236
236
|
this.tm = setTimeout(() => {
|
|
237
237
|
reject(new Error('timeout'))
|
|
238
238
|
}, 1000 * 60 * 60)
|
|
239
|
-
this.ref1 = autoRun(
|
|
239
|
+
this.ref1 = autoRun(() => {
|
|
240
240
|
const { transferHistory } = store
|
|
241
241
|
const first = transferHistory.find(t => {
|
|
242
242
|
return (t.id === obj.id || t.originalId === obj.id) && t.unzip
|
|
@@ -257,7 +257,7 @@ export default class BatchOp extends PureComponent {
|
|
|
257
257
|
return new Promise((resolve, reject) => {
|
|
258
258
|
document.querySelector('.session-current .type-tab.sftp').click()
|
|
259
259
|
const { store } = window
|
|
260
|
-
this.ref2 = autoRun(
|
|
260
|
+
this.ref2 = autoRun(() => {
|
|
261
261
|
const { tabs } = store
|
|
262
262
|
const last = tabs.find(t => t.id === tab.id)
|
|
263
263
|
if (
|
|
@@ -305,7 +305,7 @@ export default class BatchOp extends PureComponent {
|
|
|
305
305
|
}
|
|
306
306
|
const { store } = window
|
|
307
307
|
store.addTab(tab)
|
|
308
|
-
this.ref = autoRun(
|
|
308
|
+
this.ref = autoRun(() => {
|
|
309
309
|
const { tabs } = store
|
|
310
310
|
const len = tabs.length
|
|
311
311
|
const last = tabs[len - 1]
|
|
@@ -112,6 +112,14 @@ export default function renderConnectionHopping (props) {
|
|
|
112
112
|
}
|
|
113
113
|
]
|
|
114
114
|
|
|
115
|
+
function renderPaths () {
|
|
116
|
+
return [
|
|
117
|
+
'👤',
|
|
118
|
+
...list.map(d => d.host),
|
|
119
|
+
form.getFieldValue('host')
|
|
120
|
+
].join(' -> ')
|
|
121
|
+
}
|
|
122
|
+
|
|
115
123
|
function renderList () {
|
|
116
124
|
return (
|
|
117
125
|
<FormItem {...tailFormItemLayout}>
|
|
@@ -127,6 +135,7 @@ export default function renderConnectionHopping (props) {
|
|
|
127
135
|
}
|
|
128
136
|
})}
|
|
129
137
|
/>
|
|
138
|
+
{renderPaths()}
|
|
130
139
|
</FormItem>
|
|
131
140
|
)
|
|
132
141
|
}
|
|
@@ -158,6 +158,9 @@ export default class BookmarkForm extends PureComponent {
|
|
|
158
158
|
item.host = item.host.trim()
|
|
159
159
|
}
|
|
160
160
|
const obj = item
|
|
161
|
+
if (obj.connectionHoppings?.length) {
|
|
162
|
+
obj.hasHopping = true
|
|
163
|
+
}
|
|
161
164
|
const { addItem, editItem } = this.props.store
|
|
162
165
|
const categoryId = obj.category
|
|
163
166
|
delete obj.category
|
|
@@ -6,7 +6,8 @@ import { useEffect } from 'react'
|
|
|
6
6
|
import {
|
|
7
7
|
Input,
|
|
8
8
|
Form,
|
|
9
|
-
TreeSelect
|
|
9
|
+
TreeSelect,
|
|
10
|
+
Switch
|
|
10
11
|
} from 'antd'
|
|
11
12
|
import { formItemLayout } from '../../common/form-layout'
|
|
12
13
|
import {
|
|
@@ -83,7 +84,7 @@ export default function LocalFormUi (props) {
|
|
|
83
84
|
},
|
|
84
85
|
{
|
|
85
86
|
validator: (_, value) =>
|
|
86
|
-
|
|
87
|
+
/^[a-z\d.+-]+:\/\/[^\s/$.?#].[^\s]*$/i.test(value)
|
|
87
88
|
? Promise.resolve()
|
|
88
89
|
: Promise.reject(new Error(e('URL must start with http:// or https://')))
|
|
89
90
|
}
|
|
@@ -117,6 +118,14 @@ export default function LocalFormUi (props) {
|
|
|
117
118
|
>
|
|
118
119
|
<Input />
|
|
119
120
|
</FormItem>
|
|
121
|
+
<FormItem
|
|
122
|
+
{...formItemLayout}
|
|
123
|
+
label='hideAddressBar'
|
|
124
|
+
name='hideAddressBar'
|
|
125
|
+
valuePropName='checked'
|
|
126
|
+
>
|
|
127
|
+
<Switch />
|
|
128
|
+
</FormItem>
|
|
120
129
|
<FormItem
|
|
121
130
|
{...formItemLayout}
|
|
122
131
|
label='type'
|
|
@@ -5,22 +5,44 @@
|
|
|
5
5
|
import { Component } from 'react'
|
|
6
6
|
import {
|
|
7
7
|
AutoComplete,
|
|
8
|
-
Input
|
|
9
|
-
Switch,
|
|
10
|
-
Tooltip
|
|
8
|
+
Input
|
|
11
9
|
} from 'antd'
|
|
12
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
batchInputLsKey,
|
|
12
|
+
commonActions,
|
|
13
|
+
terminalWebType,
|
|
14
|
+
terminalRdpType,
|
|
15
|
+
terminalVncType
|
|
16
|
+
} from '../../common/constants'
|
|
17
|
+
import TabSelect from './tab-select'
|
|
13
18
|
import postMsg from '../../common/post-msg'
|
|
14
19
|
import classNames from 'classnames'
|
|
15
20
|
|
|
16
21
|
const e = window.translate
|
|
17
22
|
|
|
18
23
|
export default class BatchInput extends Component {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
constructor (props) {
|
|
25
|
+
super(props)
|
|
26
|
+
this.state = {
|
|
27
|
+
cmd: '',
|
|
28
|
+
selectedTabIds: [props.currentTabId],
|
|
29
|
+
open: false,
|
|
30
|
+
enter: false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
componentDidUpdate (prevProps) {
|
|
35
|
+
if (prevProps.currentTabId !== this.props.currentTabId) {
|
|
36
|
+
this.setState(prevState => {
|
|
37
|
+
const newSelectedTabIds = prevState.selectedTabIds.filter(
|
|
38
|
+
id => id !== this.props.currentTabId
|
|
39
|
+
)
|
|
40
|
+
newSelectedTabIds.unshift(this.props.currentTabId)
|
|
41
|
+
return {
|
|
42
|
+
selectedTabIds: newSelectedTabIds
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
|
24
46
|
}
|
|
25
47
|
|
|
26
48
|
componentWillUnmount () {
|
|
@@ -28,12 +50,12 @@ export default class BatchInput extends Component {
|
|
|
28
50
|
}
|
|
29
51
|
|
|
30
52
|
handleEnter = (e) => {
|
|
31
|
-
const { cmd,
|
|
53
|
+
const { cmd, selectedTabIds } = this.state
|
|
32
54
|
if (!cmd.trim()) {
|
|
33
55
|
return
|
|
34
56
|
}
|
|
35
57
|
window.store.addBatchInput(cmd)
|
|
36
|
-
this.props.input(cmd,
|
|
58
|
+
this.props.input(cmd, selectedTabIds)
|
|
37
59
|
this.setState({
|
|
38
60
|
cmd: '',
|
|
39
61
|
open: false
|
|
@@ -41,6 +63,43 @@ export default class BatchInput extends Component {
|
|
|
41
63
|
e.stopPropagation()
|
|
42
64
|
}
|
|
43
65
|
|
|
66
|
+
onSelectAll = () => {
|
|
67
|
+
this.setState({
|
|
68
|
+
selectedTabIds: this.getTabs().map(tab => tab.id)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
onSelectNone = () => {
|
|
73
|
+
this.setState({
|
|
74
|
+
selectedTabIds: [this.props.currentTabId]
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
filterValidTabIds = (tabIds) => {
|
|
79
|
+
return tabIds.filter(id => {
|
|
80
|
+
return this.props.tabs.some(tab => tab.id === id)
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
onSelect = (id) => {
|
|
85
|
+
this.setState(prevState => {
|
|
86
|
+
const selectedTabIds = prevState.selectedTabIds.includes(id)
|
|
87
|
+
? prevState.selectedTabIds.filter(tabId => tabId !== id)
|
|
88
|
+
: [...prevState.selectedTabIds, id]
|
|
89
|
+
|
|
90
|
+
// Ensure at least the current tab is selected
|
|
91
|
+
if (selectedTabIds.length === 0) {
|
|
92
|
+
return {
|
|
93
|
+
selectedTabIds: [this.props.currentTabId]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
selectedTabIds
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
44
103
|
handleChange = (v = '') => {
|
|
45
104
|
let vv = v.replace(/^\d+:/, '').replace(/\n$/, '')
|
|
46
105
|
if (vv === batchInputLsKey) {
|
|
@@ -58,7 +117,8 @@ export default class BatchInput extends Component {
|
|
|
58
117
|
|
|
59
118
|
handleClick = () => {
|
|
60
119
|
this.setState({
|
|
61
|
-
open: true
|
|
120
|
+
open: true,
|
|
121
|
+
selectedTabIds: this.filterValidTabIds(this.state.selectedTabIds)
|
|
62
122
|
})
|
|
63
123
|
}
|
|
64
124
|
|
|
@@ -116,8 +176,22 @@ export default class BatchInput extends Component {
|
|
|
116
176
|
this.timer = setTimeout(this.leave, 5000)
|
|
117
177
|
}
|
|
118
178
|
|
|
179
|
+
getTabs = () => {
|
|
180
|
+
const { currentTabId } = this.props
|
|
181
|
+
return this.props.tabs.filter(tab => {
|
|
182
|
+
return tab.type !== terminalWebType &&
|
|
183
|
+
tab.type !== terminalRdpType &&
|
|
184
|
+
tab.type !== terminalVncType
|
|
185
|
+
}).sort((a, b) => {
|
|
186
|
+
// Current tab goes first
|
|
187
|
+
if (a.id === currentTabId) return -1
|
|
188
|
+
if (b.id === currentTabId) return 1
|
|
189
|
+
return 0
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
|
|
119
193
|
render () {
|
|
120
|
-
const { cmd, open,
|
|
194
|
+
const { cmd, open, selectedTabIds, enter } = this.state
|
|
121
195
|
const opts = {
|
|
122
196
|
options: this.buildOptions(),
|
|
123
197
|
placeholder: e('batchInput'),
|
|
@@ -139,6 +213,14 @@ export default class BatchInput extends Component {
|
|
|
139
213
|
placeholder: e('batchInput'),
|
|
140
214
|
className: 'batch-input-holder'
|
|
141
215
|
}
|
|
216
|
+
const tabSelectProps = {
|
|
217
|
+
currentTabId: this.props.currentTabId,
|
|
218
|
+
tabs: this.getTabs(),
|
|
219
|
+
selectedTabIds,
|
|
220
|
+
onSelectAll: this.onSelectAll,
|
|
221
|
+
onSelectNone: this.onSelectNone,
|
|
222
|
+
onSelect: this.onSelect
|
|
223
|
+
}
|
|
142
224
|
return (
|
|
143
225
|
<span
|
|
144
226
|
className={cls}
|
|
@@ -162,13 +244,7 @@ export default class BatchInput extends Component {
|
|
|
162
244
|
autoSize={{ minRows: 1 }}
|
|
163
245
|
/>
|
|
164
246
|
</AutoComplete>
|
|
165
|
-
<
|
|
166
|
-
<Switch
|
|
167
|
-
className='mg1l'
|
|
168
|
-
checked={toAll}
|
|
169
|
-
onChange={this.handleChangeAll}
|
|
170
|
-
/>
|
|
171
|
-
</Tooltip>
|
|
247
|
+
<TabSelect {...tabSelectProps} />
|
|
172
248
|
</span>
|
|
173
249
|
</span>
|
|
174
250
|
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button
|
|
3
|
+
} from 'antd'
|
|
4
|
+
import {
|
|
5
|
+
CheckCircleOutlined
|
|
6
|
+
} from '@ant-design/icons'
|
|
7
|
+
import createName from '../../common/create-title'
|
|
8
|
+
|
|
9
|
+
export default function BatchInputTabItem (props) {
|
|
10
|
+
function handleSelect (id) {
|
|
11
|
+
props.onSelect(
|
|
12
|
+
props.id
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const { tab, selected, isCurrent } = props
|
|
17
|
+
const title = createName(tab)
|
|
18
|
+
const btnProps = {
|
|
19
|
+
className: 'mg1r mg1b iblock',
|
|
20
|
+
onClick: handleSelect,
|
|
21
|
+
title,
|
|
22
|
+
type: selected ? 'primary' : 'default'
|
|
23
|
+
}
|
|
24
|
+
const icon = selected ? <CheckCircleOutlined className='mg1r' /> : null
|
|
25
|
+
const pre = isCurrent ? <b>*</b> : ''
|
|
26
|
+
return (
|
|
27
|
+
<Button
|
|
28
|
+
{...btnProps}
|
|
29
|
+
>
|
|
30
|
+
{pre} {icon} {tab.tabCount}. {title}
|
|
31
|
+
</Button>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -26,11 +26,10 @@ export default auto(function FooterEntry (props) {
|
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function batchInput (cmd,
|
|
29
|
+
function batchInput (cmd, selectedTabIds) {
|
|
30
30
|
postMessage({
|
|
31
31
|
action: terminalActions.batchInput,
|
|
32
|
-
|
|
33
|
-
toAll,
|
|
32
|
+
selectedTabIds,
|
|
34
33
|
cmd
|
|
35
34
|
})
|
|
36
35
|
}
|
|
@@ -55,11 +54,16 @@ export default auto(function FooterEntry (props) {
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
function renderBatchInputs () {
|
|
57
|
+
const batchProps = {
|
|
58
|
+
input: batchInput,
|
|
59
|
+
batchInputs: props.store.batchInputs,
|
|
60
|
+
tabs: props.store.tabs,
|
|
61
|
+
currentTabId: props.store.currentTabId
|
|
62
|
+
}
|
|
58
63
|
return (
|
|
59
64
|
<div className='terminal-footer-unit terminal-footer-center'>
|
|
60
65
|
<BatchInput
|
|
61
|
-
|
|
62
|
-
batchInputs={props.store.batchInputs}
|
|
66
|
+
{...batchProps}
|
|
63
67
|
/>
|
|
64
68
|
</div>
|
|
65
69
|
)
|
|
@@ -79,7 +83,7 @@ export default auto(function FooterEntry (props) {
|
|
|
79
83
|
minWidth: 30
|
|
80
84
|
},
|
|
81
85
|
placeholder: e('encode'),
|
|
82
|
-
defaultValue: props.currentTab?.encode,
|
|
86
|
+
defaultValue: props.store.currentTab?.encode,
|
|
83
87
|
onSelect: handleSwitchEncoding,
|
|
84
88
|
size: 'small',
|
|
85
89
|
popupMatchSelectWidth: false
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Popover
|
|
3
|
+
} from 'antd'
|
|
4
|
+
import TabItem from './batch-item'
|
|
5
|
+
import {
|
|
6
|
+
CodeOutlined
|
|
7
|
+
} from '@ant-design/icons'
|
|
8
|
+
|
|
9
|
+
export default function TabSelect (props) {
|
|
10
|
+
const { selectedTabIds, tabs, currentTabId } = props
|
|
11
|
+
function renderTabs () {
|
|
12
|
+
return tabs.map(tab => {
|
|
13
|
+
const selected = selectedTabIds.includes(tab.id)
|
|
14
|
+
const itemProps = {
|
|
15
|
+
tab,
|
|
16
|
+
selected,
|
|
17
|
+
onSelect: props.onSelect,
|
|
18
|
+
id: tab.id,
|
|
19
|
+
isCurrent: tab.id === currentTabId
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
<TabItem
|
|
23
|
+
key={tab.id}
|
|
24
|
+
{...itemProps}
|
|
25
|
+
/>
|
|
26
|
+
)
|
|
27
|
+
})
|
|
28
|
+
}
|
|
29
|
+
function renderBtns () {
|
|
30
|
+
return (
|
|
31
|
+
<div className='pd1t pd2b font12'>
|
|
32
|
+
<span
|
|
33
|
+
className='mg1r pointer'
|
|
34
|
+
onClick={props.onSelectAll}
|
|
35
|
+
>
|
|
36
|
+
All
|
|
37
|
+
</span>
|
|
38
|
+
<span
|
|
39
|
+
className='pointer'
|
|
40
|
+
onClick={props.onSelectNone}
|
|
41
|
+
>
|
|
42
|
+
None
|
|
43
|
+
</span>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
function renderContent () {
|
|
48
|
+
return (
|
|
49
|
+
<div className='pd1x'>
|
|
50
|
+
{renderBtns()}
|
|
51
|
+
{renderTabs()}
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
return (
|
|
56
|
+
<Popover
|
|
57
|
+
content={renderContent()}
|
|
58
|
+
trigger='click'
|
|
59
|
+
>
|
|
60
|
+
<span className='pointer iblock pd1x'>
|
|
61
|
+
({selectedTabIds.length}) <CodeOutlined />
|
|
62
|
+
</span>
|
|
63
|
+
</Popover>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
@@ -37,7 +37,9 @@ export class KeywordHighlighterAddon {
|
|
|
37
37
|
if (keyword) {
|
|
38
38
|
try {
|
|
39
39
|
const regex = new RegExp(`(${keyword})`, 'gi')
|
|
40
|
-
|
|
40
|
+
if (regex.test(text)) {
|
|
41
|
+
return text.replace(regex, this.colorize(color))
|
|
42
|
+
}
|
|
41
43
|
} catch (e) {
|
|
42
44
|
window.store.onError(e)
|
|
43
45
|
}
|
|
@@ -329,15 +329,15 @@ clear\r`
|
|
|
329
329
|
addTimeStampToTermLog,
|
|
330
330
|
type,
|
|
331
331
|
cmd,
|
|
332
|
+
selectedTabIds = [],
|
|
332
333
|
currentTabId,
|
|
333
334
|
pid,
|
|
334
|
-
toAll,
|
|
335
335
|
inputOnly,
|
|
336
336
|
zoomValue
|
|
337
337
|
} = e?.data || {}
|
|
338
338
|
|
|
339
339
|
const { id: currentTabIdProp } = this.props.tab
|
|
340
|
-
const tabIdMatch = currentTabId === currentTabIdProp
|
|
340
|
+
const tabIdMatch = selectedTabIds.includes(currentTabIdProp) || currentTabId === currentTabIdProp
|
|
341
341
|
if (
|
|
342
342
|
action === terminalActions.zoom &&
|
|
343
343
|
tabIdMatch
|
|
@@ -349,10 +349,7 @@ clear\r`
|
|
|
349
349
|
) {
|
|
350
350
|
this.switchEncoding(encode)
|
|
351
351
|
} else if (
|
|
352
|
-
action === terminalActions.batchInput &&
|
|
353
|
-
(
|
|
354
|
-
toAll || tabIdMatch
|
|
355
|
-
)
|
|
352
|
+
action === terminalActions.batchInput && tabIdMatch
|
|
356
353
|
) {
|
|
357
354
|
this.batchInput(cmd)
|
|
358
355
|
} else if (
|
|
@@ -1220,22 +1217,16 @@ clear\r`
|
|
|
1220
1217
|
if (pick(term, 'buffer._onBufferChange._listeners')) {
|
|
1221
1218
|
term.buffer._onBufferChange._listeners.push(this.onBufferChange)
|
|
1222
1219
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
this.fitAddon.fit()
|
|
1230
|
-
term.loadAddon(this.zmodemAddon)
|
|
1231
|
-
term.zmodemAttach(this)
|
|
1232
|
-
}
|
|
1220
|
+
term.loadAddon(new WebLinksAddon(this.webLinkHandler))
|
|
1221
|
+
term.focus()
|
|
1222
|
+
this.zmodemAddon = new AddonZmodem()
|
|
1223
|
+
this.fitAddon.fit()
|
|
1224
|
+
term.loadAddon(this.zmodemAddon)
|
|
1225
|
+
term.zmodemAttach(this)
|
|
1233
1226
|
term.displayRaw = displayRaw
|
|
1234
1227
|
term.loadAddon(
|
|
1235
1228
|
new KeywordHighlighterAddon(keywords)
|
|
1236
1229
|
)
|
|
1237
|
-
window.store.triggerResize()
|
|
1238
|
-
window.store.focus()
|
|
1239
1230
|
}
|
|
1240
1231
|
|
|
1241
1232
|
onResize = throttle(() => {
|
|
@@ -34,6 +34,13 @@ export default function TerminalInfoResource (props) {
|
|
|
34
34
|
) {
|
|
35
35
|
return null
|
|
36
36
|
}
|
|
37
|
+
function getColorForPercent (percent) {
|
|
38
|
+
if (percent >= 90) return '#ff4d4f'
|
|
39
|
+
if (percent >= 70) return '#faad14'
|
|
40
|
+
if (percent >= 50) return '#1890ff'
|
|
41
|
+
return '#52c41a'
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
function renderItem (obj) {
|
|
38
45
|
if (isEmpty(obj)) {
|
|
39
46
|
return <div className='pd1b' key={obj.name}>NA</div>
|
|
@@ -48,6 +55,7 @@ export default function TerminalInfoResource (props) {
|
|
|
48
55
|
const p = hasPercent
|
|
49
56
|
? percent
|
|
50
57
|
: computePercent(used, total) || 0
|
|
58
|
+
const color = getColorForPercent(p)
|
|
51
59
|
const fmt = hasPercent
|
|
52
60
|
? (p) => `${name}: ${p || ''}%`
|
|
53
61
|
: (p) => `${name}: ${p || ''}%(${used || ''}/${total || ''})`
|
|
@@ -57,6 +65,7 @@ export default function TerminalInfoResource (props) {
|
|
|
57
65
|
style={{ width: '50%' }}
|
|
58
66
|
percent={p}
|
|
59
67
|
format={fmt}
|
|
68
|
+
strokeColor={color}
|
|
60
69
|
/>
|
|
61
70
|
</div>
|
|
62
71
|
)
|
|
@@ -8,8 +8,9 @@ export default function WebSession (props) {
|
|
|
8
8
|
height,
|
|
9
9
|
reloadTab
|
|
10
10
|
} = props
|
|
11
|
-
const urlRegex = /^
|
|
12
|
-
|
|
11
|
+
const urlRegex = /^[a-z\d.+-]+:\/\/[^\s/$.?#].[^\s]*$/i
|
|
12
|
+
|
|
13
|
+
const { url = '' } = tab
|
|
13
14
|
const addrProps = {
|
|
14
15
|
url,
|
|
15
16
|
title: tab.title,
|
|
@@ -46,12 +47,20 @@ export default function WebSession (props) {
|
|
|
46
47
|
// }, [])
|
|
47
48
|
|
|
48
49
|
function renderView () {
|
|
50
|
+
if (!urlRegex.test(tab.url)) {
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
URL: <b>{url}</b> not valid
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
const hOffset = tab.hideAddressBar ? 30 : -12
|
|
49
58
|
if (window.et.isWebApp) {
|
|
50
59
|
const iframeProps = {
|
|
51
60
|
src: url,
|
|
52
61
|
style: {
|
|
53
62
|
width: (width - 10) + 'px',
|
|
54
|
-
height: (height
|
|
63
|
+
height: (height + hOffset) + 'px'
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
return (
|
|
@@ -62,7 +71,7 @@ export default function WebSession (props) {
|
|
|
62
71
|
src: url,
|
|
63
72
|
style: {
|
|
64
73
|
width: (width - 10) + 'px',
|
|
65
|
-
height: (height
|
|
74
|
+
height: (height + hOffset) + 'px'
|
|
66
75
|
},
|
|
67
76
|
disableblinkfeatures: 'true',
|
|
68
77
|
disablewebsecurity: 'true',
|
|
@@ -76,7 +85,9 @@ export default function WebSession (props) {
|
|
|
76
85
|
|
|
77
86
|
return (
|
|
78
87
|
<div className='web-session-wrap'>
|
|
79
|
-
|
|
88
|
+
{!tab.hideAddressBar && (
|
|
89
|
+
<AddressBar {...addrProps} />
|
|
90
|
+
)}
|
|
80
91
|
<div className='pd1'>
|
|
81
92
|
{renderView()}
|
|
82
93
|
</div>
|
package/client/store/watch.js
CHANGED
|
@@ -18,14 +18,14 @@ import * as ls from '../common/safe-local-storage'
|
|
|
18
18
|
import { debounce, isEmpty } from 'lodash-es'
|
|
19
19
|
|
|
20
20
|
export default store => {
|
|
21
|
-
// autoRun(
|
|
21
|
+
// autoRun(() => {
|
|
22
22
|
// store.focus()
|
|
23
23
|
// // store.termSearchOpen = false
|
|
24
24
|
// store.termSearchMatchCount = 0
|
|
25
25
|
// return store.currentTabId
|
|
26
26
|
// }).start()
|
|
27
27
|
|
|
28
|
-
// autoRun(
|
|
28
|
+
// autoRun(() => {
|
|
29
29
|
// if (store.menuOpened) {
|
|
30
30
|
// store.initMenuEvent()
|
|
31
31
|
// } else {
|
|
@@ -35,7 +35,7 @@ export default store => {
|
|
|
35
35
|
// })
|
|
36
36
|
|
|
37
37
|
for (const name of dbNamesForWatch) {
|
|
38
|
-
autoRun(
|
|
38
|
+
autoRun(async () => {
|
|
39
39
|
await update(
|
|
40
40
|
`${name}:order`,
|
|
41
41
|
store.getItems(name).map(d => d.id)
|
|
@@ -48,12 +48,12 @@ export default store => {
|
|
|
48
48
|
}, func => debounce(func, 100)).start()
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
autoRun(
|
|
51
|
+
autoRun(async () => {
|
|
52
52
|
ls.setItem(resolutionsLsKey, store._resolutions)
|
|
53
53
|
return store._resolutions
|
|
54
54
|
}).start()
|
|
55
55
|
|
|
56
|
-
autoRun(
|
|
56
|
+
autoRun(() => {
|
|
57
57
|
if (!store.showModal) {
|
|
58
58
|
store.focus()
|
|
59
59
|
} else {
|
|
@@ -62,44 +62,44 @@ export default store => {
|
|
|
62
62
|
return store.showModal
|
|
63
63
|
}).start()
|
|
64
64
|
|
|
65
|
-
autoRun(
|
|
65
|
+
autoRun(() => {
|
|
66
66
|
if (!isEmpty(store.config)) {
|
|
67
67
|
window.pre.runGlobalAsync('saveUserConfig', store.config)
|
|
68
68
|
}
|
|
69
69
|
return store._config
|
|
70
70
|
}, func => debounce(func, 100)).start()
|
|
71
71
|
|
|
72
|
-
autoRun(
|
|
72
|
+
autoRun(() => {
|
|
73
73
|
store.updateLastDataUpdateTime()
|
|
74
74
|
return store.config.theme
|
|
75
75
|
}, func => debounce(func, 100)).start()
|
|
76
76
|
|
|
77
|
-
autoRun(
|
|
77
|
+
autoRun(() => {
|
|
78
78
|
store.updateTabsStatus()
|
|
79
79
|
return store.fileTransfers
|
|
80
80
|
}, func => debounce(func, 100)).start()
|
|
81
81
|
|
|
82
|
-
autoRun(
|
|
82
|
+
autoRun(() => {
|
|
83
83
|
ls.setItemJSON(sftpDefaultSortSettingKey, store.sftpSortSetting)
|
|
84
84
|
return store._sftpSortSetting
|
|
85
85
|
}).start()
|
|
86
86
|
|
|
87
|
-
autoRun(
|
|
87
|
+
autoRun(() => {
|
|
88
88
|
ls.setItemJSON(expandedKeysLsKey, store.expandedKeys)
|
|
89
89
|
return store._expandedKeys
|
|
90
90
|
}).start()
|
|
91
91
|
|
|
92
|
-
autoRun(
|
|
92
|
+
autoRun(() => {
|
|
93
93
|
ls.setItemJSON(localAddrBookmarkLsKey, store.addressBookmarksLocal)
|
|
94
94
|
return store._addressBookmarksLocal
|
|
95
95
|
}).start()
|
|
96
96
|
|
|
97
|
-
autoRun(
|
|
97
|
+
autoRun(() => {
|
|
98
98
|
ls.setItemJSON(checkedKeysLsKey, store.checkedKeys)
|
|
99
99
|
return store._checkedKeys
|
|
100
100
|
}).start()
|
|
101
101
|
|
|
102
|
-
autoRun(
|
|
102
|
+
autoRun(() => {
|
|
103
103
|
const tabs = store.getTabs()
|
|
104
104
|
const { currentTabId } = store
|
|
105
105
|
const tab = tabs.find(t => t.id === currentTabId)
|