@electerm/electerm-react 3.15.69 → 3.15.86
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/main/error-wrapper.jsx +2 -1
- package/client/components/session/session.styl +10 -1
- package/client/components/sftp/file-read.js +9 -2
- package/client/components/sftp/sftp-entry.jsx +1 -1
- package/client/components/vnc/vnc-session.jsx +1 -1
- package/client/components/web/web-session.jsx +6 -8
- package/client/store/watch.js +5 -1
- package/package.json +1 -1
|
@@ -121,6 +121,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
|
|
121
121
|
<img
|
|
122
122
|
src='https://electerm.org/electerm-wechat-group-qr.jpg'
|
|
123
123
|
className='mwm-100'
|
|
124
|
+
width={200}
|
|
124
125
|
/>
|
|
125
126
|
</div>
|
|
126
127
|
</>
|
|
@@ -133,7 +134,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
|
|
133
134
|
return (
|
|
134
135
|
<div className='pd3 error-wrapper'>
|
|
135
136
|
<div className='pd2y'>
|
|
136
|
-
<img src={logoPath1} className='iblock mwm-100' />
|
|
137
|
+
<img src={logoPath1} className='iblock mwm-100' width={100} />
|
|
137
138
|
</div>
|
|
138
139
|
<h1>
|
|
139
140
|
<FrownOutlined className='mg1r iblock' />
|
|
@@ -57,9 +57,18 @@
|
|
|
57
57
|
&.session-batch-active
|
|
58
58
|
display block
|
|
59
59
|
|
|
60
|
+
.term-sftp-box
|
|
61
|
+
height 100%
|
|
60
62
|
.web-session-wrap
|
|
61
|
-
height
|
|
63
|
+
height 100%
|
|
62
64
|
background var(--main)
|
|
65
|
+
overflow hidden
|
|
66
|
+
display flex
|
|
67
|
+
flex-direction column
|
|
68
|
+
.web-session-content
|
|
69
|
+
flex 1
|
|
70
|
+
min-height 0
|
|
71
|
+
overflow hidden
|
|
63
72
|
.session-v-info
|
|
64
73
|
line-height 30px
|
|
65
74
|
.vnc-scroll-wrapper
|
|
@@ -104,13 +104,20 @@ export const getFolderFromFilePath = (filePath, isRemote) => {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
function toMs (ms, date) {
|
|
108
|
+
const n = Number(ms)
|
|
109
|
+
if (Number.isFinite(n)) return n
|
|
110
|
+
const d = Number(date)
|
|
111
|
+
return Number.isFinite(d) ? d : 0
|
|
112
|
+
}
|
|
113
|
+
|
|
107
114
|
export const getLocalFileInfo = async (filePath) => {
|
|
108
115
|
const statr = await window.fs.statAsync(filePath)
|
|
109
116
|
const stat = await window.fs.lstatAsync(filePath)
|
|
110
117
|
return {
|
|
111
118
|
size: stat.size,
|
|
112
|
-
accessTime: stat.
|
|
113
|
-
modifyTime: stat.
|
|
119
|
+
accessTime: toMs(stat.atimeMs, stat.atime),
|
|
120
|
+
modifyTime: toMs(stat.mtimeMs, stat.mtime),
|
|
114
121
|
mode: stat.mode,
|
|
115
122
|
owner: stat.uid,
|
|
116
123
|
group: stat.gid,
|
|
@@ -222,7 +222,7 @@ export default class Sftp extends Component {
|
|
|
222
222
|
let aValue = a[sortProp]
|
|
223
223
|
let bValue = b[sortProp]
|
|
224
224
|
|
|
225
|
-
if (typeof aValue === 'string') {
|
|
225
|
+
if (typeof aValue === 'string' && typeof bValue === 'string') {
|
|
226
226
|
aValue = aValue.toLowerCase()
|
|
227
227
|
bValue = bValue.toLowerCase()
|
|
228
228
|
return isDesc
|
|
@@ -24,7 +24,7 @@ import './vnc.styl'
|
|
|
24
24
|
async function loadVncModule () {
|
|
25
25
|
if (window.novnc) return
|
|
26
26
|
console.debug('[VNC-CLIENT] Loading noVNC module...')
|
|
27
|
-
const mod = await import('@novnc/novnc
|
|
27
|
+
const mod = await import('@novnc/novnc')
|
|
28
28
|
window.novnc = {
|
|
29
29
|
RFB: mod.default
|
|
30
30
|
}
|
|
@@ -5,8 +5,6 @@ import React, { useState, useRef, useEffect, useCallback } from 'react'
|
|
|
5
5
|
export default function WebSession (props) {
|
|
6
6
|
const {
|
|
7
7
|
tab,
|
|
8
|
-
width,
|
|
9
|
-
height,
|
|
10
8
|
reloadTab
|
|
11
9
|
} = props
|
|
12
10
|
const [zoom, setZoom] = useState(1.0)
|
|
@@ -104,13 +102,13 @@ export default function WebSession (props) {
|
|
|
104
102
|
</div>
|
|
105
103
|
)
|
|
106
104
|
}
|
|
107
|
-
const hOffset = tab.hideAddressBar ? 30 : -12
|
|
108
105
|
if (window.et.isWebApp) {
|
|
109
106
|
const iframeProps = {
|
|
110
107
|
src: url,
|
|
111
108
|
style: {
|
|
112
|
-
width:
|
|
113
|
-
height:
|
|
109
|
+
width: '100%',
|
|
110
|
+
height: '100%',
|
|
111
|
+
border: 'none'
|
|
114
112
|
}
|
|
115
113
|
}
|
|
116
114
|
return (
|
|
@@ -120,8 +118,8 @@ export default function WebSession (props) {
|
|
|
120
118
|
const viewProps = {
|
|
121
119
|
src: url,
|
|
122
120
|
style: {
|
|
123
|
-
width:
|
|
124
|
-
height:
|
|
121
|
+
width: '100%',
|
|
122
|
+
height: '100%',
|
|
125
123
|
background: '#fff'
|
|
126
124
|
},
|
|
127
125
|
disableblinkfeatures: 'true',
|
|
@@ -139,7 +137,7 @@ export default function WebSession (props) {
|
|
|
139
137
|
{!tab.hideAddressBar && (
|
|
140
138
|
<AddressBar {...addrProps} />
|
|
141
139
|
)}
|
|
142
|
-
<div className='
|
|
140
|
+
<div className='web-session-content'>
|
|
143
141
|
{renderView()}
|
|
144
142
|
</div>
|
|
145
143
|
<WebAuthModal
|
package/client/store/watch.js
CHANGED
|
@@ -31,6 +31,11 @@ export default store => {
|
|
|
31
31
|
old,
|
|
32
32
|
n
|
|
33
33
|
)
|
|
34
|
+
// Update snapshot immediately before async DB writes to prevent
|
|
35
|
+
// race conditions: a second autoRun firing before the first
|
|
36
|
+
// completes would see stale oldState and re-insert the same items,
|
|
37
|
+
// causing NeDB unique constraint errors.
|
|
38
|
+
refsStatic.add('oldState-' + name, deepCopy(n) || [])
|
|
34
39
|
await Promise.all([
|
|
35
40
|
...removed.map(item => remove(name, item.id)),
|
|
36
41
|
...updated.map(item => update(item.id, item, name, false)),
|
|
@@ -41,7 +46,6 @@ export default store => {
|
|
|
41
46
|
`${name}:order`,
|
|
42
47
|
newOrder
|
|
43
48
|
)
|
|
44
|
-
refsStatic.add('oldState-' + name, deepCopy(n) || [])
|
|
45
49
|
if (name === 'bookmarks') {
|
|
46
50
|
store.bookmarksMap = new Map(
|
|
47
51
|
n.map(d => [d.id, d])
|