8000 Add side mode to webview (#271) · FutureYu/vscode-leetcode@52a84d3 · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 52a84d3

Browse files
Vigilansjdneo
authored andcommitted
Add side mode to webview (LeetCode-OpenSource#271)
1 parent 8d3e09f commit 52a84d3

12 files changed

+97
-34
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
| `leetcode.outputFolder`| Specify the relative path to save the problem files. Besides using customized path, there are also several reserved words which can be used here: <ul><li>`${tag}`: Categorize the problem according to their tags.<li>`${language}`: Categorize the problem according to their language.</li><li>`${difficulty}`: Categorize the problem according to their difficulty.</li></ul> | N/A |
142142
| `leetcode.enableStatusBar` | Specify whether the LeetCode status bar will be shown or not. | `true` |
143143
| `leetcode.enableShortcuts` | Specify whether the submit and test shortcuts in editor or not. | `true` |
144+
| `leetcode.enableSideMode` | Specify whether `preview`, `solution` and `submission` tab should be grouped into the second editor column when solving a problem. | `true` |
144145
| `leetcode.nodePath` | Specify the `Node.js` executable path. | `node` |
145146

146147
## Want Help?

docs/README_zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
| `leetcode.outputFolder` | 指定保存文件时所用的相对文件夹路径。除了用户自定义路径外,也可以使用保留项,包括:<ul><li>`${tag}`: 根据题目的类别进行分类。<li>`${language}`: 根据题目的语言进行分类。</li><li>`${difficulty}`: 根据题目的难度进行分类。</li></ul> | N/A |
142142
| `leetcode.enableStatusBar` | 指定是否在 VS Code 下方显示插件状态栏。 | `true` |
143143
| `leetcode.enableShortcuts` | 指定是否在 VS Code 编辑文件下方显示提交和测试的快捷按钮。 | `true` |
144+
| `leetcode.enableSideMode` | 指定在解决一道题时,是否将`问题预览``高票答案``提交结果`窗口集中在编辑器的第二栏。 | `true` |
144145
| `leetcode.nodePath` | 指定 `Node.js` 可执行文件的路径。 | `node` |
145146

146147
## 需要帮助?

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@
301301
"scope": "application",
302302
"description": "Show the submit and test shortcuts in editor or not."
303303
},
304+
"leetcode.enableSideMode": {
305+
"type": "boolean",
306+
"default": true,
307+
"scope": "application",
308+
"description": "Determine whether to group all webview pages into the second editor column when solving problems."
309+
},
304310
"leetcode.nodePath": {
305311
"type": "string",
306312
"default": "node",
@@ -338,6 +344,6 @@
338344
"markdown-it": "^8.4.2",
339345
"require-from-string": "^2.0.2",
340346
"unescape-js": "^1.1.1",
341-
"vsc-leetcode-cli": "2.6.3"
347+
"vsc-leetcode-cli": "2.6.4"
342348
}
343349
}

src/commands/show.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,15 @@ import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared";
1313
import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils";
1414
import { selectWorkspaceFolder } from "../utils/workspaceUtils";
1515
import * as wsl from "../utils/wslUtils";
16+
import { leetCodePreviewProvider } from "../webview/leetCodePreviewProvider";
1617
import { leetCodeSolutionProvider } from "../webview/leetCodeSolutionProvider";
1718
import * as list from "./list";
1819

20+
export async function previewProblem(node: IProblem, isSideMode: boolean = false): Promise<void> {
21+
const descString: string = await leetCodeExecutor.getDescription(node);
22+
leetCodePreviewProvider.show(descString, node, isSideMode);
23+
}
24+
1925
export async function showProblem(node?: LeetCodeNode): Promise<void> {
2026
if (!node) {
2127
return;
@@ -51,7 +57,7 @@ export async function showSolution(node?: LeetCodeNode): Promise<void> {
5157
}
5258
try {
5359
const solution: string = await leetCodeExecutor.showSolution(node, language);
54-
await leetCodeSolutionProvider.show(unescapeJS(solution), node);
60+
leetCodeSolutionProvider.show(unescapeJS(solution), node);
5561
} catch (error) {
5662
leetCodeChannel.appendLine(error.toString());
5763
await promptForOpenOutputChannel("Failed to fetch the top voted solution. Please open the output channel for details.", DialogType.error);
@@ -95,7 +101,7 @@ async function showProblemInternal(node: IProblem): Promise<void> {
95101
// SUGGESTION: group config retriving into one file
96102
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
97103
let outDir: string = await selectWorkspaceFolder();
98-
let relativePath: string = (leetCodeConfig.get<string>("outputFolder") || "").trim();
104+
let relativePath: string = (leetCodeConfig.get<string>("outputFolder", "")).trim();
99105
const matchResult: RegExpMatchArray | null = relativePath.match(/\$\{(.*?)\}/);
100106
if (matchResult) {
101107
const resolvedPath: string | undefined = await resolveRelativePath(matchResult[1].toLocaleLowerCase(), node, language);
@@ -111,12 +117,23 @@ async function showProblemInternal(node: IProblem): Promise<void> {
111117

112118
const originFilePath: string = await leetCodeExecutor.showProblem(node, language, outDir);
113119
const filePath: string = wsl.useWsl() ? await wsl.toWinPath(originFilePath) : originFilePath;
114-
await vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false, viewColumn: vscode.ViewColumn.One });
120+
await Promise.all([
121+
vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false, viewColumn: vscode.ViewColumn.One }),
122+
movePreviewAsideIfNeeded(node),
123+
]);
115124
} catch (error) {
116125
await promptForOpenOutputChannel("Failed to show the problem. Please open the output channel for details.", DialogType.error);
117126
}
118127
}
119128

129+
async function movePreviewAsideIfNeeded(node: IProblem): Promise<void> {
130+
if (vscode.workspace.getConfiguration("leetcode").get<boolean>("enableSideMode", true)) {
131+
return previewProblem(node, true);
132+
} else {
133+
return Promise.resolve();
134+
}
135+
}
136+
120137
async function parseProblemsToPicks(p: Promise<IProblem[]>): Promise<Array<IQuickItemEx<IProblem>>> {
121138
return new Promise(async (resolve: (res: Array<IQuickItemEx<IProblem>>) => void): Promise<void> => {
122139
const picks: Array<IQuickItemEx<IProblem>> = (await p).map((problem: IProblem) => Object.assign({}, {

src/commands/submit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export async function submitSolution(uri?: vscode.Uri): Promise<void> {
2121

2222
try {
2323
const result: string = await leetCodeExecutor.submitSolution(filePath);
24-
await leetCodeSubmissionProvider.show(result);
24+
leetCodeSubmissionProvider.show(result);
2525
} catch (error) {
2626
await promptForOpenOutputChannel("Failed to submit the solution. Please open the output channel for details.", DialogType.error);
2727
}

src/commands/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export async function testSolution(uri?: vscode.Uri): Promise<void> {
8181
if (!result) {
8282
return;
8383
}
84-
await leetCodeSubmissionProvider.show(result);
84+
leetCodeSubmissionProvider.show(result);
8585
} catch (error) {
8686
await promptForOpenOutputChannel("Failed to test the solution. Please open the output channel for details.", DialogType.error);
8787
}

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
5151
vscode.commands.registerCommand("leetcode.signout", () => leetCodeManager.signOut()),
5252
vscode.commands.registerCommand("leetcode.selectSessions", () => session.selectSession()),
5353
vscode.commands.registerCommand("leetcode.createSession", () => session.createSession()),
54-
vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => leetCodePreviewProvider.show(node)),
54+
vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => show.previewProblem(node)),
5555
vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)),
5656
vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()),
5757
vscode.commands.registerCommand("leetcode.showSolution", (node: LeetCodeNode) => show.showSolution(node)),

src/webview/LeetCodeWebview.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import { ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode";
4+
import { commands, ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode";
55
import { markdownEngine } from "./markdownEngine";
66

77
export abstract class LeetCodeWebview implements Disposable {
88

9+
protected readonly viewType: string = "leetcode.webview";
910
protected panel: WebviewPanel | undefined;
1011
private listeners: Disposable[] = [];
1112

@@ -16,9 +17,9 @@ export abstract class LeetCodeWebview implements Disposable {
1617
}
1718

1819
protected showWebviewInternal(): void {
19-
const { viewType, title, viewColumn, preserveFocus } = this.getWebviewOption();
20+
const { title, viewColumn, preserveFocus } = this.getWebviewOption();
2021
if (!this.panel) {
21-
this.panel = window.createWebviewPanel(viewType, title, { viewColumn, preserveFocus }, {
22+
this.panel = window.createWebviewPanel(this.viewType, title, { viewColumn, preserveFocus }, {
2223
enableScripts: true,
2324
enableCommandUris: true,
2425
enableFindWidget: true,
@@ -30,7 +31,14 @@ export abstract class LeetCodeWebview implements Disposable {
3031
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.listeners);
3132
} else {
3233
this.panel.title = title;
33-
this.panel.reveal(viewColumn, preserveFocus);
34+
if (viewColumn === ViewColumn.Two) {
35+
// Make sure second group exists. See vscode#71608 issue
36+
commands.executeCommand("workbench.action.focusSecondEditorGroup").then(() => {
37+
this.panel!.reveal(viewColumn, preserveFocus);
38+
});
39+
} else {
40+
this.panel.reveal(viewColumn, preserveFocus);
41+
}
3442
}
3543
this.panel.webview.html = this.getWebviewContent();
3644
}
@@ -57,7 +65,6 @@ export abstract class LeetCodeWebview implements Disposable {
5765
}
5866

5967
export interface ILeetCodeWebviewOption {
60-
viewType: string;
6168
title: string;
6269
viewColumn: ViewColumn;
6370
preserveFocus?: boolean;

src/webview/leetCodePreviewProvider.ts

Lines changed: 33 additions & 11 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,44 @@
22
// Licensed under the MIT license.
33

44
import { commands, ViewColumn } from "vscode";
5-
import { leetCodeExecutor } from "../leetCodeExecutor";
65
import { IProblem } from "../shared";
76
import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview";
87
import { markdownEngine } from "./markdownEngine";
98

109
class LeetCodePreviewProvider extends LeetCodeWebview {
1110

11+
protected readonly viewType: string = "leetcode.preview";
1212
private node: IProblem;
1313
private description: IDescription;
14+
private sideMode: boolean = false;
1415

15-
public async show(node: IProblem): Promise<void> {
16-
this.description = this.parseDescription(await leetCodeExecutor.getDescription(node), node);
16+
public isSideMode(): boolean {
17+
return this.sideMode;
18+
}
19+
20+
public show(descString: string, node: IProblem, isSideMode: boolean = false): void {
21+
this.description = this.parseDescription(descString, node);
1722
this.node = node;
23+
this.sideMode = isSideMode;
1824
this.showWebviewInternal();
25+
if (this.sideMode) {
26+
this.hideSideBar(); // For better view area
27+
}
1928
}
2029

2130
protected getWebviewOption(): ILeetCodeWebviewOption {
22-
return {
23-
viewType: "leetcode.preview",
24-
title: `${this.node.name}: Preview`,
25-
viewColumn: ViewColumn.One,
26-
};
31+
if (!this.sideMode) {
32+
return {
33+
title: `${this.node.name}: Preview`,
34+
viewColumn: ViewColumn.One,
35+
};
36+
} else {
37+
return {
38+
title: "Description",
39+
viewColumn: ViewColumn.Two,
40+
preserveFocus: true,
41+
};
42+
}
2743
}
2844

2945
protected getWebviewContent(): string {
@@ -84,18 +100,18 @@ class LeetCodePreviewProvider extends LeetCodeWebview {
84100
<html>
85101
<head>
86102
${markdownEngine.getStyles()}
87-
${button.style}
103+
${!this.sideMode ? button.style : ""}
88104
</head>
89105
<body>
90106
${head}
91107
${info}
92108
${tags}
93109
${companies}
94110
${body}
95-
${button.element}
111+
${!this.sideMode ? button.element : ""}
96112
<script>
97113
const vscode = acquireVsCodeApi();
98-
${button.script}
114+
${!this.sideMode ? button.script : ""}
99115
</script>
100116
</body>
101117
</html>
@@ -106,6 +122,7 @@ class LeetCodePreviewProvider extends LeetCodeWebview {
106122
super.onDidDisposeWebview();
107123
delete this.node;
108124
delete this.description;
125+
this.sideMode = false;
109126
}
110127

111128
protected async onDidReceiveMessage(message: IWebViewMessage): Promise<void> {
@@ -117,6 +134,11 @@ class LeetCodePreviewProvider extends LeetCodeWebview {
117134
}
118135
}
119136

137+
private async hideSideBar(): Promise<void> {
138+
await commands.executeCommand("workbench.action.focusSideBar");
139+
await commands.executeCommand("workbench.action.toggleSidebarVisibility");
140+
}
141+
120142
private parseDescription(descString: string, problem: IProblem): IDescription {
121143
const [
122144
/* title */, ,

src/webview/leetCodeSolutionProvider.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,33 @@
33

44
import { ViewColumn } from "vscode";
55
import { IProblem } from "../shared";
6+
import { leetCodePreviewProvider } from "./leetCodePreviewProvider";
67
import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview";
78
import { markdownEngine } from "./markdownEngine";
89

910
class LeetCodeSolutionProvider extends LeetCodeWebview {
1011

12+
protected readonly viewType: string = "leetcode.solution";
1113
private solution: Solution;
1214

13-
public async show(solutionString: string, problem: IProblem): Promise<void> {
15+
public show(solutionString: string, problem: IProblem): void {
1416
this.solution = this.parseSolution(solutionString, problem);
1517
this.showWebviewInternal();
1618
}
1719

1820
protected getWebviewOption(): ILeetCodeWebviewOption {
19-
return {
20-
viewType: "leetcode.solution",
21-
title: `${this.solution.problem}: Solution`,
22-
viewColumn: ViewColumn.One,
23-
};
21+
if (!leetCodePreviewProvider.isSideMode()) {
22+
return {
23+
title: `${this.solution.problem}: Solution`,
24+
viewColumn: ViewColumn.One,
25+
};
26+
} else {
27+
return {
28+
title: "Solution",
29+
viewColumn: ViewColumn.Two,
30+
preserveFocus: true,
31+
};
32+
}
2433
}
2534

2635
protected getWebviewContent(): string {

src/webview/leetCodeSubmissionProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ import { markdownEngine } from "./markdownEngine";
77

88
class LeetCodeSubmissionProvider extends LeetCodeWebview {
99

10+
protected readonly viewType: string = "leetcode.submission";
1011
private result: string;
1112

12-
public async show(result: string): Promise<void> {
13+
public show(result: string): void {
1314
this.result = result;
1415
this.showWebviewInternal();
1516
}
1617

1718
protected getWebviewOption(): ILeetCodeWebviewOption {
1819
return {
19-
viewType: "leetcode.submission",
2020
title: "Submission",
2121
viewColumn: ViewColumn.Two,
2222
};

0 commit comments

Comments
 (0)
0