提交 08e5839d 编写于 作者: P Peng Lyu

Merge branch 'rebornix/commentscontrol' of github.com:microsoft/vscode into...

Merge branch 'rebornix/commentscontrol' of github.com:microsoft/vscode into rebornix/commentscontrol
......@@ -1239,9 +1239,16 @@ export interface CommentWidget {
/**
* @internal
*/
export interface CommentInput {
value: string;
uri: URI;
}
/**
* @internal
*/
export interface CommentThread2 {
commentThreadHandle: number; // use optional type for now to avoid breaking existing api
commentThreadHandle: number;
extensionId: string;
threadId: string;
resource: string;
......@@ -1249,8 +1256,8 @@ export interface CommentThread2 {
comments: Comment[];
onDidChangeComments: Event<Comment[]>;
collapsibleState?: CommentThreadCollapsibleState;
input: string;
onDidChangeInput: Event<string>;
input: CommentInput;
onDidChangeInput: Event<CommentInput>;
acceptInputCommands: Command[];
onDidChangeAcceptInputCommands: Event<Command[]>;
}
......@@ -1321,22 +1328,22 @@ export interface CommentThreadChangedEvent {
/**
* Added comment threads.
*/
readonly added: CommentThread[];
readonly added: (CommentThread | CommentThread2)[];
/**
* Removed comment threads.
*/
readonly removed: CommentThread[];
readonly removed: (CommentThread | CommentThread2)[];
/**
* Changed comment threads.
*/
readonly changed: CommentThread[];
readonly changed: (CommentThread | CommentThread2)[];
/**
* changed draft mode.
*/
readonly draftMode: DraftMode;
readonly draftMode?: DraftMode;
}
/**
......
......@@ -799,6 +799,7 @@ declare module 'vscode' {
* Whether the thread should be collapsed or expanded when opening the document. Defaults to Collapsed.
*/
collapsibleState?: CommentThreadCollapsibleState;
dispose?(): void;
}
/**
......@@ -966,8 +967,8 @@ declare module 'vscode' {
readonly id: string;
readonly label: string;
/**
* The active (focused) comment widget.
*/
* The active (focused) comment widget.
*/
readonly widget?: CommentWidget;
createCommentThread(id: string, resource: Uri, range: Range, comments: Comment[], acceptInputCommands: Command[], collapsibleState?: CommentThreadCollapsibleState): CommentThread;
createCommentingRanges(resource: Uri, ranges: Range[], acceptInputCommands: Command[]): CommentingRanges;
......
......@@ -81,33 +81,18 @@ export class MainThreadDocumentCommentProvider implements modes.DocumentCommentP
}
export class MainThreadCommentThread implements modes.CommentThread2 {
private _input: string = '';
get input(): string {
private _input?: modes.CommentInput;
get input(): modes.CommentInput | undefined {
return this._input;
}
set input(value: string) {
set input(value: modes.CommentInput | undefined) {
this._input = value;
this._onDidChangeInput.fire(value);
}
private _onDidChangeInput = new Emitter<string>();
get onDidChangeInput(): Event<string> { return this._onDidChangeInput.event; }
private _activeComment?: modes.Comment;
get activeComment(): modes.Comment {
return this._activeComment;
}
set activeComment(comment: modes.Comment | undefined) {
this._activeComment = comment;
this._onDidChangeActiveComment.fire(comment);
}
private _onDidChangeActiveComment = new Emitter<modes.Comment | undefined>();
get onDidChangeActiveComment(): Event<modes.Comment | undefined> { return this._onDidChangeActiveComment.event; }
private _onDidChangeInput = new Emitter<modes.CommentInput | undefined>();
get onDidChangeInput(): Event<modes.CommentInput | undefined> { return this._onDidChangeInput.event; }
public get comments(): modes.Comment[] {
return this._comments;
......@@ -200,10 +185,23 @@ export class MainThreadCommentControl {
return this._handle;
}
get id(): string {
return this._id;
}
get proxy(): ExtHostCommentsShape {
return this._proxy;
}
get label(): string {
return this._label;
}
private _threads: Map<number, MainThreadCommentThread> = new Map<number, MainThreadCommentThread>();
private _commentingRanges: Map<number, MainThreadCommentingRanges> = new Map<number, MainThreadCommentingRanges>();
constructor(
private _proxy: ExtHostCommentsShape,
private _commentService: ICommentService,
private _handle: number,
private _id: string,
private _label: string
......@@ -223,6 +221,12 @@ export class MainThreadCommentControl {
);
this._threads.set(commentThreadHandle, thread);
this._commentService.updateComments(`${this.handle}`, {
added: [thread],
removed: [],
changed: [],
draftMode: modes.DraftMode.NotSupported
});
return thread;
}
......@@ -230,6 +234,14 @@ export class MainThreadCommentControl {
deleteCommentThread(commentThreadHandle: number) {
let thread = this._threads.get(commentThreadHandle);
this._threads.delete(commentThreadHandle);
this._commentService.updateComments(`${this.handle}`, {
added: [],
removed: [thread],
changed: [],
draftMode: modes.DraftMode.NotSupported
});
thread.dispose();
}
......@@ -277,7 +289,11 @@ export class MainThreadCommentControl {
updateInput(commentThreadHandle: number, input: string) {
let thread = this._threads.get(commentThreadHandle);
thread.input = input;
let commentInput = thread.input;
if (commentInput) {
commentInput.value = input;
thread.input = commentInput;
}
}
getDocumentComments(resource: URI) {
......@@ -288,7 +304,7 @@ export class MainThreadCommentControl {
}
}
return <ICommentInfo> {
return <ICommentInfo>{
owner: String(this.handle),
threads: ret,
commentingRanges: [],
......@@ -307,6 +323,7 @@ export class MainThreadCommentControl {
@extHostNamedCustomer(MainContext.MainThreadComments)
export class MainThreadComments extends Disposable implements MainThreadCommentsShape {
private _disposables: IDisposable[];
private _activeCommentThreadDisposables: IDisposable[];
private _proxy: ExtHostCommentsShape;
private _documentProviders = new Map<number, IDisposable>();
private _workspaceProviders = new Map<number, IDisposable>();
......@@ -315,7 +332,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
private _activeCommentThread?: MainThreadCommentThread;
private _activeComment?: modes.Comment;
private _input?: string;
private _input?: modes.CommentInput;
private _openPanelListener: IDisposable | null;
constructor(
......@@ -328,6 +345,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
) {
super();
this._disposables = [];
this._activeCommentThreadDisposables = [];
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostComments);
this._disposables.push(this._commentService.onDidChangeActiveCommentThread(async thread => {
let control = (thread as MainThreadCommentThread).control;
......@@ -336,26 +354,28 @@ export class MainThreadComments extends Disposable implements MainThreadComments
return;
}
this._activeCommentThreadDisposables = dispose(this._activeCommentThreadDisposables);
this._activeCommentThread = thread as MainThreadCommentThread;
this._activeCommentThread.onDidChangeInput(input => { // todo, dispose
this._activeCommentThreadDisposables.push(this._activeCommentThread.onDidChangeInput(input => { // todo, dispose
this._input = input;
this._proxy.$onActiveCommentWidgetChange(control.handle, this._activeCommentThread, this._activeComment, this._input);
});
this._activeCommentThread.onDidChangeActiveComment(comment => { // todo, dispose
this._activeComment = comment;
this._proxy.$onActiveCommentWidgetChange(control.handle, this._activeCommentThread, this._activeComment, this._input);
});
this._proxy.$onActiveCommentWidgetChange(control.handle, this._activeCommentThread, this._activeComment, this._input ? this._input.value : undefined);
}));
await this._proxy.$onActiveCommentWidgetChange(control.handle, this._activeCommentThread, this._activeComment, this._input);
await this._proxy.$onActiveCommentWidgetChange(control.handle, this._activeCommentThread, this._activeComment, this._input ? this._input.value : undefined);
}));
}
$registerCommentControl(handle: number, id: string, label: string): void {
const provider = new MainThreadCommentControl(this._proxy, handle, id, label);
const provider = new MainThreadCommentControl(this._proxy, this._commentService, handle, id, label);
this._commentService.registerCommentControl(String(handle), provider);
this._commentControls.set(handle, provider);
const commentsPanelAlreadyConstructed = this._panelService.getPanels().some(panel => panel.id === COMMENTS_PANEL_ID);
if (!commentsPanelAlreadyConstructed) {
this.registerPanel(commentsPanelAlreadyConstructed);
}
this._commentService.setWorkspaceComments(String(handle), []);
}
$createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, comments: modes.Comment[], commands: modes.Command[], collapseState: modes.CommentThreadCollapsibleState): modes.CommentThread2 | undefined {
......@@ -459,6 +479,18 @@ export class MainThreadComments extends Disposable implements MainThreadComments
this._commentService.registerDataProvider(providerId, handler);
}
private registerPanel(commentsPanelAlreadyConstructed: boolean) {
if (!commentsPanelAlreadyConstructed) {
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(new PanelDescriptor(
CommentsPanel,
COMMENTS_PANEL_ID,
COMMENTS_PANEL_TITLE,
'commentsPanel',
10
));
}
}
/**
* If the comments panel has never been opened, the constructor for it has not yet run so it has
* no listeners for comment threads being set or updated. Listen for the panel opening for the
......@@ -492,13 +524,9 @@ export class MainThreadComments extends Disposable implements MainThreadComments
this._handlers.set(handle, providerId);
const commentsPanelAlreadyConstructed = this._panelService.getPanels().some(panel => panel.id === COMMENTS_PANEL_ID);
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(new PanelDescriptor(
CommentsPanel,
COMMENTS_PANEL_ID,
COMMENTS_PANEL_TITLE,
'commentsPanel',
10
));
if (!commentsPanelAlreadyConstructed) {
this.registerPanel(commentsPanelAlreadyConstructed);
}
const openPanel = this._configurationService.getValue<ICommentsConfiguration>('comments').openPanel;
......@@ -598,6 +626,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
dispose(): void {
this._disposables = dispose(this._disposables);
this._activeCommentThreadDisposables = dispose(this._activeCommentThreadDisposables);
this._workspaceProviders.forEach(value => dispose(value));
this._workspaceProviders.clear();
this._documentProviders.forEach(value => dispose(value));
......
......@@ -305,7 +305,6 @@ export class CommentNode extends Disposable {
this._commentEditor.layout({ width: container.clientWidth - 14, height: 90 });
this._commentEditor.focus();
const lastLine = this._commentEditorModel.getLineCount();
const lastColumn = this._commentEditorModel.getLineContent(lastLine).length + 1;
this._commentEditor.setSelection(new Selection(lastLine, lastColumn, lastLine, lastColumn));
......@@ -319,11 +318,28 @@ export class CommentNode extends Disposable {
let commentThread = this.commentThread as modes.CommentThread2;
if (commentThread.commentThreadHandle) {
commentThread.input = this.comment.body.value;
commentThread.input = {
uri: this._commentEditor.getModel().uri,
value: this.comment.body.value
};
this.commentService.setActiveCommentThread(commentThread);
this._commentEditorDisposables.push(this._commentEditor.onDidFocusEditorWidget(() => {
commentThread.input = {
uri: this._commentEditor.getModel().uri,
value: this.comment.body.value
};
this.commentService.setActiveCommentThread(commentThread);
}));
this._commentEditorDisposables.push(this._commentEditor.onDidChangeModelContent(e => {
let newVal = this._commentEditor.getValue();
if (newVal !== commentThread.input) {
commentThread.input = newVal;
if (commentThread.input && this._commentEditor.getModel().uri === commentThread.input.uri) {
let newVal = this._commentEditor.getValue();
if (newVal !== commentThread.input.value) {
let input = commentThread.input;
input.value = newVal;
commentThread.input = input;
}
}
}));
}
......@@ -356,7 +372,10 @@ export class CommentNode extends Disposable {
if (useCommand) {
let commentThread = this.commentThread as modes.CommentThread2;
commentThread.input = newBody;
commentThread.input = {
uri: this._commentEditor.getModel().uri,
value: newBody
};
this.commentService.setActiveCommentThread(commentThread);
let commandId = this.comment.editCommand!.id;
let args = this.comment.editCommand!.arguments || [];
......@@ -480,7 +499,6 @@ export class CommentNode extends Disposable {
}
update(newComment: modes.Comment) {
this.comment = newComment;
if (newComment.body !== this.comment.body) {
this._body.removeChild(this._md);
......@@ -488,6 +506,8 @@ export class CommentNode extends Disposable {
this._body.appendChild(this._md);
}
this.comment = newComment;
if (newComment.isDraft) {
this._isPendingLabel.innerText = 'Pending';
} else {
......
......@@ -258,6 +258,7 @@ export class ReviewZoneWidget extends ZoneWidget {
let currentComment = commentThread.comments[i];
let oldCommentNode = this._commentElements.filter(commentNode => commentNode.comment.commentId === currentComment.commentId);
if (oldCommentNode.length) {
oldCommentNode[0].update(currentComment);
lastCommentElement = oldCommentNode[0].domNode;
newCommentNodeList.unshift(oldCommentNode[0]);
} else {
......@@ -342,18 +343,36 @@ export class ReviewZoneWidget extends ZoneWidget {
this._localToDispose.push(this._commentEditor);
this._localToDispose.push(this._commentEditor.getModel().onDidChangeContent(() => this.setCommentEditorDecorations()));
if ((this._commentThread as modes.CommentThread2).commentThreadHandle !== undefined) {
this._localToDispose.push(this._commentEditor.onDidFocusEditorWidget(() => {
let commentThread = this._commentThread as modes.CommentThread2;
commentThread.input = {
uri: this._commentEditor.getModel().uri,
value: this._commentEditor.getValue()
};
this.commentService.setActiveCommentThread(this._commentThread);
}));
this._localToDispose.push(this._commentEditor.getModel().onDidChangeContent(() => {
let modelContent = this._commentEditor.getValue();
if ((this._commentThread as modes.CommentThread2).input !== modelContent) {
(this._commentThread as modes.CommentThread2).input = modelContent;
let thread = (this._commentThread as modes.CommentThread2);
if (thread.input.uri === this._commentEditor.getModel().uri && thread.input.value !== modelContent) {
let newInput: modes.CommentInput = thread.input;
newInput.value = modelContent;
thread.input = newInput;
}
}));
this._localToDispose.push((this._commentThread as modes.CommentThread2).onDidChangeInput(input => {
if (this._commentEditor.getValue() !== input) {
this._commentEditor.setValue(input);
let thread = (this._commentThread as modes.CommentThread2);
if (thread.input.uri !== this._commentEditor.getModel().uri) {
return;
}
if (input === '') {
if (this._commentEditor.getValue() !== input.value) {
this._commentEditor.setValue(input.value);
if (input.value === '') {
this._pendingComment = '';
if (dom.hasClass(this._commentForm, 'expand')) {
dom.removeClass(this._commentForm, 'expand');
......@@ -554,9 +573,11 @@ export class ReviewZoneWidget extends ZoneWidget {
let commandId = command.id;
let args = command.arguments || [];
this._localToDispose.push(button.onDidClick(async () => {
commentThread.input = this._commentEditor.getValue();
commentThread.input = {
uri: this._commentEditor.getModel().uri,
value: this._commentEditor.getValue()
};
this.commentService.setActiveCommentThread(this._commentThread);
await this.commandService.executeCommand(commandId, ...args);
}));
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册