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

Prevent multiple empty comment threads from being created at same position

上级 acd6c007
...@@ -1286,7 +1286,7 @@ export interface CommentingRanges { ...@@ -1286,7 +1286,7 @@ export interface CommentingRanges {
readonly resource: URI; readonly resource: URI;
ranges: IRange[]; ranges: IRange[];
newCommentThreadCommand?: Command; newCommentThreadCommand?: Command;
newCommentThreadCallback?: (uri: UriComponents, range: IRange) => void; newCommentThreadCallback?: (uri: UriComponents, range: IRange) => Promise<void>;
} }
/** /**
......
...@@ -1165,7 +1165,7 @@ export interface ExtHostCommentsShape { ...@@ -1165,7 +1165,7 @@ export interface ExtHostCommentsShape {
$provideCommentingRanges(commentControllerHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise<IRange[] | undefined>; $provideCommentingRanges(commentControllerHandle: number, uriComponents: UriComponents, token: CancellationToken): Promise<IRange[] | undefined>;
$provideReactionGroup(commentControllerHandle: number): Promise<modes.CommentReaction[] | undefined>; $provideReactionGroup(commentControllerHandle: number): Promise<modes.CommentReaction[] | undefined>;
$toggleReaction(commentControllerHandle: number, threadHandle: number, uri: UriComponents, comment: modes.Comment, reaction: modes.CommentReaction): Promise<void>; $toggleReaction(commentControllerHandle: number, threadHandle: number, uri: UriComponents, comment: modes.Comment, reaction: modes.CommentReaction): Promise<void>;
$createNewCommentWidgetCallback(commentControllerHandle: number, uriComponents: UriComponents, range: IRange, token: CancellationToken): void; $createNewCommentWidgetCallback(commentControllerHandle: number, uriComponents: UriComponents, range: IRange, token: CancellationToken): Promise<void>;
$replyToCommentThread(handle: number, document: UriComponents, range: IRange, commentThread: modes.CommentThread, text: string): Promise<modes.CommentThread | null>; $replyToCommentThread(handle: number, document: UriComponents, range: IRange, commentThread: modes.CommentThread, text: string): Promise<modes.CommentThread | null>;
$editComment(handle: number, document: UriComponents, comment: modes.Comment, text: string): Promise<void>; $editComment(handle: number, document: UriComponents, comment: modes.Comment, text: string): Promise<void>;
$deleteComment(handle: number, document: UriComponents, comment: modes.Comment): Promise<void>; $deleteComment(handle: number, document: UriComponents, comment: modes.Comment): Promise<void>;
......
...@@ -374,8 +374,8 @@ export class MainThreadCommentController { ...@@ -374,8 +374,8 @@ export class MainThreadCommentController {
threads: ret, threads: ret,
commentingRanges: commentingRanges ? commentingRanges: commentingRanges ?
{ {
resource: resource, ranges: commentingRanges, newCommentThreadCallback: (uri: UriComponents, range: IRange) => { resource: resource, ranges: commentingRanges, newCommentThreadCallback: async (uri: UriComponents, range: IRange) => {
this._proxy.$createNewCommentWidgetCallback(this.handle, uri, range, token); await this._proxy.$createNewCommentWidgetCallback(this.handle, uri, range, token);
} }
} : [], } : [],
draftMode: modes.DraftMode.NotSupported draftMode: modes.DraftMode.NotSupported
......
...@@ -145,15 +145,15 @@ export class ExtHostComments implements ExtHostCommentsShape { ...@@ -145,15 +145,15 @@ export class ExtHostComments implements ExtHostCommentsShape {
}); });
} }
$createNewCommentWidgetCallback(commentControllerHandle: number, uriComponents: UriComponents, range: IRange, token: CancellationToken): void { $createNewCommentWidgetCallback(commentControllerHandle: number, uriComponents: UriComponents, range: IRange, token: CancellationToken): Promise<void> {
const commentController = this._commentControllers.get(commentControllerHandle); const commentController = this._commentControllers.get(commentControllerHandle);
if (!commentController || !commentController.emptyCommentThreadFactory) { if (!commentController || !commentController.emptyCommentThreadFactory) {
return; return Promise.resolve();
} }
const document = this._documents.getDocument(URI.revive(uriComponents)); const document = this._documents.getDocument(URI.revive(uriComponents));
commentController.emptyCommentThreadFactory.createEmptyCommentThread(document, extHostTypeConverter.Range.to(range)); return asPromise(() => commentController.emptyCommentThreadFactory!.createEmptyCommentThread(document, extHostTypeConverter.Range.to(range))).then(() => Promise.resolve());
} }
registerWorkspaceCommentProvider( registerWorkspaceCommentProvider(
......
...@@ -168,6 +168,8 @@ export class ReviewController implements IEditorContribution { ...@@ -168,6 +168,8 @@ export class ReviewController implements IEditorContribution {
private mouseDownInfo: { lineNumber: number } | null = null; private mouseDownInfo: { lineNumber: number } | null = null;
private _commentingRangeSpaceReserved = false; private _commentingRangeSpaceReserved = false;
private _computePromise: CancelablePromise<Array<ICommentInfo | null>> | null; private _computePromise: CancelablePromise<Array<ICommentInfo | null>> | null;
private _addInProgress: boolean;
private _emptyThreadsToAddQueue: number[] = [];
private _computeCommentingRangePromise: CancelablePromise<ICommentInfo[]> | null; private _computeCommentingRangePromise: CancelablePromise<ICommentInfo[]> | null;
private _computeCommentingRangeScheduler: Delayer<Array<ICommentInfo | null>> | null; private _computeCommentingRangeScheduler: Delayer<Array<ICommentInfo | null>> | null;
private _pendingCommentCache: { [key: number]: { [key: string]: string } }; private _pendingCommentCache: { [key: number]: { [key: string]: string } };
...@@ -546,25 +548,41 @@ export class ReviewController implements IEditorContribution { ...@@ -546,25 +548,41 @@ export class ReviewController implements IEditorContribution {
if (e.target.element.className.indexOf('comment-diff-added') >= 0) { if (e.target.element.className.indexOf('comment-diff-added') >= 0) {
const lineNumber = e.target.position!.lineNumber; const lineNumber = e.target.position!.lineNumber;
this.addCommentAtLine(lineNumber); this.addOrToggleCommentAtLine(lineNumber);
} }
} }
public addOrToggleCommentAtLine(lineNumber: number): void { public async addOrToggleCommentAtLine(lineNumber: number): Promise<void> {
// The widget's position is undefined until the widget has been displayed, so rely on the glyph position instead // If an add is already in progress, queue the next add and process it after the current one finishes to
const existingCommentsAtLine = this._commentWidgets.filter(widget => widget.getGlyphPosition() === lineNumber); // prevent empty comment threads from being added to the same line.
if (existingCommentsAtLine.length) { if (!this._addInProgress) {
existingCommentsAtLine.forEach(widget => widget.toggleExpand(lineNumber)); this._addInProgress = true;
return; // The widget's position is undefined until the widget has been displayed, so rely on the glyph position instead
const existingCommentsAtLine = this._commentWidgets.filter(widget => widget.getGlyphPosition() === lineNumber);
if (existingCommentsAtLine.length) {
existingCommentsAtLine.forEach(widget => widget.toggleExpand(lineNumber));
this.processNextThreadToAdd();
return;
} else {
this.addCommentAtLine(lineNumber);
}
} else { } else {
this.addCommentAtLine(lineNumber); this._emptyThreadsToAddQueue.push(lineNumber);
}
}
private processNextThreadToAdd(): void {
this._addInProgress = false;
const lineNumber = this._emptyThreadsToAddQueue.shift();
if (lineNumber) {
this.addOrToggleCommentAtLine(lineNumber);
} }
} }
public addCommentAtLine(lineNumber: number): void { public addCommentAtLine(lineNumber: number): Promise<void> {
const newCommentInfo = this._commentingRangeDecorator.getMatchedCommentAction(lineNumber); const newCommentInfo = this._commentingRangeDecorator.getMatchedCommentAction(lineNumber);
if (!newCommentInfo || !this.editor.hasModel()) { if (!newCommentInfo || !this.editor.hasModel()) {
return; return Promise.resolve();
} }
const { replyCommand, ownerId, extensionId, commentingRangesInfo } = newCommentInfo; const { replyCommand, ownerId, extensionId, commentingRangesInfo } = newCommentInfo;
...@@ -579,17 +597,26 @@ export class ReviewController implements IEditorContribution { ...@@ -579,17 +597,26 @@ export class ReviewController implements IEditorContribution {
this._commandService.executeCommand(commandId, ...args); this._commandService.executeCommand(commandId, ...args);
} }
} else if (commentingRangesInfo.newCommentThreadCallback) { } else if (commentingRangesInfo.newCommentThreadCallback) {
commentingRangesInfo.newCommentThreadCallback(this.editor.getModel().uri, range); return commentingRangesInfo.newCommentThreadCallback(this.editor.getModel().uri, range)
.then(_ => {
this.processNextThreadToAdd();
})
.catch(e => {
this.notificationService.error(`Adding a new comment thread failed: ${e}`);
this.processNextThreadToAdd();
});
} }
} else { } else {
const commentInfo = this._commentInfos.filter(info => info.owner === ownerId); const commentInfo = this._commentInfos.filter(info => info.owner === ownerId);
if (!commentInfo || !commentInfo.length) { if (!commentInfo || !commentInfo.length) {
return; return Promise.resolve();
} }
const draftMode = commentInfo[0].draftMode; const draftMode = commentInfo[0].draftMode;
this.addComment(lineNumber, replyCommand, ownerId, extensionId, draftMode, null); this.addComment(lineNumber, replyCommand, ownerId, extensionId, draftMode, null);
} }
return Promise.resolve();
} }
...@@ -735,8 +762,7 @@ CommandsRegistry.registerCommand({ ...@@ -735,8 +762,7 @@ CommandsRegistry.registerCommand({
} }
const position = activeEditor.getPosition(); const position = activeEditor.getPosition();
controller.addOrToggleCommentAtLine(position.lineNumber); return controller.addOrToggleCommentAtLine(position.lineNumber);
return Promise.resolve();
} }
}); });
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册