Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a12d746

Browse files
committed
Apply mdEngine to preview provider
1 parent 43feaa3 commit a12d746

File tree

2 files changed

+105
-37
lines changed

2 files changed

+105
-37
lines changed

src/extension.ts

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

src/webview/leetCodePreviewProvider.ts

Lines changed: 104 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import { commands, Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from "vscode";
55
import { leetCodeExecutor } from "../leetCodeExecutor";
66
import { IProblem } from "../shared";
7+
import { markdownEngine } from "./markdownEngine";
8+
79
class LeetCodePreviewProvider implements Disposable {
810

911
private context: ExtensionContext;
@@ -14,22 +16,29 @@ class LeetCodePreviewProvider implements Disposable {
1416
this.context = context;
1517
}
1618

17-
public async preview(node: IProblem): Promise<void> {
19+
public async show(node: IProblem): Promise<void> {
20+
// Fetch problem first before creating webview panel
21+
const descString: string = await leetCodeExecutor.getDescription(node);
22+
1823
this.node = node;
1924
if (!this.panel) {
20-
this.panel = window.createWebviewPanel("leetcode.preview", "Preview Problem", ViewColumn.Active, {
25+
this.panel = window.createWebviewPanel("leetcode.preview", "Preview Problem", ViewColumn.One, {
2126
enableScripts: true,
2227
enableCommandUris: true,
2328
enableFindWidget: true,
2429
retainContextWhenHidden: true,
30+
localResourceRoots: markdownEngine.localResourceRoots,
2531
});
2632

2733
this.panel.webview.onDidReceiveMessage(async (message: IWebViewMessage) => {
2834
switch (message.command) {
29-
case "ShowProblem":
35+
case "ShowProblem": {
3036
await commands.executeCommand("leetcode.showProblem", this.node);
31-
this.dispose();
32-
return;
37+
await commands.executeCommand("workbench.action.focusSecondEditorGroup");
38+
commands.executeCommand("workbench.action.toggleSidebarVisibility");
39+
this.panel!.reveal(ViewColumn.Two, true);
40+
break;
41+
}
3342
}
3443
}, this, this.context.subscriptions);
3544

@@ -38,9 +47,10 @@ class LeetCodePreviewProvider implements Disposable {
3847
}, null, this.context.subscriptions);
3948
}
4049

41-
this.panel.webview.html = await this.provideHtmlContent(node);
50+
const description: IDescription = this.parseDescription(descString, node);
51+
this.panel.webview.html = this.getWebViewContent(description);
4252
this.panel.title = `${node.name}: Preview`;
43-
this.panel.reveal();
53+
this.panel.reveal(ViewColumn.One);
4454
}
4555

4656
public dispose(): void {
@@ -49,21 +59,35 @@ class LeetCodePreviewProvider implements Disposable {
4959
}
5060
}
5161

52-
public async provideHtmlContent(node: IProblem): Promise<string> {
53-
return await this.renderHTML(node);
62+
private parseDescription(descString: string, problem: IProblem): IDescription {
63+
const [
64+
/* title */, ,
65+
url, ,
66+
/* tags */, ,
67+
/* langs */, ,
68+
category,
69+
difficulty,
70+
accepted,
71+
submissions,
72+
/* testcase */, ,
73+
...body
74+
] = descString.split("\n");
75+
return {
76+
title: problem.name,
77+
url,
78+
tags: problem.tags,
79+
companies: problem.companies,
80+
category: category.slice(2),
81+
difficulty: difficulty.slice(2),
82+
accepted: accepted.split(": ")[1],
83+
submissions: submissions.split(": ")[1],
84+
body: body.join("\n").replace(/<pre>\s*([^]+?)\s*<\/pre>/g, "<pre><code>$1</code></pre>"),
85+
};
5486
}
5587

56-
private async renderHTML(node: IProblem): Promise<string> {
57-
const description: string = await leetCodeExecutor.getDescription(node);
58-
const descriptionHTML: string = description.replace(/\n/g, "<br>");
59-
const htmlTemplate: string = `
60-
<!DOCTYPE html>
61-
<html>
62-
<head>
63-
<meta charset="UTF-8">
64-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
65-
<title>Preview Problem</title>
66-
</head>
88+
private getWebViewContent(desc: IDescription): string {
89+
const mdStyles: string = markdownEngine.getStylesHTML();
90+
const buttonStyle: string = `
6791
<style>
6892
#solve {
6993
position: fixed;
@@ -82,31 +106,75 @@ class LeetCodePreviewProvider implements Disposable {
82106
border: 0;
83107
}
84108
</style>
109+
`;
110+
const { title, url, category, difficulty, accepted, submissions, body } = desc;
111+
const head: string = markdownEngine.render(`# [${title}](${url})`);
112+
const info: string = markdownEngine.render([
113+
`| Category | Difficulty | Accepted | Submissions |`,
114+
`| :------: | :--------: | :------: | :---------: |`,
115+
`| ${category} | ${difficulty} | ${accepted} | ${submissions} |`,
116+
].join("\n"));
117+
const tags: string = [
118+
`<details>`,
119+
`<summary><strong>Tags</strong></summary>`,
120+
markdownEngine.render(
121+
desc.tags
122+
.map((t: string) => `[\`${t}\`](https://leetcode.com/tag/${t})`)
123+
.join(" | "),
124+
),
125+
`</details>`,
126+
].join("\n");
127+
const companies: string = [
128+
`<details>`,
129+
`<summary><strong>Companies</strong></summary>`,
130+
markdownEngine.render(
131+
desc.companies
132+
.map((c: string) => `\`${c}\``)
133+
.join(" | "),
134+
),
135+
`</details>`,
136+
].join("\n");
137+
return `
138+
<!DOCTYPE html>
139+
<html>
140+
<head>
141+
${mdStyles}
142+
${buttonStyle}
143+
</head>
85144
<body>
86-
<div >
87-
${ descriptionHTML}
88-
</div>
145+
${head}
146+
${info}
147+
${tags}
148+
${companies}
149+
${body}
89150
<button id="solve">Code Now</button>
90151
<script>
91-
(function() {
92-
const vscode = acquireVsCodeApi();
93-
let button = document.getElementById('solve');
94-
button.onclick = solveHandler;
95-
function solveHandler() {
96-
vscode.postMessage({
97-
command: 'ShowProblem',
98-
});
99-
}
100-
}());
152+
const vscode = acquireVsCodeApi();
153+
const button = document.getElementById('solve');
154+
button.onclick = () => vscode.postMessage({
155+
command: 'ShowProblem',
156+
});
101157
</script>
102158
</body>
103-
</html>
159+
</html>
104160
`;
105-
return htmlTemplate;
106161
}
107162

108163
}
109-
export interface IWebViewMessage {
164+
165+
interface IDescription {
166+
title: string;
167+
url: string;
168+
tags: string[];
169+
companies: string[];
170+
category: string;
171+
difficulty: string;
172+
accepted: string;
173+
submissions: string;
174+
body: string;
175+
}
176+
177+
interface IWebViewMessage {
110178
command: string;
111179
}
112180

0 commit comments

Comments
 (0)