@electerm/electerm-react 1.37.110 → 1.37.126
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/components/common/input-auto-focus.jsx +2 -1
- package/client/components/common/native-input.jsx +30 -0
- package/client/components/common/native-input.styl +7 -0
- package/client/components/setting-panel/tree-list.jsx +19 -7
- package/client/components/sftp/file-item.jsx +28 -16
- package/client/components/sftp/file-read.js +27 -1
- package/client/components/sftp/transfer-conflict.jsx +11 -3
- package/client/components/sidebar/bookmark.jsx +1 -1
- package/client/components/sidebar/sidebar.styl +2 -0
- package/client/components/tabs/app-drag.jsx +0 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { Input } from 'antd'
|
|
6
|
+
import InputNative from './native-input'
|
|
6
7
|
import React from 'react'
|
|
7
8
|
import { findLastIndex } from 'lodash-es'
|
|
8
9
|
import uid from '../../common/uid'
|
|
@@ -57,7 +58,7 @@ export default class InputAutoFocus extends React.PureComponent {
|
|
|
57
58
|
const { type, ...rest } = this.props
|
|
58
59
|
const Dom = type === 'password'
|
|
59
60
|
? Input.Password
|
|
60
|
-
: Input
|
|
61
|
+
: type === 'native' ? InputNative : Input
|
|
61
62
|
return (
|
|
62
63
|
<Dom
|
|
63
64
|
{...rest}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* input with auto focus
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import React from 'react'
|
|
6
|
+
import './native-input.styl'
|
|
7
|
+
|
|
8
|
+
export default function InputNative (props) {
|
|
9
|
+
const { value, type, onChange, onPressEnter, addonAfter = null, ...rest } = props
|
|
10
|
+
return (
|
|
11
|
+
<span
|
|
12
|
+
className='ant-input-group-wrapper'
|
|
13
|
+
data-id={props['data-id']}
|
|
14
|
+
>
|
|
15
|
+
<span className='ant-input-wrapper ant-input-group'>
|
|
16
|
+
<input
|
|
17
|
+
class='ant-input native-input'
|
|
18
|
+
type='text'
|
|
19
|
+
value={value}
|
|
20
|
+
onChange={onChange}
|
|
21
|
+
onPressEnter={onPressEnter}
|
|
22
|
+
{...rest}
|
|
23
|
+
/>
|
|
24
|
+
</span>
|
|
25
|
+
<span class='ant-input-group-addon'>
|
|
26
|
+
{addonAfter}
|
|
27
|
+
</span>
|
|
28
|
+
</span>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -334,7 +334,7 @@ export default class ItemListTree extends Component {
|
|
|
334
334
|
|
|
335
335
|
renderSearch = () => {
|
|
336
336
|
return (
|
|
337
|
-
<div className='pd1y
|
|
337
|
+
<div className='pd1y'>
|
|
338
338
|
<Search
|
|
339
339
|
onChange={this.handleChange}
|
|
340
340
|
value={this.state.keyword}
|
|
@@ -590,6 +590,7 @@ export default class ItemListTree extends Component {
|
|
|
590
590
|
onChange={this.handleChangeEdit}
|
|
591
591
|
onPressEnter={this.handleSubmitEdit}
|
|
592
592
|
addonAfter={confirm}
|
|
593
|
+
type='native'
|
|
593
594
|
/>
|
|
594
595
|
)
|
|
595
596
|
}
|
|
@@ -723,15 +724,25 @@ export default class ItemListTree extends Component {
|
|
|
723
724
|
title,
|
|
724
725
|
this.state.keyword
|
|
725
726
|
)
|
|
727
|
+
const propsAll = {
|
|
728
|
+
className: cls,
|
|
729
|
+
title: titleAll,
|
|
730
|
+
onContextMenu: e => this.onContextMenu(e, item, isGroup)
|
|
731
|
+
}
|
|
732
|
+
const titleProps = {
|
|
733
|
+
className: 'tree-item-title elli',
|
|
734
|
+
style: this.props.staticList
|
|
735
|
+
? { maxWidth: (this.props.store.leftSidebarWidth - 110) + 'px' }
|
|
736
|
+
: undefined
|
|
737
|
+
}
|
|
738
|
+
const key = item.id || uid()
|
|
726
739
|
return (
|
|
727
740
|
<div
|
|
728
|
-
|
|
729
|
-
key={
|
|
730
|
-
title={titleAll}
|
|
731
|
-
onContextMenu={e => this.onContextMenu(e, item, isGroup)}
|
|
741
|
+
{...propsAll}
|
|
742
|
+
key={key}
|
|
732
743
|
>
|
|
733
744
|
<div
|
|
734
|
-
|
|
745
|
+
{...titleProps}
|
|
735
746
|
>
|
|
736
747
|
{tag}{titleHighlight}
|
|
737
748
|
</div>
|
|
@@ -892,6 +903,7 @@ export default class ItemListTree extends Component {
|
|
|
892
903
|
onPressEnter={this.handleSubmitSub}
|
|
893
904
|
onChange={this.handleChangeBookmarkGroupTitleSub}
|
|
894
905
|
addonAfter={confirm}
|
|
906
|
+
type='native'
|
|
895
907
|
/>
|
|
896
908
|
)}
|
|
897
909
|
/>
|
|
@@ -965,7 +977,7 @@ export default class ItemListTree extends Component {
|
|
|
965
977
|
{
|
|
966
978
|
this.renderSearch()
|
|
967
979
|
}
|
|
968
|
-
<div className='item-list-wrap
|
|
980
|
+
<div className='item-list-wrap' style={listStyle}>
|
|
969
981
|
{this.renderNewBookmarkGroup()}
|
|
970
982
|
<Tree
|
|
971
983
|
{...treeProps}
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from '../../common/constants'
|
|
29
29
|
import findParent from '../../common/find-parent'
|
|
30
30
|
import sorter from '../../common/index-sorter'
|
|
31
|
-
import { getFolderFromFilePath } from './file-read'
|
|
31
|
+
import { getFolderFromFilePath, getLocalFileInfo, checkFolderSize } from './file-read'
|
|
32
32
|
import { readClipboard, copy as copyToClipboard, hasFileInClipboardText } from '../../common/clipboard'
|
|
33
33
|
import fs from '../../common/fs'
|
|
34
34
|
import time from '../../common/time'
|
|
@@ -286,7 +286,7 @@ export default class FileSection extends React.Component {
|
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
onDropFile = (fromFiles, toFile, fromFileManager) => {
|
|
289
|
+
onDropFile = async (fromFiles, toFile, fromFileManager) => {
|
|
290
290
|
const { type: fromType } = fromFiles[0]
|
|
291
291
|
const {
|
|
292
292
|
id,
|
|
@@ -295,7 +295,6 @@ export default class FileSection extends React.Component {
|
|
|
295
295
|
} = toFile
|
|
296
296
|
|
|
297
297
|
let operation = ''
|
|
298
|
-
|
|
299
298
|
// same side and drop to file = drop to folder
|
|
300
299
|
if (!fromFileManager && fromType === toType && !isDirectoryTo) {
|
|
301
300
|
return
|
|
@@ -321,7 +320,25 @@ export default class FileSection extends React.Component {
|
|
|
321
320
|
}
|
|
322
321
|
|
|
323
322
|
// other side, do transfer
|
|
324
|
-
|
|
323
|
+
let files = fromFiles
|
|
324
|
+
if (fromFileManager) {
|
|
325
|
+
files = await this.filterFiles(fromFiles)
|
|
326
|
+
}
|
|
327
|
+
this.transferDrop(files, toFile, operation)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
filterFiles = async (files) => {
|
|
331
|
+
const res = []
|
|
332
|
+
for (const file of files) {
|
|
333
|
+
const { name, path } = file
|
|
334
|
+
const info = await getLocalFileInfo(
|
|
335
|
+
resolve(path, name)
|
|
336
|
+
)
|
|
337
|
+
if (info) {
|
|
338
|
+
res.push(info)
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return res
|
|
325
342
|
}
|
|
326
343
|
|
|
327
344
|
transferDrop = (fromFiles, toFile, operation) => {
|
|
@@ -763,7 +780,7 @@ export default class FileSection extends React.Component {
|
|
|
763
780
|
}
|
|
764
781
|
}
|
|
765
782
|
|
|
766
|
-
getTransferList = (
|
|
783
|
+
getTransferList = async (
|
|
767
784
|
file,
|
|
768
785
|
toPathBase,
|
|
769
786
|
_typeTo,
|
|
@@ -793,15 +810,16 @@ export default class FileSection extends React.Component {
|
|
|
793
810
|
operation
|
|
794
811
|
}
|
|
795
812
|
if (isDirectory) {
|
|
813
|
+
const zip = await checkFolderSize(this.props, file)
|
|
796
814
|
Object.assign(obj, {
|
|
797
|
-
zip
|
|
798
|
-
skipExpand:
|
|
815
|
+
zip,
|
|
816
|
+
skipExpand: zip
|
|
799
817
|
})
|
|
800
818
|
}
|
|
801
819
|
return [obj]
|
|
802
820
|
}
|
|
803
821
|
|
|
804
|
-
doTransferSelected = (
|
|
822
|
+
doTransferSelected = async (
|
|
805
823
|
e,
|
|
806
824
|
selectedFiles = this.props.selectedFiles,
|
|
807
825
|
toPathBase,
|
|
@@ -810,7 +828,7 @@ export default class FileSection extends React.Component {
|
|
|
810
828
|
) => {
|
|
811
829
|
let all = []
|
|
812
830
|
for (const f of selectedFiles) {
|
|
813
|
-
const arr = this.getTransferList(f, toPathBase, typeTo, operation)
|
|
831
|
+
const arr = await this.getTransferList(f, toPathBase, typeTo, operation)
|
|
814
832
|
all = [
|
|
815
833
|
...all,
|
|
816
834
|
...arr
|
|
@@ -821,13 +839,7 @@ export default class FileSection extends React.Component {
|
|
|
821
839
|
|
|
822
840
|
transfer = async () => {
|
|
823
841
|
const { file } = this.state
|
|
824
|
-
const arr = this.getTransferList(file)
|
|
825
|
-
this.props.addTransferList(arr)
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
zipTransferDirectory = () => {
|
|
829
|
-
const { file } = this.state
|
|
830
|
-
const arr = this.getTransferList(file)
|
|
842
|
+
const arr = await this.getTransferList(file)
|
|
831
843
|
this.props.addTransferList(arr)
|
|
832
844
|
}
|
|
833
845
|
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import generate from '../../common/uid'
|
|
6
6
|
import fs from '../../common/fs'
|
|
7
|
-
import { isWin } from '../../common/constants'
|
|
7
|
+
import { isWin, typeMap } from '../../common/constants'
|
|
8
|
+
import resolve from '../../common/resolve'
|
|
8
9
|
|
|
9
10
|
export const getFileExt = fileName => {
|
|
10
11
|
const sep = '.'
|
|
@@ -79,3 +80,28 @@ export const getRemoteFileInfo = async (sftp, filePath) => {
|
|
|
79
80
|
isDirectory: stat.isDirectory
|
|
80
81
|
}
|
|
81
82
|
}
|
|
83
|
+
|
|
84
|
+
export async function checkFolderSize (props, f) {
|
|
85
|
+
const pth = resolve(f.path, f.name)
|
|
86
|
+
const func = f.type === typeMap.remote
|
|
87
|
+
? props.sftp
|
|
88
|
+
: window.fs
|
|
89
|
+
const {
|
|
90
|
+
size,
|
|
91
|
+
count
|
|
92
|
+
} = await func.getFolderSize(pth)
|
|
93
|
+
.catch(err => {
|
|
94
|
+
console.log('get folder size fail', err)
|
|
95
|
+
return { size: 0, count: 0 }
|
|
96
|
+
})
|
|
97
|
+
if (count === 0) {
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
100
|
+
if (size >= 600) {
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
if (size / count >= 100) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
@@ -6,7 +6,13 @@
|
|
|
6
6
|
import { useRef } from 'react'
|
|
7
7
|
import { useDelta, useConditionalEffect } from 'react-delta'
|
|
8
8
|
import { maxTransport, typeMap } from '../../common/constants'
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
getLocalFileInfo,
|
|
11
|
+
getRemoteFileInfo,
|
|
12
|
+
getFolderFromFilePath,
|
|
13
|
+
getFileExt,
|
|
14
|
+
checkFolderSize
|
|
15
|
+
} from './file-read'
|
|
10
16
|
import copy from 'json-deep-copy'
|
|
11
17
|
import { findIndex, find } from 'lodash-es'
|
|
12
18
|
import generate from '../../common/uid'
|
|
@@ -263,8 +269,10 @@ export default (props) => {
|
|
|
263
269
|
toFile = await checkExist(typeTo, toPath)
|
|
264
270
|
}
|
|
265
271
|
if (fromFile.isDirectory) {
|
|
266
|
-
|
|
267
|
-
|
|
272
|
+
const skip = await checkFolderSize(props, fromFile)
|
|
273
|
+
.then(d => d && typeFrom !== typeTo)
|
|
274
|
+
tr.zip = skip
|
|
275
|
+
tr.skipExpand = skip
|
|
268
276
|
}
|
|
269
277
|
if (fromPath === toPath && typeFrom === typeTo) {
|
|
270
278
|
return updateTransferAction({
|