提交 c5f0bac2 编写于 作者: R Rachel Macfarlane

Create issue directly if signed in, fixes #95165

上级 0faf1550
...@@ -441,7 +441,11 @@ export class IssueReporter extends Disposable { ...@@ -441,7 +441,11 @@ export class IssueReporter extends Disposable {
private updatePreviewButtonState() { private updatePreviewButtonState() {
if (this.isPreviewEnabled()) { if (this.isPreviewEnabled()) {
this.previewButton.label = localize('previewOnGitHub', "Preview on GitHub"); if (this.configuration.data.githubAccessToken) {
this.previewButton.label = localize('createOnGitHub', "Create on GitHub");
} else {
this.previewButton.label = localize('previewOnGitHub', "Preview on GitHub");
}
this.previewButton.enabled = true; this.previewButton.enabled = true;
} else { } else {
this.previewButton.enabled = false; this.previewButton.enabled = false;
...@@ -776,6 +780,35 @@ export class IssueReporter extends Disposable { ...@@ -776,6 +780,35 @@ export class IssueReporter extends Disposable {
return isValid; return isValid;
} }
private async submitToGitHub(issueTitle: string, issueBody: string, gitHubDetails: { owner: string, repositoryName: string }): Promise<boolean> {
const url = `https://api.github.com/repos/${gitHubDetails.owner}/${gitHubDetails.repositoryName}/issues`;
const init = {
method: 'POST',
body: JSON.stringify({
title: issueTitle,
body: issueBody
}),
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.configuration.data.githubAccessToken}`
})
};
return new Promise((resolve, reject) => {
window.fetch(url, init).then((response) => {
if (response.ok) {
response.json().then(result => {
ipcRenderer.send('vscode:openExternal', result.html_url);
ipcRenderer.send('vscode:closeIssueReporter');
resolve(true);
});
} else {
resolve(false);
}
});
});
}
private async createIssue(): Promise<boolean> { private async createIssue(): Promise<boolean> {
if (!this.validateInputs()) { if (!this.validateInputs()) {
// If inputs are invalid, set focus to the first one and add listeners on them // If inputs are invalid, set focus to the first one and add listeners on them
...@@ -808,8 +841,16 @@ export class IssueReporter extends Disposable { ...@@ -808,8 +841,16 @@ export class IssueReporter extends Disposable {
this.hasBeenSubmitted = true; this.hasBeenSubmitted = true;
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value); const issueTitle = (<HTMLInputElement>this.getElementById('issue-title')).value;
const issueBody = this.issueReporterModel.serialize(); const issueBody = this.issueReporterModel.serialize();
const issueUrl = this.issueReporterModel.fileOnExtension() ? this.getExtensionGitHubUrl() : this.configuration.product.reportIssueUrl!;
const gitHubDetails = this.parseGitHubUrl(issueUrl);
if (this.configuration.data.githubAccessToken && gitHubDetails) {
return this.submitToGitHub(issueTitle, issueBody, gitHubDetails);
}
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value);
let url = baseUrl + `&body=${encodeURIComponent(issueBody)}`; let url = baseUrl + `&body=${encodeURIComponent(issueBody)}`;
if (url.length > MAX_URL_LENGTH) { if (url.length > MAX_URL_LENGTH) {
...@@ -839,6 +880,20 @@ export class IssueReporter extends Disposable { ...@@ -839,6 +880,20 @@ export class IssueReporter extends Disposable {
}); });
} }
private parseGitHubUrl(url: string): undefined | { repositoryName: string, owner: string } {
// Assumes a GitHub url to a particular repo, https://github.com/repositoryName/owner.
// Repository name and owner cannot contain '/'
const match = /^https?:\/\/github\.com\/([^\/]*)\/([^\/]*).*/.exec(url);
if (match && match.length) {
return {
owner: match[1],
repositoryName: match[2]
};
}
return undefined;
}
private getExtensionGitHubUrl(): string { private getExtensionGitHubUrl(): string {
let repositoryUrl = ''; let repositoryUrl = '';
const bugsUrl = this.getExtensionBugsUrl(); const bugsUrl = this.getExtensionBugsUrl();
......
...@@ -56,6 +56,7 @@ export interface IssueReporterData extends WindowData { ...@@ -56,6 +56,7 @@ export interface IssueReporterData extends WindowData {
issueType?: IssueType; issueType?: IssueType;
extensionId?: string; extensionId?: string;
experiments?: string; experiments?: string;
githubAccessToken: string;
readonly issueTitle?: string; readonly issueTitle?: string;
readonly issueBody?: string; readonly issueBody?: string;
} }
......
...@@ -17,6 +17,7 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions'; ...@@ -17,6 +17,7 @@ import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { ITASExperimentService } from 'vs/workbench/services/experiment/common/experimentService'; import { ITASExperimentService } from 'vs/workbench/services/experiment/common/experimentService';
import { IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
export class WorkbenchIssueService implements IWorkbenchIssueService { export class WorkbenchIssueService implements IWorkbenchIssueService {
declare readonly _serviceBrand: undefined; declare readonly _serviceBrand: undefined;
...@@ -28,7 +29,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { ...@@ -28,7 +29,8 @@ export class WorkbenchIssueService implements IWorkbenchIssueService {
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService, @IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService,
@INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService, @INativeWorkbenchEnvironmentService private readonly environmentService: INativeWorkbenchEnvironmentService,
@IProductService private readonly productService: IProductService, @IProductService private readonly productService: IProductService,
@ITASExperimentService private readonly experimentService: ITASExperimentService @ITASExperimentService private readonly experimentService: ITASExperimentService,
@IAuthenticationService private readonly authenticationService: IAuthenticationService
) { } ) { }
async openReporter(dataOverrides: Partial<IssueReporterData> = {}): Promise<void> { async openReporter(dataOverrides: Partial<IssueReporterData> = {}): Promise<void> {
...@@ -52,12 +54,15 @@ export class WorkbenchIssueService implements IWorkbenchIssueService { ...@@ -52,12 +54,15 @@ export class WorkbenchIssueService implements IWorkbenchIssueService {
}; };
}); });
const experiments = await this.experimentService.getCurrentExperiments(); const experiments = await this.experimentService.getCurrentExperiments();
const githubSessions = await this.authenticationService.getSessions('github');
const potentialSessions = githubSessions.filter(session => session.scopes.includes('repo'));
const theme = this.themeService.getColorTheme(); const theme = this.themeService.getColorTheme();
const issueReporterData: IssueReporterData = Object.assign({ const issueReporterData: IssueReporterData = Object.assign({
styles: getIssueReporterStyles(theme), styles: getIssueReporterStyles(theme),
zoomLevel: getZoomLevel(), zoomLevel: getZoomLevel(),
enabledExtensions: extensionData, enabledExtensions: extensionData,
experiments: experiments?.join('\n') experiments: experiments?.join('\n'),
githubAccessToken: potentialSessions[0]?.accessToken
}, dataOverrides); }, dataOverrides);
return this.issueService.openReporter(issueReporterData); return this.issueService.openReporter(issueReporterData);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册