@electerm/electerm-react 3.15.160 → 3.15.163
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 +1 -0
- package/client/common/update-check.js +27 -6
- package/client/components/main/upgrade.jsx +9 -1
- package/client/components/sftp/address-bar.jsx +39 -5
- package/client/components/sftp/list-table-ui.jsx +19 -2
- package/client/components/sftp/sftp-entry.jsx +1 -1
- package/client/components/sftp/sftp.styl +14 -0
- package/client/components/tree-list/tree-list.jsx +5 -2
- package/client/css/mobile.styl +19 -0
- package/package.json +1 -1
|
@@ -251,6 +251,7 @@ export const checkedKeysLsKey = 'checked-keys'
|
|
|
251
251
|
export const quickCommandLabelsLsKey = 'quick-command-label'
|
|
252
252
|
export const localAddrBookmarkLsKey = 'local-addr-bookmark-keys'
|
|
253
253
|
export const dismissDelKeyTipLsKey = 'dismiss-del-key-tip'
|
|
254
|
+
export const treeSortLsKey = 'tree-sort'
|
|
254
255
|
export const sshTunnelHelpLink = 'https://github.com/electerm/electerm/wiki/How-to-use-ssh-tunnel'
|
|
255
256
|
export const proxyHelpLink = 'https://github.com/electerm/electerm/wiki/proxy-format'
|
|
256
257
|
export const regexHelpLink = 'https://github.com/electerm/electerm/wiki/Terminal-keywords-highlight-regular-expression-exmaples'
|
|
@@ -69,6 +69,23 @@ export async function getLatestReleaseVersion (n) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
export function getDownloadUrl (browserDownloadUrl, mirror) {
|
|
73
|
+
if (!browserDownloadUrl) {
|
|
74
|
+
return ''
|
|
75
|
+
}
|
|
76
|
+
if (mirror === 'gh-proxy') {
|
|
77
|
+
return `https://electerm-mirror.html5beta.com/${browserDownloadUrl}`
|
|
78
|
+
} if (mirror === 'sourceforge') {
|
|
79
|
+
const arr = browserDownloadUrl.split('/')
|
|
80
|
+
const len = arr.length
|
|
81
|
+
return `https://master.dl.sourceforge.net/project/electerm.mirror/${arr[len - 2]}/${arr[len - 1]}?viasf=1`
|
|
82
|
+
} else if (mirror === 'r2') {
|
|
83
|
+
return `https://electerm-store.html5beta.com/r/${browserDownloadUrl.split('/').pop()}`
|
|
84
|
+
} else {
|
|
85
|
+
return browserDownloadUrl
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
72
89
|
export async function getLatestReleaseInfo () {
|
|
73
90
|
let url = `${baseUpdateCheckUrls[0]}/data/electerm-github-release.json`
|
|
74
91
|
let res = await getInfo(url)
|
|
@@ -76,10 +93,14 @@ export async function getLatestReleaseInfo () {
|
|
|
76
93
|
url = `${baseUpdateCheckUrls[1]}/data/electerm-github-release.json`
|
|
77
94
|
res = await getInfo(url)
|
|
78
95
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
if (!res || !res.release) {
|
|
97
|
+
return undefined
|
|
98
|
+
}
|
|
99
|
+
const { installSrc } = window.store
|
|
100
|
+
const asset = (res.release.assets || []).find(r => r.name.includes(installSrc))
|
|
101
|
+
return {
|
|
102
|
+
body: res.release.body,
|
|
103
|
+
date: dayjs(res.release.published_at).format('YYYY-MM-DD'),
|
|
104
|
+
browserDownloadUrl: asset ? asset.browser_download_url : ''
|
|
105
|
+
}
|
|
85
106
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PureComponent } from 'react'
|
|
2
2
|
import { CloseOutlined, MinusSquareOutlined, UpCircleOutlined } from '@ant-design/icons'
|
|
3
3
|
import { Button, Select, Space } from 'antd'
|
|
4
|
-
import { getLatestReleaseInfo, getLatestReleaseVersion } from '../../common/update-check'
|
|
4
|
+
import { getLatestReleaseInfo, getLatestReleaseVersion, getDownloadUrl } from '../../common/update-check'
|
|
5
5
|
import upgrade from '../../common/upgrade'
|
|
6
6
|
import compare from '../../common/version-compare'
|
|
7
7
|
import Link from '../common/external-link'
|
|
@@ -136,6 +136,14 @@ export default class Upgrade extends PureComponent {
|
|
|
136
136
|
}
|
|
137
137
|
)
|
|
138
138
|
}
|
|
139
|
+
if (window.et.downloadUpgradeFromBrowser) {
|
|
140
|
+
const { releaseInfo } = this.props.upgradeInfo
|
|
141
|
+
const downloadUrl = getDownloadUrl(releaseInfo?.browserDownloadUrl, this.state.mirror)
|
|
142
|
+
if (downloadUrl) {
|
|
143
|
+
window.openLink(downloadUrl)
|
|
144
|
+
}
|
|
145
|
+
return
|
|
146
|
+
}
|
|
139
147
|
this.changeProps({
|
|
140
148
|
upgrading: true
|
|
141
149
|
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef, useEffect } from 'react'
|
|
1
|
+
import React, { useRef, useEffect, useState } from 'react'
|
|
2
2
|
import {
|
|
3
3
|
ArrowUpOutlined,
|
|
4
4
|
EyeInvisibleFilled,
|
|
@@ -7,11 +7,13 @@ import {
|
|
|
7
7
|
ArrowRightOutlined,
|
|
8
8
|
LoadingOutlined,
|
|
9
9
|
HomeOutlined,
|
|
10
|
-
PlusOutlined
|
|
10
|
+
PlusOutlined,
|
|
11
|
+
MenuOutlined
|
|
11
12
|
} from '@ant-design/icons'
|
|
12
13
|
import {
|
|
13
14
|
Input,
|
|
14
|
-
Tooltip
|
|
15
|
+
Tooltip,
|
|
16
|
+
Popover
|
|
15
17
|
} from 'antd'
|
|
16
18
|
import {
|
|
17
19
|
typeMap
|
|
@@ -22,10 +24,11 @@ import KeywordFilter from './keyword-filter'
|
|
|
22
24
|
|
|
23
25
|
const e = window.translate
|
|
24
26
|
|
|
25
|
-
function
|
|
27
|
+
function AddressPrefixIcons (props) {
|
|
26
28
|
const {
|
|
27
29
|
type,
|
|
28
|
-
host
|
|
30
|
+
host,
|
|
31
|
+
realPath
|
|
29
32
|
} = props
|
|
30
33
|
const isShow = props[`${type}ShowHiddenFile`]
|
|
31
34
|
const title = `${isShow ? e('hide') : e('show')} ${e('hfd')}`
|
|
@@ -75,6 +78,37 @@ function renderAddonBefore (props, realPath) {
|
|
|
75
78
|
)
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
function MobileAddressPrefix (props) {
|
|
82
|
+
const [open, setOpen] = useState(false)
|
|
83
|
+
const content = (
|
|
84
|
+
<div className='sftp-addr-menu-content'>
|
|
85
|
+
<AddressPrefixIcons {...props} />
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
88
|
+
return (
|
|
89
|
+
<Popover
|
|
90
|
+
content={content}
|
|
91
|
+
trigger='click'
|
|
92
|
+
placement='bottomLeft'
|
|
93
|
+
open={open}
|
|
94
|
+
onOpenChange={setOpen}
|
|
95
|
+
>
|
|
96
|
+
<MenuOutlined className='sftp-addr-menu-icon' />
|
|
97
|
+
</Popover>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function renderAddonBefore (props, realPath) {
|
|
102
|
+
if (window.store.isMobile) {
|
|
103
|
+
return (
|
|
104
|
+
<MobileAddressPrefix {...props} realPath={realPath} />
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
return (
|
|
108
|
+
<AddressPrefixIcons {...props} realPath={realPath} />
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
78
112
|
function renderAddonAfter (isLoadingRemote, onGoto, GoIcon, type, handleUploadFromBrowser) {
|
|
79
113
|
const handleClick = (e) => {
|
|
80
114
|
e.stopPropagation()
|
|
@@ -137,6 +137,23 @@ export default class FileListTable extends Component {
|
|
|
137
137
|
]
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* In mobile mode, only show the file name to save horizontal space.
|
|
142
|
+
* Returns the effective properties used for rendering both the
|
|
143
|
+
* table header and individual file items.
|
|
144
|
+
*/
|
|
145
|
+
getRenderProperties = () => {
|
|
146
|
+
if (window.store.isMobile) {
|
|
147
|
+
return [{
|
|
148
|
+
id: 'name',
|
|
149
|
+
max: 98,
|
|
150
|
+
min: 2,
|
|
151
|
+
size: 100
|
|
152
|
+
}]
|
|
153
|
+
}
|
|
154
|
+
return this.state.properties
|
|
155
|
+
}
|
|
156
|
+
|
|
140
157
|
getPropsAll = () => {
|
|
141
158
|
return [
|
|
142
159
|
'name',
|
|
@@ -179,7 +196,7 @@ export default class FileListTable extends Component {
|
|
|
179
196
|
onContextMenu: this.onContextMenu,
|
|
180
197
|
onClickName: this.onClickName,
|
|
181
198
|
onResize: this.onResize,
|
|
182
|
-
properties: this.
|
|
199
|
+
properties: this.getRenderProperties(),
|
|
183
200
|
sortDirection: this.props.sortDirection,
|
|
184
201
|
sortProp: this.props.sortProp,
|
|
185
202
|
maxWidth: this.props.width
|
|
@@ -274,7 +291,7 @@ export default class FileListTable extends Component {
|
|
|
274
291
|
const fileProps = {
|
|
275
292
|
...this.props.getFileProps(item, type),
|
|
276
293
|
cls,
|
|
277
|
-
properties: this.
|
|
294
|
+
properties: this.getRenderProperties(),
|
|
278
295
|
setClickFileId: this.setClickFileId
|
|
279
296
|
}
|
|
280
297
|
return (
|
|
@@ -1211,7 +1211,7 @@ export default class Sftp extends Component {
|
|
|
1211
1211
|
renderSftpPanelTitle (type, username, host) {
|
|
1212
1212
|
if (type === typeMap.remote) {
|
|
1213
1213
|
return (
|
|
1214
|
-
<div className='sftp-panel-title pd1t pd1b pd1x alignright'>
|
|
1214
|
+
<div className='sftp-panel-title pd1t pd1b pd1x alignright elli'>
|
|
1215
1215
|
<ReloadOutlined
|
|
1216
1216
|
className='mg1r pointer'
|
|
1217
1217
|
onClick={this.handleReloadRemoteSftp}
|
|
@@ -185,3 +185,17 @@
|
|
|
185
185
|
&:hover
|
|
186
186
|
&.active
|
|
187
187
|
color var(--success)
|
|
188
|
+
|
|
189
|
+
.sftp-addr-menu-icon
|
|
190
|
+
cursor pointer
|
|
191
|
+
font-size 14px
|
|
192
|
+
color var(--text)
|
|
193
|
+
&:hover
|
|
194
|
+
color var(--text-light)
|
|
195
|
+
|
|
196
|
+
.sftp-addr-menu-content
|
|
197
|
+
display flex
|
|
198
|
+
align-items center
|
|
199
|
+
padding 4px 0
|
|
200
|
+
flex-wrap wrap
|
|
201
|
+
gap 4px
|
|
@@ -9,8 +9,10 @@ import { uniq, filter, pick } from 'lodash-es'
|
|
|
9
9
|
import {
|
|
10
10
|
maxBookmarkGroupTitleLength,
|
|
11
11
|
defaultBookmarkGroupId,
|
|
12
|
-
settingMap
|
|
12
|
+
settingMap,
|
|
13
|
+
treeSortLsKey
|
|
13
14
|
} from '../../common/constants'
|
|
15
|
+
import { getItemJSON, setItemJSON } from '../../common/safe-local-storage'
|
|
14
16
|
import findParentBySel from '../../common/find-parent'
|
|
15
17
|
import copy from 'json-deep-copy'
|
|
16
18
|
import NewButtonsGroup from './bookmark-toolbar'
|
|
@@ -45,7 +47,7 @@ export default class ItemListTree extends Component {
|
|
|
45
47
|
categoryColor: '',
|
|
46
48
|
categoryId: '',
|
|
47
49
|
searchSelectedRowKey: '',
|
|
48
|
-
sort: null
|
|
50
|
+
sort: getItemJSON(treeSortLsKey, null)
|
|
49
51
|
}
|
|
50
52
|
this.listRef = React.createRef()
|
|
51
53
|
}
|
|
@@ -111,6 +113,7 @@ export default class ItemListTree extends Component {
|
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
handleSortChange = sort => {
|
|
116
|
+
setItemJSON(treeSortLsKey, sort)
|
|
114
117
|
this.setState({ sort })
|
|
115
118
|
}
|
|
116
119
|
|
package/client/css/mobile.styl
CHANGED
|
@@ -132,3 +132,22 @@
|
|
|
132
132
|
margin-inline-end 0
|
|
133
133
|
&::before
|
|
134
134
|
display none
|
|
135
|
+
|
|
136
|
+
// ---- 7. Terminal info panel button group: on narrow screens the connected
|
|
137
|
+
// button row in terminal info panel wraps, but antd styles it as a
|
|
138
|
+
// single horizontal strip. When the row wraps, the UI looks broken.
|
|
139
|
+
// Convert each button to a standalone pill so wrapping stays tidy.
|
|
140
|
+
.terminal-info-base
|
|
141
|
+
.ant-space-compact
|
|
142
|
+
display flex
|
|
143
|
+
flex-wrap wrap
|
|
144
|
+
gap 6px
|
|
145
|
+
.ant-btn
|
|
146
|
+
border-radius 3px
|
|
147
|
+
margin-right 0
|
|
148
|
+
|
|
149
|
+
// ---- 8. Upgrade panel: fixed 440px width overflows narrow mobile screens.
|
|
150
|
+
// Constrain it to the viewport minus the right offset (10px) and a
|
|
151
|
+
// matching left gap so it never extends past the screen edge.
|
|
152
|
+
.upgrade-panel
|
|
153
|
+
max-width calc(100vw - 20px)
|