@electerm/electerm-react 1.50.46 → 1.50.65

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.
@@ -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(store, () => {
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(store, () => {
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(store, () => {
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 {
@@ -76,6 +77,18 @@ export default function LocalFormUi (props) {
76
77
  hasFeedback
77
78
  name='url'
78
79
  required
80
+ rules={[
81
+ {
82
+ required: true,
83
+ message: e('Please input URL')
84
+ },
85
+ {
86
+ validator: (_, value) =>
87
+ /^[a-z\d.+-]+:\/\/[^\s/$.?#].[^\s]*$/i.test(value)
88
+ ? Promise.resolve()
89
+ : Promise.reject(new Error(e('URL must start with http:// or https://')))
90
+ }
91
+ ]}
79
92
  >
80
93
  <Input />
81
94
  </FormItem>
@@ -98,6 +111,21 @@ export default function LocalFormUi (props) {
98
111
  showSearch
99
112
  />
100
113
  </FormItem>
114
+ <FormItem
115
+ {...formItemLayout}
116
+ label={e('useragent')}
117
+ name='useragent'
118
+ >
119
+ <Input />
120
+ </FormItem>
121
+ <FormItem
122
+ {...formItemLayout}
123
+ label='hideAddressBar'
124
+ name='hideAddressBar'
125
+ valuePropName='checked'
126
+ >
127
+ <Switch />
128
+ </FormItem>
101
129
  <FormItem
102
130
  {...formItemLayout}
103
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 { batchInputLsKey, commonActions } from '../../common/constants'
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
- state = {
20
- cmd: '',
21
- toAll: false,
22
- open: false,
23
- enter: false
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, toAll } = this.state
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, toAll)
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, toAll, enter } = this.state
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
- <Tooltip title={e('runInAllTerminals')}>
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, toAll) {
29
+ function batchInput (cmd, selectedTabIds) {
30
30
  postMessage({
31
31
  action: terminalActions.batchInput,
32
- currentTabId: props.store.currentTabId,
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
- input={batchInput}
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
+ }
@@ -133,8 +133,7 @@ export default auto(function Layout (props) {
133
133
  ])
134
134
  }
135
135
  const footerProps = {
136
- store,
137
- currentTab
136
+ store
138
137
  }
139
138
  const qmProps = pick(store, [
140
139
  'quickCommandTags',
@@ -5,7 +5,6 @@ import { findIndex, pick } from 'lodash-es'
5
5
  import classNames from 'classnames'
6
6
  import generate from '../../common/id-with-stamp'
7
7
  import copy from 'json-deep-copy'
8
- import wait from '../../common/wait.js'
9
8
  import Tabs from '../tabs/index.jsx'
10
9
  import {
11
10
  tabActions,
@@ -146,7 +145,7 @@ class Sessions extends Component {
146
145
  })
147
146
  }
148
147
 
149
- addTab = (_tab, _index) => {
148
+ addTab = (_tab, _index, callback) => {
150
149
  this.setState((oldState) => {
151
150
  const tabs = copy(oldState.tabs)
152
151
  const index = typeof _index === 'undefined'
@@ -167,6 +166,9 @@ class Sessions extends Component {
167
166
  }, () => {
168
167
  this.updateStoreTabs(this.state.tabs)
169
168
  this.updateStoreCurrentTabId(this.state.currentTabId)
169
+ if (callback) {
170
+ callback()
171
+ }
170
172
  })
171
173
  }
172
174
 
@@ -207,42 +209,39 @@ class Sessions extends Component {
207
209
  window.store.currentTabId = this.state.currentTabId
208
210
  }
209
211
 
210
- reloadTab = async (tabToReload) => {
211
- this.setState(async oldState => {
212
- const tab = copy(
213
- tabToReload
214
- )
215
- tab.pane = paneMap.terminal
216
- const { id } = tab
217
- const tabs = copy(oldState.tabs)
218
- tab.id = generate()
219
- tab.status = statusMap.processing
220
- const index = findIndex(tabs, t => t.id === id)
221
- this.addTab(tab, index)
222
- await wait(30)
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
223
  this.delTab(id)
224
+ this.onChangeTabId(tab.id)
224
225
  })
225
226
  }
226
227
 
227
228
  onDuplicateTab = (tabToDup) => {
228
- this.setState(oldState => {
229
- const defaultStatus = statusMap.processing
230
- let tab = copy(tabToDup)
231
- updateCount(tab)
232
- const tabs = copy(oldState.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
- })
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)
246
245
  }
247
246
 
248
247
  onChangeTabId = id => {
@@ -37,7 +37,9 @@ export class KeywordHighlighterAddon {
37
37
  if (keyword) {
38
38
  try {
39
39
  const regex = new RegExp(`(${keyword})`, 'gi')
40
- text = text.replace(regex, this.colorize(color))
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,14 @@ clear\r`
329
329
  addTimeStampToTermLog,
330
330
  type,
331
331
  cmd,
332
- currentTabId,
332
+ selectedTabIds = [],
333
333
  pid,
334
- toAll,
335
334
  inputOnly,
336
335
  zoomValue
337
336
  } = e?.data || {}
338
337
 
339
338
  const { id: currentTabIdProp } = this.props.tab
340
- const tabIdMatch = currentTabId === currentTabIdProp
339
+ const tabIdMatch = selectedTabIds.includes(currentTabIdProp)
341
340
  if (
342
341
  action === terminalActions.zoom &&
343
342
  tabIdMatch
@@ -351,7 +350,7 @@ clear\r`
351
350
  } else if (
352
351
  action === terminalActions.batchInput &&
353
352
  (
354
- toAll || tabIdMatch
353
+ tabIdMatch
355
354
  )
356
355
  ) {
357
356
  this.batchInput(cmd)
@@ -1220,22 +1219,16 @@ clear\r`
1220
1219
  if (pick(term, 'buffer._onBufferChange._listeners')) {
1221
1220
  term.buffer._onBufferChange._listeners.push(this.onBufferChange)
1222
1221
  }
1223
- const cid = this.props.currentTabId
1224
- const tid = this.props.tab.id
1225
- if (cid === tid && this.props.tab.status === statusMap.success) {
1226
- term.loadAddon(new WebLinksAddon(this.webLinkHandler))
1227
- term.focus()
1228
- this.zmodemAddon = new AddonZmodem()
1229
- this.fitAddon.fit()
1230
- term.loadAddon(this.zmodemAddon)
1231
- term.zmodemAttach(this)
1232
- }
1222
+ term.loadAddon(new WebLinksAddon(this.webLinkHandler))
1223
+ term.focus()
1224
+ this.zmodemAddon = new AddonZmodem()
1225
+ this.fitAddon.fit()
1226
+ term.loadAddon(this.zmodemAddon)
1227
+ term.zmodemAttach(this)
1233
1228
  term.displayRaw = displayRaw
1234
1229
  term.loadAddon(
1235
1230
  new KeywordHighlighterAddon(keywords)
1236
1231
  )
1237
- window.store.triggerResize()
1238
- window.store.focus()
1239
1232
  }
1240
1233
 
1241
1234
  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
  )
@@ -1,4 +1,5 @@
1
1
  import AddressBar from './address-bar'
2
+ // import React, { useEffect } from 'react'
2
3
 
3
4
  export default function WebSession (props) {
4
5
  const {
@@ -7,8 +8,11 @@ export default function WebSession (props) {
7
8
  height,
8
9
  reloadTab
9
10
  } = props
11
+ const urlRegex = /^[a-z\d.+-]+:\/\/[^\s/$.?#].[^\s]*$/i
12
+
13
+ const { url = '' } = tab
10
14
  const addrProps = {
11
- url: tab.url,
15
+ url,
12
16
  title: tab.title,
13
17
  description: tab.description,
14
18
  onOpen: () => {
@@ -20,22 +24,72 @@ export default function WebSession (props) {
20
24
  )
21
25
  }
22
26
  }
23
- const viewProps = {
24
- src: tab.url,
25
- style: {
26
- width: (width - 10) + 'px',
27
- height: (height - 12) + 'px'
28
- },
29
- disableblinkfeatures: 'true',
30
- disablewebsecurity: 'true'
27
+
28
+ // TODO: 支持自定义Header和Cookie
29
+ // useEffect(() => {
30
+ // const webview = document.querySelector('webview')
31
+ // if (webview) {
32
+ // // 添加事件监听,输出所有的事件
33
+ // webview.addEventListener('did-start-loading', (e) => {
34
+ // console.log('did-start-loading', e)
35
+ // })
36
+ // }
37
+ // }, []);
38
+
39
+ // 打开webview的开发者工具
40
+ // useEffect(() => {
41
+ // const webview = document.querySelector('webview')
42
+ // if (webview) {
43
+ // webview.addEventListener('dom-ready', () => {
44
+ // webview.openDevTools()
45
+ // })
46
+ // }
47
+ // }, [])
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
58
+ if (window.et.isWebApp) {
59
+ const iframeProps = {
60
+ src: url,
61
+ style: {
62
+ width: (width - 10) + 'px',
63
+ height: (height + hOffset) + 'px'
64
+ }
65
+ }
66
+ return (
67
+ <iframe {...iframeProps} />
68
+ )
69
+ }
70
+ const viewProps = {
71
+ src: url,
72
+ style: {
73
+ width: (width - 10) + 'px',
74
+ height: (height + hOffset) + 'px'
75
+ },
76
+ disableblinkfeatures: 'true',
77
+ disablewebsecurity: 'true',
78
+ allowpopups: 'true',
79
+ useragent: tab.useragent || 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
80
+ }
81
+ return (
82
+ <webview {...viewProps} />
83
+ )
31
84
  }
85
+
32
86
  return (
33
87
  <div className='web-session-wrap'>
34
- <AddressBar {...addrProps} />
88
+ {!tab.hideAddressBar && (
89
+ <AddressBar {...addrProps} />
90
+ )}
35
91
  <div className='pd1'>
36
- <webview
37
- {...viewProps}
38
- />
92
+ {renderView()}
39
93
  </div>
40
94
  </div>
41
95
  )
@@ -1,7 +1,7 @@
1
1
  import { createRoot } from 'react-dom/client'
2
2
  import 'antd/dist/reset.css'
3
3
  import '@xterm/xterm/css/xterm.css'
4
- import '../common/trzsz'
4
+ import '../common/trzsz.js'
5
5
  import 'firacode/distr/fira_code.css'
6
6
  import Main from '../components/main/index.jsx'
7
7
 
@@ -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(store, () => {
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(store, () => {
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(store, async () => {
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(store, async () => {
51
+ autoRun(async () => {
52
52
  ls.setItem(resolutionsLsKey, store._resolutions)
53
53
  return store._resolutions
54
54
  }).start()
55
55
 
56
- autoRun(store, () => {
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(store, () => {
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(store, () => {
72
+ autoRun(() => {
73
73
  store.updateLastDataUpdateTime()
74
74
  return store.config.theme
75
75
  }, func => debounce(func, 100)).start()
76
76
 
77
- autoRun(store, () => {
77
+ autoRun(() => {
78
78
  store.updateTabsStatus()
79
79
  return store.fileTransfers
80
80
  }, func => debounce(func, 100)).start()
81
81
 
82
- autoRun(store, () => {
82
+ autoRun(() => {
83
83
  ls.setItemJSON(sftpDefaultSortSettingKey, store.sftpSortSetting)
84
84
  return store._sftpSortSetting
85
85
  }).start()
86
86
 
87
- autoRun(store, () => {
87
+ autoRun(() => {
88
88
  ls.setItemJSON(expandedKeysLsKey, store.expandedKeys)
89
89
  return store._expandedKeys
90
90
  }).start()
91
91
 
92
- autoRun(store, () => {
92
+ autoRun(() => {
93
93
  ls.setItemJSON(localAddrBookmarkLsKey, store.addressBookmarksLocal)
94
94
  return store._addressBookmarksLocal
95
95
  }).start()
96
96
 
97
- autoRun(store, () => {
97
+ autoRun(() => {
98
98
  ls.setItemJSON(checkedKeysLsKey, store.checkedKeys)
99
99
  return store._checkedKeys
100
100
  }).start()
101
101
 
102
- autoRun(store, () => {
102
+ autoRun(() => {
103
103
  const tabs = store.getTabs()
104
104
  const { currentTabId } = store
105
105
  const tab = tabs.find(t => t.id === currentTabId)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electerm/electerm-react",
3
- "version": "1.50.46",
3
+ "version": "1.50.65",
4
4
  "description": "react components src for electerm",
5
5
  "main": "./client/components/main/main.jsx",
6
6
  "license": "MIT",