Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
79d8060a
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,发现更多精彩内容 >>
提交
79d8060a
编写于
2月 12, 2018
作者:
R
Rachel Macfarlane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add toggle for duplicate search API in issue reporter, #43519
上级
1a4c5b43
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
168 addition
and
71 deletion
+168
-71
src/vs/code/electron-browser/issue/issueReporter.html
src/vs/code/electron-browser/issue/issueReporter.html
+2
-1
src/vs/code/electron-browser/issue/issueReporterMain.ts
src/vs/code/electron-browser/issue/issueReporterMain.ts
+137
-63
src/vs/code/electron-browser/issue/media/issueReporter.css
src/vs/code/electron-browser/issue/media/issueReporter.css
+13
-2
src/vs/platform/issue/common/issue.ts
src/vs/platform/issue/common/issue.ts
+4
-0
src/vs/platform/issue/electron-main/issueService.ts
src/vs/platform/issue/electron-main/issueService.ts
+12
-5
未找到文件。
src/vs/code/electron-browser/issue/issueReporter.html
浏览文件 @
79d8060a
...
...
@@ -4,7 +4,8 @@
<head>
<meta
charset=
"utf-8"
/>
<meta
http-equiv=
"Content-Security-Policy"
content=
"default-src 'none'; img-src 'self' https: data:; media-src 'none'; child-src 'self'; object-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https:;"
>
<!-- TODO change connect-src back to HTTPS -->
<meta
http-equiv=
"Content-Security-Policy"
content=
"default-src 'none'; img-src 'self' https: data:; media-src 'none'; child-src 'self'; object-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self' http:; font-src 'self' https:;"
>
<style>body
{
display
:
none
}
</style>
</head>
...
...
src/vs/code/electron-browser/issue/issueReporterMain.ts
浏览文件 @
79d8060a
...
...
@@ -31,7 +31,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper
import
{
WindowsChannelClient
}
from
'
vs/platform/windows/common/windowsIpc
'
;
import
{
EnvironmentService
}
from
'
vs/platform/environment/node/environmentService
'
;
import
{
IssueReporterModel
}
from
'
vs/code/electron-browser/issue/issueReporterModel
'
;
import
{
IssueReporterData
,
IssueReporterStyles
,
IssueType
,
ISettingsSearchIssueReporterData
}
from
'
vs/platform/issue/common/issue
'
;
import
{
IssueReporterData
,
IssueReporterStyles
,
IssueType
,
ISettingsSearchIssueReporterData
,
IssueReporterFeatures
}
from
'
vs/platform/issue/common/issue
'
;
import
BaseHtml
from
'
vs/code/electron-browser/issue/issueReporterPage
'
;
import
{
ILocalExtension
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
debounce
}
from
'
vs/base/common/decorators
'
;
...
...
@@ -39,8 +39,14 @@ import * as platform from 'vs/base/common/platform';
const
MAX_URL_LENGTH
=
5400
;
interface
SearchResult
{
html_url
:
string
;
title
:
string
;
}
export
interface
IssueReporterConfiguration
extends
IWindowConfiguration
{
data
:
IssueReporterData
;
features
:
IssueReporterFeatures
;
}
export
function
startup
(
configuration
:
IssueReporterConfiguration
)
{
...
...
@@ -55,6 +61,7 @@ export class IssueReporter extends Disposable {
private
telemetryService
:
ITelemetryService
;
private
issueReporterModel
:
IssueReporterModel
;
private
shouldQueueSearch
=
true
;
private
features
:
IssueReporterFeatures
;
private
receivedSystemInfo
=
false
;
private
receivedPerformanceInfo
=
false
;
...
...
@@ -78,6 +85,8 @@ export class IssueReporter extends Disposable {
reprosWithoutExtensions
:
false
});
this
.
features
=
configuration
.
features
;
ipcRenderer
.
on
(
'
issuePerformanceInfoResponse
'
,
(
event
,
info
)
=>
{
this
.
issueReporterModel
.
update
(
info
);
this
.
receivedPerformanceInfo
=
true
;
...
...
@@ -175,15 +184,15 @@ export class IssueReporter extends Disposable {
}
if
(
styles
.
sliderBackgroundColor
)
{
content
.
push
(
`body::-webkit-scrollbar-thumb { background-color:
${
styles
.
sliderBackgroundColor
}
; }`
);
content
.
push
(
`
.issues-container::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb { background-color:
${
styles
.
sliderBackgroundColor
}
; }`
);
}
if
(
styles
.
sliderActiveColor
)
{
content
.
push
(
`body::-webkit-scrollbar-thumb:active { background-color:
${
styles
.
sliderActiveColor
}
; }`
);
content
.
push
(
`
.issues-container::-webkit-scrollbar-thumb:active,
body::-webkit-scrollbar-thumb:active { background-color:
${
styles
.
sliderActiveColor
}
; }`
);
}
if
(
styles
.
sliderHoverColor
)
{
content
.
push
(
`body::-webkit-scrollbar-thumb:hover { background-color:
${
styles
.
sliderHoverColor
}
; }`
);
content
.
push
(
`
.issues-container::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover { background-color:
${
styles
.
sliderHoverColor
}
; }`
);
}
styleTag
.
innerHTML
=
content
.
join
(
'
\n
'
);
...
...
@@ -321,7 +330,7 @@ export class IssueReporter extends Disposable {
this
.
issueReporterModel
.
update
({
issueDescription
:
(
<
HTMLInputElement
>
event
.
target
).
value
});
});
document
.
getElementById
(
'
issue-title
'
).
addEventListener
(
'
input
'
,
(
e
)
=>
{
this
.
search
GitHub
(
e
);
});
document
.
getElementById
(
'
issue-title
'
).
addEventListener
(
'
input
'
,
(
e
)
=>
{
this
.
search
Issues
(
e
);
});
document
.
getElementById
(
'
github-submit-btn
'
).
addEventListener
(
'
click
'
,
()
=>
this
.
createIssue
());
...
...
@@ -405,62 +414,120 @@ export class IssueReporter extends Disposable {
}
@
debounce
(
300
)
private
search
GitHub
(
event
:
Event
):
void
{
private
search
Issues
(
event
:
Event
):
void
{
const
title
=
(
<
HTMLInputElement
>
event
.
target
).
value
;
const
similarIssues
=
document
.
getElementById
(
'
similar-issues
'
);
if
(
title
)
{
const
query
=
`is:issue+repo:microsoft/vscode+
${
title
}
`
;
window
.
fetch
(
`https://api.github.com/search/issues?q=
${
query
}
`
).
then
((
response
)
=>
{
response
.
json
().
then
(
result
=>
{
similarIssues
.
innerHTML
=
''
;
if
(
result
&&
result
.
items
&&
result
.
items
.
length
)
{
const
issues
=
$
(
'
ul
'
);
const
issuesText
=
$
(
'
div.list-title
'
);
issuesText
.
textContent
=
localize
(
'
similarIssues
'
,
"
Similar issues
"
);
const
{
items
}
=
result
;
const
numResultsToDisplay
=
items
.
length
<
5
?
items
.
length
:
5
;
for
(
let
i
=
0
;
i
<
numResultsToDisplay
;
i
++
)
{
const
link
=
$
(
'
a
'
,
{
href
:
items
[
i
].
html_url
});
link
.
textContent
=
items
[
i
].
title
;
link
.
addEventListener
(
'
click
'
,
openLink
);
link
.
addEventListener
(
'
auxclick
'
,
openLink
);
const
item
=
$
(
'
li
'
,
{},
link
);
issues
.
appendChild
(
item
);
}
similarIssues
.
appendChild
(
issuesText
);
similarIssues
.
appendChild
(
issues
);
}
else
if
(
result
&&
result
.
items
)
{
const
message
=
$
(
'
div.list-title
'
);
message
.
textContent
=
localize
(
'
noResults
'
,
"
No results found
"
);
similarIssues
.
appendChild
(
message
);
}
else
{
const
message
=
$
(
'
div.list-title
'
);
message
.
textContent
=
localize
(
'
rateLimited
'
,
"
GitHub query limit exceeded. Please wait.
"
);
similarIssues
.
appendChild
(
message
);
const
resetTime
=
response
.
headers
.
get
(
'
X-RateLimit-Reset
'
);
const
timeToWait
=
parseInt
(
resetTime
)
-
Math
.
floor
(
Date
.
now
()
/
1000
);
if
(
this
.
shouldQueueSearch
)
{
this
.
shouldQueueSearch
=
false
;
setTimeout
(()
=>
{
this
.
searchGitHub
(
event
);
this
.
shouldQueueSearch
=
true
;
},
timeToWait
*
1000
);
}
throw
new
Error
(
result
.
message
);
if
(
this
.
features
.
useDuplicateSearch
)
{
this
.
searchDuplicates
(
title
);
}
else
{
this
.
searchGitHub
(
title
);
}
}
else
{
this
.
clearSearchResults
();
}
}
private
clearSearchResults
():
void
{
const
similarIssues
=
document
.
getElementById
(
'
similar-issues
'
);
similarIssues
.
innerHTML
=
''
;
}
private
searchDuplicates
(
title
:
string
):
void
{
// TODO: Change to HTTPS
const
url
=
'
http://vscode-probot.westus.cloudapp.azure.com:5010/duplicate_candidates
'
;
const
init
=
{
method
:
'
POST
'
,
body
:
JSON
.
stringify
({
title
}),
headers
:
new
Headers
({
'
Content-Type
'
:
'
application/json
'
})
};
window
.
fetch
(
url
,
init
).
then
((
response
)
=>
{
response
.
json
().
then
(
result
=>
{
this
.
clearSearchResults
();
if
(
result
&&
result
.
candidates
)
{
const
normalizedResults
=
result
.
candidates
.
map
(
result
=>
{
return
{
html_url
:
`https://github.com/Microsoft/vscode/issues/
${
result
.
number
}
`
,
title
:
result
.
title
};
});
this
.
displaySearchResults
(
normalizedResults
);
}
else
{
throw
new
Error
();
}
}).
catch
((
error
)
=>
{
this
.
logSearchError
(
error
);
});
}).
catch
((
error
)
=>
{
this
.
logSearchError
(
error
);
});
}
private
searchGitHub
(
title
:
string
):
void
{
const
query
=
`is:issue+repo:microsoft/vscode+
${
title
}
`
;
const
similarIssues
=
document
.
getElementById
(
'
similar-issues
'
);
window
.
fetch
(
`https://api.github.com/search/issues?q=
${
query
}
`
).
then
((
response
)
=>
{
response
.
json
().
then
(
result
=>
{
similarIssues
.
innerHTML
=
''
;
if
(
result
&&
result
.
items
)
{
this
.
displaySearchResults
(
result
.
items
);
}
else
{
// If the items property isn't present, the rate limit has been hit
const
message
=
$
(
'
div.list-title
'
);
message
.
textContent
=
localize
(
'
rateLimited
'
,
"
GitHub query limit exceeded. Please wait.
"
);
similarIssues
.
appendChild
(
message
);
const
resetTime
=
response
.
headers
.
get
(
'
X-RateLimit-Reset
'
);
const
timeToWait
=
parseInt
(
resetTime
)
-
Math
.
floor
(
Date
.
now
()
/
1000
);
if
(
this
.
shouldQueueSearch
)
{
this
.
shouldQueueSearch
=
false
;
setTimeout
(()
=>
{
this
.
searchGitHub
(
title
);
this
.
shouldQueueSearch
=
true
;
},
timeToWait
*
1000
);
}
}).
catch
((
error
)
=>
{
th
is
.
logSearchError
(
error
);
}
);
th
row
new
Error
(
result
.
message
);
}
}).
catch
((
error
)
=>
{
this
.
logSearchError
(
error
);
});
}).
catch
((
error
)
=>
{
this
.
logSearchError
(
error
);
});
}
private
displaySearchResults
(
results
:
SearchResult
[])
{
const
similarIssues
=
document
.
getElementById
(
'
similar-issues
'
);
if
(
results
.
length
)
{
const
issues
=
$
(
'
ul.issues-container
'
);
const
issuesText
=
$
(
'
div.list-title
'
);
issuesText
.
textContent
=
localize
(
'
similarIssues
'
,
"
Similar issues
"
);
const
numResultsToDisplay
=
results
.
length
<
5
?
results
.
length
:
5
;
for
(
let
i
=
0
;
i
<
numResultsToDisplay
;
i
++
)
{
const
link
=
$
(
'
a
'
,
{
href
:
results
[
i
].
html_url
});
link
.
textContent
=
results
[
i
].
title
;
link
.
addEventListener
(
'
click
'
,
(
e
)
=>
this
.
openLink
(
e
));
link
.
addEventListener
(
'
auxclick
'
,
(
e
)
=>
this
.
openLink
(
<
MouseEvent
>
e
));
const
item
=
$
(
'
li.issue
'
,
{},
link
);
issues
.
appendChild
(
item
);
}
similarIssues
.
appendChild
(
issuesText
);
similarIssues
.
appendChild
(
issues
);
}
else
{
similarIssues
.
innerHTML
=
''
;
const
message
=
$
(
'
div.list-title
'
);
message
.
textContent
=
localize
(
'
noResults
'
,
"
No results found
"
);
similarIssues
.
appendChild
(
message
);
}
}
...
...
@@ -703,6 +770,22 @@ export class IssueReporter extends Disposable {
return
table
;
}
private
openLink
(
event
:
MouseEvent
):
void
{
event
.
preventDefault
();
event
.
stopPropagation
();
// Exclude right click
if
(
event
.
which
<
3
)
{
shell
.
openExternal
((
<
HTMLAnchorElement
>
event
.
target
).
href
);
/* __GDPR__
"issueReporterViewSimilarIssue" : {
"usingDuplicatesAPI" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this
.
telemetryService
.
publicLog
(
'
issueReporterViewSimilarIssue
'
,
{
usingDuplicatesAPI
:
this
.
features
.
useDuplicateSearch
});
}
}
}
// helper functions
...
...
@@ -713,12 +796,3 @@ function hide(el) {
function
show
(
el
)
{
el
.
classList
.
remove
(
'
hidden
'
);
}
function
openLink
(
event
:
MouseEvent
)
{
event
.
preventDefault
();
event
.
stopPropagation
();
// Exclude right click
if
(
event
.
which
<
3
)
{
shell
.
openExternal
((
<
HTMLAnchorElement
>
event
.
target
).
href
);
}
}
src/vs/code/electron-browser/issue/media/issueReporter.css
浏览文件 @
79d8060a
...
...
@@ -281,6 +281,7 @@ input, select, textarea {
a
{
color
:
#CCCCCC
;
text-decoration
:
none
;
}
.invalid-input
{
...
...
@@ -347,10 +348,20 @@ button {
}
}
body
::-webkit-scrollbar
{
.issues-container
::-webkit-scrollbar
,
body
::-webkit-scrollbar
{
width
:
14px
;
}
body
::-webkit-scrollbar-thumb
{
.issues-container
::-webkit-scrollbar
,
body
::-webkit-scrollbar-thumb
{
min-height
:
20px
;
}
.issues-container
{
margin-top
:
.5em
;
height
:
108px
;
overflow-y
:
auto
;
}
.issues-container
>
.issue
{
padding
:
1px
0
;
}
\ No newline at end of file
src/vs/platform/issue/common/issue.ts
浏览文件 @
79d8060a
...
...
@@ -55,6 +55,10 @@ export interface ISettingsSearchIssueReporterData extends IssueReporterData {
filterResultCount
:
number
;
}
export
interface
IssueReporterFeatures
{
useDuplicateSearch
:
boolean
;
}
export
interface
IIssueService
{
_serviceBrand
:
any
;
openReporter
(
data
:
IssueReporterData
):
TPromise
<
void
>
;
...
...
src/vs/platform/issue/electron-main/issueService.ts
浏览文件 @
79d8060a
...
...
@@ -9,12 +9,13 @@ import { TPromise, Promise } from 'vs/base/common/winjs.base';
import
{
localize
}
from
'
vs/nls
'
;
import
*
as
objects
from
'
vs/base/common/objects
'
;
import
{
parseArgs
}
from
'
vs/platform/environment/node/argv
'
;
import
{
IIssueService
,
IssueReporterData
}
from
'
vs/platform/issue/common/issue
'
;
import
{
IIssueService
,
IssueReporterData
,
IssueReporterFeatures
}
from
'
vs/platform/issue/common/issue
'
;
import
{
BrowserWindow
,
ipcMain
,
screen
}
from
'
electron
'
;
import
{
ILaunchService
}
from
'
vs/code/electron-main/launch
'
;
import
{
getPerformanceInfo
,
PerformanceInfo
,
getSystemInfo
,
SystemInfo
}
from
'
vs/code/electron-main/diagnostics
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
isMacintosh
}
from
'
vs/base/common/platform
'
;
import
{
IConfigurationService
}
from
'
../../configuration/common/configuration
'
;
const
DEFAULT_BACKGROUND_COLOR
=
'
#1E1E1E
'
;
...
...
@@ -26,7 +27,8 @@ export class IssueService implements IIssueService {
constructor
(
private
machineId
:
string
,
@
IEnvironmentService
private
environmentService
:
IEnvironmentService
,
@
ILaunchService
private
launchService
:
ILaunchService
@
ILaunchService
private
launchService
:
ILaunchService
,
@
IConfigurationService
private
configurationService
:
IConfigurationService
)
{
}
openReporter
(
data
:
IssueReporterData
):
TPromise
<
void
>
{
...
...
@@ -61,7 +63,11 @@ export class IssueService implements IIssueService {
this
.
_issueWindow
.
setMenuBarVisibility
(
false
);
// workaround for now, until a menu is implemented
this
.
_issueWindow
.
loadURL
(
this
.
getIssueReporterPath
(
data
));
const
features
:
IssueReporterFeatures
=
{
useDuplicateSearch
:
this
.
configurationService
.
getValue
<
boolean
>
(
'
issueReporter.searchDuplicates
'
)
};
this
.
_issueWindow
.
loadURL
(
this
.
getIssueReporterPath
(
data
,
features
));
return
TPromise
.
as
(
null
);
}
...
...
@@ -158,13 +164,14 @@ export class IssueService implements IIssueService {
});
}
private
getIssueReporterPath
(
data
:
IssueReporterData
)
{
private
getIssueReporterPath
(
data
:
IssueReporterData
,
features
:
IssueReporterFeatures
)
{
const
windowConfiguration
=
{
appRoot
:
this
.
environmentService
.
appRoot
,
nodeCachedDataDir
:
this
.
environmentService
.
nodeCachedDataDir
,
windowId
:
this
.
_issueWindow
.
id
,
machineId
:
this
.
machineId
,
data
data
,
features
};
const
environment
=
parseArgs
(
process
.
argv
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录