Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
0db2e7c7
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
0db2e7c7
编写于
5月 13, 2020
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
explorer - fixes for upload folder from web
上级
3a289949
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
72 addition
and
26 deletion
+72
-26
src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
...s/workbench/contrib/files/browser/views/explorerViewer.ts
+72
-26
未找到文件。
src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
浏览文件 @
0db2e7c7
...
...
@@ -616,7 +616,7 @@ export class FilesFilter implements ITreeFilter<ExplorerItem, FuzzyScore> {
}
}
//
//
Explorer Sorter
// Explorer Sorter
export
class
FileSorter
implements
ITreeSorter
<
ExplorerItem
>
{
constructor
(
...
...
@@ -624,7 +624,7 @@ export class FileSorter implements ITreeSorter<ExplorerItem> {
@
IWorkspaceContextService
private
readonly
contextService
:
IWorkspaceContextService
)
{
}
public
compare
(
statA
:
ExplorerItem
,
statB
:
ExplorerItem
):
number
{
compare
(
statA
:
ExplorerItem
,
statB
:
ExplorerItem
):
number
{
// Do not sort roots
if
(
statA
.
isRoot
)
{
if
(
statB
.
isRoot
)
{
...
...
@@ -712,6 +712,27 @@ const getFileOverwriteConfirm = (name: string) => {
};
};
interface
IWebkitDataTransfer
{
items
:
IWebkitDataTransferItem
[];
}
interface
IWebkitDataTransferItem
{
webkitGetAsEntry
():
IWebkitDataTransferItemEntry
;
}
interface
IWebkitDataTransferItemEntry
{
name
:
string
;
isFile
:
boolean
;
isDirectory
:
boolean
;
file
(
resolve
:
(
file
:
File
)
=>
void
,
reject
:
()
=>
void
):
void
;
createReader
():
IWebkitDataTransferItemEntryReader
;
}
interface
IWebkitDataTransferItemEntryReader
{
readEntries
(
resolve
:
(
file
:
IWebkitDataTransferItemEntry
[])
=>
void
,
reject
:
()
=>
void
):
void
}
export
class
FileDragAndDrop
implements
ITreeDragAndDrop
<
ExplorerItem
>
{
private
static
readonly
CONFIRM_DND_SETTING_KEY
=
'
explorer.confirmDragAndDrop
'
;
...
...
@@ -756,7 +777,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop<ExplorerItem> {
const
iconLabelName
=
getIconLabelNameFromHTMLElement
(
originalEvent
.
target
);
if
(
iconLabelName
&&
iconLabelName
.
index
<
iconLabelName
.
count
-
1
)
{
const
result
=
this
.
_on
DragOver
(
data
,
compressedTarget
,
targetIndex
,
originalEvent
);
const
result
=
this
.
handle
DragOver
(
data
,
compressedTarget
,
targetIndex
,
originalEvent
);
if
(
result
)
{
if
(
iconLabelName
.
element
!==
this
.
compressedDragOverElement
)
{
...
...
@@ -780,10 +801,10 @@ export class FileDragAndDrop implements ITreeDragAndDrop<ExplorerItem> {
}
this
.
compressedDropTargetDisposable
.
dispose
();
return
this
.
_on
DragOver
(
data
,
target
,
targetIndex
,
originalEvent
);
return
this
.
handle
DragOver
(
data
,
target
,
targetIndex
,
originalEvent
);
}
private
_on
DragOver
(
data
:
IDragAndDropData
,
target
:
ExplorerItem
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
):
boolean
|
ITreeDragOverReaction
{
private
handle
DragOver
(
data
:
IDragAndDropData
,
target
:
ExplorerItem
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
):
boolean
|
ITreeDragOverReaction
{
const
isCopy
=
originalEvent
&&
((
originalEvent
.
ctrlKey
&&
!
isMacintosh
)
||
(
originalEvent
.
altKey
&&
isMacintosh
));
const
fromDesktop
=
data
instanceof
DesktopDragAndDropData
;
const
effect
=
(
fromDesktop
||
isCopy
)
?
ListDragOverEffect
.
Copy
:
ListDragOverEffect
.
Move
;
...
...
@@ -939,58 +960,84 @@ export class FileDragAndDrop implements ITreeDragAndDrop<ExplorerItem> {
}
private
async
handleWebExternalDrop
(
data
:
DesktopDragAndDropData
,
target
:
ExplorerItem
,
originalEvent
:
DragEvent
):
Promise
<
void
>
{
const
items
=
(
originalEvent
as
any
).
dataTransfer
.
items
;
for
(
let
item
of
items
)
{
const
entry
=
item
.
webkitGetAsEntry
();
await
this
.
uploadFileEntry
(
entry
,
target
.
resource
,
target
);
const
items
=
(
originalEvent
.
dataTransfer
as
unknown
as
IWebkitDataTransfer
).
items
;
// Somehow the items thing is being modified at random, maybe as a security
// measure since this is a DND operation. As such, we copy the items into
// an array we own as early as possible before using it.
const
entries
:
IWebkitDataTransferItemEntry
[]
=
[];
for
(
const
item
of
items
)
{
entries
.
push
(
item
.
webkitGetAsEntry
());
}
if
(
items
.
length
===
1
)
{
await
this
.
editorService
.
openEditor
({
resource
:
joinPath
(
target
.
resource
,
entry
.
name
),
options
:
{
pinned
:
true
}
});
const
results
:
{
isFile
:
boolean
,
resource
:
URI
}[]
=
[];
for
(
let
entry
of
entries
)
{
const
result
=
await
this
.
doUploadWebFileEntry
(
entry
,
target
.
resource
,
target
);
if
(
result
)
{
results
.
push
(
result
);
}
}
// Open uploaded file in editor only if we upload just one
if
(
results
.
length
===
1
&&
results
[
0
].
isFile
)
{
await
this
.
editorService
.
openEditor
({
resource
:
results
[
0
].
resource
,
options
:
{
pinned
:
true
}
});
}
}
private
async
uploadFileEntry
(
entry
:
any
,
parentResource
:
URI
,
target
:
ExplorerItem
|
undefined
):
Promise
<
void
>
{
private
async
doUploadWebFileEntry
(
entry
:
IWebkitDataTransferItemEntry
,
parentResource
:
URI
,
target
:
ExplorerItem
|
undefined
):
Promise
<
{
isFile
:
boolean
,
resource
:
URI
}
|
undefined
>
{
if
(
!
entry
.
isFile
&&
!
entry
.
isDirectory
)
{
return
undefined
;
}
const
resource
=
joinPath
(
parentResource
,
entry
.
name
);
if
(
entry
.
isFile
)
{
// Handle file upload
if
(
target
&&
target
.
getChild
(
entry
.
name
))
{
const
{
confirmed
}
=
await
this
.
dialogService
.
confirm
(
getFileOverwriteConfirm
(
resource
.
path
));
if
(
!
confirmed
)
{
return
;
}
// Confirm overwrite as needed
if
(
target
&&
target
.
getChild
(
entry
.
name
))
{
const
{
confirmed
}
=
await
this
.
dialogService
.
confirm
(
getFileOverwriteConfirm
(
resource
.
path
));
if
(
!
confirmed
)
{
return
undefined
;
}
}
// Handle file upload
if
(
entry
.
isFile
)
{
const
file
=
await
new
Promise
<
File
>
((
resolve
,
reject
)
=>
entry
.
file
(
resolve
,
reject
));
const
reader
=
new
FileReader
();
reader
.
readAsArrayBuffer
(
file
);
reader
.
onload
=
async
(
event
)
=>
{
const
name
=
file
.
name
;
if
(
typeof
name
===
'
string
'
&&
event
.
target
?.
result
instanceof
ArrayBuffer
)
{
await
this
.
fileService
.
writeFile
(
resource
,
VSBuffer
.
wrap
(
new
Uint8Array
(
event
.
target
.
result
)));
}
};
}
else
if
(
entry
.
isDirectory
)
{
// Handle folder upload
return
{
isFile
:
true
,
resource
};
}
// Handle folder upload
else
{
await
this
.
fileService
.
createFolder
(
resource
);
// Recursive upload files in this directory
const
folderTarget
=
target
&&
target
.
getChild
(
entry
.
name
)
||
undefined
;
const
dirReader
=
entry
.
createReader
();
const
childEntries
=
await
new
Promise
<
an
y
[]
>
((
resolve
,
reject
)
=>
{
const
childEntries
=
await
new
Promise
<
IWebkitDataTransferItemEntr
y
[]
>
((
resolve
,
reject
)
=>
{
dirReader
.
readEntries
(
resolve
,
reject
);
});
for
(
let
childEntry
of
childEntries
)
{
await
this
.
upload
FileEntry
(
childEntry
,
resource
,
folderTarget
);
await
this
.
doUploadWeb
FileEntry
(
childEntry
,
resource
,
folderTarget
);
}
return
{
isFile
:
false
,
resource
};
}
}
private
async
handleExternalDrop
(
data
:
DesktopDragAndDropData
,
target
:
ExplorerItem
,
originalEvent
:
DragEvent
):
Promise
<
void
>
{
const
droppedResources
=
extractResources
(
originalEvent
,
true
);
// Check for dropped external files to be folders
const
droppedResources
=
extractResources
(
originalEvent
,
true
);
const
result
=
await
this
.
fileService
.
resolveAll
(
droppedResources
.
map
(
droppedResource
=>
({
resource
:
droppedResource
.
resource
})));
// Pass focus to window
...
...
@@ -999,7 +1046,6 @@ export class FileDragAndDrop implements ITreeDragAndDrop<ExplorerItem> {
// Handle folders by adding to workspace if we are in workspace context
const
folders
=
result
.
filter
(
r
=>
r
.
success
&&
r
.
stat
&&
r
.
stat
.
isDirectory
).
map
(
result
=>
({
uri
:
result
.
stat
!
.
resource
}));
if
(
folders
.
length
>
0
)
{
const
buttons
=
[
folders
.
length
>
1
?
localize
(
'
copyFolders
'
,
"
&&Copy Folders
"
)
:
localize
(
'
copyFolder
'
,
"
&&Copy Folder
"
),
localize
(
'
cancel
'
,
"
Cancel
"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录