Skip to content

Commit 9b2553c

Browse files
committed
feat(mr): diff view.
1 parent 5b4498a commit 9b2553c

File tree

7 files changed

+94
-16
lines changed

7 files changed

+94
-16
lines changed

src/codingServer.ts

Lines changed: 25 additions & 6 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, SessionData, TokenType } from './typings/commonTypes';
15+
import { RepoInfo, ISessionData, TokenType } from './typings/commonTypes';
1616
import { keychain } from './common/keychain';
1717
import Logger from './common/logger';
1818

@@ -45,7 +45,7 @@ export class CodingServer {
4545

4646
private _loggedIn: boolean = false;
4747
private _context: vscode.ExtensionContext;
48-
private _session: SessionData | null = null;
48+
private _session: ISessionData | null = null;
4949

5050
constructor(context: vscode.ExtensionContext) {
5151
this._context = context;
@@ -59,7 +59,7 @@ export class CodingServer {
5959
}
6060
}
6161

62-
private async _readSessions(): Promise<SessionData | null> {
62+
private async _readSessions(): Promise<ISessionData | null> {
6363
const [accessToken, refreshToken] = await Promise.all([
6464
keychain.getToken(TokenType.AccessToken),
6565
keychain.getToken(TokenType.RefreshToken),
@@ -81,7 +81,7 @@ export class CodingServer {
8181
return null;
8282
}
8383

84-
public async getSessionData(accessToken: TokenType.AccessToken, refreshToken: TokenType.RefreshToken): Promise<SessionData> {
84+
public async getSessionData(accessToken: TokenType.AccessToken, refreshToken: TokenType.RefreshToken): Promise<ISessionData> {
8585
try {
8686
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
8787
if (!repoInfo?.team) {
@@ -90,7 +90,7 @@ export class CodingServer {
9090

9191
const result = await this.getUserInfo(repoInfo.team || ``, accessToken);
9292
const { data: userInfo } = result;
93-
const ret: SessionData = {
93+
const ret: ISessionData = {
9494
id: nanoid(),
9595
user: userInfo,
9696
accessToken,
@@ -131,7 +131,7 @@ export class CodingServer {
131131
});
132132
}
133133

134-
public async login(team: string, scopes: string = SCOPES): Promise<SessionData | null> {
134+
public async login(team: string, scopes: string = SCOPES): Promise<ISessionData | null> {
135135
const { access_token: accessToken, refresh_token: refreshToken } = await this.startOAuth(team, scopes);
136136
if (accessToken && refreshToken) {
137137
try {
@@ -305,6 +305,25 @@ export class CodingServer {
305305
}
306306
}
307307

308+
public async getRemoteFileContent(path: string) {
309+
try {
310+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as RepoInfo;
311+
if (!repoInfo?.team) {
312+
throw new Error(`team not exist`);
313+
}
314+
315+
const { body } = await got.get(`https://${repoInfo.team}.coding.net/p/${repoInfo.project}/d/${repoInfo.repo}/git/raw/${path}`, {
316+
searchParams: {
317+
access_token: this._session?.accessToken,
318+
},
319+
});
320+
321+
return body;
322+
} catch (err) {
323+
return ``;
324+
}
325+
}
326+
308327
get loggedIn() {
309328
return this._loggedIn;
310329
}

src/extension.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as vscode from 'vscode';
2+
import got from 'got';
23

34
// import Logger from './common/logger';
45
import { uriHandler, CodingServer } from './codingServer';
56
import { Panel } from './panel';
6-
import { IFileNode, MRTreeDataProvider } from './tree/mr-tree';
7-
import { ReleaseTreeDataProvider } from './tree/release-tree';
7+
import { IFileNode, MRTreeDataProvider } from './tree/mrTree';
8+
import { ReleaseTreeDataProvider } from './tree/releaseTree';
89
import { RepoInfo } from './typings/commonTypes';
910

1011
export async function activate(context: vscode.ExtensionContext) {
@@ -105,8 +106,9 @@ export async function activate(context: vscode.ExtensionContext) {
105106
);
106107
context.subscriptions.push(
107108
vscode.commands.registerCommand(`codingPlugin.showDiff`, async (file: IFileNode) => {
108-
console.log(context.storageUri, context.globalStorageUri, file);
109-
// await vscode.commands.executeCommand(`vscode.diff`, vscode.Uri);
109+
const newFileUri = vscode.Uri.parse(file.path, false).with({ scheme: `mr`, query: `commit=${file.newSha}&path=${file.path}` });
110+
const oldFileUri = newFileUri.with({ query: `commit=${file.oldSha}&path=${file.path}`});
111+
await vscode.commands.executeCommand(`vscode.diff`, oldFileUri, newFileUri, `${file.name} (Merge Request)`, { preserveFocus: true });
110112
}),
111113
);
112114

src/tree/inMemMRContentProvider.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
import * as vscode from 'vscode';
4+
import { CodingServer } from '../codingServer';
5+
6+
export class InMemMRContentProvider implements vscode.TextDocumentContentProvider {
7+
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
8+
private _context: vscode.ExtensionContext;
9+
private _service: CodingServer;
10+
11+
get onDidChange(): vscode.Event<vscode.Uri> {
12+
return this._onDidChange.event;
13+
}
14+
15+
fireDidChange(uri: vscode.Uri) {
16+
this._onDidChange.fire(uri);
17+
}
18+
19+
private _mrFileChangeContentProviders: { [key: number]: (uri: vscode.Uri) => Promise<string> } = {};
20+
21+
constructor(context: vscode.ExtensionContext, service: CodingServer) {
22+
this._context = context;
23+
this._service = service;
24+
}
25+
26+
async provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): Promise<string> {
27+
const params = new URLSearchParams(decodeURIComponent(uri.query));
28+
const commit = params.get(`commit`);
29+
const path = params.get(`path`);
30+
return await this._service.getRemoteFileContent(`${commit}/${path}`);
31+
}
32+
33+
registerTextDocumentContentProvider(mrNumber: number, provider: (uri: vscode.Uri) => Promise<string>): vscode.Disposable {
34+
this._mrFileChangeContentProviders[mrNumber] = provider;
35+
36+
return {
37+
dispose: () => {
38+
delete this._mrFileChangeContentProviders[mrNumber];
39+
},
40+
};
41+
}
42+
}
43+
44+
export function getInMemMRContentProvider(context: vscode.ExtensionContext, service: CodingServer): InMemMRContentProvider {
45+
return new InMemMRContentProvider(context, service);
46+
}

src/tree/mr-tree.ts renamed to src/tree/mrTree.ts

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

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

8+
import { getInMemMRContentProvider } from './inMemMRContentProvider'
9+
810
enum MRType {
911
Open = `open`,
1012
Closed = `close`,
@@ -30,13 +32,17 @@ type ITreeNode = string | number | IMRDiffStat | IFileNode | IMRData;
3032
export class MRTreeDataProvider implements vscode.TreeDataProvider<ListItem<ITreeNode>> {
3133
private _onDidChangeTreeData: vscode.EventEmitter<ListItem<ITreeNode> | undefined | void> = new vscode.EventEmitter<ListItem<ITreeNode> | undefined | void>();
3234
readonly onDidChangeTreeData: vscode.Event<ListItem<ITreeNode> | undefined | void> = this._onDidChangeTreeData.event;
35+
private _disposables: vscode.Disposable[];
3336

3437
private _context: vscode.ExtensionContext;
3538
private _service: CodingServer;
3639

3740
constructor(context: vscode.ExtensionContext, service: CodingServer) {
3841
this._context = context;
3942
this._service = service;
43+
44+
this._disposables = [];
45+
this._disposables.push(vscode.workspace.registerTextDocumentContentProvider('mr', getInMemMRContentProvider(context, this._service)));
4046
}
4147

4248
public refresh(): any {
@@ -114,6 +120,10 @@ export class MRTreeDataProvider implements vscode.TreeDataProvider<ListItem<ITre
114120
return Promise.resolve([]);
115121
}
116122
}
123+
124+
dispose() {
125+
this._disposables.forEach(dispose => dispose.dispose());
126+
}
117127
}
118128

119129
export class ListItem<T> extends vscode.TreeItem {
@@ -157,7 +167,7 @@ export class MRItem extends ListItem<IMRData> {
157167
async getChildren(diffStat: IMRDiffStat): Promise<ListItem<string | number | IFileNode>[]> {
158168
const files = this._transformTree(diffStat);
159169
const repoInfo = this.context.workspaceState.get(`repoInfo`, {});
160-
const session = this.context.workspaceState.get(`session`, {} as SessionData);
170+
const session = this.context.workspaceState.get(`session`, {}) as ISessionData;
161171

162172
return [
163173
new ListItem(
@@ -266,5 +276,3 @@ export class FileNode extends ListItem<IFileNode> {
266276
return this;
267277
}
268278
}
269-
270-
File renamed without changes.

src/tsconfig.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
"compilerOptions": {
33
"module": "commonjs",
44
"target": "es2019",
5-
"lib": ["ES2019"],
5+
"lib": [
6+
"ES2019",
7+
"dom"
8+
],
69
"outDir": "../out",
710
"sourceMap": true,
811
"strict": true,

src/typings/commonTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export enum TokenType {
1111
RefreshToken = `refreshToken` ,
1212
}
1313

14-
export interface SessionData {
14+
export interface ISessionData {
1515
id: string;
1616
user: UserResponse | null;
1717
accessToken: string;

0 commit comments

Comments
 (0)