提交 c4efd003 编写于 作者: P Peng Lyu

show diff view editor for outdated comments.

上级 3ef1b53c
......@@ -84,6 +84,10 @@
"command": "pr.openDescription",
"title": "View Pull Request Description"
},
{
"command": "pr.viewChanges",
"title": "View Changes"
},
{
"command": "review.openFile",
"title": "Open File",
......
......@@ -9,6 +9,7 @@ import { PullRequestModel } from './common/models/pullRequestModel';
import { FileChangeTreeItem } from './common/treeItems';
import { ReviewManager } from './review/reviewManager';
import { PullRequestOverviewPanel } from './common/pullRequestOverview';
import { fromGitUri, toGitUri } from './common/uri';
export function registerCommands(context: vscode.ExtensionContext) {
// initialize resources
......@@ -50,4 +51,18 @@ export function registerCommands(context: vscode.ExtensionContext) {
// Create and show a new webview
PullRequestOverviewPanel.createOrShow(context.extensionPath, pr);
}));
context.subscriptions.push(vscode.commands.registerCommand('pr.viewChanges', async (fileChange: FileChangeTreeItem) => {
// Show the file change in a diff view.
let { path, ref, commit } = fromGitUri(fileChange.filePath);
let previousCommit = `${commit}^`;
let previousFileUri = fileChange.filePath.with({
query: JSON.stringify({
path: path,
ref: ref,
commit: previousCommit
})
});
return vscode.commands.executeCommand('vscode.diff', previousFileUri, fileChange.filePath, `${fileChange.fileName} from ${commit}`);
}));
}
......@@ -397,7 +397,14 @@ export class ReviewManager implements vscode.DecorationProvider {
commentId: comment.id,
body: new vscode.MarkdownString(comment.body),
userName: comment.user.login,
gravatar: comment.user.avatar_url
gravatar: comment.user.avatar_url,
command: {
title: 'View Changes',
command: 'pr.viewChanges',
arguments: [
fileChange
]
}
};
}),
collapsibleState: collapsibleState
......
......@@ -985,6 +985,7 @@ export interface Comment {
readonly body: IMarkdownString;
readonly userName: string;
readonly gravatar: string;
readonly command?: Command;
}
export interface CommentThreadChangedEvent {
......
......@@ -5180,6 +5180,7 @@ declare namespace monaco.languages {
readonly body: IMarkdownString;
readonly userName: string;
readonly gravatar: string;
readonly command?: Command;
}
export interface CommentThreadChangedEvent {
......
......@@ -554,6 +554,7 @@ declare module 'vscode' {
body: MarkdownString;
userName: string;
gravatar: string;
command?: Command;
}
export interface CommentThreadChangedEvent {
......
......@@ -75,7 +75,7 @@ export class ExtHostComments implements ExtHostCommentsShape {
return asWinJsPromise(token => {
let provider = this._documentProviders.get(handle);
return provider.createNewCommentThread(data.document, ran, text, token);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread) : null);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
}
$replyToCommentThread(handle: number, uri: UriComponents, range: IRange, thread: modes.CommentThread, text: string): TPromise<modes.CommentThread> {
......@@ -89,7 +89,7 @@ export class ExtHostComments implements ExtHostCommentsShape {
return asWinJsPromise(token => {
let provider = this._documentProviders.get(handle);
return provider.replyToCommentThread(data.document, ran, convertFromCommentThread(thread), text, token);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread) : null);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
}
$provideDocumentComments(handle: number, uri: UriComponents): TPromise<modes.CommentInfo> {
......@@ -114,7 +114,7 @@ export class ExtHostComments implements ExtHostCommentsShape {
return asWinJsPromise(token => {
return provider.provideWorkspaceComments(token);
}).then(comments =>
comments.map(x => convertToCommentThread(x)
comments.map(x => convertToCommentThread(x, this._commandsConverter)
));
}
......@@ -123,9 +123,9 @@ export class ExtHostComments implements ExtHostCommentsShape {
this._proxy.$onDidCommentThreadsChange(handle, {
owner: handle,
changed: event.changed.map(x => convertToCommentThread(x)),
added: event.added.map(x => convertToCommentThread(x)),
removed: event.removed.map(x => convertToCommentThread(x))
changed: event.changed.map(x => convertToCommentThread(x, this._commandsConverter)),
added: event.added.map(x => convertToCommentThread(x, this._commandsConverter)),
removed: event.removed.map(x => convertToCommentThread(x, this._commandsConverter))
});
});
}
......@@ -134,17 +134,17 @@ export class ExtHostComments implements ExtHostCommentsShape {
function convertCommentInfo(owner: number, vscodeCommentInfo: vscode.CommentInfo, commandsConverter: CommandsConverter): modes.CommentInfo {
return {
owner: owner,
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(x)),
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(x, commandsConverter)),
commentingRanges: vscodeCommentInfo.commentingRanges ? vscodeCommentInfo.commentingRanges.map(range => extHostTypeConverter.Range.from(range)) : []
};
}
function convertToCommentThread(vscodeCommentThread: vscode.CommentThread): modes.CommentThread {
function convertToCommentThread(vscodeCommentThread: vscode.CommentThread, commandsConverter: CommandsConverter): modes.CommentThread {
return {
threadId: vscodeCommentThread.threadId,
resource: vscodeCommentThread.resource.toString(),
range: extHostTypeConverter.Range.from(vscodeCommentThread.range),
comments: vscodeCommentThread.comments.map(convertToComment),
comments: vscodeCommentThread.comments.map(comment => convertToComment(comment, commandsConverter)),
collapsibleState: vscodeCommentThread.collapsibleState
};
}
......@@ -168,11 +168,12 @@ function convertFromComment(comment: modes.Comment): vscode.Comment {
};
}
function convertToComment(vscodeComment: vscode.Comment): modes.Comment {
function convertToComment(vscodeComment: vscode.Comment, commandsConverter: CommandsConverter): modes.Comment {
return {
commentId: vscodeComment.commentId,
body: extHostTypeConverter.MarkdownString.from(vscodeComment.body),
userName: vscodeComment.userName,
gravatar: vscodeComment.gravatar
gravatar: vscodeComment.gravatar,
command: vscodeComment.command ? commandsConverter.toInternal(vscodeComment.command) : null
};
}
......@@ -9,7 +9,7 @@ import { IAction } from 'vs/base/common/actions';
import { debounceEvent } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { CollapseAllAction, DefaultAccessibilityProvider, DefaultController, DefaultDragAndDrop } from 'vs/base/parts/tree/browser/treeDefaults';
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
import { isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
import { CommentThread, CommentThreadChangedEvent } from 'vs/editor/common/modes';
import { localize } from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -23,6 +23,10 @@ import { CommentsDataFilter, CommentsDataSource, CommentsModelRenderer } from 'v
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
import { ICommentService } from 'vs/workbench/services/comments/electron-browser/commentService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ICommandService } from '../../../../platform/commands/common/commands';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { TextDiffEditor } from '../../../browser/parts/editor/textDiffEditor';
import { DiffEditorWidget } from '../../../../editor/browser/widget/diffEditorWidget';
export const COMMENTS_PANEL_ID = 'workbench.panel.comments';
export const COMMENTS_PANEL_TITLE = 'Comments';
......@@ -39,6 +43,7 @@ export class CommentsPanel extends Panel {
@IInstantiationService private instantiationService: IInstantiationService,
@ICommentService private commentService: ICommentService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@ICommandService private commandService: ICommandService,
@ITelemetryService telemetryService: ITelemetryService,
@IThemeService themeService: IThemeService,
@IActivityService private activityService: IActivityService
......@@ -151,24 +156,65 @@ export class CommentsPanel extends Panel {
}
});
});
Promise.all([this.editorService.openEditor({
resource: element.resource,
options: {
pinned: pinned,
preserveFocus: preserveFocus,
selection: range
}
}, sideBySide), setCommentsForFile]).then(vals => {
let editor = vals[0];
const threadToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].threadId : element.threadId;
const commentToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].comment.commentId : element.comment.commentId;
const control = editor.getControl();
if (threadToReveal && isCodeEditor(control)) {
const controller = ReviewController.get(control);
controller.revealCommentThread(threadToReveal, commentToReveal);
}
setCommentsForFile = null;
});
const threadToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].threadId : element.threadId;
const commentToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].comment : element.comment;
if (commentToReveal.command) {
Promise.all([
this.commandService.executeCommand(commentToReveal.command.id, ...commentToReveal.command.arguments),
setCommentsForFile
]).then(_ => {
let activeInput = this.editorService.getActiveEditorInput();
if (activeInput && activeInput instanceof DiffEditorInput) {
let activeEditor = this.editorService.getActiveEditor();
const control = activeEditor.getControl() as DiffEditorWidget;
const originalEditorControl = control.getOriginalEditor();
const modifiedEditorControl = control.getModifiedEditor();
let controller;
if (activeInput.originalInput.getResource().toString() === element.resource.toString()) {
controller = ReviewController.get(originalEditorControl);
} else if (activeInput.modifiedInput.getResource().toString() === element.resource.toString()) {
controller = ReviewController.get(modifiedEditorControl);
}
if (controller) {
controller.revealCommentThread(threadToReveal, commentToReveal.commentId);
}
} else {
let currentActiveResource = activeInput ? activeInput.getResource() : void 0;
if (currentActiveResource && currentActiveResource.toString() === element.resource.toString()) {
const control = this.editorService.getActiveEditor().getControl();
if (threadToReveal && isCodeEditor(control)) {
const controller = ReviewController.get(control);
controller.revealCommentThread(threadToReveal, commentToReveal.commentId);
}
}
}
return true;
});
} else {
Promise.all([this.editorService.openEditor({
resource: element.resource,
options: {
pinned: pinned,
preserveFocus: preserveFocus,
selection: range
}
}, sideBySide), setCommentsForFile]).then(vals => {
let editor = vals[0];
const control = editor.getControl();
if (threadToReveal && isCodeEditor(control)) {
const controller = ReviewController.get(control);
console.log(commentToReveal.command);
controller.revealCommentThread(threadToReveal, commentToReveal.commentId);
}
setCommentsForFile = null;
});
}
return true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册