diff --git a/package.json b/package.json index fb8ff548..1e6ce79a 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,24 @@ "title": "Submit to LeetCode", "category": "LeetCode" }, + { + "command": "leetcode.addFavorite", + "title": "Add to Favorite List", + "category": "LeetCode", + "icon": { + "light": "resources/light/like.png", + "dark": "resources/dark/like.png" + } + }, + { + "command": "leetcode.removeFavorite", + "title": "Remove from Favorite List", + "category": "LeetCode", + "icon": { + "light": "resources/light/dislike.png", + "dark": "resources/dark/dislike.png" + } + }, { "command": "leetcode.switchDefaultLanguage", "title": "Switch Default Language", @@ -178,18 +196,28 @@ "view/item/context": [ { "command": "leetcode.previewProblem", - "when": "view == leetCodeExplorer && viewItem == problem", + "when": "view == leetCodeExplorer && viewItem =~ /problem*/", "group": "leetcode@1" }, { "command": "leetcode.showProblem", - "when": "view == leetCodeExplorer && viewItem == problem", + "when": "view == leetCodeExplorer && viewItem =~ /problem*/", "group": "leetcode@2" }, { "command": "leetcode.showSolution", - "when": "view == leetCodeExplorer && viewItem == problem", + "when": "view == leetCodeExplorer && viewItem =~ /problem*/", "group": "leetcode@3" + }, + { + "command": "leetcode.addFavorite", + "when": "view == leetCodeExplorer && viewItem == problem", + "group": "inline" + }, + { + "command": "leetcode.removeFavorite", + "when": "view == leetCodeExplorer && viewItem == problem-favorite", + "group": "inline" } ], "commandPalette": [ @@ -204,6 +232,14 @@ { "command": "leetcode.previewProblem", "when": "never" + }, + { + "command": "leetcode.addFavorite", + "when": "never" + }, + { + "command": "leetcode.removeFavorite", + "when": "never" } ], "explorer/context": [ diff --git a/resources/dark/dislike.png b/resources/dark/dislike.png new file mode 100644 index 00000000..4a4fe020 Binary files /dev/null and b/resources/dark/dislike.png differ diff --git a/resources/dark/like.png b/resources/dark/like.png new file mode 100644 index 00000000..613fccd4 Binary files /dev/null and b/resources/dark/like.png differ diff --git a/resources/light/dislike.png b/resources/light/dislike.png new file mode 100644 index 00000000..b514f0f3 Binary files /dev/null and b/resources/light/dislike.png differ diff --git a/resources/light/like.png b/resources/light/like.png new file mode 100644 index 00000000..0f7081d2 Binary files /dev/null and b/resources/light/like.png differ diff --git a/src/commands/star.ts b/src/commands/star.ts new file mode 100644 index 00000000..baae0b07 --- /dev/null +++ b/src/commands/star.ts @@ -0,0 +1,26 @@ + +// Copyright (c) jdneo. All rights reserved. +// Licensed under the MIT license. + +import { LeetCodeNode } from "../explorer/LeetCodeNode"; +import { leetCodeTreeDataProvider } from "../explorer/LeetCodeTreeDataProvider"; +import { leetCodeExecutor } from "../leetCodeExecutor"; +import { DialogType, promptForOpenOutputChannel } from "../utils/uiUtils"; + +export async function addFavorite(node: LeetCodeNode): Promise { + try { + await leetCodeExecutor.toggleFavorite(node, true); + leetCodeTreeDataProvider.refresh(); + } catch (error) { + await promptForOpenOutputChannel("Failed to add the problem to favorite. Please open the output channel for details.", DialogType.error); + } +} + +export async function removeFavorite(node: LeetCodeNode): Promise { + try { + await leetCodeExecutor.toggleFavorite(node, false); + leetCodeTreeDataProvider.refresh(); + } catch (error) { + await promptForOpenOutputChannel("Failed to remove the problem from favorite. Please open the output channel for details.", DialogType.error); + } +} diff --git a/src/explorer/LeetCodeTreeDataProvider.ts b/src/explorer/LeetCodeTreeDataProvider.ts index ac115424..69445bbb 100644 --- a/src/explorer/LeetCodeTreeDataProvider.ts +++ b/src/explorer/LeetCodeTreeDataProvider.ts @@ -38,13 +38,20 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider vscode.commands.registerCommand("leetcode.testSolution", (uri?: vscode.Uri) => test.testSolution(uri)), vscode.commands.registerCommand("leetcode.submitSolution", (uri?: vscode.Uri) => submit.submitSolution(uri)), vscode.commands.registerCommand("leetcode.switchDefaultLanguage", () => switchDefaultLanguage()), + vscode.commands.registerCommand("leetcode.addFavorite", (node: LeetCodeNode) => star.addFavorite(node)), + vscode.commands.registerCommand("leetcode.removeFavorite", (node: LeetCodeNode) => star.removeFavorite(node)), ); await leetCodeExecutor.switchEndpoint(plugin.getLeetCodeEndpoint()); diff --git a/src/leetCodeExecutor.ts b/src/leetCodeExecutor.ts index 8bef00fa..04b89013 100644 --- a/src/leetCodeExecutor.ts +++ b/src/leetCodeExecutor.ts @@ -162,6 +162,14 @@ class LeetCodeExecutor implements Disposable { } } + public async toggleFavorite(node: IProblem, addToFavorite: boolean): Promise { + const commandParams: string[] = [await this.getLeetCodeBinaryPath(), "star", node.id]; + if (!addToFavorite) { + commandParams.push("-d"); + } + await this.executeCommandWithProgressEx("Updating the favorite list...", "node", commandParams); + } + public async getCompaniesAndTags(): Promise<{ companies: { [key: string]: string[] }, tags: { [key: string]: string[] } }> { // preprocess the plugin source const companiesTagsPath: string = path.join(await leetCodeExecutor.getLeetCodeRootPath(), "lib", "plugins", "company.js");