From dbeddabf12c843266bc0b6a875b628df7c820e50 Mon Sep 17 00:00:00 2001 From: Hyuni Date: Tue, 5 Mar 2019 17:33:37 +0800 Subject: [PATCH 1/7] Add Click the tree explorer should open the topic (#132) --- src/explorer/LeetCodeNode.ts | 9 +++++++++ src/explorer/LeetCodeTreeDataProvider.ts | 1 + 2 files changed, 10 insertions(+) diff --git a/src/explorer/LeetCodeNode.ts b/src/explorer/LeetCodeNode.ts index ad5211cb..fd8323f4 100644 --- a/src/explorer/LeetCodeNode.ts +++ b/src/explorer/LeetCodeNode.ts @@ -1,6 +1,7 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. +import { Command } from "vscode"; import { IProblem, ProblemState } from "../shared"; export class LeetCodeNode { @@ -48,4 +49,12 @@ export class LeetCodeNode { public get parentName(): string { return this.parentNodeName; } + + public get selectedCommand(): Command { + return { + title: "Open Problem", + command: "leetcode.showProblem", + arguments: [this], + }; + } } diff --git a/src/explorer/LeetCodeTreeDataProvider.ts b/src/explorer/LeetCodeTreeDataProvider.ts index da9ca751..206d87c6 100644 --- a/src/explorer/LeetCodeTreeDataProvider.ts +++ b/src/explorer/LeetCodeTreeDataProvider.ts @@ -52,6 +52,7 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider Date: Wed, 6 Mar 2019 18:16:02 +0800 Subject: [PATCH 2/7] Add Preview Function(#132) --- package.json | 10 +++++ src/commands/show.ts | 21 ++++++++- src/explorer/LeetCodeNode.ts | 8 ++++ src/explorer/LeetCodeTreeDataProvider.ts | 2 +- src/extension.ts | 1 + src/leetCodeExecutor.ts | 4 ++ src/shared.ts | 8 ++++ src/utils/webviewUtils.ts | 54 ++++++++++++++++++++++++ 8 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/utils/webviewUtils.ts diff --git a/package.json b/package.json index 8a316d76..22d3fd3b 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,11 @@ "command": "leetcode.showProblem", "title": "Show Problem", "category": "LeetCode" + }, + { + "command": "leetcode.previewProblem", + "title": "Preview Problem", + "category": "LeetCode" }, { "command": "leetcode.searchProblem", @@ -164,6 +169,11 @@ "command": "leetcode.showProblem", "when": "view == leetCodeExplorer && viewItem == problem", "group": "leetcode@1" + }, + { + "command": "leetcode.previewProblem", + "when": "view == leetCodeExplorer && viewItem == problem", + "group": "leetcode@1" } ], "commandPalette": [ diff --git a/src/commands/show.ts b/src/commands/show.ts index d1ce1cf4..af52e352 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -8,8 +8,9 @@ import { LeetCodeNode } from "../explorer/LeetCodeNode"; import { leetCodeChannel } from "../leetCodeChannel"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; -import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared"; +import { Command, IProblem, IQuickItemEx, IWebViewMessage, languages, ProblemState } from "../shared"; import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; +import { renderHTML } from "../utils/webviewUtils"; import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import * as list from "./list"; @@ -135,3 +136,21 @@ async function resolveRelativePath(value: string, node: IProblem, selectedLangua throw new Error(errorMsg); } } + +export async function previewProblem(node: IProblem): Promise { + const panelType: string = "previewProblem"; + const panelTitle: string = node.name; + const panel: vscode.WebviewPanel = vscode.window.createWebviewPanel(panelType, panelTitle, vscode.ViewColumn.Active, { + enableScripts: true, + enableCommandUris: true, + }); + panel.webview.onDidReceiveMessage(async (message: IWebViewMessage) => { + switch (message.command) { + case Command.ShowProblem: + await showProblemInternal(node); + panel.dispose(); + return; + } + }); + panel.webview.html = await renderHTML(node); +} diff --git a/src/explorer/LeetCodeNode.ts b/src/explorer/LeetCodeNode.ts index fd8323f4..366e7eb9 100644 --- a/src/explorer/LeetCodeNode.ts +++ b/src/explorer/LeetCodeNode.ts @@ -50,6 +50,14 @@ export class LeetCodeNode { return this.parentNodeName; } + public get previewCommand(): Command { + return { + title: "Preview Problem", + command: "leetcode.previewProblem", + arguments: [this], + }; + } + public get selectedCommand(): Command { return { title: "Open Problem", diff --git a/src/explorer/LeetCodeTreeDataProvider.ts b/src/explorer/LeetCodeTreeDataProvider.ts index 206d87c6..8b5ed89d 100644 --- a/src/explorer/LeetCodeTreeDataProvider.ts +++ b/src/explorer/LeetCodeTreeDataProvider.ts @@ -52,7 +52,7 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider vscode.commands.registerCommand("leetcode.signout", () => leetCodeManager.signOut()), vscode.commands.registerCommand("leetcode.selectSessions", () => session.selectSession()), vscode.commands.registerCommand("leetcode.createSession", () => session.createSession()), + vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => show.previewProblem(node)), vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)), vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()), vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()), diff --git a/src/leetCodeExecutor.ts b/src/leetCodeExecutor.ts index 373bda11..3566cd93 100644 --- a/src/leetCodeExecutor.ts +++ b/src/leetCodeExecutor.ts @@ -87,6 +87,10 @@ class LeetCodeExecutor { return filePath; } + public async getDescription(node: IProblem): Promise { + return await this.executeCommandWithProgressEx("Fetching problem description...", "node", [await this.getLeetCodeBinaryPath(), "show", node.id, "-x"]); + } + public async listSessions(): Promise { return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session"]); } diff --git a/src/shared.ts b/src/shared.ts index 942e5ba1..6f42995c 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -91,3 +91,11 @@ export enum Category { Company = "Company", Favorite = "Favorite", } + +export enum Command { + ShowProblem = "ShowProblem", +} + +export interface IWebViewMessage { + command: string; +} diff --git a/src/utils/webviewUtils.ts b/src/utils/webviewUtils.ts new file mode 100644 index 00000000..6cd3349b --- /dev/null +++ b/src/utils/webviewUtils.ts @@ -0,0 +1,54 @@ +import { leetCodeExecutor } from "../leetCodeExecutor"; +import { Command, IProblem } from "../shared"; + +export async function renderHTML(node: IProblem): Promise { + const description: string = await leetCodeExecutor.getDescription(node); + const descriptionHTML: string = description.replace(/\n/g, "
"); + const htmlTemplate: string = ` + + + + + + Preview Problem + + + +
+ ${ descriptionHTML} +
+ + + + + `; + return htmlTemplate; +} From 7f8d3bd29ea7f466b0a444232f6ee7fa60f9ab9b Mon Sep 17 00:00:00 2001 From: Hyuni Date: Fri, 8 Mar 2019 15:02:17 +0800 Subject: [PATCH 3/7] Add Preview Function(#132) Remove unused function Use rem instead of px Use the VS Code embed CSS vars in Preivew Webview Use spaces instead of tabs in package.json Use previewProvider to manage preivew logic --- package.json | 5 ++-- src/commands/show.ts | 21 +------------- src/explorer/LeetCodeNode.ts | 7 ----- src/extension.ts | 5 +++- src/leetcodePreviewProvider.ts | 53 ++++++++++++++++++++++++++++++++++ src/shared.ts | 4 --- src/utils/webviewUtils.ts | 16 +++++----- 7 files changed, 69 insertions(+), 42 deletions(-) create mode 100644 src/leetcodePreviewProvider.ts diff --git a/package.json b/package.json index 22d3fd3b..0c5c7b31 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "onCommand:leetcode.createSession", "onCommand:leetcode.refreshExplorer", "onCommand:leetcode.showProblem", + "onCommand:leetcode.previewProblem", "onCommand:leetcode.searchProblem", "onCommand:leetcode.testSolution", "onCommand:leetcode.submitSolution", @@ -94,7 +95,7 @@ "title": "Show Problem", "category": "LeetCode" }, - { + { "command": "leetcode.previewProblem", "title": "Preview Problem", "category": "LeetCode" @@ -170,7 +171,7 @@ "when": "view == leetCodeExplorer && viewItem == problem", "group": "leetcode@1" }, - { + { "command": "leetcode.previewProblem", "when": "view == leetCodeExplorer && viewItem == problem", "group": "leetcode@1" diff --git a/src/commands/show.ts b/src/commands/show.ts index af52e352..d1ce1cf4 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -8,9 +8,8 @@ import { LeetCodeNode } from "../explorer/LeetCodeNode"; import { leetCodeChannel } from "../leetCodeChannel"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; -import { Command, IProblem, IQuickItemEx, IWebViewMessage, languages, ProblemState } from "../shared"; +import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared"; import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; -import { renderHTML } from "../utils/webviewUtils"; import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import * as list from "./list"; @@ -136,21 +135,3 @@ async function resolveRelativePath(value: string, node: IProblem, selectedLangua throw new Error(errorMsg); } } - -export async function previewProblem(node: IProblem): Promise { - const panelType: string = "previewProblem"; - const panelTitle: string = node.name; - const panel: vscode.WebviewPanel = vscode.window.createWebviewPanel(panelType, panelTitle, vscode.ViewColumn.Active, { - enableScripts: true, - enableCommandUris: true, - }); - panel.webview.onDidReceiveMessage(async (message: IWebViewMessage) => { - switch (message.command) { - case Command.ShowProblem: - await showProblemInternal(node); - panel.dispose(); - return; - } - }); - panel.webview.html = await renderHTML(node); -} diff --git a/src/explorer/LeetCodeNode.ts b/src/explorer/LeetCodeNode.ts index 366e7eb9..3f685b70 100644 --- a/src/explorer/LeetCodeNode.ts +++ b/src/explorer/LeetCodeNode.ts @@ -58,11 +58,4 @@ export class LeetCodeNode { }; } - public get selectedCommand(): Command { - return { - title: "Open Problem", - command: "leetcode.showProblem", - arguments: [this], - }; - } } diff --git a/src/extension.ts b/src/extension.ts index 44574e42..82c96616 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -15,6 +15,7 @@ import { LeetCodeTreeDataProvider } from "./explorer/LeetCodeTreeDataProvider"; import { leetCodeChannel } from "./leetCodeChannel"; import { leetCodeExecutor } from "./leetCodeExecutor"; import { leetCodeManager } from "./leetCodeManager"; +import { leetCodePreviewProvider } from "./leetCodePreviewProvider"; import { leetCodeResultProvider } from "./leetCodeResultProvider"; import { leetCodeStatusBarItem } from "./leetCodeStatusBarItem"; @@ -29,11 +30,13 @@ export async function activate(context: vscode.ExtensionContext): Promise }); const leetCodeTreeDataProvider: LeetCodeTreeDataProvider = new LeetCodeTreeDataProvider(context); + leetCodePreviewProvider.initialize(context); leetCodeResultProvider.initialize(context); context.subscriptions.push( leetCodeStatusBarItem, leetCodeChannel, + leetCodePreviewProvider, leetCodeResultProvider, vscode.window.registerTreeDataProvider("leetCodeExplorer", leetCodeTreeDataProvider), vscode.languages.registerCodeLensProvider({ scheme: "file" }, codeLensProvider), @@ -43,7 +46,7 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand("leetcode.signout", () => leetCodeManager.signOut()), vscode.commands.registerCommand("leetcode.selectSessions", () => session.selectSession()), vscode.commands.registerCommand("leetcode.createSession", () => session.createSession()), - vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => show.previewProblem(node)), + vscode.commands.registerCommand("leetcode.previewProblem", (node: LeetCodeNode) => leetCodePreviewProvider.preview(node)), vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)), vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()), vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()), diff --git a/src/leetcodePreviewProvider.ts b/src/leetcodePreviewProvider.ts new file mode 100644 index 00000000..7ce3861f --- /dev/null +++ b/src/leetcodePreviewProvider.ts @@ -0,0 +1,53 @@ +import { commands, Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from "vscode"; +import { IProblem, IWebViewMessage } from "./shared"; +import { renderHTML } from "./utils/webviewUtils"; + +class LeetCodePreviewProvider implements Disposable { + + private context: ExtensionContext; + private panel: WebviewPanel | undefined; + + public initialize(context: ExtensionContext): void { + this.context = context; + } + + public async preview(node: IProblem): Promise { + if (!this.panel) { + const panelType: string = "previewProblem"; + const panelTitle: string = node.name; + this.panel = window.createWebviewPanel(panelType, panelTitle, ViewColumn.Active, { + enableScripts: true, + enableCommandUris: true, + enableFindWidget: true, + retainContextWhenHidden: true, + }); + } + + this.panel.onDidDispose(() => { + this.panel = undefined; + }, null, this.context.subscriptions); + + + this.panel.webview.onDidReceiveMessage(async (message: IWebViewMessage) => { + switch (message.command) { + case 'ShowProblem': + await commands.executeCommand("leetcode.showProblem", node); + this.dispose(); + return; + } + }); + this.panel.webview.html = await this.provideHtmlContent(node); + } + + public dispose(): void { + if (this.panel) { + this.panel.dispose(); + } + } + + private async provideHtmlContent(node: IProblem): Promise { + return await renderHTML(node) + } +} + +export const leetCodePreviewProvider: LeetCodePreviewProvider = new LeetCodePreviewProvider(); diff --git a/src/shared.ts b/src/shared.ts index 6f42995c..1cc84d01 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -92,10 +92,6 @@ export enum Category { Favorite = "Favorite", } -export enum Command { - ShowProblem = "ShowProblem", -} - export interface IWebViewMessage { command: string; } diff --git a/src/utils/webviewUtils.ts b/src/utils/webviewUtils.ts index 6cd3349b..5441cf44 100644 --- a/src/utils/webviewUtils.ts +++ b/src/utils/webviewUtils.ts @@ -1,5 +1,5 @@ import { leetCodeExecutor } from "../leetCodeExecutor"; -import { Command, IProblem } from "../shared"; +import { IProblem } from "../shared"; export async function renderHTML(node: IProblem): Promise { const description: string = await leetCodeExecutor.getDescription(node); @@ -15,16 +15,16 @@ export async function renderHTML(node: IProblem): Promise { + +
+ ${ descriptionHTML} +
+ + + + + `; + return htmlTemplate; + } + +} +export interface IWebViewMessage { + command: string; +} + +export const leetCodePreviewProvider: LeetCodePreviewProvider = new LeetCodePreviewProvider(); diff --git a/src/leetcodePreviewProvider.ts b/src/leetcodePreviewProvider.ts deleted file mode 100644 index ef94c0f9..00000000 --- a/src/leetcodePreviewProvider.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { commands, Disposable, ExtensionContext, ViewColumn, WebviewPanel, window } from "vscode"; -import { IProblem, IWebViewMessage } from "./shared"; -import { renderHTML } from "./utils/webviewUtils"; - -class LeetCodePreviewProvider implements Disposable { - - private context: ExtensionContext; - private panel: WebviewPanel | undefined; - - public initialize(context: ExtensionContext): void { - this.context = context; - } - - public async preview(node: IProblem): Promise { - if (!this.panel) { - const panelType: string = "previewProblem"; - const panelTitle: string = node.name; - this.panel = window.createWebviewPanel(panelType, panelTitle, ViewColumn.Active, { - enableScripts: true, - enableCommandUris: true, - enableFindWidget: true, - retainContextWhenHidden: true, - }); - } - - this.panel.onDidDispose(() => { - this.panel = undefined; - }, null, this.context.subscriptions); - - this.panel.webview.onDidReceiveMessage(async (message: IWebViewMessage) => { - switch (message.command) { - case "ShowProblem": - await commands.executeCommand("leetcode.showProblem", node); - this.dispose(); - return; - } - }); - this.panel.webview.html = await this.provideHtmlContent(node); - } - - public dispose(): void { - if (this.panel) { - this.panel.dispose(); - } - } - - private async provideHtmlContent(node: IProblem): Promise { - return await renderHTML(node); - } -} - -export const leetCodePreviewProvider: LeetCodePreviewProvider = new LeetCodePreviewProvider(); diff --git a/src/shared.ts b/src/shared.ts index 1cc84d01..942e5ba1 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -91,7 +91,3 @@ export enum Category { Company = "Company", Favorite = "Favorite", } - -export interface IWebViewMessage { - command: string; -} diff --git a/src/utils/webviewUtils.ts b/src/utils/webviewUtils.ts deleted file mode 100644 index 5441cf44..00000000 --- a/src/utils/webviewUtils.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { leetCodeExecutor } from "../leetCodeExecutor"; -import { IProblem } from "../shared"; - -export async function renderHTML(node: IProblem): Promise { - const description: string = await leetCodeExecutor.getDescription(node); - const descriptionHTML: string = description.replace(/\n/g, "
"); - const htmlTemplate: string = ` - - - - - - Preview Problem - - - -
- ${ descriptionHTML} -
- - - - - `; - return htmlTemplate; -} From 7e2c843898f94d61e2bda30c7f575d18efa0aa8f Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Tue, 12 Mar 2019 19:39:17 +0800 Subject: [PATCH 7/7] minor fixes --- package.json | 4 ++++ src/leetCodeExecutor.ts | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5e8d848a..f86cfa7b 100644 --- a/package.json +++ b/package.json @@ -181,6 +181,10 @@ { "command": "leetcode.showProblem", "when": "never" + }, + { + "command": "leetcode.previewProblem", + "when": "never" } ], "explorer/context": [ diff --git a/src/leetCodeExecutor.ts b/src/leetCodeExecutor.ts index 3566cd93..f4080a95 100644 --- a/src/leetCodeExecutor.ts +++ b/src/leetCodeExecutor.ts @@ -75,20 +75,20 @@ class LeetCodeExecutor { ); } - public async showProblem(node: IProblem, language: string, outDir: string): Promise { - const fileName: string = genFileName(node, language); + public async showProblem(problemNode: IProblem, language: string, outDir: string): Promise { + const fileName: string = genFileName(problemNode, language); const filePath: string = path.join(outDir, fileName); if (!await fse.pathExists(filePath)) { - const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", node.id, "-cx", "-l", language]); + const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-cx", "-l", language]); await fse.writeFile(filePath, codeTemplate); } return filePath; } - public async getDescription(node: IProblem): Promise { - return await this.executeCommandWithProgressEx("Fetching problem description...", "node", [await this.getLeetCodeBinaryPath(), "show", node.id, "-x"]); + public async getDescription(problemNode: IProblem): Promise { + return await this.executeCommandWithProgressEx("Fetching problem description...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-x"]); } public async listSessions(): Promise {