Skip to content

Commit 2ed73ee

Browse files
committed
fix(mr tree): disable duplicate click on mr files.
1 parent 3b742c3 commit 2ed73ee

File tree

3 files changed

+100
-62
lines changed

3 files changed

+100
-62
lines changed

src/extension.ts

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ import { uriHandler, CodingServer } from 'src/codingServer';
66
import { Panel } from 'src/panel';
77
import { IFileNode, MRTreeDataProvider } from 'src/tree/mrTree';
88
import { ReleaseTreeDataProvider } from 'src/tree/releaseTree';
9-
import { IRepoInfo, IMRWebViewDetail, ISessionData } from 'src/typings/commonTypes';
9+
import {
10+
IRepoInfo,
11+
IMRWebViewDetail,
12+
ISessionData,
13+
ICachedCommentThreads,
14+
ICachedCommentController,
15+
} from 'src/typings/commonTypes';
1016
import { GitService } from 'src/common/gitService';
1117
import { MRUriScheme } from 'src/common/contants';
1218
import { IDiffComment, IMRData, IFileDiffParam, IDiffFile } from 'src/typings/respResult';
13-
import { replyNote, ReviewComment } from './reviewCommentController';
19+
import { replyNote, ReviewComment, makeCommentRangeProvider } from 'src/reviewCommentController';
1420
import { getDiffLineNumber, isHunkLine } from 'src/common/utils';
1521

1622
export async function activate(context: vscode.ExtensionContext) {
@@ -48,59 +54,10 @@ export async function activate(context: vscode.ExtensionContext) {
4854
});
4955

5056
const tdService = new TurndownService();
51-
const commentController = vscode.comments.createCommentController(
52-
'mrDiffComment',
53-
'Merge request diff comments',
54-
);
55-
context.subscriptions.push(commentController);
56-
57-
const commentThreads: { [key: string]: vscode.CommentThread[] } = {};
5857
const diffFileData: { [key: string]: IDiffFile } = {};
59-
60-
commentController.commentingRangeProvider = {
61-
provideCommentingRanges: async (
62-
document: vscode.TextDocument,
63-
token: vscode.CancellationToken,
64-
) => {
65-
if (document.uri.scheme !== MRUriScheme) {
66-
return [];
67-
}
68-
69-
try {
70-
const params = new URLSearchParams(decodeURIComponent(document.uri.query));
71-
const mrId = params.get('id') || ``;
72-
let param: IFileDiffParam = {
73-
path: params.get('path') ?? ``,
74-
base: params.get('leftSha') ?? ``,
75-
compare: params.get('rightSha') ?? ``,
76-
mergeRequestId: mrId ?? ``,
77-
};
78-
const fileIdent = `${params.get(`mr`)}/${params.get(`path`)}`;
79-
80-
const { data } = await codingSrv.fetchFileDiffs(param);
81-
diffFileData[fileIdent] = data;
82-
const { diffLines } = data;
83-
84-
const ret = diffLines.reduce((result, i) => {
85-
const isHunk = isHunkLine(i.text);
86-
if (!isHunk) {
87-
return result;
88-
}
89-
90-
const [left, right] = getDiffLineNumber(i.text);
91-
const [start, end] = params.get('right') === `true` ? right : left;
92-
if (start > 0) {
93-
result.push(new vscode.Range(start - 1, 0, end, 0));
94-
}
95-
return result;
96-
}, [] as vscode.Range[]);
97-
return ret;
98-
} catch (e) {
99-
console.error('fetch diff lines failed.');
100-
return [];
101-
}
102-
},
103-
};
58+
const cachedCommentThreads: ICachedCommentThreads = {};
59+
const cachedCommentControllers: ICachedCommentController = {};
60+
let selectedMrFile = ``;
10461

10562
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
10663
context.subscriptions.push(
@@ -247,6 +204,12 @@ export async function activate(context: vscode.ExtensionContext) {
247204
vscode.commands.registerCommand(
248205
`codingPlugin.showDiff`,
249206
async (file: IFileNode, mr: IMRData) => {
207+
const curMrFile = `${mr.iid}/${file.path}`;
208+
if (selectedMrFile === curMrFile) {
209+
return;
210+
}
211+
selectedMrFile = curMrFile;
212+
250213
const headUri = vscode.Uri.parse(file.path, false).with({
251214
scheme: MRUriScheme,
252215
query: `leftSha=${file.oldSha}&rightSha=${file.newSha}&path=${file.path}&right=true&mr=${mr.iid}&id=${mr.id}`,
@@ -262,9 +225,24 @@ export async function activate(context: vscode.ExtensionContext) {
262225
{ preserveFocus: true },
263226
);
264227

265-
commentThreads[mr.iid]?.forEach((c) => {
228+
const cacheId = `${mr.iid}/${file.path}`;
229+
// cachedCommentControllers[cacheId]?.dispose();
230+
cachedCommentThreads[cacheId]?.forEach((c) => {
266231
c?.dispose();
267232
});
233+
cachedCommentThreads[cacheId] = [];
234+
235+
let commentController = cachedCommentControllers[cacheId];
236+
if (!commentController) {
237+
commentController = vscode.comments.createCommentController(
238+
`mr-${mr.iid}`,
239+
`mr-${mr.iid}-comment-controller`,
240+
);
241+
commentController.commentingRangeProvider = {
242+
provideCommentingRanges: makeCommentRangeProvider(codingSrv, diffFileData),
243+
};
244+
cachedCommentControllers[cacheId] = commentController;
245+
}
268246

269247
try {
270248
const commentResp = await codingSrv.getMRComments(mr.iid);
@@ -284,11 +262,10 @@ export async function activate(context: vscode.ExtensionContext) {
284262

285263
Object.values(validComments).forEach((i) => {
286264
const root = i[0];
287-
const isLeft = root.change_type === 2;
288265
const isRight = root.change_type === 1;
289266

290267
const rootLine = root.diffFile.diffLines[root.diffFile.diffLines.length - 1];
291-
const lineNum = isLeft ? rootLine.leftNo - 1 : rootLine.rightNo - 1;
268+
const lineNum = isRight ? rootLine.rightNo - 1 : rootLine.leftNo - 1;
292269
const range = new vscode.Range(lineNum, 0, lineNum, 0);
293270

294271
const commentList: vscode.Comment[] = i
@@ -319,7 +296,9 @@ export async function activate(context: vscode.ExtensionContext) {
319296
commentThread.comments = commentList;
320297
commentThread.collapsibleState = vscode.CommentThreadCollapsibleState.Expanded;
321298

322-
commentThreads[mr.iid] = (commentThreads[mr.iid] ?? []).concat(commentThread);
299+
cachedCommentThreads[cacheId] = (cachedCommentThreads[mr.iid] ?? []).concat(
300+
commentThread,
301+
);
323302
});
324303
} finally {
325304
}
@@ -331,15 +310,17 @@ export async function activate(context: vscode.ExtensionContext) {
331310
vscode.commands.registerCommand(
332311
`codingPlugin.diff.createComment`,
333312
async (reply: vscode.CommentReply) => {
334-
replyNote(reply, context, codingSrv, diffFileData);
313+
const cachedThreadId = await replyNote(reply, context, codingSrv, diffFileData);
314+
cachedCommentThreads[cachedThreadId].push(reply.thread);
335315
},
336316
),
337317
);
338318
context.subscriptions.push(
339319
vscode.commands.registerCommand(
340320
`codingPlugin.diff.replyComment`,
341321
async (reply: vscode.CommentReply) => {
342-
replyNote(reply, context, codingSrv, diffFileData);
322+
const cachedThreadId = await replyNote(reply, context, codingSrv, diffFileData);
323+
cachedCommentThreads[cachedThreadId].push(reply.thread);
343324
},
344325
),
345326
);

src/reviewCommentController.ts

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import * as vscode from 'vscode';
22

3-
import { ISessionData, IDiffFileData } from 'src/typings/commonTypes';
4-
import { EmptyUserAvatar } from 'src/common/contants';
3+
import { ISessionData, IDiffFileData, ICachedCommentThreads } from 'src/typings/commonTypes';
4+
import { EmptyUserAvatar, MRUriScheme } from 'src/common/contants';
55
import { CodingServer } from 'src/codingServer';
6+
import { IDiffComment, IMRData, IFileDiffParam, IDiffFile } from 'src/typings/respResult';
7+
import { getDiffLineNumber, isHunkLine } from 'src/common/utils';
68

79
let commentIdx = 0;
810
export class ReviewComment implements vscode.Comment {
@@ -53,6 +55,7 @@ export async function replyNote(
5355
line,
5456
path,
5557
position,
58+
anchor: `diff-${diffFile.pathMD5}`,
5659
});
5760

5861
const curUser = context.workspaceState.get<ISessionData>(`session`);
@@ -78,4 +81,49 @@ export async function replyNote(
7881

7982
thread.comments = [...thread.comments, newComment];
8083
} catch (e) {}
84+
85+
return `${params.get('mr')}/${path}`;
8186
}
87+
88+
export const makeCommentRangeProvider = (
89+
codingSrv: CodingServer,
90+
diffFileData: IDiffFileData,
91+
) => async (document: vscode.TextDocument, token: vscode.CancellationToken) => {
92+
if (document.uri.scheme !== MRUriScheme) {
93+
return [];
94+
}
95+
96+
try {
97+
const params = new URLSearchParams(decodeURIComponent(document.uri.query));
98+
const mrId = params.get('id') || ``;
99+
let param: IFileDiffParam = {
100+
path: params.get('path') ?? ``,
101+
base: params.get('leftSha') ?? ``,
102+
compare: params.get('rightSha') ?? ``,
103+
mergeRequestId: mrId ?? ``,
104+
};
105+
const fileIdent = `${params.get(`mr`)}/${params.get(`path`)}`;
106+
107+
const { data } = await codingSrv.fetchFileDiffs(param);
108+
diffFileData[fileIdent] = data;
109+
const { diffLines } = data;
110+
111+
const ret = diffLines.reduce((result, i) => {
112+
const isHunk = isHunkLine(i.text);
113+
if (!isHunk) {
114+
return result;
115+
}
116+
117+
const [left, right] = getDiffLineNumber(i.text);
118+
const [start, end] = params.get('right') === `true` ? right : left;
119+
if (start > 0) {
120+
result.push(new vscode.Range(start - 1, 0, end, 0));
121+
}
122+
return result;
123+
}, [] as vscode.Range[]);
124+
return ret;
125+
} catch (e) {
126+
console.error('fetch diff lines failed.');
127+
return [];
128+
}
129+
};

src/typings/commonTypes.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as vscode from 'vscode';
12
import { IDiffFile, IMRDetail, IMRStatusItem, IUserItem } from './respResult';
23

34
export interface IRepoInfo {
@@ -45,3 +46,11 @@ export interface IMRWebViewDetail {
4546
export interface IDiffFileData {
4647
[key: string]: IDiffFile;
4748
}
49+
50+
export interface ICachedCommentThreads {
51+
[key: string]: vscode.CommentThread[];
52+
}
53+
54+
export interface ICachedCommentController {
55+
[key: string]: vscode.CommentController;
56+
}

0 commit comments

Comments
 (0)