Skip to content

Commit ab35ce9

Browse files
laurentlbalexr00
andauthored
Comments view: add badge with the number of unresolved comments (microsoft#164743)
* Comments view: add badge with the number of unresolved comments Fixes microsoft#164623 * fix formatting * Remove duplicate listeners to resolve undercounting Co-authored-by: Alex Ross <[email protected]>
1 parent 02a64e1 commit ab35ce9

File tree

1 file changed

+41
-9
lines changed

1 file changed

+41
-9
lines changed

src/vs/workbench/contrib/comments/browser/commentsView.ts

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ import { CommentsFilters, CommentsFiltersChangeEvent } from 'vs/workbench/contri
3636
import { Memento, MementoObject } from 'vs/workbench/common/memento';
3737
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
3838
import { FilterOptions } from 'vs/workbench/contrib/comments/browser/commentsFilterOptions';
39+
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
40+
import { CommentThreadState } from 'vs/editor/common/languages';
41+
import { IDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
3942

4043
const CONTEXT_KEY_HAS_COMMENTS = new RawContextKey<boolean>('commentsView.hasComments', false);
4144
const VIEW_STORAGE_ID = 'commentsViewState';
@@ -47,9 +50,11 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
4750
private messageBoxContainer!: HTMLElement;
4851
private commentsModel!: CommentsModel;
4952
private totalComments: number = 0;
53+
private totalUnresolved = 0;
5054
private readonly hasCommentsContextKey: IContextKey<boolean>;
5155
private readonly filter: Filter;
5256
readonly filters: CommentsFilters;
57+
private readonly activity = this._register(new MutableDisposable<IDisposable>());
5358

5459
private currentHeight = 0;
5560
private currentWidth = 0;
@@ -73,6 +78,7 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
7378
@ICommentService private readonly commentService: ICommentService,
7479
@ITelemetryService telemetryService: ITelemetryService,
7580
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
81+
@IActivityService readonly activityService: IActivityService,
7682
@IStorageService readonly storageService: IStorageService
7783
) {
7884
const stateMemento = new Memento(VIEW_STORAGE_ID, storageService);
@@ -97,15 +103,6 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
97103
}, this.contextKeyService));
98104
this.filter = new Filter(new FilterOptions(this.filterWidget.getFilterText(), this.filters.showResolved, this.filters.showUnresolved));
99105

100-
this._register(this.commentService.onDidSetAllCommentThreads(e => {
101-
this.totalComments += e.commentThreads.length;
102-
}));
103-
104-
this._register(this.commentService.onDidUpdateCommentThreads(e => {
105-
this.totalComments += e.added.length;
106-
this.totalComments -= e.removed.length;
107-
}));
108-
109106
this._register(this.filters.onDidChange((event: CommentsFiltersChangeEvent) => {
110107
if (event.showResolved || event.showUnresolved) {
111108
this.updateFilter();
@@ -114,6 +111,16 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
114111
this._register(this.filterWidget.onDidChangeFilterText(() => this.updateFilter()));
115112
}
116113

114+
private updateBadge(unresolved: number) {
115+
if (unresolved === this.totalUnresolved) {
116+
return;
117+
}
118+
119+
this.totalUnresolved = unresolved;
120+
const message = nls.localize('totalUnresolvedComments', '{0} Unresolved Comments', this.totalUnresolved);
121+
this.activity.value = this.activityService.showViewActivity(this.id, { badge: new NumberBadge(this.totalUnresolved, () => message) });
122+
}
123+
117124
override saveState(): void {
118125
this.viewState['filter'] = this.filterWidget.getFilterText();
119126
this.viewState['filterHistory'] = this.filterWidget.getHistory();
@@ -389,11 +396,36 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
389396

390397
private onAllCommentsChanged(e: IWorkspaceCommentThreadsEvent): void {
391398
this.commentsModel.setCommentThreads(e.ownerId, e.commentThreads);
399+
400+
this.totalComments += e.commentThreads.length;
401+
402+
let unresolved = 0;
403+
for (const thread of e.commentThreads) {
404+
if (thread.state === CommentThreadState.Unresolved) {
405+
unresolved++;
406+
}
407+
}
408+
this.updateBadge(unresolved);
409+
392410
this.refresh();
393411
}
394412

395413
private onCommentsUpdated(e: ICommentThreadChangedEvent): void {
396414
const didUpdate = this.commentsModel.updateCommentThreads(e);
415+
416+
this.totalComments += e.added.length;
417+
this.totalComments -= e.removed.length;
418+
419+
let unresolved = 0;
420+
for (const resource of this.commentsModel.resourceCommentThreads) {
421+
for (const thread of resource.commentThreads) {
422+
if (thread.threadState === CommentThreadState.Unresolved) {
423+
unresolved++;
424+
}
425+
}
426+
}
427+
this.updateBadge(unresolved);
428+
397429
if (didUpdate) {
398430
this.refresh();
399431
}

0 commit comments

Comments
 (0)