From e3dccd9e8a5111bbb96b0b87d92887d748400a88 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Sat, 22 Jun 2019 13:44:18 +0800 Subject: [PATCH 1/5] init --- src/commands/session.ts | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/commands/session.ts b/src/commands/session.ts index 5cf37724..11c96f88 100644 --- a/src/commands/session.ts +++ b/src/commands/session.ts @@ -33,11 +33,11 @@ export async function getSessionList(): Promise { } export async function selectSession(): Promise { - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(parseSessionsToPicks()); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(parseSessionsToPicks(true /* includeOperation */)); if (!choice || choice.description === "Active") { return; } - if (choice.value === ":createNewSession") { + if (choice.value === ":createSession") { await vscode.commands.executeCommand("leetcode.createSession"); return; } @@ -50,7 +50,7 @@ export async function selectSession(): Promise { } } -async function parseSessionsToPicks(): Promise>> { +async function parseSessionsToPicks(includeOperations: boolean = false): Promise>> { return new Promise(async (resolve: (res: Array>) => void): Promise => { try { const sessions: ISession[] = await getSessionList(); @@ -60,12 +60,10 @@ async function parseSessionsToPicks(): Promise>> { detail: `AC Questions: ${s.acQuestions}, AC Submits: ${s.acSubmits}`, value: s.id, })); - picks.push({ - label: "$(plus) Create a new session", - description: "", - detail: "Click this item to create a new session", - value: ":createNewSession", - }); + + if (includeOperations) { + picks.push(...parseSessionManagementOperations()); + } resolve(picks); } catch (error) { return await promptForOpenOutputChannel("Failed to list sessions. Please open the output channel for details.", DialogType.error); @@ -73,6 +71,20 @@ async function parseSessionsToPicks(): Promise>> { }); } +function parseSessionManagementOperations(): Array> { + return [{ + label: "$(plus) Create a session", + description: "", + detail: "Click this item to create a session", + value: ":createSession", + }, { + label: "$(trashcan) Delete a session", + description: "", + detail: "Click this item to DELETE a session", + value: ":deleteSession", + }]; +} + export async function createSession(): Promise { const session: string | undefined = await vscode.window.showInputBox({ prompt: "Enter the new session name.", From d10e4b77a7b03842bbd533e8b8ab477ddfba642c Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Thu, 27 Jun 2019 20:50:57 +0800 Subject: [PATCH 2/5] Support delete the session --- package-lock.json | 6 +-- package.json | 14 ++---- src/commands/session.ts | 59 ++++++++++++++++++++++---- src/extension.ts | 3 +- src/leetCodeExecutor.ts | 8 +++- src/statusbar/LeetCodeStatusBarItem.ts | 2 +- 6 files changed, 65 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0dbe10b8..46afe0b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1786,9 +1786,9 @@ } }, "vsc-leetcode-cli": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/vsc-leetcode-cli/-/vsc-leetcode-cli-2.6.7.tgz", - "integrity": "sha512-OBTF0XV9drJEdGCOysx/nCmmzgqBOnn6baH9On6ZbTNr9chl3reuC7OfKHNts/DzEW71wStT7Xg2N2WJSMsojw==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/vsc-leetcode-cli/-/vsc-leetcode-cli-2.6.8.tgz", + "integrity": "sha512-Zo1GBWgr7orJawlTUmXMUCGpPJ8RThoHMh9vABiPJO3n+uhPgLNGkuETIKk7u+I1dD7FHk+G/IxfD5siR49z2A==", "requires": { "ansi-styles": "3.2.1", "cheerio": "0.20.0", diff --git a/package.json b/package.json index d0f5360e..0ba3e9aa 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,7 @@ "onCommand:leetcode.toggleLeetCodeCn", "onCommand:leetcode.signin", "onCommand:leetcode.signout", - "onCommand:leetcode.selectSessions", - "onCommand:leetcode.createSession", + "onCommand:leetcode.manageSessions", "onCommand:leetcode.refreshExplorer", "onCommand:leetcode.showProblem", "onCommand:leetcode.previewProblem", @@ -72,13 +71,8 @@ "category": "LeetCode" }, { - "command": "leetcode.selectSessions", - "title": "Select Session", - "category": "LeetCode" - }, - { - "command": "leetcode.createSession", - "title": "Create New Session", + "command": "leetcode.manageSessions", + "title": "Manage Sessions", "category": "LeetCode" }, { @@ -394,6 +388,6 @@ "markdown-it": "^8.4.2", "require-from-string": "^2.0.2", "unescape-js": "^1.1.1", - "vsc-leetcode-cli": "2.6.7" + "vsc-leetcode-cli": "2.6.8" } } diff --git a/src/commands/session.ts b/src/commands/session.ts index 11c96f88..fad45903 100644 --- a/src/commands/session.ts +++ b/src/commands/session.ts @@ -32,17 +32,21 @@ export async function getSessionList(): Promise { return sessions; } -export async function selectSession(): Promise { - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(parseSessionsToPicks(true /* includeOperation */)); +export async function manageSessions(): Promise { + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick(parseSessionsToPicks(true /* includeOperation */)); if (!choice || choice.description === "Active") { return; } if (choice.value === ":createSession") { - await vscode.commands.executeCommand("leetcode.createSession"); + await createSession(); + return; + } + if (choice.value === ":deleteSession") { + await deleteSession(); return; } try { - await leetCodeExecutor.enableSession(choice.value); + await leetCodeExecutor.enableSession((choice.value as ISession).id); vscode.window.showInformationMessage(`Successfully switched to session '${choice.label}'.`); await vscode.commands.executeCommand("leetcode.refreshExplorer"); } catch (error) { @@ -50,15 +54,15 @@ export async function selectSession(): Promise { } } -async function parseSessionsToPicks(includeOperations: boolean = false): Promise>> { - return new Promise(async (resolve: (res: Array>) => void): Promise => { +async function parseSessionsToPicks(includeOperations: boolean = false): Promise>> { + return new Promise(async (resolve: (res: Array>) => void): Promise => { try { const sessions: ISession[] = await getSessionList(); - const picks: Array> = sessions.map((s: ISession) => Object.assign({}, { + const picks: Array> = sessions.map((s: ISession) => Object.assign({}, { label: `${s.active ? "$(check) " : ""}${s.name}`, description: s.active ? "Active" : "", detail: `AC Questions: ${s.acQuestions}, AC Submits: ${s.acSubmits}`, - value: s.id, + value: s, })); if (includeOperations) { @@ -85,7 +89,7 @@ function parseSessionManagementOperations(): Array> { }]; } -export async function createSession(): Promise { +async function createSession(): Promise { const session: string | undefined = await vscode.window.showInputBox({ prompt: "Enter the new session name.", validateInput: (s: string): string | undefined => s && s.trim() ? undefined : "Session name must not be empty", @@ -101,6 +105,43 @@ export async function createSession(): Promise { } } +async function deleteSession(): Promise { + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( + parseSessionsToPicks(false /* includeOperation */), + { placeHolder: "Please select the session you want to delete" }, + ); + if (!choice) { + return; + } + + const selectedSession: ISession = choice.value as ISession; + if (selectedSession.active) { + vscode.window.showInformationMessage("Cannot delete an active session."); + return; + } + + const action: string | undefined = await vscode.window.showWarningMessage(`This operation cannot be reverted. Are you sure to delete the session: ${selectedSession.name}?`, "Yes"); + if (action !== "Yes") { + return; + } + + const confirm: string | undefined = await vscode.window.showInputBox({ + prompt: "Enter 'yes' to confirm deleting the session", + validateInput: (value: string): string => { + if (value === "yes") { + return ""; + } else { + return "Enter 'yes' to confirm"; + } + }, + }); + + if (confirm === "yes") { + await leetCodeExecutor.deleteSession(selectedSession.id); + vscode.window.showInformationMessage("The session has been successfully deleted."); + } +} + export interface ISession { active: boolean; id: string; diff --git a/src/extension.ts b/src/extension.ts index a2467c8d..4d33d803 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -51,8 +51,7 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand("leetcode.toggleLeetCodeCn", () => plugin.switchEndpoint()), vscode.commands.registerCommand("leetcode.signin", () => leetCodeManager.signIn()), 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.manageSessions", () => session.manageSessions()), 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()), diff --git a/src/leetCodeExecutor.ts b/src/leetCodeExecutor.ts index ad2d0514..c3ef495c 100644 --- a/src/leetCodeExecutor.ts +++ b/src/leetCodeExecutor.ts @@ -124,8 +124,12 @@ class LeetCodeExecutor implements Disposable { return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-e", name]); } - public async createSession(name: string): Promise { - return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-c", name]); + public async createSession(id: string): Promise { + return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-c", id]); + } + + public async deleteSession(id: string): Promise { + return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-d", id]); } public async submitSolution(filePath: string): Promise { diff --git a/src/statusbar/LeetCodeStatusBarItem.ts b/src/statusbar/LeetCodeStatusBarItem.ts index 5ca9bde6..35ca7412 100644 --- a/src/statusbar/LeetCodeStatusBarItem.ts +++ b/src/statusbar/LeetCodeStatusBarItem.ts @@ -9,7 +9,7 @@ export class LeetCodeStatusBarItem implements vscode.Disposable { constructor() { this.statusBarItem = vscode.window.createStatusBarItem(); - this.statusBarItem.command = "leetcode.selectSessions"; + this.statusBarItem.command = "leetcode.manageSessions"; } public updateStatusBar(status: UserStatus, user?: string): void { From 7d1c4c40750a2335d0cd0551f403f8d2f3e30165 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 28 Jun 2019 12:51:11 +0800 Subject: [PATCH 3/5] Use DialogOptions --- src/commands/session.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/commands/session.ts b/src/commands/session.ts index fad45903..a1c86260 100644 --- a/src/commands/session.ts +++ b/src/commands/session.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; import { IQuickItemEx } from "../shared"; -import { DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; +import { DialogType, promptForOpenOutputChannel, promptForSignIn, DialogOptions } from "../utils/uiUtils"; export async function getSessionList(): Promise { const signInStatus: string | undefined = leetCodeManager.getUser(); @@ -120,8 +120,12 @@ async function deleteSession(): Promise { return; } - const action: string | undefined = await vscode.window.showWarningMessage(`This operation cannot be reverted. Are you sure to delete the session: ${selectedSession.name}?`, "Yes"); - if (action !== "Yes") { + const action: vscode.MessageItem | undefined = await vscode.window.showWarningMessage( + `This operation cannot be reverted. Are you sure to delete the session: ${selectedSession.name}?`, + DialogOptions.yes, + DialogOptions.no, + ); + if (action !== DialogOptions.yes) { return; } From 253b75485c67c6d4b9c65a106f3d39907a63d9d2 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 28 Jun 2019 12:57:41 +0800 Subject: [PATCH 4/5] Fix lint error --- src/commands/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/session.ts b/src/commands/session.ts index a1c86260..f86d4cf3 100644 --- a/src/commands/session.ts +++ b/src/commands/session.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; import { IQuickItemEx } from "../shared"; -import { DialogType, promptForOpenOutputChannel, promptForSignIn, DialogOptions } from "../utils/uiUtils"; +import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; export async function getSessionList(): Promise { const signInStatus: string | undefined = leetCodeManager.getUser(); From 5918cd014d8acfdfecde34dc4bd17337a37d92a5 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 28 Jun 2019 12:59:35 +0800 Subject: [PATCH 5/5] Update document --- README.md | 2 +- docs/README_zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8943f671..cc0bffea 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Manage Session

-- To manage your LeetCode sessions, just clicking the `LeetCode: ***` at the bottom of the status bar. You can **switch** between sessions or **create** a new session. +- To manage your LeetCode sessions, just clicking the `LeetCode: ***` at the bottom of the status bar. You can **switch** between sessions or **create**, **delete** a session. ## Settings diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index d1a06b16..0a3e23e5 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -110,7 +110,7 @@ 管理存档

-- 点击位于 VS Code 底部状态栏的 `LeetCode: ***` 管理 `LeetCode 存档`。你可以**切换**存档或者**创建**新的存档。 +- 点击位于 VS Code 底部状态栏的 `LeetCode: ***` 管理 `LeetCode 存档`。你可以**切换**存档或者**创建**,**删除**存档。 ## 插件配置项