Skip to content

Commit 341736b

Browse files
committed
feat: mr comment.
1 parent 27106f2 commit 341736b

File tree

7 files changed

+114
-15
lines changed

7 files changed

+114
-15
lines changed

src/codingServer.ts

+28
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
ICreateCommentResp,
2020
IMRStatusResp,
2121
IMRCommentResp,
22+
IFileDiffParam,
23+
IFileDiffResp,
2224
} from 'src/typings/respResult';
2325

2426
import { PromiseAdapter, promiseFromEvent, parseQuery, parseCloneUrl } from 'src/common/utils';
@@ -717,6 +719,32 @@ export class CodingServer {
717719
}
718720
}
719721

722+
public async fetchFileDiffs(param: IFileDiffParam) {
723+
try {
724+
const { repoApiPrefix } = await this.getApiPrefix();
725+
const resp: IFileDiffResp = await got
726+
.get(`http://127.0.0.1:5000/api/git/compare_with_path`, {
727+
// .get(`${repoApiPrefix}/compare_with_path`, {
728+
searchParams: {
729+
access_token: this._session?.accessToken,
730+
base: param.base,
731+
compare: param.compare,
732+
path: encodeURIComponent(param.path),
733+
mergeRequestId: param.mergeRequestId,
734+
},
735+
})
736+
.json();
737+
738+
if (resp.code) {
739+
return Promise.reject(resp);
740+
}
741+
742+
return resp;
743+
} catch (e) {
744+
return Promise.reject(e);
745+
}
746+
}
747+
720748
get loggedIn() {
721749
return this._loggedIn;
722750
}

src/common/contants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export const MRUriScheme = `coding-mr`;
2+
3+
export const EmptyUserAvatar = `https://coding-net-production-static-ci.codehub.cn/7167f369-59ff-4196-bb76-a9959cf2b906.png`;

src/common/utils.ts

+12
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,15 @@ export function getNonce() {
6666
}
6767
return text;
6868
}
69+
70+
const HunkRegExp = /@@.+@@/g;
71+
export const isHunkLine = (hunk: string) => HunkRegExp.test(hunk);
72+
73+
export const getDiffLineNumber = (hunk: string) => {
74+
const matchedHunks = hunk.match(/[-+]\d+,\d+/g) || [];
75+
return matchedHunks.map((i) => {
76+
const [start, sum] = i.match(/\d+/g)?.map((j) => +j) || [0, 0];
77+
const end = start + sum > 0 ? start + sum - 1 : 0;
78+
return [start, end];
79+
});
80+
};

src/extension.ts

+42-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { IRepoInfo, IMRWebViewDetail, ISessionData } from 'src/typings/commonTyp
1010
import { GitService } from 'src/common/gitService';
1111
import { ReviewComment, replyNote } from './reviewCommentController';
1212
import { MRUriScheme } from 'src/common/contants';
13-
import { IDiffComment, IMRData } from 'src/typings/respResult';
13+
import { IDiffComment, IMRData, IFileDiffParam } from 'src/typings/respResult';
14+
import { getDiffLineNumber, isHunkLine } from 'src/common/utils';
1415

1516
export async function activate(context: vscode.ExtensionContext) {
1617
await GitService.init();
@@ -54,13 +55,42 @@ export async function activate(context: vscode.ExtensionContext) {
5455
context.subscriptions.push(commentController);
5556

5657
commentController.commentingRangeProvider = {
57-
provideCommentingRanges: (document: vscode.TextDocument, token: vscode.CancellationToken) => {
58+
provideCommentingRanges: async (
59+
document: vscode.TextDocument,
60+
token: vscode.CancellationToken,
61+
) => {
5862
if (document.uri.scheme !== MRUriScheme) {
59-
return;
63+
return [];
6064
}
6165

62-
const lineCount = document.lineCount;
63-
return [new vscode.Range(0, 0, lineCount - 1, 0)];
66+
try {
67+
const params = new URLSearchParams(decodeURIComponent(document.uri.query));
68+
const iid = params.get('mr') || ``;
69+
let param: IFileDiffParam = {
70+
path: params.get('path') ?? ``,
71+
base: params.get('leftSha') ?? ``,
72+
compare: params.get('rightSha') ?? ``,
73+
mergeRequestId: iid ?? ``,
74+
};
75+
const {
76+
data: { diffLines },
77+
} = await codingSrv.fetchFileDiffs(param);
78+
const ret = diffLines.reduce((result, i) => {
79+
const isHunk = isHunkLine(i.text);
80+
if (!isHunk) {
81+
return result;
82+
}
83+
84+
const [left, right] = getDiffLineNumber(i.text);
85+
const [start, end] = params.get('right') ? right : left;
86+
result.push(new vscode.Range(start, 0, end, 0));
87+
return result;
88+
}, [] as vscode.Range[]);
89+
return ret;
90+
} catch (e) {
91+
console.error('fetch diff lines failed.');
92+
return [];
93+
}
6494
},
6595
};
6696

@@ -211,9 +241,11 @@ export async function activate(context: vscode.ExtensionContext) {
211241
async (file: IFileNode, mr: IMRData) => {
212242
const headUri = vscode.Uri.parse(file.path, false).with({
213243
scheme: MRUriScheme,
214-
query: `commit=${file.newSha}&path=${file.path}`,
244+
query: `leftSha=${file.oldSha}&rightSha=${file.newSha}&path=${file.path}&right=true&mr=${mr.iid}`,
245+
});
246+
const parentUri = headUri.with({
247+
query: `leftSha=${file.oldSha}&rightSha=${file.newSha}&path=${file.path}&right=false&mr=${mr.iid}`,
215248
});
216-
const parentUri = headUri.with({ query: `commit=${file.oldSha}&path=${file.path}` });
217249
await vscode.commands.executeCommand(
218250
`vscode.diff`,
219251
parentUri,
@@ -224,6 +256,7 @@ export async function activate(context: vscode.ExtensionContext) {
224256

225257
try {
226258
const commentResp = await codingSrv.getMRComments(mr.iid);
259+
227260
(commentResp.data as IDiffComment[][])
228261
.filter((i) => {
229262
const first = i[0];
@@ -268,15 +301,15 @@ export async function activate(context: vscode.ExtensionContext) {
268301
vscode.commands.registerCommand(
269302
`codingPlugin.diff.createComment`,
270303
(reply: vscode.CommentReply) => {
271-
replyNote(reply);
304+
replyNote(reply, context);
272305
},
273306
),
274307
);
275308
context.subscriptions.push(
276309
vscode.commands.registerCommand(
277310
`codingPlugin.diff.replyComment`,
278311
(reply: vscode.CommentReply) => {
279-
replyNote(reply);
312+
replyNote(reply, context);
280313
},
281314
),
282315
);

src/reviewCommentController.ts

+18-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as vscode from 'vscode';
2+
import { ISessionData } from 'src/typings/commonTypes';
3+
import { EmptyUserAvatar } from 'src/common/contants';
24

35
let commentId = 1;
46

@@ -16,18 +18,29 @@ export class ReviewComment implements vscode.Comment {
1618
}
1719
}
1820

19-
export function replyNote(reply: vscode.CommentReply) {
21+
export function replyNote(reply: vscode.CommentReply, context: vscode.ExtensionContext) {
22+
const curUser = context.workspaceState.get<ISessionData>(`session`);
23+
const commentAuthor: vscode.CommentAuthorInformation = curUser?.user
24+
? {
25+
name: `${curUser.user.name} (${curUser.user.global_key})`,
26+
iconPath: vscode.Uri.parse(curUser.user.avatar, false),
27+
}
28+
: {
29+
name: `vscode user`,
30+
iconPath: vscode.Uri.parse(EmptyUserAvatar, false),
31+
};
2032
const thread = reply.thread;
33+
thread.contextValue = `editable`;
2134
const newComment = new ReviewComment(
2235
reply.text,
2336
vscode.CommentMode.Preview,
24-
{ name: 'vscode' },
37+
commentAuthor,
2538
thread,
2639
thread.comments.length ? 'canDelete' : undefined,
2740
);
28-
if (thread.contextValue === 'draft') {
29-
newComment.label = 'pending';
30-
}
41+
// if (thread.contextValue === 'draft') {
42+
// newComment.label = 'pending';
43+
// }
3144

3245
thread.comments = [...thread.comments, newComment];
3346
}

src/tree/inMemMRContentProvider.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class InMemMRContentProvider implements vscode.TextDocumentContentProvide
3030
token: vscode.CancellationToken,
3131
): Promise<string> {
3232
const params = new URLSearchParams(decodeURIComponent(uri.query));
33-
const commit = params.get(`commit`);
33+
const commit = params.get(`right`) ? params.get(`rightSha`) : params.get('leftSha');
3434
const path = params.get(`path`);
3535
return await this._service.getRemoteFileContent(`${commit}/${path}`);
3636
}

src/typings/respResult.ts

+11
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,14 @@ export type IMRComment = IDiffComment | IActivityComment;
342342
export interface IMRCommentResp extends CodingResponse {
343343
data: IMRComment[][];
344344
}
345+
346+
export interface IFileDiffParam {
347+
path: string;
348+
base: string;
349+
compare: string;
350+
mergeRequestId: string;
351+
}
352+
353+
export interface IFileDiffResp extends CodingResponse {
354+
data: IDiffFile;
355+
}

0 commit comments

Comments
 (0)