@electerm/electerm-react 1.38.30 → 1.38.41
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/choose-save-folder.js +22 -0
- package/client/common/constants.js +1 -1
- package/client/common/download.jsx +31 -0
- package/client/common/trzsz.js +2 -18
- package/client/components/setting-panel/list.styl +3 -0
- package/client/components/setting-panel/tree-list.styl +4 -0
- package/client/components/shortcuts/shortcuts-defaults.js +7 -7
- package/client/components/tabs/index.jsx +11 -0
- package/client/components/terminal/index.jsx +17 -14
- package/client/components/terminal-info/activity.jsx +2 -2
- package/client/components/terminal-info/base.jsx +12 -1
- package/client/components/terminal-info/disk.jsx +2 -1
- package/client/components/terminal-info/network.jsx +2 -1
- package/client/components/terminal-info/up.jsx +3 -1
- package/client/store/index.js +2 -2
- package/client/store/sync.js +15 -2
- package/package.json +1 -1
- package/client/common/download.js +0 -16
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const {
|
|
2
|
+
openDialog
|
|
3
|
+
} = window.api
|
|
4
|
+
|
|
5
|
+
export async function chooseSaveDirectory () {
|
|
6
|
+
const savePaths = await openDialog({
|
|
7
|
+
title: 'Choose a folder to save file(s)',
|
|
8
|
+
message: 'Choose a folder to save file(s)',
|
|
9
|
+
properties: [
|
|
10
|
+
'openDirectory',
|
|
11
|
+
'showHiddenFiles',
|
|
12
|
+
'createDirectory',
|
|
13
|
+
'noResolveAliases',
|
|
14
|
+
'treatPackageAsDirectory',
|
|
15
|
+
'dontAddToRecent'
|
|
16
|
+
]
|
|
17
|
+
})
|
|
18
|
+
if (!savePaths || !savePaths.length) {
|
|
19
|
+
return undefined
|
|
20
|
+
}
|
|
21
|
+
return savePaths[0]
|
|
22
|
+
}
|
|
@@ -20,7 +20,7 @@ const buildConst = (props) => {
|
|
|
20
20
|
export const logoPath1 = logoPath1Ref.replace(/^\//, '')
|
|
21
21
|
export const logoPath2 = logoPath2Ref.replace(/^\//, '')
|
|
22
22
|
export const logoPath3 = logoPath3Ref.replace(/^\//, '')
|
|
23
|
-
export const maxEditFileSize = 1024 *
|
|
23
|
+
export const maxEditFileSize = 1024 * 3000
|
|
24
24
|
export const defaultBookmarkGroupId = 'default'
|
|
25
25
|
export const newBookmarkIdPrefix = 'new-bookmark'
|
|
26
26
|
export const unexpectedPacketErrorDesc = 'Unexpected packet'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* simulate download
|
|
3
|
+
*/
|
|
4
|
+
import { notification } from 'antd'
|
|
5
|
+
import ShowItem from '../components/common/show-item'
|
|
6
|
+
import { chooseSaveDirectory } from './choose-save-folder'
|
|
7
|
+
|
|
8
|
+
export default async function download (filename, text) {
|
|
9
|
+
const savePath = await chooseSaveDirectory()
|
|
10
|
+
if (!savePath) {
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
const path = window.require('path')
|
|
14
|
+
const filePath = path.join(savePath, filename)
|
|
15
|
+
const r = await window.fs.writeFile(filePath, text).catch(window.store.onError)
|
|
16
|
+
if (!r) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
notification.success({
|
|
20
|
+
message: '',
|
|
21
|
+
description: (
|
|
22
|
+
<div>
|
|
23
|
+
<ShowItem
|
|
24
|
+
to={filePath}
|
|
25
|
+
>
|
|
26
|
+
{filePath}
|
|
27
|
+
</ShowItem>
|
|
28
|
+
</div>
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
}
|
package/client/common/trzsz.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TrzszFilter } from 'trzsz'
|
|
2
|
+
import { chooseSaveDirectory } from './choose-save-folder'
|
|
2
3
|
|
|
3
4
|
const {
|
|
4
5
|
openDialog
|
|
@@ -36,24 +37,7 @@ window.newTrzsz = function (
|
|
|
36
37
|
})
|
|
37
38
|
},
|
|
38
39
|
// choose a directory to save the received files
|
|
39
|
-
chooseSaveDirectory
|
|
40
|
-
const savePaths = await openDialog({
|
|
41
|
-
title: 'Choose a folder to save file(s)',
|
|
42
|
-
message: 'Choose a folder to save file(s)',
|
|
43
|
-
properties: [
|
|
44
|
-
'openDirectory',
|
|
45
|
-
'showHiddenFiles',
|
|
46
|
-
'createDirectory',
|
|
47
|
-
'noResolveAliases',
|
|
48
|
-
'treatPackageAsDirectory',
|
|
49
|
-
'dontAddToRecent'
|
|
50
|
-
]
|
|
51
|
-
})
|
|
52
|
-
if (!savePaths || !savePaths.length) {
|
|
53
|
-
return undefined
|
|
54
|
-
}
|
|
55
|
-
return savePaths[0]
|
|
56
|
-
},
|
|
40
|
+
chooseSaveDirectory,
|
|
57
41
|
// the terminal columns
|
|
58
42
|
terminalColumns,
|
|
59
43
|
// there is a windows shell
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
width 16px
|
|
10
10
|
line-height 26px
|
|
11
11
|
height 20px
|
|
12
|
+
position absolute
|
|
13
|
+
right 0
|
|
14
|
+
top 0
|
|
12
15
|
.tree-item
|
|
13
16
|
display flex
|
|
14
17
|
&.is-category
|
|
@@ -25,6 +28,7 @@
|
|
|
25
28
|
overflow hidden
|
|
26
29
|
white-space nowrap
|
|
27
30
|
text-overflow ellipsis
|
|
31
|
+
padding-right 20px
|
|
28
32
|
.sidebar-panel .tree-item-title
|
|
29
33
|
max-width 180px
|
|
30
34
|
.with-plus
|
|
@@ -50,13 +50,13 @@ export default () => {
|
|
|
50
50
|
shortcut: 'ctrl+l,ctrl+shift+l',
|
|
51
51
|
shortcutMac: 'meta+l'
|
|
52
52
|
},
|
|
53
|
-
{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
},
|
|
53
|
+
// {
|
|
54
|
+
// name: 'terminal_selectAll',
|
|
55
|
+
// shortcut: 'ctrl+a,ctrl+shift+a',
|
|
56
|
+
// shortcutMac: 'meta+a',
|
|
57
|
+
// skipMac: true,
|
|
58
|
+
// readonly: true
|
|
59
|
+
// },
|
|
60
60
|
{
|
|
61
61
|
name: 'terminal_copy',
|
|
62
62
|
shortcut: 'ctrl+c,ctrl+shift+c',
|
|
@@ -49,6 +49,7 @@ export default class Tabs extends React.Component {
|
|
|
49
49
|
tabsRef
|
|
50
50
|
} = this
|
|
51
51
|
tabsRef.current.addEventListener('mousedown', this.handleClickEvent)
|
|
52
|
+
tabsRef.current.addEventListener('mousewheel', this.handleWheelEvent)
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
componentDidUpdate (prevProps) {
|
|
@@ -129,6 +130,16 @@ export default class Tabs extends React.Component {
|
|
|
129
130
|
this.dom.scrollLeft = scrollLeft
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
handleWheelEvent = (e) => {
|
|
134
|
+
if (this.isOverflow()) {
|
|
135
|
+
if (e.deltaY < 0) {
|
|
136
|
+
this.handleScrollLeft()
|
|
137
|
+
} else {
|
|
138
|
+
this.handleScrollRight()
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
handleClickMenu = ({ key }) => {
|
|
133
144
|
const id = key.split('##')[1]
|
|
134
145
|
this.props.onChangeTabId(id)
|
|
@@ -234,10 +234,10 @@ class Term extends Component {
|
|
|
234
234
|
this.onClear()
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
selectAllShortcut = (e) => {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
237
|
+
// selectAllShortcut = (e) => {
|
|
238
|
+
// e.stopPropagation()
|
|
239
|
+
// this.term.selectAll()
|
|
240
|
+
// }
|
|
241
241
|
|
|
242
242
|
copyShortcut = (e) => {
|
|
243
243
|
const sel = this.term.getSelection()
|
|
@@ -425,6 +425,9 @@ class Term extends Component {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
webLinkHandler = (event, url) => {
|
|
428
|
+
if (event?.button === 2) {
|
|
429
|
+
return false
|
|
430
|
+
}
|
|
428
431
|
if (!this.props.config.ctrlOrMetaOpenTerminalLink) {
|
|
429
432
|
return window.openLink(url, '_blank')
|
|
430
433
|
}
|
|
@@ -757,9 +760,9 @@ class Term extends Component {
|
|
|
757
760
|
this.term.focus()
|
|
758
761
|
}
|
|
759
762
|
|
|
760
|
-
onSelectAll = () => {
|
|
761
|
-
|
|
762
|
-
}
|
|
763
|
+
// onSelectAll = () => {
|
|
764
|
+
// this.term.selectAll()
|
|
765
|
+
// }
|
|
763
766
|
|
|
764
767
|
onClear = () => {
|
|
765
768
|
this.term.clear()
|
|
@@ -810,7 +813,7 @@ class Term extends Component {
|
|
|
810
813
|
const copyShortcut = this.getShortcut('terminal_copy')
|
|
811
814
|
const pasteShortcut = this.getShortcut('terminal_paste')
|
|
812
815
|
const clearShortcut = this.getShortcut('terminal_clear')
|
|
813
|
-
const selectAllShortcut = this.getShortcut('terminal_selectAll')
|
|
816
|
+
// const selectAllShortcut = this.getShortcut('terminal_selectAll')
|
|
814
817
|
const searchShortcut = this.getShortcut('terminal_search')
|
|
815
818
|
return [
|
|
816
819
|
{
|
|
@@ -833,12 +836,12 @@ class Term extends Component {
|
|
|
833
836
|
text: e('clear'),
|
|
834
837
|
subText: clearShortcut
|
|
835
838
|
},
|
|
836
|
-
{
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
},
|
|
839
|
+
// {
|
|
840
|
+
// func: 'onSelectAll',
|
|
841
|
+
// icon: 'SelectOutlined',
|
|
842
|
+
// text: e('selectAll'),
|
|
843
|
+
// subText: selectAllShortcut
|
|
844
|
+
// },
|
|
842
845
|
{
|
|
843
846
|
func: 'toggleSearch',
|
|
844
847
|
icon: 'SearchOutlined',
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Table, Tooltip, Popconfirm } from 'antd'
|
|
6
6
|
import { isEmpty } from 'lodash-es'
|
|
7
|
-
import { CloseCircleOutlined } from '@ant-design/icons'
|
|
7
|
+
import { CloseCircleOutlined, BarsOutlined } from '@ant-design/icons'
|
|
8
8
|
import colsParser from './data-cols-parser'
|
|
9
9
|
|
|
10
10
|
const { prefix } = window
|
|
@@ -47,7 +47,7 @@ export default function TerminalInfoActivities (props) {
|
|
|
47
47
|
}
|
|
48
48
|
return (
|
|
49
49
|
<div className='terminal-info-section terminal-info-act'>
|
|
50
|
-
<div className='pd1y bold'
|
|
50
|
+
<div className='pd1y bold'><BarsOutlined /> Activities</div>
|
|
51
51
|
<Table {...ps} />
|
|
52
52
|
</div>
|
|
53
53
|
)
|
|
@@ -15,10 +15,20 @@ import ShowItem from '../common/show-item'
|
|
|
15
15
|
import defaults from '../../common/default-setting'
|
|
16
16
|
import postMsg from '../../common/post-msg'
|
|
17
17
|
import { toggleTerminalLog, toggleTerminalLogTimestamp } from '../terminal/terminal-apis'
|
|
18
|
+
import { ClockCircleOutlined, BorderlessTableOutlined, DatabaseOutlined, BarsOutlined, ApiOutlined, PartitionOutlined } from '@ant-design/icons'
|
|
18
19
|
|
|
19
20
|
const { prefix } = window
|
|
20
21
|
const st = prefix('setting')
|
|
21
22
|
|
|
23
|
+
const mapper = {
|
|
24
|
+
uptime: <ClockCircleOutlined />,
|
|
25
|
+
cpu: <BorderlessTableOutlined />,
|
|
26
|
+
mem: <DatabaseOutlined />,
|
|
27
|
+
activities: <BarsOutlined />,
|
|
28
|
+
network: <ApiOutlined />,
|
|
29
|
+
disks: <PartitionOutlined />
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
export default class TerminalInfoBase extends Component {
|
|
23
33
|
state = {
|
|
24
34
|
saveTerminalLogToFile: false,
|
|
@@ -154,6 +164,7 @@ export default class TerminalInfoBase extends Component {
|
|
|
154
164
|
size='small'
|
|
155
165
|
onClick={() => this.toggleTerminalLogInfo(f)}
|
|
156
166
|
className='cap'
|
|
167
|
+
icon={mapper[f]}
|
|
157
168
|
>
|
|
158
169
|
{f}
|
|
159
170
|
</Button>
|
|
@@ -196,7 +207,7 @@ export default class TerminalInfoBase extends Component {
|
|
|
196
207
|
}
|
|
197
208
|
</span>
|
|
198
209
|
</div>
|
|
199
|
-
<div className='
|
|
210
|
+
<div className='pd2y'>
|
|
200
211
|
{
|
|
201
212
|
this.renderInfoSelection()
|
|
202
213
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { Table } from 'antd'
|
|
6
6
|
import { isEmpty } from 'lodash-es'
|
|
7
7
|
import colsParser from './data-cols-parser'
|
|
8
|
+
import { PartitionOutlined } from '@ant-design/icons'
|
|
8
9
|
|
|
9
10
|
export default function TerminalInfoDisk (props) {
|
|
10
11
|
const { disks, isRemote, terminalInfos } = props
|
|
@@ -22,7 +23,7 @@ export default function TerminalInfoDisk (props) {
|
|
|
22
23
|
}
|
|
23
24
|
return (
|
|
24
25
|
<div className='terminal-info-section terminal-info-disk'>
|
|
25
|
-
<div className='pd1y bold'
|
|
26
|
+
<div className='pd1y bold'><PartitionOutlined /> File system</div>
|
|
26
27
|
<Table {...ps} />
|
|
27
28
|
</div>
|
|
28
29
|
)
|
|
@@ -7,6 +7,7 @@ import { isEmpty } from 'lodash-es'
|
|
|
7
7
|
import { useEffect, useState } from 'react'
|
|
8
8
|
import { formatBytes } from '../../common/byte-format'
|
|
9
9
|
import copy from 'json-deep-copy'
|
|
10
|
+
import { ApiOutlined } from '@ant-design/icons'
|
|
10
11
|
|
|
11
12
|
export default function TerminalInfoDisk (props) {
|
|
12
13
|
const { network, isRemote, terminalInfos } = props
|
|
@@ -107,7 +108,7 @@ export default function TerminalInfoDisk (props) {
|
|
|
107
108
|
}
|
|
108
109
|
return (
|
|
109
110
|
<div className='terminal-info-section terminal-info-network'>
|
|
110
|
-
<div className='pd1y bold'
|
|
111
|
+
<div className='pd1y bold'><ApiOutlined /> Network</div>
|
|
111
112
|
<Table {...ps} />
|
|
112
113
|
</div>
|
|
113
114
|
)
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* up time info
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { ClockCircleOutlined } from '@ant-design/icons'
|
|
6
|
+
|
|
5
7
|
export default function TerminalInfoUp (props) {
|
|
6
8
|
const { uptime, isRemote, terminalInfos } = props
|
|
7
9
|
if (!isRemote || !terminalInfos.includes('uptime')) {
|
|
@@ -9,7 +11,7 @@ export default function TerminalInfoUp (props) {
|
|
|
9
11
|
}
|
|
10
12
|
return (
|
|
11
13
|
<div className='terminal-info-section terminal-info-up'>
|
|
12
|
-
<b
|
|
14
|
+
<b><ClockCircleOutlined /> uptime</b>: {uptime}
|
|
13
15
|
</div>
|
|
14
16
|
)
|
|
15
17
|
}
|
package/client/store/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import loadDataExtend from './load-data'
|
|
|
8
8
|
import dbUpgradeExtend from './db-upgrade'
|
|
9
9
|
import eventExtend from './event'
|
|
10
10
|
import syncExtend from './sync'
|
|
11
|
-
import
|
|
11
|
+
import appUpgradeExtend from './app-upgrade'
|
|
12
12
|
import bookmarkGroupExtend from './bookmark-group'
|
|
13
13
|
import bookmarkExtend from './bookmark'
|
|
14
14
|
import commonExtend from './common'
|
|
@@ -288,7 +288,7 @@ loadDataExtend(Store)
|
|
|
288
288
|
eventExtend(Store)
|
|
289
289
|
dbUpgradeExtend(Store)
|
|
290
290
|
syncExtend(Store)
|
|
291
|
-
|
|
291
|
+
appUpgradeExtend(Store)
|
|
292
292
|
bookmarkGroupExtend(Store)
|
|
293
293
|
bookmarkExtend(Store)
|
|
294
294
|
commonExtend(Store)
|
package/client/store/sync.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* sync data to github gist related
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { without, get, pick, debounce } from 'lodash-es'
|
|
5
|
+
import { without, get, pick, debounce, findIndex } from 'lodash-es'
|
|
6
6
|
import copy from 'json-deep-copy'
|
|
7
7
|
import {
|
|
8
8
|
settingMap, packInfo, syncTypes
|
|
9
9
|
} from '../common/constants'
|
|
10
|
-
import { remove, dbNames, insert, update } from '../common/db'
|
|
10
|
+
import { remove, dbNames, insert, update, getData } from '../common/db'
|
|
11
11
|
import fetch from '../common/fetch-from-server'
|
|
12
12
|
import download from '../common/download'
|
|
13
13
|
import { fixBookmarks } from '../common/db-fix'
|
|
@@ -169,6 +169,10 @@ export default (Store) => {
|
|
|
169
169
|
objs[`${n}.json`] = {
|
|
170
170
|
content: str
|
|
171
171
|
}
|
|
172
|
+
const order = await getData(`${n}:order`)
|
|
173
|
+
objs[`${n}.order.json`] = {
|
|
174
|
+
content: JSON.stringify(order)
|
|
175
|
+
}
|
|
172
176
|
}
|
|
173
177
|
const res = await fetchData(type, 'update', [gistId, {
|
|
174
178
|
description: 'sync electerm data',
|
|
@@ -235,6 +239,15 @@ export default (Store) => {
|
|
|
235
239
|
} else if (n === settingMap.bookmarks) {
|
|
236
240
|
arr = fixBookmarks(arr)
|
|
237
241
|
}
|
|
242
|
+
let strOrder = get(gist, `files["${n}.order.json"].content`)
|
|
243
|
+
if (strOrder) {
|
|
244
|
+
strOrder = JSON.parse(strOrder)
|
|
245
|
+
arr.sort((a, b) => {
|
|
246
|
+
const ai = findIndex(strOrder, r => r === a.id)
|
|
247
|
+
const bi = findIndex(strOrder, r => r === b.id)
|
|
248
|
+
return ai - bi
|
|
249
|
+
})
|
|
250
|
+
}
|
|
238
251
|
toInsert.push({
|
|
239
252
|
name: n,
|
|
240
253
|
value: arr
|
package/package.json
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* simulate download
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export default function download (filename, text) {
|
|
6
|
-
const pom = document.createElement('a')
|
|
7
|
-
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text))
|
|
8
|
-
pom.setAttribute('download', filename)
|
|
9
|
-
if (document.createEvent) {
|
|
10
|
-
const event = document.createEvent('MouseEvents')
|
|
11
|
-
event.initEvent('click', true, true)
|
|
12
|
-
pom.dispatchEvent(event)
|
|
13
|
-
} else {
|
|
14
|
-
pom.click()
|
|
15
|
-
}
|
|
16
|
-
}
|