From c71b0579a84e4613f79bbcc2e79ca2a27895aec5 Mon Sep 17 00:00:00 2001 From: XzZZzX02 Date: Fri, 15 Nov 2024 10:51:23 +0800 Subject: [PATCH 1/5] feat: add custom code snippets support for LeetCode problems --- package.json | 6 ++++++ src/leetCodeExecutor.ts | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 53552b7..1e35657 100644 --- a/package.json +++ b/package.json @@ -705,6 +705,12 @@ "default": true, "scope": "application", "description": "Allow LeetCode to report anonymous usage data to improve the product." + }, + "leetcode.codeSnippets": { + "type": "string", + "default": "", + "scope": "application", + "description": "Custom code snippets for LeetCode problems." } } } diff --git a/src/leetCodeExecutor.ts b/src/leetCodeExecutor.ts index d2332c7..3f11247 100644 --- a/src/leetCodeExecutor.ts +++ b/src/leetCodeExecutor.ts @@ -1,6 +1,7 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. +import * as vscode from "vscode"; import * as cp from "child_process"; import * as fse from "fs-extra"; import * as os from "os"; @@ -110,7 +111,19 @@ class LeetCodeExecutor implements Disposable { if (!await fse.pathExists(filePath)) { await fse.createFile(filePath); - const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, cmd); + let codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, cmd); + const lines = codeTemplate.split(/\r?\n/); + const targetIndex = lines.findIndex(line => line.includes('// @lc code=start')); + const codeSnippet: string = vscode.workspace.getConfiguration('leetcode').get('codeSnippets', ''); + if (targetIndex !== -1 && codeSnippet.trim() !== '') { + let insertIndex = targetIndex; + while (insertIndex - 1 >= 0 && lines[insertIndex - 1].trim() === '') { + lines.splice(insertIndex - 1, 1); + insertIndex--; + } + lines.splice(insertIndex, 0, codeSnippet); + } + codeTemplate = lines.join('\n'); await fse.writeFile(filePath, codeTemplate); } } From beefdc6c5b5e40c1d73767a3df33f69992c6ad8e Mon Sep 17 00:00:00 2001 From: XzZZzX02 Date: Sun, 17 Nov 2024 02:33:29 +0800 Subject: [PATCH 2/5] feat: update version and add daily challenge feature --- package-lock.json | 4 +-- package.json | 26 ++++++--------- src/commands/show.ts | 11 +++++++ src/extension.ts | 3 +- src/request/query-daily-challange.ts | 13 ++++++++ src/shared.ts | 49 ++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 19 deletions(-) create mode 100644 src/request/query-daily-challange.ts diff --git a/package-lock.json b/package-lock.json index 2ac17cf..aa5d515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-leetcode", - "version": "0.18.1", + "version": "0.18.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-leetcode", - "version": "0.18.1", + "version": "0.18.4", "license": "MIT", "dependencies": { "axios": "^1.6.8", diff --git a/package.json b/package.json index 1e35657..11a8bb7 100644 --- a/package.json +++ b/package.json @@ -25,22 +25,6 @@ "interview" ], "preview": true, - "activationEvents": [ - "onCommand:leetcode.toggleLeetCodeCn", - "onCommand:leetcode.signin", - "onCommand:leetcode.signout", - "onCommand:leetcode.manageSessions", - "onCommand:leetcode.refreshExplorer", - "onCommand:leetcode.pickOne", - "onCommand:leetcode.showProblem", - "onCommand:leetcode.previewProblem", - "onCommand:leetcode.searchProblem", - "onCommand:leetcode.testSolution", - "onCommand:leetcode.submitSolution", - "onCommand:leetcode.switchDefaultLanguage", - "onCommand:leetcode.problems.sort", - "onView:leetCodeExplorer" - ], "main": "./out/src/extension", "contributes": { "commands": [ @@ -141,6 +125,11 @@ "title": "Sort Problems", "category": "LeetCode", "icon": "$(sort-precedence)" + }, + { + "command": "leetcode.pickDaily", + "title": "Pick Daily Chanllenge", + "category": "LeetCode" } ], "viewsContainers": { @@ -223,6 +212,11 @@ "command": "leetcode.removeFavorite", "when": "view == leetCodeExplorer && viewItem == problem-favorite", "group": "inline" + }, + { + "command": "leetcode.pickDaily", + "when": "view == leetCodeExplorer", + "group": "leetcode@4" } ], "commandPalette": [ diff --git a/src/commands/show.ts b/src/commands/show.ts index eccf557..122d479 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -30,6 +30,7 @@ import { leetCodeSolutionProvider } from "../webview/leetCodeSolutionProvider"; import * as list from "./list"; import { getLeetCodeEndpoint } from "./plugin"; import { globalState } from "../globalState"; +import { queryDailyChallenge } from "../request/query-daily-challange"; export async function previewProblem(input: IProblem | vscode.Uri, isSideMode: boolean = false): Promise { let node: IProblem; @@ -70,6 +71,16 @@ export async function pickOne(): Promise { await showProblemInternal(randomProblem); } +export async function pickDailyChallenge(): Promise { + const dailyChallengeID: string = await queryDailyChallenge(); + const node: IProblem | undefined = explorerNodeManager.getNodeById(dailyChallengeID); + if (!node) { + vscode.window.showErrorMessage(`No daily challenge found for today.`); + return; + } + await showProblemInternal(node); +} + export async function showProblem(node?: LeetCodeNode): Promise { if (!node) { return; diff --git a/src/extension.ts b/src/extension.ts index 439673f..7a899e0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -97,7 +97,8 @@ export async function activate(context: vscode.ExtensionContext): Promise 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)), - vscode.commands.registerCommand("leetcode.problems.sort", () => plugin.switchSortingStrategy()) + vscode.commands.registerCommand("leetcode.problems.sort", () => plugin.switchSortingStrategy()), + vscode.commands.registerCommand("leetcode.pickDaily", () => show.pickDailyChallenge()) ); await leetCodeExecutor.switchEndpoint(plugin.getLeetCodeEndpoint()); diff --git a/src/request/query-daily-challange.ts b/src/request/query-daily-challange.ts new file mode 100644 index 0000000..d71409d --- /dev/null +++ b/src/request/query-daily-challange.ts @@ -0,0 +1,13 @@ +import {getUrl, getDailyQueryStr, getDailyProblemID} from "../shared"; +import {LcAxios} from "../utils/httpUtils"; + +export const queryDailyChallenge = async (): Promise => { + return LcAxios(getUrl("graphql"), { + method: "POST", + data: { + query: getDailyQueryStr(), + variables: {}, + operationName: 'questionOfToday' + }, + }).then((res) => getDailyProblemID(res)); +}; diff --git a/src/shared.ts b/src/shared.ts index e8b59d8..95d3bbf 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import * as vscode from "vscode"; +import { AxiosResponse } from "axios"; export interface IQuickItemEx extends vscode.QuickPickItem { value: T; @@ -156,3 +157,51 @@ export const getUrl = (key: string) => { return urls[key]; } }; + +export const getEndpoint = (): string => { + const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); + return leetCodeConfig.get("endpoint", Endpoint.LeetCode); +} + + +export const getDailyQueryStr = (): string => { + const dailyQueryStrs = { + LeetCode: ` + query questionOfToday { + activeDailyCodingChallengeQuestion { + question { + frontendQuestionId: questionFrontendId + } + } + } + `, + LeetCodeCN: ` + query questionOfToday { + todayRecord { + question { + frontendQuestionId: questionFrontendId + } + } + } + ` + } + const point: string = getEndpoint(); + switch (point) { + case Endpoint.LeetCodeCN: + return dailyQueryStrs.LeetCodeCN; + case Endpoint.LeetCode: + return dailyQueryStrs.LeetCode; + } + return ""; +} + +export const getDailyProblemID = (res: AxiosResponse): string => { + const point = getEndpoint(); + switch (point) { + case Endpoint.LeetCodeCN: + return res.data.data.todayRecord[0].question.frontendQuestionId; + case Endpoint.LeetCode: + return res.data.data.todayRecord[0].question.frontendQuestionId; + } + return ""; +} From 0696a48d554584fe73870eb3b6108755bb0d4d41 Mon Sep 17 00:00:00 2001 From: XzZZzX02 Date: Sun, 17 Nov 2024 22:12:43 +0800 Subject: [PATCH 3/5] feat: add daily challenge category and implement related node retrieval --- src/explorer/LeetCodeTreeDataProvider.ts | 2 ++ src/explorer/explorerNodeManager.ts | 10 ++++++++++ src/shared.ts | 1 + 3 files changed, 13 insertions(+) diff --git a/src/explorer/LeetCodeTreeDataProvider.ts b/src/explorer/LeetCodeTreeDataProvider.ts index 9c29894..f6adc72 100644 --- a/src/explorer/LeetCodeTreeDataProvider.ts +++ b/src/explorer/LeetCodeTreeDataProvider.ts @@ -85,6 +85,8 @@ export class LeetCodeTreeDataProvider implements vscode.TreeDataProvider = new Map(); @@ -53,6 +54,10 @@ class ExplorerNodeManager implements Disposable { id: Category.Favorite, name: Category.Favorite, }), false), + new LeetCodeNode(Object.assign({}, defaultProblem, { + id: Category.Daily, + name: Category.Daily, + }), false) ]; } @@ -148,6 +153,11 @@ class ExplorerNodeManager implements Disposable { return this.applySortingStrategy(res); } + public async getDailyChallengeNode(): Promise { + const dailyChallengeID: string = await queryDailyChallenge(); + return this.getNodeById(dailyChallengeID) ? [this.getNodeById(dailyChallengeID)!] : []; + } + public dispose(): void { this.explorerNodeMap.clear(); this.companySet.clear(); diff --git a/src/shared.ts b/src/shared.ts index 95d3bbf..bb15215 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -102,6 +102,7 @@ export enum Category { Tag = "Tag", Company = "Company", Favorite = "Favorite", + Daily = "Daily Challenge" } export const supportedPlugins: string[] = ["company", "solution.discuss", "leetcode.cn"]; From cac44adaef47c4836519c7c946d740649ff3b61f Mon Sep 17 00:00:00 2001 From: XzZZzX02 Date: Sun, 17 Nov 2024 22:22:39 +0800 Subject: [PATCH 4/5] feat: refactor endpoint retrieval and enhance daily challenge query handling --- src/commands/plugin.ts | 5 ++- src/request/query-daily-challange.ts | 46 ++++++++++++++++++++++++++- src/shared.ts | 47 +--------------------------- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/commands/plugin.ts b/src/commands/plugin.ts index d2ed4b6..94e9ff4 100644 --- a/src/commands/plugin.ts +++ b/src/commands/plugin.ts @@ -4,7 +4,7 @@ import * as vscode from "vscode"; import { leetCodeTreeDataProvider } from "../explorer/LeetCodeTreeDataProvider"; import { leetCodeExecutor } from "../leetCodeExecutor"; -import { IQuickItemEx } from "../shared"; +import { getEndpoint, IQuickItemEx } from "../shared"; import { Endpoint, SortingStrategy } from "../shared"; import { DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; import { deleteCache } from "./cache"; @@ -50,8 +50,7 @@ export async function switchEndpoint(): Promise { } export function getLeetCodeEndpoint(): string { - const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); - return leetCodeConfig.get("endpoint", Endpoint.LeetCode); + return getEndpoint(); } const SORT_ORDER: SortingStrategy[] = [ diff --git a/src/request/query-daily-challange.ts b/src/request/query-daily-challange.ts index d71409d..251b888 100644 --- a/src/request/query-daily-challange.ts +++ b/src/request/query-daily-challange.ts @@ -1,5 +1,49 @@ -import {getUrl, getDailyQueryStr, getDailyProblemID} from "../shared"; +import {getUrl, getEndpoint, Endpoint} from "../shared"; import {LcAxios} from "../utils/httpUtils"; +import {AxiosResponse} from "axios"; + + +export const getDailyQueryStr = (): string => { + const dailyQueryStrs = { + LeetCode: ` + query questionOfToday { + activeDailyCodingChallengeQuestion { + question { + frontendQuestionId: questionFrontendId + } + } + } + `, + LeetCodeCN: ` + query questionOfToday { + todayRecord { + question { + frontendQuestionId: questionFrontendId + } + } + } + ` + } + const point: string = getEndpoint(); + switch (point) { + case Endpoint.LeetCodeCN: + return dailyQueryStrs.LeetCodeCN; + case Endpoint.LeetCode: + return dailyQueryStrs.LeetCode; + } + return ""; +} + +export const getDailyProblemID = (res: AxiosResponse): string => { + const point = getEndpoint(); + switch (point) { + case Endpoint.LeetCodeCN: + return res.data.data.todayRecord[0].question.frontendQuestionId; + case Endpoint.LeetCode: + return res.data.data.todayRecord[0].question.frontendQuestionId; + } + return ""; +} export const queryDailyChallenge = async (): Promise => { return LcAxios(getUrl("graphql"), { diff --git a/src/shared.ts b/src/shared.ts index bb15215..e155e04 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -2,7 +2,6 @@ // Licensed under the MIT license. import * as vscode from "vscode"; -import { AxiosResponse } from "axios"; export interface IQuickItemEx extends vscode.QuickPickItem { value: T; @@ -148,8 +147,7 @@ export const urlsCn = { }; export const getUrl = (key: string) => { - const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); - const point = leetCodeConfig.get("endpoint", Endpoint.LeetCode); + const point = getEndpoint(); switch (point) { case Endpoint.LeetCodeCN: return urlsCn[key]; @@ -163,46 +161,3 @@ export const getEndpoint = (): string => { const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); return leetCodeConfig.get("endpoint", Endpoint.LeetCode); } - - -export const getDailyQueryStr = (): string => { - const dailyQueryStrs = { - LeetCode: ` - query questionOfToday { - activeDailyCodingChallengeQuestion { - question { - frontendQuestionId: questionFrontendId - } - } - } - `, - LeetCodeCN: ` - query questionOfToday { - todayRecord { - question { - frontendQuestionId: questionFrontendId - } - } - } - ` - } - const point: string = getEndpoint(); - switch (point) { - case Endpoint.LeetCodeCN: - return dailyQueryStrs.LeetCodeCN; - case Endpoint.LeetCode: - return dailyQueryStrs.LeetCode; - } - return ""; -} - -export const getDailyProblemID = (res: AxiosResponse): string => { - const point = getEndpoint(); - switch (point) { - case Endpoint.LeetCodeCN: - return res.data.data.todayRecord[0].question.frontendQuestionId; - case Endpoint.LeetCode: - return res.data.data.todayRecord[0].question.frontendQuestionId; - } - return ""; -} From 90e9670956aa6d8517ca3b74a4f78e0d05103950 Mon Sep 17 00:00:00 2001 From: XzZZzX02 Date: Sun, 17 Nov 2024 22:54:59 +0800 Subject: [PATCH 5/5] fix --- package.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/package.json b/package.json index 11a8bb7..427d885 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,22 @@ "interview" ], "preview": true, + "activationEvents": [ + "onCommand:leetcode.toggleLeetCodeCn", + "onCommand:leetcode.signin", + "onCommand:leetcode.signout", + "onCommand:leetcode.manageSessions", + "onCommand:leetcode.refreshExplorer", + "onCommand:leetcode.pickOne", + "onCommand:leetcode.showProblem", + "onCommand:leetcode.previewProblem", + "onCommand:leetcode.searchProblem", + "onCommand:leetcode.testSolution", + "onCommand:leetcode.submitSolution", + "onCommand:leetcode.switchDefaultLanguage", + "onCommand:leetcode.problems.sort", + "onView:leetCodeExplorer" + ], "main": "./out/src/extension", "contributes": { "commands": [ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy