Skip to content

Commit 6a4c15d

Browse files
committed
Issues with comment duplication and formatting when tagging copilot for follow-up
Fixes #7915
1 parent 6b4533b commit 6a4c15d

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

src/common/utils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,16 @@ export async function stringReplaceAsync(str: string, regex: RegExp, asyncFn: (s
982982
return str.replace(regex, () => data[offset++]);
983983
}
984984

985+
export async function arrayFindIndexAsync<T>(arr: T[], predicate: (value: T, index: number, array: T[]) => Promise<boolean>): Promise<number> {
986+
for (let i = 0; i < arr.length; i++) {
987+
// Evaluate predicate sequentially to allow early exit on first match
988+
if (await predicate(arr[i], i, arr)) {
989+
return i;
990+
}
991+
}
992+
return -1;
993+
}
994+
985995
export async function batchPromiseAll<T>(items: readonly T[], batchSize: number, processFn: (item: T) => Promise<void>): Promise<void> {
986996
const batches = Math.ceil(items.length / batchSize);
987997

src/view/pullRequestCommentController.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,8 @@ export class PullRequestCommentController extends CommentControllerBase implemen
227227
}
228228
}
229229

230-
private onDidChangeReviewThreads(e: ReviewThreadChangeEvent): void {
231-
e.added.forEach(async (thread) => {
230+
private async onDidChangeReviewThreads(e: ReviewThreadChangeEvent): Promise<void> {
231+
for (const thread of e.added) {
232232
const fileName = thread.path;
233233
const index = this._pendingCommentThreadAdds.findIndex(t => {
234234
const samePath = this._folderRepoManager.gitRelativeRootPath(t.uri.path) === thread.path;
@@ -278,26 +278,26 @@ export class PullRequestCommentController extends CommentControllerBase implemen
278278
} else {
279279
this._commentThreadCache[key] = [newThread];
280280
}
281-
});
281+
}
282282

283-
e.changed.forEach(thread => {
283+
for (const thread of e.changed) {
284284
const key = this.getCommentThreadCacheKey(thread.path, thread.diffSide === DiffSide.LEFT);
285285
const index = this._commentThreadCache[key] ? this._commentThreadCache[key].findIndex(t => t.gitHubThreadId === thread.id) : -1;
286286
if (index > -1) {
287287
const matchingThread = this._commentThreadCache[key][index];
288288
updateThread(this._context, matchingThread, thread, this._githubRepositories);
289289
}
290-
});
290+
}
291291

292-
e.removed.forEach(async thread => {
292+
for (const thread of e.removed) {
293293
const key = this.getCommentThreadCacheKey(thread.path, thread.diffSide === DiffSide.LEFT);
294294
const index = this._commentThreadCache[key].findIndex(t => t.gitHubThreadId === thread.id);
295295
if (index > -1) {
296296
const matchingThread = this._commentThreadCache[key][index];
297297
this._commentThreadCache[key].splice(index, 1);
298298
matchingThread.dispose();
299299
}
300-
});
300+
}
301301
}
302302

303303
protected override onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {

src/view/reviewCommentController.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Logger from '../common/logger';
1919
import { PR_SETTINGS_NAMESPACE, PULL_BRANCH, PULL_PR_BRANCH_BEFORE_CHECKOUT, PullPRBranchVariants } from '../common/settingKeys';
2020
import { ITelemetry } from '../common/telemetry';
2121
import { fromReviewUri, ReviewUriParams, Schemes, toReviewUri } from '../common/uri';
22-
import { formatError, groupBy, uniqBy } from '../common/utils';
22+
import { arrayFindIndexAsync, formatError, groupBy, uniqBy } from '../common/utils';
2323
import { FolderRepositoryManager } from '../github/folderRepositoryManager';
2424
import { GHPRComment, GHPRCommentThread, TemporaryComment } from '../github/prComment';
2525
import { PullRequestOverviewPanel } from '../github/pullRequestOverview';
@@ -275,12 +275,12 @@ export class ReviewCommentController extends CommentControllerBase implements Co
275275
);
276276

277277
this._register(
278-
activePullRequest.onDidChangeReviewThreads(e => {
278+
activePullRequest.onDidChangeReviewThreads(async e => {
279279
const githubRepositories = this.githubReposForPullRequest(this._folderRepoManager.activePullRequest);
280-
e.added.forEach(async thread => {
280+
for (const thread of e.added) {
281281
const { path } = thread;
282282

283-
const index = this._pendingCommentThreadAdds.findIndex(async t => {
283+
const index = await arrayFindIndexAsync(this._pendingCommentThreadAdds, async t => {
284284
const fileName = this._folderRepoManager.gitRelativeRootPath(t.uri.path);
285285
if (fileName !== thread.path) {
286286
return false;
@@ -324,24 +324,24 @@ export class ReviewCommentController extends CommentControllerBase implements Co
324324
} else {
325325
threadMap[path] = [newThread];
326326
}
327-
});
327+
}
328328

329-
e.changed.forEach(thread => {
329+
for (const thread of e.changed) {
330330
const match = this._findMatchingThread(thread);
331331
if (match.index > -1) {
332332
const matchingThread = match.threadMap[thread.path][match.index];
333333
updateThread(this._context, matchingThread, thread, githubRepositories);
334334
}
335-
});
335+
}
336336

337-
e.removed.forEach(thread => {
337+
for (const thread of e.removed) {
338338
const match = this._findMatchingThread(thread);
339339
if (match.index > -1) {
340340
const matchingThread = match.threadMap[thread.path][match.index];
341341
match.threadMap[thread.path].splice(match.index, 1);
342342
matchingThread.dispose();
343343
}
344-
});
344+
}
345345

346346
this.updateResourcesWithCommentingRanges();
347347
}),

0 commit comments

Comments
 (0)