mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 02:58:31 -05:00
Vscode merge (#4582)
* Merge from vscode 37cb23d3dd4f9433d56d4ba5ea3203580719a0bd * fix issues with merges * bump node version in azpipe * replace license headers * remove duplicate launch task * fix build errors * fix build errors * fix tslint issues * working through package and linux build issues * more work * wip * fix packaged builds * working through linux build errors * wip * wip * wip * fix mac and linux file limits * iterate linux pipeline * disable editor typing * revert series to parallel * remove optimize vscode from linux * fix linting issues * revert testing change * add work round for new node * readd packaging for extensions * fix issue with angular not resolving decorator dependencies
This commit is contained in:
161
src/vs/workbench/contrib/comments/common/commentModel.ts
Normal file
161
src/vs/workbench/contrib/comments/common/commentModel.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { Comment, CommentThread, CommentThreadChangedEvent } from 'vs/editor/common/modes';
|
||||
import { groupBy, firstIndex, flatten } from 'vs/base/common/arrays';
|
||||
import { localize } from 'vs/nls';
|
||||
import { values } from 'vs/base/common/map';
|
||||
|
||||
export interface ICommentThreadChangedEvent extends CommentThreadChangedEvent {
|
||||
owner: string;
|
||||
}
|
||||
|
||||
export class CommentNode {
|
||||
threadId: string;
|
||||
range: IRange;
|
||||
comment: Comment;
|
||||
replies: CommentNode[] = [];
|
||||
resource: URI;
|
||||
|
||||
constructor(threadId: string, resource: URI, comment: Comment, range: IRange) {
|
||||
this.threadId = threadId;
|
||||
this.comment = comment;
|
||||
this.resource = resource;
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
hasReply(): boolean {
|
||||
return this.replies && this.replies.length !== 0;
|
||||
}
|
||||
}
|
||||
|
||||
export class ResourceWithCommentThreads {
|
||||
id: string;
|
||||
commentThreads: CommentNode[]; // The top level comments on the file. Replys are nested under each node.
|
||||
resource: URI;
|
||||
|
||||
constructor(resource: URI, commentThreads: CommentThread[]) {
|
||||
this.id = resource.toString();
|
||||
this.resource = resource;
|
||||
this.commentThreads = commentThreads.filter(thread => thread.comments.length).map(thread => ResourceWithCommentThreads.createCommentNode(resource, thread));
|
||||
}
|
||||
|
||||
public static createCommentNode(resource: URI, commentThread: CommentThread): CommentNode {
|
||||
const { threadId, comments, range } = commentThread;
|
||||
const commentNodes: CommentNode[] = comments.map(comment => new CommentNode(threadId!, resource, comment, range));
|
||||
if (commentNodes.length > 1) {
|
||||
commentNodes[0].replies = commentNodes.slice(1, commentNodes.length);
|
||||
}
|
||||
|
||||
return commentNodes[0];
|
||||
}
|
||||
}
|
||||
|
||||
export class CommentsModel {
|
||||
resourceCommentThreads: ResourceWithCommentThreads[];
|
||||
commentThreadsMap: Map<string, ResourceWithCommentThreads[]>;
|
||||
|
||||
constructor() {
|
||||
this.resourceCommentThreads = [];
|
||||
this.commentThreadsMap = new Map<string, ResourceWithCommentThreads[]>();
|
||||
}
|
||||
|
||||
public setCommentThreads(owner: string, commentThreads: CommentThread[]): void {
|
||||
this.commentThreadsMap.set(owner, this.groupByResource(commentThreads));
|
||||
this.resourceCommentThreads = flatten(values(this.commentThreadsMap));
|
||||
}
|
||||
|
||||
public updateCommentThreads(event: ICommentThreadChangedEvent): boolean {
|
||||
const { owner, removed, changed, added } = event;
|
||||
|
||||
let threadsForOwner = this.commentThreadsMap.get(owner) || [];
|
||||
|
||||
removed.forEach(thread => {
|
||||
// Find resource that has the comment thread
|
||||
const matchingResourceIndex = firstIndex(threadsForOwner, (resourceData) => resourceData.id === thread.resource);
|
||||
const matchingResourceData = threadsForOwner[matchingResourceIndex];
|
||||
|
||||
// Find comment node on resource that is that thread and remove it
|
||||
const index = firstIndex(matchingResourceData.commentThreads, (commentThread) => commentThread.threadId === thread.threadId);
|
||||
matchingResourceData.commentThreads.splice(index, 1);
|
||||
|
||||
// If the comment thread was the last thread for a resource, remove that resource from the list
|
||||
if (matchingResourceData.commentThreads.length === 0) {
|
||||
threadsForOwner.splice(matchingResourceIndex, 1);
|
||||
}
|
||||
});
|
||||
|
||||
changed.forEach(thread => {
|
||||
// Find resource that has the comment thread
|
||||
const matchingResourceIndex = firstIndex(threadsForOwner, (resourceData) => resourceData.id === thread.resource);
|
||||
const matchingResourceData = threadsForOwner[matchingResourceIndex];
|
||||
|
||||
// Find comment node on resource that is that thread and replace it
|
||||
const index = firstIndex(matchingResourceData.commentThreads, (commentThread) => commentThread.threadId === thread.threadId);
|
||||
if (index >= 0) {
|
||||
matchingResourceData.commentThreads[index] = ResourceWithCommentThreads.createCommentNode(URI.parse(matchingResourceData.id), thread);
|
||||
} else {
|
||||
matchingResourceData.commentThreads.push(ResourceWithCommentThreads.createCommentNode(URI.parse(matchingResourceData.id), thread));
|
||||
}
|
||||
});
|
||||
|
||||
added.forEach(thread => {
|
||||
const existingResource = threadsForOwner.filter(resourceWithThreads => resourceWithThreads.resource.toString() === thread.resource);
|
||||
if (existingResource.length) {
|
||||
const resource = existingResource[0];
|
||||
if (thread.comments.length) {
|
||||
resource.commentThreads.push(ResourceWithCommentThreads.createCommentNode(resource.resource, thread));
|
||||
}
|
||||
} else {
|
||||
threadsForOwner.push(new ResourceWithCommentThreads(URI.parse(thread.resource!), [thread]));
|
||||
}
|
||||
});
|
||||
|
||||
this.commentThreadsMap.set(owner, threadsForOwner);
|
||||
this.resourceCommentThreads = flatten(values(this.commentThreadsMap));
|
||||
|
||||
return removed.length > 0 || changed.length > 0 || added.length > 0;
|
||||
}
|
||||
|
||||
public hasCommentThreads(): boolean {
|
||||
return !!this.resourceCommentThreads.length;
|
||||
}
|
||||
|
||||
public getMessage(): string {
|
||||
if (!this.resourceCommentThreads.length) {
|
||||
return localize('noComments', "There are no comments on this review.");
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private groupByResource(commentThreads: CommentThread[]): ResourceWithCommentThreads[] {
|
||||
const resourceCommentThreads: ResourceWithCommentThreads[] = [];
|
||||
const commentThreadsByResource = new Map<string, ResourceWithCommentThreads>();
|
||||
for (const group of groupBy(commentThreads, CommentsModel._compareURIs)) {
|
||||
commentThreadsByResource.set(group[0].resource!, new ResourceWithCommentThreads(URI.parse(group[0].resource!), group));
|
||||
}
|
||||
|
||||
commentThreadsByResource.forEach((v, i, m) => {
|
||||
resourceCommentThreads.push(v);
|
||||
});
|
||||
|
||||
return resourceCommentThreads;
|
||||
}
|
||||
|
||||
private static _compareURIs(a: CommentThread, b: CommentThread) {
|
||||
const resourceA = a.resource!.toString();
|
||||
const resourceB = b.resource!.toString();
|
||||
if (resourceA < resourceB) {
|
||||
return -1;
|
||||
} else if (resourceA > resourceB) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user