From 0fc73941e1e29a897933a2057ca09e2039bf5244 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Fri, 26 Apr 2019 20:29:55 +0800 Subject: [PATCH 1/4] Provide several hints for better user experience --- package.json | 20 +++++++++++++++++++- src/commands/show.ts | 14 +++++++++----- src/utils/uiUtils.ts | 15 +++++++++++++++ src/webview/LeetCodeWebview.ts | 11 +++++++++++ src/webview/leetCodeSubmissionProvider.ts | 13 ++++++++++++- 5 files changed, 66 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 7f8d6368..e5db7d80 100644 --- a/package.json +++ b/package.json @@ -262,12 +262,30 @@ "scope": "application", "description": "Default language for solving the problems." }, - "leetcode.showSetDefaultLanguageHint": { + "leetcode.hint.setDefaultLanguage": { "type": "boolean", "default": true, "scope": "application", "description": "Show a hint to set the default language." }, + "leetcode.hint.configWebviewMarkdown": { + "type": "boolean", + "default": true, + "scope": "application", + "description": "Show a hint to change webview appearance through markdown config." + }, + "leetcode.hint.commentDescription": { + "type": "boolean", + "default": true, + "scope": "application", + "description": "Show a hint to enable comment description in solution code file." + }, + "leetcode.hint.commandShortcut": { + "type": "boolean", + "default": true, + "scope": "application", + "description": "Show a hint to configure commands key binding." + }, "leetcode.useWsl": { "type": "boolean", "default": false, diff --git a/src/commands/show.ts b/src/commands/show.ts index 1f7b7e52..511fe658 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -10,7 +10,7 @@ import { leetCodeChannel } from "../leetCodeChannel"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared"; -import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; +import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn, promptHintMessage } from "../utils/uiUtils"; import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import { leetCodePreviewProvider } from "../webview/leetCodePreviewProvider"; @@ -64,7 +64,6 @@ export async function showSolution(node?: LeetCodeNode): Promise { } } -// SUGGESTION: group config retriving into one file async function fetchProblemLanguage(): Promise { const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let defaultLanguage: string | undefined = leetCodeConfig.get("defaultLanguage"); @@ -74,7 +73,7 @@ async function fetchProblemLanguage(): Promise { const language: string | undefined = defaultLanguage || await vscode.window.showQuickPick(languages, { placeHolder: "Select the language you want to use", ignoreFocusOut: true }); // fire-and-forget default language query (async (): Promise => { - if (language && !defaultLanguage && leetCodeConfig.get("showSetDefaultLanguageHint")) { + if (language && !defaultLanguage && leetCodeConfig.get("hint.setDefaultLanguage")) { const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage( `Would you like to set '${language}' as your default language?`, DialogOptions.yes, @@ -84,7 +83,7 @@ async function fetchProblemLanguage(): Promise { if (choice === DialogOptions.yes) { leetCodeConfig.update("defaultLanguage", language, true /* UserSetting */); } else if (choice === DialogOptions.never) { - leetCodeConfig.update("showSetDefaultLanguageHint", false, true /* UserSetting */); + leetCodeConfig.update("hint.setDefaultLanguage", false, true /* UserSetting */); } } })(); @@ -98,7 +97,6 @@ async function showProblemInternal(node: IProblem): Promise { return; } - // SUGGESTION: group config retriving into one file const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let outDir: string = await selectWorkspaceFolder(); let relativePath: string = (leetCodeConfig.get("outputFolder", "")).trim(); @@ -120,6 +118,12 @@ async function showProblemInternal(node: IProblem): Promise { await Promise.all([ vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false, viewColumn: vscode.ViewColumn.One }), movePreviewAsideIfNeeded(node), + promptHintMessage( + "commentDescription", + 'You can generate problem description as comment in the solution code file by enabling "leetcode.showCommentDescription".', + "Open configuration", + (): Thenable => vscode.commands.executeCommand("workbench.action.openSettings", "leetcode.showCommentDescription"), + ), ]); } catch (error) { await promptForOpenOutputChannel("Failed to show the problem. Please open the output channel for details.", DialogType.error); diff --git a/src/utils/uiUtils.ts b/src/utils/uiUtils.ts index 3f17c97b..b968d8ed 100644 --- a/src/utils/uiUtils.ts +++ b/src/utils/uiUtils.ts @@ -4,6 +4,7 @@ import * as vscode from "vscode"; import { getLeetCodeEndpoint } from "../commands/plugin"; import { leetCodeChannel } from "../leetCodeChannel"; +import { getWorkspaceConfiguration } from "./workspaceUtils"; export namespace DialogOptions { export const open: vscode.MessageItem = { title: "Open" }; @@ -57,6 +58,20 @@ export async function promptForSignIn(): Promise { } } +export async function promptHintMessage(config: string, message: string, choiceConfirm: string, onConfirm: () => Thenable): Promise { + if (getWorkspaceConfiguration().get(`hint.${config}`)) { + const choiceNoShowAgain: string = "Don't show again"; + const choice: string | undefined = await vscode.window.showInformationMessage( + message, choiceConfirm, choiceNoShowAgain, + ); + if (choice === choiceConfirm) { + await onConfirm(); + } else if (choice === choiceNoShowAgain) { + await getWorkspaceConfiguration().update(`hint.${config}`, false, true /* UserSetting */); + } + } +} + export async function showFileSelectDialog(): Promise { const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined; const options: vscode.OpenDialogOptions = { diff --git a/src/webview/LeetCodeWebview.ts b/src/webview/LeetCodeWebview.ts index adac21e8..88fc9893 100644 --- a/src/webview/LeetCodeWebview.ts +++ b/src/webview/LeetCodeWebview.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import { commands, ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode"; +import { promptHintMessage } from "../utils/uiUtils"; import { markdownEngine } from "./markdownEngine"; export abstract class LeetCodeWebview implements Disposable { @@ -41,6 +42,7 @@ export abstract class LeetCodeWebview implements Disposable { } } this.panel.webview.html = this.getWebviewContent(); + this.showMarkdownConfigHint(); } protected onDidDisposeWebview(): void { @@ -62,6 +64,15 @@ export abstract class LeetCodeWebview implements Disposable { protected abstract getWebviewOption(): ILeetCodeWebviewOption; protected abstract getWebviewContent(): string; + + private async showMarkdownConfigHint(): Promise { + await promptHintMessage( + "configWebviewMarkdown", + 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', + "Open configuration", + (): Thenable => commands.executeCommand("workbench.action.openSettings", "markdown.preview"), + ); + } } export interface ILeetCodeWebviewOption { diff --git a/src/webview/leetCodeSubmissionProvider.ts b/src/webview/leetCodeSubmissionProvider.ts index 6905099e..61ac45ea 100644 --- a/src/webview/leetCodeSubmissionProvider.ts +++ b/src/webview/leetCodeSubmissionProvider.ts @@ -1,7 +1,8 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. -import { ViewColumn } from "vscode"; +import { commands, ViewColumn } from "vscode"; +import { promptHintMessage } from "../utils/uiUtils"; import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview"; import { markdownEngine } from "./markdownEngine"; @@ -13,6 +14,7 @@ class LeetCodeSubmissionProvider extends LeetCodeWebview { public show(result: string): void { this.result = result; this.showWebviewInternal(); + this.showKeybindingsHint(); } protected getWebviewOption(): ILeetCodeWebviewOption { @@ -40,6 +42,15 @@ class LeetCodeSubmissionProvider extends LeetCodeWebview { super.onDidDisposeWebview(); delete this.result; } + + private async showKeybindingsHint(): Promise { + await promptHintMessage( + "commandShortcut", + 'You can configure custom key bindings with "test", "submit" or any other command in Preferences > Keyboard Shortcuts.', + "Open Keybindings", + (): Thenable => commands.executeCommand("workbench.action.openGlobalKeybindings", "leetcode solution"), + ); + } } export const leetCodeSubmissionProvider: LeetCodeSubmissionProvider = new LeetCodeSubmissionProvider(); From 8e2f6913b96de1d0bb5bb91534da02c9144ab623 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sun, 28 Apr 2019 11:12:33 +0800 Subject: [PATCH 2/4] Wrap open settings & keybindings function --- src/commands/show.ts | 4 ++-- src/utils/uiUtils.ts | 11 ++++++++++- src/webview/LeetCodeWebview.ts | 4 ++-- src/webview/leetCodeSubmissionProvider.ts | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index 511fe658..08dea4c6 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -10,7 +10,7 @@ import { leetCodeChannel } from "../leetCodeChannel"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared"; -import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn, promptHintMessage } from "../utils/uiUtils"; +import { DialogOptions, DialogType, openSettingsEditor, promptForOpenOutputChannel, promptForSignIn, promptHintMessage } from "../utils/uiUtils"; import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import { leetCodePreviewProvider } from "../webview/leetCodePreviewProvider"; @@ -122,7 +122,7 @@ async function showProblemInternal(node: IProblem): Promise { "commentDescription", 'You can generate problem description as comment in the solution code file by enabling "leetcode.showCommentDescription".', "Open configuration", - (): Thenable => vscode.commands.executeCommand("workbench.action.openSettings", "leetcode.showCommentDescription"), + (): Promise => openSettingsEditor("leetcode.showCommentDescription"), ), ]); } catch (error) { diff --git a/src/utils/uiUtils.ts b/src/utils/uiUtils.ts index b968d8ed..3be59146 100644 --- a/src/utils/uiUtils.ts +++ b/src/utils/uiUtils.ts @@ -58,7 +58,7 @@ export async function promptForSignIn(): Promise { } } -export async function promptHintMessage(config: string, message: string, choiceConfirm: string, onConfirm: () => Thenable): Promise { +export async function promptHintMessage(config: string, message: string, choiceConfirm: string, onConfirm: () => Promise): Promise { if (getWorkspaceConfiguration().get(`hint.${config}`)) { const choiceNoShowAgain: string = "Don't show again"; const choice: string | undefined = await vscode.window.showInformationMessage( @@ -72,6 +72,15 @@ export async function promptHintMessage(config: string, message: string, choiceC } } +export async function openSettingsEditor(query?: string): Promise { + await vscode.commands.executeCommand("workbench.action.openSettings", query); +} + +export async function openKeybindingsEditor(query?: string): Promise { + await vscode.commands.executeCommand("workbench.action.openGlobalKeybindings", query); +} + + export async function showFileSelectDialog(): Promise { const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined; const options: vscode.OpenDialogOptions = { diff --git a/src/webview/LeetCodeWebview.ts b/src/webview/LeetCodeWebview.ts index 88fc9893..4d106927 100644 --- a/src/webview/LeetCodeWebview.ts +++ b/src/webview/LeetCodeWebview.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { commands, ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode"; -import { promptHintMessage } from "../utils/uiUtils"; +import { promptHintMessage, openSettingsEditor } from "../utils/uiUtils"; import { markdownEngine } from "./markdownEngine"; export abstract class LeetCodeWebview implements Disposable { @@ -70,7 +70,7 @@ export abstract class LeetCodeWebview implements Disposable { "configWebviewMarkdown", 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', "Open configuration", - (): Thenable => commands.executeCommand("workbench.action.openSettings", "markdown.preview"), + (): Promise => openSettingsEditor("markdown.preview"), ); } } diff --git a/src/webview/leetCodeSubmissionProvider.ts b/src/webview/leetCodeSubmissionProvider.ts index 61ac45ea..46d4784f 100644 --- a/src/webview/leetCodeSubmissionProvider.ts +++ b/src/webview/leetCodeSubmissionProvider.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { commands, ViewColumn } from "vscode"; -import { promptHintMessage } from "../utils/uiUtils"; +import { promptHintMessage, openKeybindingsEditor } from "../utils/uiUtils"; import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview"; import { markdownEngine } from "./markdownEngine"; @@ -48,7 +48,7 @@ class LeetCodeSubmissionProvider extends LeetCodeWebview { "commandShortcut", 'You can configure custom key bindings with "test", "submit" or any other command in Preferences > Keyboard Shortcuts.', "Open Keybindings", - (): Thenable => commands.executeCommand("workbench.action.openGlobalKeybindings", "leetcode solution"), + (): Promise => openKeybindingsEditor("leetcode solution"), ); } } From fc95c8c0d1672775ac91308f9b3a019701870cd7 Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sun, 28 Apr 2019 11:16:05 +0800 Subject: [PATCH 3/4] Resolve comments in review --- src/commands/show.ts | 2 +- src/utils/uiUtils.ts | 4 ++-- src/webview/LeetCodeWebview.ts | 4 ++-- src/webview/leetCodeSubmissionProvider.ts | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index 08dea4c6..8f7ebace 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -119,7 +119,7 @@ async function showProblemInternal(node: IProblem): Promise { vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false, viewColumn: vscode.ViewColumn.One }), movePreviewAsideIfNeeded(node), promptHintMessage( - "commentDescription", + "hint.commentDescription", 'You can generate problem description as comment in the solution code file by enabling "leetcode.showCommentDescription".', "Open configuration", (): Promise => openSettingsEditor("leetcode.showCommentDescription"), diff --git a/src/utils/uiUtils.ts b/src/utils/uiUtils.ts index 3be59146..baf7d488 100644 --- a/src/utils/uiUtils.ts +++ b/src/utils/uiUtils.ts @@ -59,7 +59,7 @@ export async function promptForSignIn(): Promise { } export async function promptHintMessage(config: string, message: string, choiceConfirm: string, onConfirm: () => Promise): Promise { - if (getWorkspaceConfiguration().get(`hint.${config}`)) { + if (getWorkspaceConfiguration().get(`${config}`)) { const choiceNoShowAgain: string = "Don't show again"; const choice: string | undefined = await vscode.window.showInformationMessage( message, choiceConfirm, choiceNoShowAgain, @@ -67,7 +67,7 @@ export async function promptHintMessage(config: string, message: string, choiceC if (choice === choiceConfirm) { await onConfirm(); } else if (choice === choiceNoShowAgain) { - await getWorkspaceConfiguration().update(`hint.${config}`, false, true /* UserSetting */); + await getWorkspaceConfiguration().update(`${config}`, false, true /* UserSetting */); } } } diff --git a/src/webview/LeetCodeWebview.ts b/src/webview/LeetCodeWebview.ts index 4d106927..6c3f2552 100644 --- a/src/webview/LeetCodeWebview.ts +++ b/src/webview/LeetCodeWebview.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { commands, ConfigurationChangeEvent, Disposable, ViewColumn, WebviewPanel, window, workspace } from "vscode"; -import { promptHintMessage, openSettingsEditor } from "../utils/uiUtils"; +import { openSettingsEditor, promptHintMessage } from "../utils/uiUtils"; import { markdownEngine } from "./markdownEngine"; export abstract class LeetCodeWebview implements Disposable { @@ -67,7 +67,7 @@ export abstract class LeetCodeWebview implements Disposable { private async showMarkdownConfigHint(): Promise { await promptHintMessage( - "configWebviewMarkdown", + "hint.configWebviewMarkdown", 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', "Open configuration", (): Promise => openSettingsEditor("markdown.preview"), diff --git a/src/webview/leetCodeSubmissionProvider.ts b/src/webview/leetCodeSubmissionProvider.ts index 46d4784f..e1703652 100644 --- a/src/webview/leetCodeSubmissionProvider.ts +++ b/src/webview/leetCodeSubmissionProvider.ts @@ -1,8 +1,8 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. -import { commands, ViewColumn } from "vscode"; -import { promptHintMessage, openKeybindingsEditor } from "../utils/uiUtils"; +import { ViewColumn } from "vscode"; +import { openKeybindingsEditor, promptHintMessage } from "../utils/uiUtils"; import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview"; import { markdownEngine } from "./markdownEngine"; @@ -45,7 +45,7 @@ class LeetCodeSubmissionProvider extends LeetCodeWebview { private async showKeybindingsHint(): Promise { await promptHintMessage( - "commandShortcut", + "hint.commandShortcut", 'You can configure custom key bindings with "test", "submit" or any other command in Preferences > Keyboard Shortcuts.', "Open Keybindings", (): Promise => openKeybindingsEditor("leetcode solution"), From 77c71403e94affe5193cac9628015ae5b22213fe Mon Sep 17 00:00:00 2001 From: Vigilans Date: Sun, 28 Apr 2019 14:17:54 +0800 Subject: [PATCH 4/4] Address comments in review --- src/commands/show.ts | 4 ++-- src/utils/uiUtils.ts | 5 ++--- src/webview/LeetCodeWebview.ts | 2 +- src/webview/leetCodeSubmissionProvider.ts | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index 6f093daa..24d3b50f 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -120,8 +120,8 @@ async function showProblemInternal(node: IProblem): Promise { movePreviewAsideIfNeeded(node), promptHintMessage( "hint.commentDescription", - 'You can generate problem description as comment in the solution code file by enabling "leetcode.showCommentDescription".', - "Open configuration", + 'You can generate the code file with problem description in the comments by enabling "leetcode.showCommentDescription".', + "Open settings", (): Promise => openSettingsEditor("leetcode.showCommentDescription"), ), ]); diff --git a/src/utils/uiUtils.ts b/src/utils/uiUtils.ts index baf7d488..845865e8 100644 --- a/src/utils/uiUtils.ts +++ b/src/utils/uiUtils.ts @@ -59,7 +59,7 @@ export async function promptForSignIn(): Promise { } export async function promptHintMessage(config: string, message: string, choiceConfirm: string, onConfirm: () => Promise): Promise { - if (getWorkspaceConfiguration().get(`${config}`)) { + if (getWorkspaceConfiguration().get(config)) { const choiceNoShowAgain: string = "Don't show again"; const choice: string | undefined = await vscode.window.showInformationMessage( message, choiceConfirm, choiceNoShowAgain, @@ -67,7 +67,7 @@ export async function promptHintMessage(config: string, message: string, choiceC if (choice === choiceConfirm) { await onConfirm(); } else if (choice === choiceNoShowAgain) { - await getWorkspaceConfiguration().update(`${config}`, false, true /* UserSetting */); + await getWorkspaceConfiguration().update(config, false, true /* UserSetting */); } } } @@ -80,7 +80,6 @@ export async function openKeybindingsEditor(query?: string): Promise { await vscode.commands.executeCommand("workbench.action.openGlobalKeybindings", query); } - export async function showFileSelectDialog(): Promise { const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined; const options: vscode.OpenDialogOptions = { diff --git a/src/webview/LeetCodeWebview.ts b/src/webview/LeetCodeWebview.ts index 6c3f2552..8532c8d5 100644 --- a/src/webview/LeetCodeWebview.ts +++ b/src/webview/LeetCodeWebview.ts @@ -69,7 +69,7 @@ export abstract class LeetCodeWebview implements Disposable { await promptHintMessage( "hint.configWebviewMarkdown", 'You can change the webview appearance ("fontSize", "lineWidth" & "fontFamily") in "markdown.preview" configuration.', - "Open configuration", + "Open settings", (): Promise => openSettingsEditor("markdown.preview"), ); } diff --git a/src/webview/leetCodeSubmissionProvider.ts b/src/webview/leetCodeSubmissionProvider.ts index e1703652..689c3a2f 100644 --- a/src/webview/leetCodeSubmissionProvider.ts +++ b/src/webview/leetCodeSubmissionProvider.ts @@ -46,7 +46,7 @@ class LeetCodeSubmissionProvider extends LeetCodeWebview { private async showKeybindingsHint(): Promise { await promptHintMessage( "hint.commandShortcut", - 'You can configure custom key bindings with "test", "submit" or any other command in Preferences > Keyboard Shortcuts.', + 'You can customize shortcut key bindings in File > Preferences > Keyboard Shortcuts with query "leetcode".', "Open Keybindings", (): Promise => openKeybindingsEditor("leetcode solution"), );