提交 260d2992 编写于 作者: M Matt Bierner

Prototyping declarative action contribution for threads

上级 bd83b6da
......@@ -8,6 +8,14 @@ import * as vscode from 'vscode';
import * as _ from 'lodash';
import { Comment } from './common/models/comment';
class PostCommentCommand {
public static readonly id = 'pr.postComment';
public static run(id: string, text: string) {
vscode.window.showInformationMessage(`posty! ${text}`);
}
}
export interface ICommentsProvider {
provideComments(uri: vscode.Uri): Promise<Comment[]>;
}
......@@ -20,6 +28,8 @@ export class CommentsProvider implements vscode.CommentProvider {
this.providers = new Map<number, ICommentsProvider>();
this._id = 0;
vscode.workspace.registerCommentProvider(this);
vscode.commands.registerCommand(PostCommentCommand.id, PostCommentCommand.run);
}
registerCommentProvider(provider: ICommentsProvider): number {
......@@ -51,7 +61,7 @@ export class CommentsProvider implements vscode.CommentProvider {
}
let sections = _.groupBy(matchingComments, comment => comment.position);
let ret = [];
let ret: vscode.CommentThread[] = [];
for (let i in sections) {
let comments = sections[i];
......@@ -63,6 +73,7 @@ export class CommentsProvider implements vscode.CommentProvider {
const newCommentEndPos = new vscode.Position(comment.diff_hunk_range.start + comment.diff_hunk_range.length - 1 - 1, 0);
ret.push({
threadId: comment.id,
range,
newCommentRange: new vscode.Range(newCommentStartPos, newCommentEndPos),
comments: comments.map(comment => {
......@@ -71,7 +82,13 @@ export class CommentsProvider implements vscode.CommentProvider {
userName: comment.user.login,
gravatar: comment.user.avatar_url
};
})
}),
actions: [
{
command: PostCommentCommand.id,
title: 'Post'
}
]
});
}
......
......@@ -27,11 +27,6 @@
],
"contributes": {
"commands": [
{
"command": "unicorn",
"title": "🦄 unicorn",
"category": "Markdown"
},
{
"command": "markdown.showPreview",
"title": "%markdown.preview.title%",
......
......@@ -939,9 +939,11 @@ export interface Command {
export interface CommentThread {
readonly threadId: string;
readonly range: IRange;
readonly newCommentRange: IRange;
readonly comments: Comment[];
readonly actions: Command[];
}
export interface Comment {
......
......@@ -28,6 +28,7 @@ import { registerThemingParticipant, ITheme, IThemeService } from 'vs/platform/t
import { peekViewEditorBackground, peekViewBorder, } from 'vs/editor/contrib/referenceSearch/referencesWidget';
import { Color } from 'vs/base/common/color';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ICommandService } from 'vs/platform/commands/common/commands';
export const ctxReviewPanelVisible = new RawContextKey<boolean>('reviewPanelVisible', false);
export const ID = 'editor.contrib.review';
......@@ -72,7 +73,10 @@ export class ReviewZoneWidget extends ZoneWidget {
private _resizeObserver: any;
private _comments: modes.Comment[];
constructor(@IThemeService private themeService: IThemeService,
constructor(
private readonly themeService: IThemeService,
private readonly commandService: ICommandService,
editor: ICodeEditor, options: IOptions = {}, comments: modes.Comment[]) {
super(editor, options);
this._resizeObserver = null;
......@@ -125,7 +129,8 @@ export class ReviewZoneWidget extends ZoneWidget {
}
display(comments: modes.Comment[], lineNumber: number) {
display(commentThread: modes.CommentThread, lineNumber: number) {
const comments = commentThread.comments;
this.show({ lineNumber: lineNumber, column: 1 }, 2);
this._bodyElement.style.display = 'none';
......@@ -161,7 +166,19 @@ export class ReviewZoneWidget extends ZoneWidget {
body.appendChild(renderMarkdown(md));
this._bodyElement.appendChild(singleCommentContainer);
}
// this._domNode.appendChild(document.createElement('textarea'));
const textArea = document.createElement('textarea');
this._bodyElement.appendChild(textArea);
for (const action of commentThread.actions) {
const button = document.createElement('button');
button.onclick = () => {
this.commandService.executeCommand(action.id, commentThread.threadId, textArea.value);
};
button.textContent = action.title;
this._bodyElement.appendChild(button);
}
this._resizeObserver = new ResizeObserver(entries => {
if (entries[0].target === this._bodyElement) {
const lineHeight = this.editor.getConfiguration().lineHeight;
......@@ -207,7 +224,8 @@ export class ReviewController implements IEditorContribution {
constructor(
editor: ICodeEditor,
@IContextKeyService contextKeyService: IContextKeyService,
@IThemeService private themeService: IThemeService
@IThemeService private themeService: IThemeService,
@ICommandService private commandService: ICommandService,
) {
this.editor = editor;
this.globalToDispose = [];
......@@ -307,11 +325,11 @@ export class ReviewController implements IEditorContribution {
return;
}
let comments = this.getComments(lineNumber);
if (comments && comments.length) {
let thread = this.getCommentThread(lineNumber);
if (thread && thread.comments.length) {
this._reviewPanelVisible.set(true);
this._zoneWidget = new ReviewZoneWidget(this.themeService, this.editor, {}, comments);
this._zoneWidget.display(this.getComments(lineNumber), lineNumber);
this._zoneWidget = new ReviewZoneWidget(this.themeService, this.commandService, this.editor, {}, thread.comments);
this._zoneWidget.display(this.getCommentThread(lineNumber), lineNumber);
}
}
......@@ -371,14 +389,14 @@ export class ReviewController implements IEditorContribution {
return true;
}
getComments(line: number): modes.Comment[] {
getCommentThread(line: number): modes.CommentThread | undefined {
for (let i = 0; i < this._commentThreads.length; i++) {
if (this._commentThreads[i].range.startLineNumber === line) {
return this._commentThreads[i].comments;
return this._commentThreads[i];
}
}
return [];
return undefined;
}
setComments(commentThreads: modes.CommentThread[]): void {
......@@ -396,8 +414,8 @@ export class ReviewController implements IEditorContribution {
});
this._commentThreads.forEach(thread => {
let zoneWidget = new ReviewZoneWidget(this.themeService, this.editor, {}, thread.comments);
zoneWidget.display(this.getComments(thread.range.startLineNumber), thread.range.startLineNumber);
let zoneWidget = new ReviewZoneWidget(this.themeService, this.commandService, this.editor, {}, thread.comments);
zoneWidget.display(this.getCommentThread(thread.range.startLineNumber), thread.range.startLineNumber);
this._zoneWidgets.push(zoneWidget);
});
......
......@@ -5029,9 +5029,11 @@ declare namespace monaco.languages {
}
export interface CommentThread {
readonly threadId: string;
readonly range: IRange;
readonly newCommentRange: IRange;
readonly comments: Comment[];
readonly actions: Command[];
}
export interface Comment {
......
......@@ -771,9 +771,11 @@ declare module 'vscode' {
//#endregion
interface CommentThread {
threadId: string;
range: Range;
newCommentRange: Range;
comments: Comment[];
actions?: Command[];
}
interface Comment {
......
......@@ -120,7 +120,7 @@ export function createApiFactory(
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
const exthostCommentProviders = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostDocuments));
const exthostCommentProviders = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands.converter, extHostDocuments));
// Check that no named customers are missing
const expected: ProxyIdentifier<any>[] = Object.keys(ExtHostContext).map((key) => ExtHostContext[key]);
......
......@@ -11,11 +11,11 @@ import URI, { UriComponents } from 'vs/base/common/uri';
import { TPromise } from 'vs/base/common/winjs.base';
import * as modes from 'vs/editor/common/modes';
import { ExtHostDocuments } from 'vs/workbench/api/node/extHostDocuments';
import * as extHostTypeConverter from 'vs/workbench/api/node/extHostTypeConverters';
import * as vscode from 'vscode';
import { flatten } from '../../../base/common/arrays';
import { ExtHostCommentsShape, IMainContext, MainContext, MainThreadCommentsShape } from './extHost.protocol';
import * as extHostTypeConverter from 'vs/workbench/api/node/extHostTypeConverters';
import { CommandsConverter } from './extHostCommands';
export class ExtHostComments implements ExtHostCommentsShape {
......@@ -27,6 +27,7 @@ export class ExtHostComments implements ExtHostCommentsShape {
constructor(
mainContext: IMainContext,
private readonly _commandsConverter: CommandsConverter,
private readonly _documents: ExtHostDocuments,
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadComments);
......@@ -58,15 +59,17 @@ export class ExtHostComments implements ExtHostCommentsShape {
return TPromise.join(allProviderResults);
})
.then(flatten)
.then(comments => comments.map(convertCommentThread));
.then(comments => comments.map(x => convertCommentThread(x, this._commandsConverter)));
}
}
function convertCommentThread(vscodeCommentThread: vscode.CommentThread): modes.CommentThread {
function convertCommentThread(vscodeCommentThread: vscode.CommentThread, commandsConverter: CommandsConverter): modes.CommentThread {
return {
threadId: vscodeCommentThread.threadId,
range: extHostTypeConverter.fromRange(vscodeCommentThread.range),
newCommentRange: extHostTypeConverter.fromRange(vscodeCommentThread.newCommentRange),
comments: vscodeCommentThread.comments.map(convertComment)
comments: vscodeCommentThread.comments.map(convertComment),
actions: vscodeCommentThread.actions.map(commandsConverter.toInternal)
};
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册