Skip to content

Commit 365fe39

Browse files
committed
WIP(mr): mr detail.
1 parent de0cada commit 365fe39

File tree

15 files changed

+128
-76
lines changed

15 files changed

+128
-76
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,3 @@
66
- `yarn install`
77
- `yarn watch` or `yarn compile`
88
- `F5` to start debugging
9-
10-
Run the `Cat Coding: Start cat coding session` to create the webview.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"Other"
1212
],
1313
"activationEvents": [
14-
"onCommand:codingPlugin.show",
14+
"onCommand:codingPlugin.showMROverview",
1515
"onCommand:codingPlugin.login",
1616
"onView:mrTreeView"
1717
],
@@ -23,7 +23,7 @@
2323
"contributes": {
2424
"commands": [
2525
{
26-
"command": "codingPlugin.show",
26+
"command": "codingPlugin.showMROverview",
2727
"title": "Show coding tree",
2828
"category": "Coding plugin"
2929
},

src/codingServer.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
} from './typings/respResult';
1313
import { PromiseAdapter, promiseFromEvent, parseQuery, parseCloneUrl } from './common/utils';
1414
import { GitService } from './common/gitService';
15-
import { RepoInfo, ISessionData, TokenType } from './typings/commonTypes';
15+
import { IRepoInfo, ISessionData, TokenType } from './typings/commonTypes';
1616
import { keychain } from './common/keychain';
1717
import Logger from './common/logger';
1818

@@ -84,7 +84,7 @@ export class CodingServer {
8484
refreshToken: TokenType.RefreshToken,
8585
): Promise<ISessionData> {
8686
try {
87-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
87+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
8888
if (!repoInfo?.team) {
8989
throw new Error(`team not exist`);
9090
}
@@ -238,7 +238,7 @@ export class CodingServer {
238238

239239
public async getMRList(repo?: string, status?: string): Promise<CodingResponse> {
240240
try {
241-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
241+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
242242
if (!repoInfo?.team) {
243243
throw new Error(`team not exist`);
244244
}
@@ -268,7 +268,7 @@ export class CodingServer {
268268

269269
public async getRepoList() {
270270
try {
271-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
271+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
272272
if (!repoInfo?.team) {
273273
throw new Error(`team not exist`);
274274
}
@@ -298,7 +298,7 @@ export class CodingServer {
298298

299299
public async getMRDiff(iid: number) {
300300
try {
301-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
301+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
302302
if (!repoInfo?.team) {
303303
throw new Error(`team not exist`);
304304
}
@@ -324,7 +324,7 @@ export class CodingServer {
324324

325325
public async getMRDetail(iid: number) {
326326
try {
327-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
327+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
328328
if (!repoInfo?.team) {
329329
throw new Error(`team not exist`);
330330
}
@@ -350,13 +350,14 @@ export class CodingServer {
350350

351351
public async getRemoteFileContent(path: string) {
352352
try {
353-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
353+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
354354
if (!repoInfo?.team) {
355355
throw new Error(`team not exist`);
356356
}
357357

358+
const url = `https://${repoInfo.team}.coding.net/p/${repoInfo.project}/d/${repoInfo.repo}/git/raw/${path}`;
358359
const { body } = await got.get(
359-
`https://${repoInfo.team}.coding.net/p/${repoInfo.project}/d/${repoInfo.repo}/git/raw/${path}`,
360+
url,
360361
{
361362
searchParams: {
362363
access_token: this._session?.accessToken,

src/common/uri.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Uri } from 'vscode';
2+
3+
export const EMPTY_IMAGE_URI = Uri.parse(`data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==`);

src/common/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Event, Disposable, Uri } from 'vscode';
2-
import { RepoInfo } from '../typings/commonTypes';
2+
import { IRepoInfo } from '../typings/commonTypes';
33

44
export interface PromiseAdapter<T, U> {
55
(value: T, resolve: (value: U | PromiseLike<U>) => void, reject: (reason: any) => void): any;
@@ -41,7 +41,7 @@ export function parseQuery(uri: Uri) {
4141
}, {});
4242
}
4343

44-
export function parseCloneUrl(url: string): RepoInfo | null {
44+
export function parseCloneUrl(url: string): IRepoInfo | null {
4545
const reg = /^(https:\/\/|git@)e\.coding\.net(\/|:)(.*)\.git$/i;
4646
const result = url.match(reg);
4747

src/extension.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import * as vscode from 'vscode';
2-
import got from 'got';
32

4-
// import Logger from './common/logger';
53
import { uriHandler, CodingServer } from './codingServer';
64
import { Panel } from './panel';
75
import { IFileNode, MRTreeDataProvider } from './tree/mrTree';
86
import { ReleaseTreeDataProvider } from './tree/releaseTree';
9-
import { RepoInfo } from './typings/commonTypes';
7+
import { IRepoInfo, IMRWebViewDetail } from './typings/commonTypes';
108

119
export async function activate(context: vscode.ExtensionContext) {
1210
const repoInfo = await CodingServer.getRepoParams();
@@ -49,19 +47,14 @@ export async function activate(context: vscode.ExtensionContext) {
4947

5048
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
5149
context.subscriptions.push(
52-
vscode.commands.registerCommand('codingPlugin.show', () => {
53-
Panel.createOrShow(context);
54-
}),
55-
);
56-
context.subscriptions.push(
57-
vscode.commands.registerCommand('codingPlugin.showDetail', (k) => {
58-
Panel.createOrShow(context);
59-
Panel.currentPanel?.broadcast(`UPDATE_CURRENCY`, k);
50+
vscode.commands.registerCommand('codingPlugin.showMROverview', (data: IMRWebViewDetail) => {
51+
Panel.createOrShow(context, data);
52+
Panel.currentPanel?.broadcast(`action.UPDATE_CURRENT_MR`, data);
6053
}),
6154
);
6255
context.subscriptions.push(
6356
vscode.commands.registerCommand('codingPlugin.login', async () => {
64-
const rInfo = context.workspaceState.get(`repoInfo`, {}) as RepoInfo;
57+
const rInfo = context.workspaceState.get(`repoInfo`, {}) as IRepoInfo;
6558
const session = await codingSrv.login(rInfo?.team || ``);
6659
if (!session?.accessToken) {
6760
console.error(`No token provided.`);
@@ -96,7 +89,7 @@ export async function activate(context: vscode.ExtensionContext) {
9689
const selection = await vscode.window.showQuickPick(list);
9790
if (!selection) return;
9891

99-
const r = context.workspaceState.get(`repoInfo`, {}) as RepoInfo;
92+
const r = context.workspaceState.get(`repoInfo`, {}) as IRepoInfo;
10093
context.workspaceState.update(`repoInfo`, {
10194
team: r?.team,
10295
project: selection?.description.replace(`/${selection?.label}`, ``),
@@ -111,15 +104,16 @@ export async function activate(context: vscode.ExtensionContext) {
111104
);
112105
context.subscriptions.push(
113106
vscode.commands.registerCommand(`codingPlugin.showDiff`, async (file: IFileNode) => {
114-
const newFileUri = vscode.Uri.parse(file.path, false).with({
107+
const headUri = vscode.Uri.parse(file.path, false).with({
108+
// path: `${file.path}.txt`,
115109
scheme: `mr`,
116110
query: `commit=${file.newSha}&path=${file.path}`,
117111
});
118-
const oldFileUri = newFileUri.with({ query: `commit=${file.oldSha}&path=${file.path}` });
112+
const parentUri = headUri.with({ query: `commit=${file.oldSha}&path=${file.path}` });
119113
await vscode.commands.executeCommand(
120114
`vscode.diff`,
121-
oldFileUri,
122-
newFileUri,
115+
parentUri,
116+
headUri,
123117
`${file.name} (Merge Request)`,
124118
{ preserveFocus: true },
125119
);
@@ -136,4 +130,5 @@ export async function activate(context: vscode.ExtensionContext) {
136130
}
137131
}
138132

139-
export function deactivate() {}
133+
export function deactivate() {
134+
}

src/panel.ts

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as vscode from 'vscode';
22
import * as path from 'path';
33

4+
import { IMRWebViewDetail } from './typings/commonTypes'
5+
46
export class Panel {
57
/**
68
* Track the currently panel. Only allow a single panel to exist at a time.
@@ -14,7 +16,7 @@ export class Panel {
1416
private readonly _extensionPath: string;
1517
private _disposables: vscode.Disposable[] = [];
1618

17-
public static createOrShow(context: vscode.ExtensionContext) {
19+
public static createOrShow(context: vscode.ExtensionContext, data: IMRWebViewDetail) {
1820
const { extensionUri, extensionPath } = context;
1921
const column = vscode.window.activeTextEditor
2022
? vscode.window.activeTextEditor.viewColumn
@@ -39,7 +41,7 @@ export class Panel {
3941
},
4042
);
4143

42-
Panel.currentPanel = new Panel(panel, extensionUri, extensionPath);
44+
Panel.currentPanel = new Panel(panel, extensionUri, extensionPath, data);
4345
}
4446

4547
public static revive(
@@ -50,21 +52,21 @@ export class Panel {
5052
Panel.currentPanel = new Panel(panel, extensionUri, extensionPath);
5153
}
5254

53-
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri, extensionPath: string) {
55+
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri, extensionPath: string, mr?: IMRWebViewDetail) {
5456
this._panel = panel;
5557
this._extensionUri = extensionUri;
5658
this._extensionPath = extensionPath;
5759

5860
// Set the webview's initial html content
59-
this._update();
61+
this._update(mr);
6062

6163
// Listen for when the panel is disposed
6264
// This happens when the user closes the panel or when the panel is closed programatically
6365
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
6466

6567
// Update the content based on view changes
6668
this._panel.onDidChangeViewState(
67-
(e) => {
69+
() => {
6870
if (this._panel.visible) {
6971
this._update();
7072
}
@@ -114,28 +116,28 @@ export class Panel {
114116
}
115117
}
116118

117-
private _update() {
119+
private _update(data?: IMRWebViewDetail) {
118120
const webview = this._panel.webview;
119121

120122
// Vary the webview's content based on where it is located in the editor.
121123
switch (this._panel.viewColumn) {
122124
case vscode.ViewColumn.Two:
123-
this._updateForCat(webview);
125+
this._updateForCat(webview, data);
124126
return;
125127

126128
case vscode.ViewColumn.Three:
127-
this._updateForCat(webview);
129+
this._updateForCat(webview, data);
128130
return;
129131

130132
case vscode.ViewColumn.One:
131133
default:
132-
this._updateForCat(webview);
134+
this._updateForCat(webview, data);
133135
return;
134136
}
135137
}
136138

137-
private _updateForCat(webview: vscode.Webview) {
138-
this._panel.title = `Coding cat ${Date.now()}`;
139+
private _updateForCat(webview: vscode.Webview, data?: IMRWebViewDetail) {
140+
this._panel.title = `Merge Request ${data?.iid || ``}`;
139141
this._panel.webview.html = this._getHtmlForWebview(webview);
140142
}
141143

@@ -148,18 +150,17 @@ export class Panel {
148150
<head>
149151
<meta charset="UTF-8">
150152
<meta name="viewport" content="width=device-width, initial-scale=1.0">
151-
<title>Coding Cat</title>
152-
153+
<title>Merge Request Overview</title>
154+
153155
<meta http-equiv="Content-Security-Policy"
154156
content="default-src 'unsafe-inline';
155157
img-src https:;
156158
script-src 'unsafe-eval' 'unsafe-inline' vscode-resource:;
157-
connect-src 'self' https:;
159+
connect-src 'self' https: *.coding.net;
158160
style-src vscode-resource: 'unsafe-inline';">
159161
</head>
160162
<body>
161163
<div id="root"></div>
162-
163164
<script src="${appUri}"></script>
164165
</body>
165166
</html>`;

src/tree/mrTree.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
22
import * as path from 'path';
33

44
import { CodingServer } from '../codingServer';
5-
import { RepoInfo, ISessionData } from '../typings/commonTypes';
5+
import { IRepoInfo, ISessionData } from '../typings/commonTypes';
66
import { IMRDiffStat, IMRData, IMRPathItem } from '../typings/respResult';
77

88
import { getInMemMRContentProvider } from './inMemMRContentProvider';
@@ -67,7 +67,7 @@ export class MRTreeDataProvider implements vscode.TreeDataProvider<ListItem<ITre
6767
return Promise.resolve([]);
6868
}
6969

70-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
70+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
7171
if (!repoInfo?.team) {
7272
throw new Error(`team not exist.`);
7373
}
@@ -116,7 +116,7 @@ export class MRTreeDataProvider implements vscode.TreeDataProvider<ListItem<ITre
116116
];
117117
}
118118

119-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
119+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
120120
if (!repoInfo?.team) {
121121
throw new Error(`team not exist`);
122122
}
@@ -199,13 +199,13 @@ export class MRItem extends ListItem<IMRData> {
199199

200200
return [
201201
new ListItem(`Description`, `mr-desc`, vscode.TreeItemCollapsibleState.None, {
202-
command: 'codingPlugin.showDetail',
202+
command: 'codingPlugin.showMROverview',
203203
title: `${this.value.iid} ${this.value.title}`,
204204
arguments: [
205205
{
206-
...repoInfo,
207-
iid: this.value.iid,
208206
type: `mr`,
207+
iid: this.value.iid,
208+
repoInfo,
209209
accessToken: session?.accessToken,
210210
},
211211
],

src/typings/commonTypes.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { UserResponse } from './respResult';
1+
import { IMRDetail, IMRDetailResponse, UserResponse } from './respResult';
22

3-
export interface RepoInfo {
3+
export interface IRepoInfo {
44
team: string;
55
project: string;
66
repo: string;
@@ -17,3 +17,22 @@ export interface ISessionData {
1717
accessToken: string;
1818
refreshToken: string;
1919
}
20+
21+
export enum GitChangeType {
22+
ADD = `ADD`,
23+
COPY = `COPY`,
24+
DELETE = `DELETE`,
25+
MODIFY = `MODIFY`,
26+
RENAME = `RENAME`,
27+
TYPE = `TYPE`,
28+
UNKNOWN = `UNKNOWN`,
29+
UNMERGED = `UNMERGED`
30+
}
31+
32+
export interface IMRWebViewDetail {
33+
type: string;
34+
iid: string;
35+
accessToken: string;
36+
repoInfo: IRepoInfo;
37+
data: IMRDetail;
38+
}

src/typings/respResult.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TokenType } from './commonTypes';
1+
import { TokenType, GitChangeType } from './commonTypes';
22

33
export interface AuthSuccessResult {
44
access_token: TokenType.AccessToken;
@@ -49,7 +49,7 @@ export interface IRepoListResponse extends CodingResponse {
4949
}
5050

5151
export interface IMRPathItem {
52-
changeType: string;
52+
changeType: GitChangeType;
5353
insertions: number;
5454
deletions: number;
5555
name: string;

0 commit comments

Comments
 (0)