提交 11d48f12 编写于 作者: R rebornix

first cut

上级 f80c9296
......@@ -1145,6 +1145,16 @@ export interface CommentInfo {
threads: CommentThread[];
commentingRanges?: IRange[];
reply?: Command;
draftMode: DraftMode;
}
/**
* @internal
*/
export enum DraftMode {
NotSupported,
InDraft,
NotInDraft
}
/**
......@@ -1223,6 +1233,13 @@ export interface DocumentCommentProvider {
replyToCommentThread(resource: URI, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise<CommentThread>;
editComment(resource: URI, comment: Comment, text: string, token: CancellationToken): Promise<void>;
deleteComment(resource: URI, comment: Comment, token: CancellationToken): Promise<void>;
startDraft?(token: CancellationToken): Promise<void>;
deleteDraft?(token: CancellationToken): Promise<void>;
finishDraft?(token: CancellationToken): Promise<void>;
startDraftLabel?: string;
deleteDraftLabel?: string;
finishDraftLabel?: string;
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
}
......
......@@ -809,6 +809,11 @@ declare module 'vscode' {
* The ranges of the document which support commenting.
*/
commentingRanges?: Range[];
/**
* If it's in draft mode or not
*/
inDraftMode?: boolean;
}
export enum CommentThreadCollapsibleState {
......@@ -903,6 +908,8 @@ declare module 'vscode' {
* The command to be executed if the comment is selected in the Comments Panel
*/
command?: Command;
isDraft?: boolean;
}
export interface CommentThreadChangedEvent {
......@@ -948,6 +955,14 @@ declare module 'vscode' {
*/
deleteComment?(document: TextDocument, comment: Comment, token: CancellationToken): Promise<void>;
startDraft?(token: CancellationToken): Promise<void>;
deleteDraft?(token: CancellationToken): Promise<void>;
finishDraft?(token: CancellationToken): Promise<void>;
startDraftLabel?: string;
deleteDraftLabel?: string;
finishDraftLabel?: string;
/**
* Notify of updates to comment threads.
*/
......
......@@ -9,7 +9,7 @@ import * as modes from 'vs/editor/common/modes';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { keys } from 'vs/base/common/map';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape } from '../node/extHost.protocol';
import { ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape, CommentProviderFeatures } from '../node/extHost.protocol';
import { ICommentService } from 'vs/workbench/parts/comments/electron-browser/commentService';
import { COMMENTS_PANEL_ID } from 'vs/workbench/parts/comments/electron-browser/commentsPanel';
......@@ -18,13 +18,18 @@ import { URI } from 'vs/base/common/uri';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { generateUuid } from 'vs/base/common/uuid';
export class ExtensionCommentProviderHandler implements modes.DocumentCommentProvider {
export class MainThreadDocumentCommentProvider implements modes.DocumentCommentProvider {
private _proxy: ExtHostCommentsShape;
private _handle: number;
private _features: CommentProviderFeatures;
get startDraftLabel(): string { return this._features.startDraftLabel; }
get deleteDraftLabel(): string { return this._features.deleteDraftLabel; }
get finishDraftLabel(): string { return this._features.finishDraftLabel; }
constructor(proxy: ExtHostCommentsShape, handle: number) {
constructor(proxy: ExtHostCommentsShape, handle: number, features: CommentProviderFeatures) {
this._proxy = proxy;
this._handle = handle;
this._features = features;
}
async provideDocumentComments(uri, token) {
......@@ -49,6 +54,7 @@ export class ExtensionCommentProviderHandler implements modes.DocumentCommentPro
onDidChangeCommentThreads = null;
}
@extHostNamedCustomer(MainContext.MainThreadComments)
export class MainThreadComments extends Disposable implements MainThreadCommentsShape {
private _disposables: IDisposable[];
......@@ -71,9 +77,9 @@ export class MainThreadComments extends Disposable implements MainThreadComments
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostComments);
}
$registerDocumentCommentProvider(handle: number): void {
$registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void {
this._documentProviders.set(handle, undefined);
const handler = new ExtensionCommentProviderHandler(this._proxy, handle);
const handler = new MainThreadDocumentCommentProvider(this._proxy, handle, features);
const providerId = generateUuid();
this._handlers.set(handle, providerId);
......
......@@ -102,8 +102,14 @@ export interface MainThreadCommandsShape extends IDisposable {
$getCommands(): Thenable<string[]>;
}
export interface CommentProviderFeatures {
startDraftLabel?: string;
deleteDraftLabel?: string;
finishDraftLabel?: string;
}
export interface MainThreadCommentsShape extends IDisposable {
$registerDocumentCommentProvider(handle: number): void;
$registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void;
$unregisterDocumentCommentProvider(handle: number): void;
$registerWorkspaceCommentProvider(handle: number, extensionId: string): void;
$unregisterWorkspaceCommentProvider(handle: number): void;
......@@ -1031,6 +1037,7 @@ export interface ExtHostCommentsShape {
$replyToCommentThread(handle: number, document: UriComponents, range: IRange, commentThread: modes.CommentThread, text: string): Thenable<modes.CommentThread>;
$editComment(handle: number, document: UriComponents, comment: modes.Comment, text: string): Thenable<void>;
$deleteComment(handle: number, document: UriComponents, comment: modes.Comment): Thenable<void>;
$getStartDraftLabel(handle: number): Thenable<string>;
$provideWorkspaceComments(handle: number): Thenable<modes.CommentThread[]>;
}
......
......@@ -52,7 +52,11 @@ export class ExtHostComments implements ExtHostCommentsShape {
): vscode.Disposable {
const handle = ExtHostComments.handlePool++;
this._documentProviders.set(handle, provider);
this._proxy.$registerDocumentCommentProvider(handle);
this._proxy.$registerDocumentCommentProvider(handle, {
startDraftLabel: provider.startDraftLabel,
deleteDraftLabel: provider.deleteDraftLabel,
finishDraftLabel: provider.finishDraftLabel
});
this.registerListeners(handle, provider);
return {
......@@ -117,6 +121,13 @@ export class ExtHostComments implements ExtHostCommentsShape {
});
}
$getStartDraftLabel(handle: number): Thenable<string> {
const provider = this._documentProviders.get(handle);
return asThenable(() => {
return provider.startDraftLabel;
});
}
$provideDocumentComments(handle: number, uri: UriComponents): Thenable<modes.CommentInfo> {
const data = this._documents.getDocumentData(URI.revive(uri));
if (!data || !data.document) {
......@@ -157,7 +168,8 @@ export class ExtHostComments implements ExtHostCommentsShape {
function convertCommentInfo(owner: number, provider: vscode.DocumentCommentProvider, vscodeCommentInfo: vscode.CommentInfo, commandsConverter: CommandsConverter): modes.CommentInfo {
return {
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(provider, x, commandsConverter)),
commentingRanges: vscodeCommentInfo.commentingRanges ? vscodeCommentInfo.commentingRanges.map(range => extHostTypeConverter.Range.from(range)) : []
commentingRanges: vscodeCommentInfo.commentingRanges ? vscodeCommentInfo.commentingRanges.map(range => extHostTypeConverter.Range.from(range)) : [],
draftMode: provider.startDraft ? (vscodeCommentInfo.inDraftMode ? modes.DraftMode.InDraft : modes.DraftMode.NotInDraft) : modes.DraftMode.NotSupported
};
}
......
......@@ -11,7 +11,7 @@ import { URI } from 'vs/base/common/uri';
import { Range } from 'vs/editor/common/core/range';
import { keys } from 'vs/base/common/map';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionCommentProviderHandler } from 'vs/workbench/api/electron-browser/mainThreadComments';
import { MainThreadDocumentCommentProvider } from 'vs/workbench/api/electron-browser/mainThreadComments';
import { assign } from 'vs/base/common/objects';
import { ICommentThreadChangedEvent } from 'vs/workbench/parts/comments/common/commentModel';
......@@ -41,7 +41,7 @@ export interface ICommentService {
setDocumentComments(resource: URI, commentInfos: ICommentInfo[]): void;
setWorkspaceComments(owner: string, commentsByResource: CommentThread[]): void;
removeWorkspaceComments(owner: string): void;
registerDataProvider(owner: string, commentProvider: ExtensionCommentProviderHandler): void;
registerDataProvider(owner: string, commentProvider: MainThreadDocumentCommentProvider): void;
unregisterDataProvider(owner: string): void;
updateComments(ownerId: string, event: CommentThreadChangedEvent): void;
createNewCommentThread(owner: string, resource: URI, range: Range, text: string): Promise<CommentThread | null>;
......@@ -49,6 +49,9 @@ export interface ICommentService {
editComment(owner: string, resource: URI, comment: Comment, text: string): Promise<void>;
deleteComment(owner: string, resource: URI, comment: Comment): Promise<boolean>;
getComments(resource: URI): Promise<ICommentInfo[]>;
getStartDraftLabel(owner: string): string;
getDeleteDraftLabel(owner: string): string;
getFinishDraftLabel(owner: string): string;
}
export class CommentService extends Disposable implements ICommentService {
......@@ -142,6 +145,36 @@ export class CommentService extends Disposable implements ICommentService {
return Promise.resolve(false);
}
getStartDraftLabel(owner: string): string | null {
const commentProvider = this._commentProviders.get(owner);
if (commentProvider) {
return commentProvider.startDraftLabel;
}
return null;
}
getDeleteDraftLabel(owner: string): string {
const commentProvider = this._commentProviders.get(owner);
if (commentProvider) {
return commentProvider.deleteDraftLabel;
}
return null;
}
getFinishDraftLabel(owner: string): string {
const commentProvider = this._commentProviders.get(owner);
if (commentProvider) {
return commentProvider.finishDraftLabel;
}
return null;
}
getComments(resource: URI): Promise<ICommentInfo[]> {
const result: Promise<ICommentInfo>[] = [];
for (const owner of keys(this._commentProviders)) {
......
......@@ -65,6 +65,7 @@ export class ReviewZoneWidget extends ZoneWidget {
private _commentGlyph: CommentGlyphWidget;
private _owner: string;
private _pendingComment: string;
private _draftMode: modes.DraftMode;
private _localToDispose: IDisposable[];
private _globalToDispose: IDisposable[];
private _markdownRenderer: MarkdownRenderer;
......@@ -91,6 +92,7 @@ export class ReviewZoneWidget extends ZoneWidget {
owner: string,
commentThread: modes.CommentThread,
pendingComment: string,
draftMode: modes.DraftMode,
options: IOptions = {}
) {
super(editor, options);
......@@ -98,6 +100,7 @@ export class ReviewZoneWidget extends ZoneWidget {
this._owner = owner;
this._commentThread = commentThread;
this._pendingComment = pendingComment;
this._draftMode = draftMode;
this._isCollapsed = commentThread.collapsibleState !== modes.CommentThreadCollapsibleState.Expanded;
this._globalToDispose = [];
this._localToDispose = [];
......@@ -348,6 +351,27 @@ export class ReviewZoneWidget extends ZoneWidget {
this.createComment(lineNumber);
});
if (this._draftMode !== modes.DraftMode.NotSupported) {
// render draft button
const draftButton = new Button(formActions);
attachButtonStyler(draftButton, this.themeService);
draftButton.label = this.commentService.getStartDraftLabel(this._owner);
draftButton.enabled = model.getValueLength() > 0;
this._localToDispose.push(this._commentEditor.onDidChangeModelContent(_ => {
if (this._commentEditor.getValue()) {
draftButton.enabled = true;
} else {
draftButton.enabled = false;
}
}));
// draftButton.onDidClick(async () => {
// let lineNumber = this._commentGlyph.getPosition().position.lineNumber;
// this.createComment(lineNumber);
// });
}
this._resizeObserver = new MutationObserver(this._refresh.bind(this));
this._resizeObserver.observe(this._bodyElement, {
......
......@@ -375,10 +375,13 @@ export class ReviewController implements IEditorContribution {
return;
}
if (!this._commentInfos.some(info => info.owner === e.owner)) {
let commentInfo = this._commentInfos.filter(info => info.owner === e.owner);
if (!commentInfo || !commentInfo.length) {
return;
}
let draftMode = commentInfo[0].draftMode;
let added = e.added.filter(thread => thread.resource.toString() === editorURI.toString());
let removed = e.removed.filter(thread => thread.resource.toString() === editorURI.toString());
let changed = e.changed.filter(thread => thread.resource.toString() === editorURI.toString());
......@@ -400,7 +403,7 @@ export class ReviewController implements IEditorContribution {
}
});
added.forEach(thread => {
let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.dialogService, this.notificationService, this.editor, e.owner, thread, null, {});
let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.dialogService, this.notificationService, this.editor, e.owner, thread, null, draftMode, {});
zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions);
this._commentWidgets.push(zoneWidget);
this._commentInfos.filter(info => info.owner === e.owner)[0].threads.push(thread);
......@@ -416,6 +419,13 @@ export class ReviewController implements IEditorContribution {
return;
}
let commentInfo = this._commentInfos.filter(info => info.owner === ownerId);
if (!commentInfo || !commentInfo.length) {
return;
}
let draftMode = commentInfo[0].draftMode;
// add new comment
this._reviewPanelVisible.set(true);
this._newCommentWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.dialogService, this.notificationService, this.editor, ownerId, {
......@@ -430,7 +440,7 @@ export class ReviewController implements IEditorContribution {
},
reply: replyCommand,
collapsibleState: CommentThreadCollapsibleState.Expanded,
}, pendingComment, {});
}, pendingComment, draftMode, {});
this.localToDispose.push(this._newCommentWidget.onDidClose(e => {
this._newCommentWidget = null;
......@@ -559,7 +569,7 @@ export class ReviewController implements IEditorContribution {
thread.collapsibleState = modes.CommentThreadCollapsibleState.Expanded;
}
let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.dialogService, this.notificationService, this.editor, info.owner, thread, pendingComment, {});
let zoneWidget = new ReviewZoneWidget(this.instantiationService, this.modeService, this.modelService, this.themeService, this.commentService, this.openerService, this.dialogService, this.notificationService, this.editor, info.owner, thread, pendingComment, info.draftMode, {});
zoneWidget.display(thread.range.startLineNumber, this._commentingRangeDecorator.commentsOptions);
this._commentWidgets.push(zoneWidget);
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册