diff --git a/CHANGELOG.md b/CHANGELOG.md index ea94ffd..357a213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# version 2.19.18 + +- 使用新的 mvc 代码结构修改 statusBar 相关内容 +- 增加自动引入 includeTemplates 设置选项,默认引入 + # version 2.19.17 - 更新基础的分数数据 data.json diff --git a/package.json b/package.json index 6dea985..a4081a4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-leetcode-problem-rating", "displayName": "LeetCode", "description": "%main.description%", - "version": "2.19.17", + "version": "2.19.18", "author": "ccagml", "publisher": "ccagml", "license": "MIT", @@ -643,6 +643,11 @@ } } }, + "leetcode-problem-rating.includeTemplatesAuto": { + "type": "boolean", + "default": true, + "description": "%main.contributes.configuration.properties.leetcode-problem-rating.includeTemplatesAuto.description%" + }, "leetcode-problem-rating.hideSolved": { "type": "boolean", "default": false, diff --git a/package.nls.json b/package.nls.json index 4d204ee..8da649f 100644 --- a/package.nls.json +++ b/package.nls.json @@ -48,6 +48,7 @@ "main.contributes.submenus.lcpr.setBricksType_sub1.label": "Set repetition time", "main.contributes.configuration.title": "leetcode-problem-rating", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.description": "Introduce some default content to prevent VSCode from wavy red lines", + "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplatesAuto.description": "auto Introduce some default content to prevent VSCode from wavy red lines", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.items.properties.language.description": "Programming language", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.items.properties.template.description": "template content", "main.contributes.configuration.properties.leetcode-problem-rating.hideSolved.description": "Hide solved problems.", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index 47f1caf..f0f51ad 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -48,6 +48,7 @@ "main.contributes.submenus.lcpr.setBricksType_sub1.label": "设置砖头类型", "main.contributes.configuration.title": "leetcode-problem-rating", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.description": "引入一些默认内容,防止VSCode都是波浪红线", + "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplatesAuto.description": "自动引入模板", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.items.properties.language.description": "哪种语言", "main.contributes.configuration.properties.leetcode-problem-rating.includeTemplates.items.properties.template.description": "模板内容", "main.contributes.configuration.properties.leetcode-problem-rating.hideSolved.description": "隐藏已解决的问题", diff --git a/src/BABA.ts b/src/BABA.ts new file mode 100644 index 0000000..3d08267 --- /dev/null +++ b/src/BABA.ts @@ -0,0 +1,68 @@ +/* + * Filename: /home/cc/leetcode-extension/src/BABA.ts + * Path: /home/cc/leetcode-extension + * Created Date: Saturday, September 23rd 2023, 8:17:16 pm + * Author: ccagml + * + * Copyright (c) 2023 ccagml . All rights reserved + */ + +import { BaseCC } from "./utils/BaseCC"; +export * as BaseCC from "./utils/BaseCC"; +export enum BabaStr { + every_second = "every_second", + StatusBarTimeMediator = "StatusBarTimeMediator", + StatusBarTimeProxy = "StatusBarTimeProxy", + RemarkMediator = "RemarkMediator", + RemarkProxy = "RemarkProxy", + submit = "submit", + showProblemFinish = "showProblemFinish", + showProblemFinishOpen = "showProblemFinishOpen", + showProblemFinishError = "showProblemFinishError", + VSCODE_DISPOST = "VSCODE_DISPOST", + statusBarTime_start = "statusBarTime_start", + statusBarTime_stop = "statusBarTime_stop", + statusBarTime_reset = "statusBarTime_reset", + StatusBarProxy = "StatusBarProxy", + StatusBarMediator = "StatusBarMediator", + statusBar_update_status = "statusBar_update_status", + statusBar_update = "statusBar_update", + statusBar_update_UserContestInfo = "statusBar_update_UserContestInfo", +} + +export class BABA { + public static fa; + public static init() { + this.fa = BaseCC.Facade.getInstance("lcpr"); + } + public static regClazz(clazz_list) { + let len = clazz_list.length; + for (let j = 0; j < len; j++) { + this[clazz_list[j].NAME] = new clazz_list[j](); + } + } + + public static dispose(): any { + this.sendNotification(BabaStr.VSCODE_DISPOST); + } + public static sendNotification(name: string, body?: any, type?: string) { + this.fa.sendNotification(name, body, type); + } + + public static getProxy(name: string) { + return this.fa.retrieveProxy(name); + } +} + +export class BABAProxy extends BaseCC.Proxy { + constructor(name: string) { + super(name); + BABA.fa.registerProxy(this); + } +} +export class BABAMediator extends BaseCC.Mediator { + constructor(name: string) { + super(name); + BABA.fa.registerMediator(this); + } +} diff --git a/src/controller/EventController.ts b/src/controller/EventController.ts index d6bab1a..8bb1744 100644 --- a/src/controller/EventController.ts +++ b/src/controller/EventController.ts @@ -8,7 +8,6 @@ */ import { eventService } from "../service/EventService"; -import { statusBarTimeService } from "../service/StatusBarTimeService"; // 事件的控制器 /* The EventController class has a method called addEvent that calls the addEvent method on the eventService class */ @@ -23,10 +22,6 @@ class EventContorller { public addEvent() { eventService.addEvent(); } - - public every_second() { - statusBarTimeService.updateSecond(); - } } export const eventController: EventContorller = new EventContorller(); diff --git a/src/controller/LoginController.ts b/src/controller/LoginController.ts index 5054a0f..30b4016 100644 --- a/src/controller/LoginController.ts +++ b/src/controller/LoginController.ts @@ -15,10 +15,10 @@ import { createEnvOption } from "../utils/CliUtils"; import { logOutput, promptForOpenOutputChannel } from "../utils/OutputUtils"; import { eventService } from "../service/EventService"; import { window, QuickPickOptions, ProgressLocation, Progress } from "vscode"; -import { statusBarService } from "../service/StatusBarService"; import { treeDataService } from "../service/TreeDataService"; import { getLeetCodeEndpoint } from "../utils/ConfigUtils"; import { bricksDataService } from "../service/BricksDataService"; +import { BABA, BabaStr } from "../BABA"; // 登录控制器 class LoginContorller { @@ -203,7 +203,7 @@ class LoginContorller { * @returns The login status of the user. */ public async getLoginStatus() { - return await statusBarService.getLoginStatus(); + return await BABA.getProxy(BabaStr.StatusBarProxy).getLoginStatus(); } // 删除所有缓存 diff --git a/src/controller/TreeViewController.ts b/src/controller/TreeViewController.ts index 4a6337c..c8f7fbd 100644 --- a/src/controller/TreeViewController.ts +++ b/src/controller/TreeViewController.ts @@ -55,7 +55,6 @@ import { } from "../utils/ConfigUtils"; import { NodeModel } from "../model/NodeModel"; import { ISearchSet } from "../model/Model"; -import { statusBarService } from "../service/StatusBarService"; import { previewService } from "../service/PreviewService"; import { executeService } from "../service/ExecuteService"; import { getNodeIdFromFile } from "../utils/SystemUtils"; @@ -80,6 +79,7 @@ import { submissionService } from "../service/SubmissionService"; import { bricksDataService } from "../service/BricksDataService"; import { groupDao } from "../dao/groupDao"; import { fileMeta, ProblemMeta } from "../utils/problemUtils"; +import { BABA, BabaStr } from "../BABA"; // 视图控制器 class TreeViewController implements Disposable { @@ -111,7 +111,8 @@ class TreeViewController implements Disposable { * @returns A promise that resolves to a string. */ public async submitSolution(uri?: vscode.Uri): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { promptForSignIn(); return; } @@ -144,7 +145,8 @@ class TreeViewController implements Disposable { */ public async testSolution(uri?: vscode.Uri): Promise { try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (sbp.getStatus() === UserStatus.SignedOut) { return; } @@ -254,7 +256,8 @@ class TreeViewController implements Disposable { */ public async testCaseDef(uri?: vscode.Uri, allCase?: boolean): Promise { try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (sbp.getStatus() === UserStatus.SignedOut) { return; } @@ -289,7 +292,8 @@ class TreeViewController implements Disposable { */ public async reTestSolution(uri?: vscode.Uri): Promise { try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (sbp.getStatus() === UserStatus.SignedOut) { return; } @@ -337,7 +341,8 @@ class TreeViewController implements Disposable { */ public async tesCaseArea(uri?: vscode.Uri, testcase?: string): Promise { try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (sbp.getStatus() === UserStatus.SignedOut) { return; } @@ -505,7 +510,8 @@ class TreeViewController implements Disposable { */ public async getAllProblems(): Promise { try { - if (statusBarService.getStatus() === UserStatus.SignedOut) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (sbp.getStatus() === UserStatus.SignedOut) { return []; } @@ -603,7 +609,7 @@ class TreeViewController implements Disposable { return; } - if (!statusBarService.getUser() && choice.value != "testapi") { + if (!BABA.getProxy(BabaStr.StatusBarProxy).getUser() && choice.value != "testapi") { promptForSignIn(); return; } @@ -701,7 +707,8 @@ class TreeViewController implements Disposable { } public async searchProblemByID(): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { promptForSignIn(); return; } @@ -769,7 +776,8 @@ class TreeViewController implements Disposable { const problems: IProblem[] = await this.getAllProblems(); let randomProblem: IProblem; - const user_score = statusBarService.getUserContestScore(); + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + const user_score = sbp.getUserContestScore(); if (user_score > 0) { let min_score: number = getPickOneByRankRangeMin(); let max_score: number = getPickOneByRankRangeMax(); @@ -851,10 +859,19 @@ class TreeViewController implements Disposable { ); if (show_code == 100) { const promises: any[] = [ - vscode.window.showTextDocument(vscode.Uri.file(finalPath), { - preview: false, - viewColumn: vscode.ViewColumn.One, - }), + vscode.window + .showTextDocument(vscode.Uri.file(finalPath), { + preview: false, + viewColumn: vscode.ViewColumn.One, + }) + .then( + (editor) => { + eventService.emit("showProblemFinishOpen", node, editor); + }, + (error) => { + eventService.emit("showProblemFinishError", node, error); + } + ), promptHintMessage( "hint.commentDescription", 'You can config how to show the problem description through "leetcode-problem-rating.showDescription".', @@ -956,13 +973,14 @@ class TreeViewController implements Disposable { } public async searchUserContest(): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { promptForSignIn(); return; } try { const needTranslation: boolean = isUseEndpointTranslation(); - const solution: string = await executeService.getUserContest(needTranslation, statusBarService.getUser() || ""); + const solution: string = await executeService.getUserContest(needTranslation, sbp.getUser() || ""); const query_result = JSON.parse(solution); const tt: userContestRanKingBase = Object.assign({}, userContestRankingObj, query_result.userContestRanking); eventService.emit("searchUserContest", tt); @@ -972,7 +990,8 @@ class TreeViewController implements Disposable { } } public async searchToday(): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { promptForSignIn(); return; } @@ -1137,7 +1156,8 @@ class TreeViewController implements Disposable { } public async refreshCheck(): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { return; } const day_start = systemUtils.getDayStart(); //获取当天零点的时间 @@ -1156,7 +1176,8 @@ class TreeViewController implements Disposable { this.waitTodayQuestion = true; await this.searchToday(); } - let user_score = statusBarService.getUserContestScore(); + + let user_score = sbp.getUserContestScore(); if (!user_score && !this.waitUserContest) { this.waitUserContest = true; await this.searchUserContest(); @@ -1168,7 +1189,10 @@ class TreeViewController implements Disposable { const temp_waitTodayQuestion: boolean = this.waitTodayQuestion; const temp_waitUserContest: boolean = this.waitUserContest; this.clearCache(); - let user_score = statusBarService.getUserContestScore(); + + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + + let user_score = sbp.getUserContestScore(); for (const problem of await this.getAllProblems()) { this.explorerNodeMap.set(problem.id, new NodeModel(problem, true, user_score)); this.fidToQid.set(problem.id, problem.qid.toString()); @@ -1188,7 +1212,8 @@ class TreeViewController implements Disposable { } public getRootNodes(): NodeModel[] { - let user_score = statusBarService.getUserContestScore(); + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + let user_score = sbp.getUserContestScore(); const baseNode: NodeModel[] = [ new NodeModel( Object.assign({}, defaultProblem, { diff --git a/src/extension.ts b/src/extension.ts index 7ffa4df..e680717 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -16,7 +16,6 @@ import { treeItemDecorationService } from "./service/TreeItemDecorationService"; import { logOutput, promptForOpenOutputChannel } from "./utils/OutputUtils"; import { executeService } from "./service/ExecuteService"; import { eventController } from "./controller/EventController"; -import { statusBarService } from "./service/StatusBarService"; import { previewService } from "./service/PreviewService"; import { solutionService } from "./service/SolutionService"; import { submissionService } from "./service/SubmissionService"; @@ -27,9 +26,14 @@ import { getLeetCodeEndpoint } from "./utils/ConfigUtils"; import { BricksType, OutPutType, RemarkComment } from "./model/Model"; import { bricksDataService } from "./service/BricksDataService"; import { bricksViewController } from "./controller/BricksViewController"; -import { statusBarTimeService } from "./service/StatusBarTimeService"; import { remarkController } from "./controller/RemarkController"; import { debugContorller } from "./controller/DebugController"; +import { BABA, BabaStr } from "./BABA"; +import { StatusBarTimeMediator, StatusBarTimeProxy } from "./statusBarTime/StatusBarTimeModule"; +import { StatusBarMediator, StatusBarProxy } from "./statusBar/StatusBarModule"; +import { RemarkProxy, RemarkMediator } from "./service/RemarkService"; + +//==================================BABA======================================== // 激活插件 /** @@ -40,6 +44,16 @@ import { debugContorller } from "./controller/DebugController"; let lcpr_timer; export async function activate(context: ExtensionContext): Promise { try { + BABA.init(); + BABA.regClazz([ + StatusBarTimeMediator, + StatusBarTimeProxy, + StatusBarProxy, + StatusBarMediator, + RemarkProxy, + RemarkMediator, + ]); + // 初始化控制器 mainContorller.initialize(context); // 检查node环境 @@ -50,14 +64,13 @@ export async function activate(context: ExtensionContext): Promise { // 资源管理 context.subscriptions.push( - statusBarService, logOutput, previewService, submissionService, solutionService, executeService, markdownService, - statusBarTimeService, + BABA, fileButtonController, treeViewController, window.registerFileDecorationProvider(treeItemDecorationService), @@ -84,9 +97,15 @@ export async function activate(context: ExtensionContext): Promise { commands.registerCommand("lcpr.addFavorite", (node: NodeModel) => treeViewController.addFavorite(node)), commands.registerCommand("lcpr.removeFavorite", (node: NodeModel) => treeViewController.removeFavorite(node)), commands.registerCommand("lcpr.problems.sort", () => treeViewController.switchSortingStrategy()), - commands.registerCommand("lcpr.statusBarTime.start", () => statusBarTimeService.start()), - commands.registerCommand("lcpr.statusBarTime.stop", () => statusBarTimeService.stop()), - commands.registerCommand("lcpr.statusBarTime.reset", () => statusBarTimeService.reset()), + commands.registerCommand("lcpr.statusBarTime.start", () => { + BABA.sendNotification(BabaStr.statusBarTime_start); + }), + commands.registerCommand("lcpr.statusBarTime.stop", () => { + BABA.sendNotification(BabaStr.statusBarTime_stop); + }), + commands.registerCommand("lcpr.statusBarTime.reset", () => { + BABA.sendNotification(BabaStr.statusBarTime_reset); + }), commands.registerCommand("lcpr.setBricksType0", (node: NodeModel) => bricksViewController.setBricksType(node, BricksType.TYPE_0) ), @@ -163,10 +182,14 @@ export async function activate(context: ExtensionContext): Promise { OutPutType.error ); } finally { - lcpr_timer = setInterval(eventController.every_second, 1000); + lcpr_timer = setInterval(lcpr_timer_callback, 1000); } } +function lcpr_timer_callback() { + BABA.sendNotification(BabaStr.every_second); +} + export function deactivate(): void { // Do nothing. if (0) { diff --git a/src/rpc/actionChain/chainNode/leetcode.ts b/src/rpc/actionChain/chainNode/leetcode.ts index e76c397..395b21e 100644 --- a/src/rpc/actionChain/chainNode/leetcode.ts +++ b/src/rpc/actionChain/chainNode/leetcode.ts @@ -445,7 +445,7 @@ and csrf token to the user object and saves the user object to the session. */ statusMessage: resp.statusMessage, msg: "密码错误?", msg1: "invalid password?", - msg2: "要是用浏览器在力扣官网登录过账号还没过期, 插件的登录会被拒绝,使得登录失败", + msg2: "要是用浏览器在力扣官网登录过账号还没过期, 插件的登录会被拒绝,使得登录失败,尝试用cookie方式登录", }); return cb(_temp_msg); } diff --git a/src/service/BricksDataService.ts b/src/service/BricksDataService.ts index c126421..810cf77 100644 --- a/src/service/BricksDataService.ts +++ b/src/service/BricksDataService.ts @@ -11,9 +11,9 @@ import { TreeDataProvider, EventEmitter, Event, TreeItem, TreeItemCollapsibleSta import { BricksNormalId, defaultProblem, ISubmitEvent } from "../model/Model"; import { bricksViewController } from "../controller/BricksViewController"; import { BricksNode } from "../model/NodeModel"; -import { statusBarService } from "./StatusBarService"; import { bricksDao } from "../dao/bricksDao"; import { groupDao } from "../dao/groupDao"; +import { BABA, BabaStr } from "../BABA"; export class BricksDataService implements TreeDataProvider { private onDidChangeTreeDataEvent: EventEmitter = new EventEmitter< @@ -66,7 +66,8 @@ export class BricksDataService implements TreeDataProvider { // 获取子节点信息 public async getChildren(element?: BricksNode | undefined): Promise { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { return [ new BricksNode( Object.assign({}, defaultProblem, { diff --git a/src/service/EventService.ts b/src/service/EventService.ts index 24320f5..127cd5c 100644 --- a/src/service/EventService.ts +++ b/src/service/EventService.ts @@ -11,11 +11,10 @@ import { EventEmitter } from "events"; import { IProblem, ITestSolutionData, UserStatus } from "../model/Model"; import { ISubmitEvent } from "../model/Model"; -import { statusBarService } from "../service/StatusBarService"; import { treeDataService } from "../service/TreeDataService"; import { bricksDataService } from "./BricksDataService"; -import { statusBarTimeService } from "./StatusBarTimeService"; import { submissionService } from "./SubmissionService"; +import { BABA, BabaStr } from "./../BABA"; class EventService extends EventEmitter { constructor() { @@ -27,8 +26,8 @@ class EventService extends EventEmitter { */ public addEvent() { this.on("statusChanged", (userStatus: UserStatus, userName?: string) => { - statusBarService.update_status(userStatus, userName); - statusBarService.update(); + BABA.sendNotification(BabaStr.statusBar_update_status, { userStatus: userStatus, userName: userName }); + BABA.sendNotification(BabaStr.statusBar_update); treeDataService.cleanUserScore(); treeDataService.refresh(); bricksDataService.refresh(); @@ -36,12 +35,12 @@ class EventService extends EventEmitter { this.on("submit", (e: ISubmitEvent) => { treeDataService.checkSubmit(e); bricksDataService.checkSubmit(e); - statusBarTimeService.checkSubmit(e); + BABA.sendNotification(BabaStr.submit, e); }); this.on("searchUserContest", (tt) => { - statusBarService.update_UserContestInfo(tt); - statusBarService.update(); + BABA.sendNotification(BabaStr.statusBar_update_UserContestInfo, tt); + BABA.sendNotification(BabaStr.statusBar_update); treeDataService.refresh(); bricksDataService.refresh(); }); @@ -51,7 +50,13 @@ class EventService extends EventEmitter { }); this.on("showProblemFinish", (node: IProblem) => { - statusBarTimeService.showProblemFinish(node); + BABA.sendNotification(BabaStr.showProblemFinish, node); + }); + this.on("showProblemFinishOpen", (node: IProblem, editor) => { + BABA.sendNotification(BabaStr.showProblemFinishOpen, { node: node, editor: editor }); + }); + this.on("showProblemFinishError", (node: IProblem, error) => { + BABA.sendNotification(BabaStr.showProblemFinishError, { node: node, error: error }); }); this.on("groupUpdate", () => { diff --git a/src/service/RemarkService.ts b/src/service/RemarkService.ts index 159e543..ce09190 100644 --- a/src/service/RemarkService.ts +++ b/src/service/RemarkService.ts @@ -14,7 +14,8 @@ import { import { treeViewController } from "../controller/TreeViewController"; import { remarkDao } from "../dao/remarkDao"; import { RemarkComment } from "../model/Model"; -import { getIncludeTemplate } from "../utils/ConfigUtils"; +import { includeTemplatesAuto, getIncludeTemplate } from "../utils/ConfigUtils"; +import { BABAMediator, BABAProxy, BaseCC, BabaStr } from "../BABA"; class RemarkService implements Disposable { private _remarkComment; @@ -59,6 +60,10 @@ class RemarkService implements Disposable { } for (let i: number = 0; i < document.lineCount; i++) { const lineContent: string = document.lineAt(i).text; + // 有了就不添加了 + if (lineContent.indexOf("@lcpr-template-start") >= 0) { + break; + } if (lineContent.indexOf("@lc code=start") >= 0) { const editor = window.activeTextEditor; @@ -193,3 +198,33 @@ class RemarkService implements Disposable { } export const remarkService: RemarkService = new RemarkService(); + +export class RemarkProxy extends BABAProxy { + static NAME = BabaStr.RemarkProxy; + constructor() { + super(RemarkProxy.NAME); + } +} + +export class RemarkMediator extends BABAMediator { + static NAME = BabaStr.RemarkMediator; + constructor() { + super(RemarkMediator.NAME); + } + + listNotificationInterests(): string[] { + return [BabaStr.showProblemFinishOpen]; + } + handleNotification(_notification: BaseCC.BaseCC.INotification) { + switch (_notification.getName()) { + case BabaStr.showProblemFinishOpen: + let temp_doc = window.activeTextEditor?.document; + if (temp_doc != undefined && includeTemplatesAuto()) { + remarkService.includeTemplates(temp_doc); + } + break; + default: + break; + } + } +} diff --git a/src/service/SubmissionService.ts b/src/service/SubmissionService.ts index 97d5cb7..0c7a7a4 100644 --- a/src/service/SubmissionService.ts +++ b/src/service/SubmissionService.ts @@ -14,8 +14,9 @@ import { ISubmitEvent, ITestSolutionData } from "../model/Model"; import { IWebViewOption } from "../model/Model"; import { promptHintMessage } from "../utils/OutputUtils"; import { isAnswerDiffColor } from "../utils/ConfigUtils"; -import { statusBarTimeService } from "../service/StatusBarTimeService"; import { eventService } from "./EventService"; +import { BABA, BabaStr } from "../BABA"; + class SubmissionService extends BaseWebViewService { protected readonly viewType: string = "leetcode.submission"; private result: IResult; @@ -30,7 +31,7 @@ class SubmissionService extends BaseWebViewService { this.result = this.parseResult(resultString); const temp = this.getSubmitEvent(); - let costTime = statusBarTimeService.getCostTimeStr(); + let costTime = BABA.getProxy(BabaStr.StatusBarTimeProxy).getCostTimeStr(); if (temp?.accepted && temp?.sub_type == "submit" && costTime) { this.result["costTime"] = [`耗时 ${costTime}`]; } diff --git a/src/service/TreeDataService.ts b/src/service/TreeDataService.ts index ac46026..f8197f5 100644 --- a/src/service/TreeDataService.ts +++ b/src/service/TreeDataService.ts @@ -21,12 +21,12 @@ import { } from "../model/Model"; import { treeViewController } from "../controller/TreeViewController"; import { NodeModel } from "../model/NodeModel"; -import { statusBarService } from "./StatusBarService"; import { scoreDao } from "../dao/scoreDao"; import { choiceDao } from "../dao/choiceDao"; import { tagsDao } from "../dao/tagsDao"; import { executeService } from "./ExecuteService"; import { promptForOpenOutputChannel } from "../utils/OutputUtils"; +import { BABA, BabaStr } from "../BABA"; export class TreeDataService implements vscode.TreeDataProvider { private context: vscode.ExtensionContext; @@ -90,7 +90,8 @@ export class TreeDataService implements vscode.TreeDataProvider { } public getChildren(element?: NodeModel | undefined): vscode.ProviderResult { - if (!statusBarService.getUser()) { + let sbp = BABA.getProxy(BabaStr.StatusBarProxy); + if (!sbp.getUser()) { return [ new NodeModel( Object.assign({}, defaultProblem, { diff --git a/src/service/StatusBarService.ts b/src/statusBar/StatusBarModule.ts similarity index 69% rename from src/service/StatusBarService.ts rename to src/statusBar/StatusBarModule.ts index 58a0592..59a7015 100644 --- a/src/service/StatusBarService.ts +++ b/src/statusBar/StatusBarModule.ts @@ -1,17 +1,18 @@ /* - * Filename: https://github.com/ccagml/leetcode-extension/src/service/StatusBarService.ts - * Path: https://github.com/ccagml/leetcode-extension - * Created Date: Thursday, October 27th 2022, 7:43:29 pm + * Filename: /home/cc/leetcode-extension/src/statusBar/StatusBarModule.ts + * Path: /home/cc/leetcode-extension + * Created Date: Wednesday, September 27th 2023, 8:27:08 pm * Author: ccagml * - * Copyright (c) 2022 ccagml . All rights reserved. + * Copyright (c) 2023 ccagml . All rights reserved */ import { ConfigurationChangeEvent, Disposable, workspace, StatusBarItem, window } from "vscode"; import { UserStatus, userContestRanKingBase } from "../model/Model"; import { enableStatusBar } from "../utils/ConfigUtils"; -import { eventService } from "./EventService"; -import { executeService } from "./ExecuteService"; +import { eventService } from "../service/EventService"; +import { executeService } from "../service/ExecuteService"; +import { BabaStr, BABAMediator, BABAProxy, BaseCC } from "../BABA"; // 状态栏工具 class StatusBarService implements Disposable { @@ -147,4 +148,62 @@ class StatusBarService implements Disposable { } } +export class StatusBarProxy extends BABAProxy { + static NAME = BabaStr.StatusBarProxy; + constructor() { + super(StatusBarProxy.NAME); + } + + public getUser() { + return statusBarService.getUser(); + } + + public getStatus() { + return statusBarService.getStatus(); + } + + public getUserContestScore(): number { + return statusBarService.getUserContestScore(); + } + + public async getLoginStatus(): Promise { + return await statusBarService.getLoginStatus(); + } +} + +export class StatusBarMediator extends BABAMediator { + static NAME = BabaStr.StatusBarMediator; + constructor() { + super(StatusBarMediator.NAME); + } + + listNotificationInterests(): string[] { + return [ + BabaStr.VSCODE_DISPOST, + BabaStr.statusBar_update_status, + BabaStr.statusBar_update, + BabaStr.statusBar_update_UserContestInfo, + ]; + } + handleNotification(_notification: BaseCC.BaseCC.INotification) { + switch (_notification.getName()) { + case BabaStr.VSCODE_DISPOST: + statusBarService.dispose(); + break; + case BabaStr.statusBar_update_status: + let body = _notification.getBody(); + statusBarService.update_status(body.userStatus, body.userName); + break; + case BabaStr.statusBar_update: + statusBarService.update(); + break; + case BabaStr.statusBar_update_UserContestInfo: + statusBarService.update_UserContestInfo(_notification.getBody()); + break; + default: + break; + } + } +} + export const statusBarService: StatusBarService = new StatusBarService(); diff --git a/src/service/StatusBarTimeService.ts b/src/statusBarTime/StatusBarTimeModule.ts similarity index 71% rename from src/service/StatusBarTimeService.ts rename to src/statusBarTime/StatusBarTimeModule.ts index eb0e0ed..9ad36c6 100644 --- a/src/service/StatusBarTimeService.ts +++ b/src/statusBarTime/StatusBarTimeModule.ts @@ -1,10 +1,10 @@ /* - * https://github.com/ccagml/leetcode-extension/src/service/StatusBarTimeService.ts - * Path: https://github.com/ccagml/leetcode-extension - * Created Date: Saturday, November 26th 2022, 2:14:53 pm + * Filename: /home/cc/leetcode-extension/src/statusBarTime/StatusBarTimeModule.ts + * Path: /home/cc/leetcode-extension + * Created Date: Wednesday, September 27th 2023, 8:26:28 pm * Author: ccagml * - * Copyright (c) 2022 ccagml . All rights reserved. + * Copyright (c) 2023 ccagml . All rights reserved */ import { Disposable, StatusBarItem, window, workspace, ConfigurationChangeEvent } from "vscode"; @@ -12,6 +12,7 @@ import { IProblem, ISubmitEvent, OutPutType } from "../model/Model"; import { promptForOpenOutputChannel } from "../utils/OutputUtils"; import { getDayNow } from "../utils/SystemUtils"; import { enableTimerBar } from "../utils/ConfigUtils"; +import { BABAMediator, BABAProxy, BaseCC, BabaStr } from "../BABA"; // 状态栏工具 class StatusBarTimeService implements Disposable { @@ -169,4 +170,61 @@ class StatusBarTimeService implements Disposable { } } +export class StatusBarTimeProxy extends BABAProxy { + static NAME = BabaStr.StatusBarTimeProxy; + constructor() { + super(StatusBarTimeProxy.NAME); + } + + public getCostTimeStr() { + return statusBarTimeService.getCostTimeStr(); + } +} + +export class StatusBarTimeMediator extends BABAMediator { + static NAME = BabaStr.StatusBarTimeMediator; + constructor() { + super(StatusBarTimeMediator.NAME); + } + + listNotificationInterests(): string[] { + return [ + BabaStr.every_second, + BabaStr.submit, + BabaStr.showProblemFinish, + BabaStr.VSCODE_DISPOST, + BabaStr.statusBarTime_start, + BabaStr.statusBarTime_stop, + BabaStr.statusBarTime_reset, + ]; + } + handleNotification(_notification: BaseCC.BaseCC.INotification) { + switch (_notification.getName()) { + case BabaStr.every_second: + statusBarTimeService.updateSecond(); + break; + case BabaStr.submit: + statusBarTimeService.checkSubmit(_notification.getBody()); + break; + case BabaStr.showProblemFinish: + statusBarTimeService.showProblemFinish(_notification.getBody()); + break; + case BabaStr.VSCODE_DISPOST: + statusBarTimeService.dispose(); + break; + case BabaStr.statusBarTime_start: + statusBarTimeService.start(); + break; + case BabaStr.statusBarTime_stop: + statusBarTimeService.stop(); + break; + case BabaStr.statusBarTime_reset: + statusBarTimeService.reset(); + break; + default: + break; + } + } +} + export const statusBarTimeService: StatusBarTimeService = new StatusBarTimeService(); diff --git a/src/utils/BaseCC.ts b/src/utils/BaseCC.ts new file mode 100644 index 0000000..fc32171 --- /dev/null +++ b/src/utils/BaseCC.ts @@ -0,0 +1,548 @@ +// https://github.com/PureMVC/puremvc-typescript-multicore-framework + +export namespace BaseCC { + // 开始的头 + export class Facade { + static MULTITON_MSG = "重复创建 Facade"; + static instanceMap = {}; + model; + view; + controller; + facade_init_key; + constructor(key: string) { + this.model = null; + this.view = null; + this.controller = null; + this.facade_init_key = null; + if (Facade.instanceMap[key]) throw Error(Facade.MULTITON_MSG); + this.initializeNotifier(key); + Facade.instanceMap[key] = this; + this.initializeFacade(); + } + initializeFacade() { + this.initializeModel(); + this.initializeController(); + this.initializeView(); + } + initializeModel() { + if (!this.model) { + this.model = Model.getInstance(this.facade_init_key); + } + } + initializeController() { + if (!this.controller) this.controller = Controller.getInstance(this.facade_init_key); + } + initializeView() { + if (!this.view) this.view = View.getInstance(this.facade_init_key); + } + registerCommand(notificationName, commandClassRef) { + this.controller.registerCommand(notificationName, commandClassRef); + } + removeCommand(notificationName) { + this.controller.removeCommand(notificationName); + } + hasCommand(notificationName) { + return this.controller.hasCommand(notificationName); + } + registerProxy(proxy) { + this.model.registerProxy(proxy); + } + retrieveProxy(proxyName) { + return this.model.retrieveProxy(proxyName); + } + removeProxy(proxyName) { + let proxy; + if (this.model) proxy = this.model.removeProxy(proxyName); + return proxy; + } + hasProxy(proxyName) { + return this.model.hasProxy(proxyName); + } + registerMediator(mediator) { + if (this.view) this.view.registerMediator(mediator); + } + retrieveMediator(mediatorName) { + return this.view.retrieveMediator(mediatorName); + } + removeMediator(mediatorName) { + let mediator; + if (this.view) mediator = this.view.removeMediator(mediatorName); + return mediator; + } + hasMediator(mediatorName) { + return this.view.hasMediator(mediatorName); + } + notifyObservers(notification) { + if (this.view) this.view.notifyObservers(notification); + } + sendNotification(name, body?, type?) { + if (typeof body === "undefined") { + body = null; + } + if (typeof type === "undefined") { + type = null; + } + this.notifyObservers(new Notification(name, body, type)); + } + initializeNotifier(key: string) { + this.facade_init_key = key; + } + static getInstance(key: string) { + if (!Facade.instanceMap[key]) Facade.instanceMap[key] = new Facade(key); + return Facade.instanceMap[key]; + } + + static hasCore(key) { + return Facade.instanceMap[key] ? true : false; + } + static removeCore(key) { + if (!Facade.instanceMap[key]) return; + Model.removeModel(key); + View.removeView(key); + Controller.removeController(key); + delete Facade.instanceMap[key]; + } + } + + export class Model implements IModel { + static MULTITON_MSG = "重复创建 Model"; + static instanceMap = {}; + proxyMap; + facade_init_key; + constructor(key) { + this.proxyMap = null; + this.facade_init_key = key; + if (Model.instanceMap[key]) throw Error(Model.MULTITON_MSG); + Model.instanceMap[key] = this; + this.facade_init_key = key; + this.proxyMap = {}; + this.initializeModel(); + } + initializeModel() {} + registerProxy(proxy) { + proxy.initializeNotifier(this.facade_init_key); + this.proxyMap[proxy.getProxyName()] = proxy; + proxy.onRegister(); + } + removeProxy(proxyName) { + let proxy = this.proxyMap[proxyName]; + if (proxy) { + delete this.proxyMap[proxyName]; + proxy.onRemove(); + } + return proxy; + } + retrieveProxy(proxyName) { + return this.proxyMap[proxyName] || null; + } + hasProxy(proxyName) { + return this.proxyMap[proxyName] != null; + } + static getInstance(key) { + if (!Model.instanceMap[key]) Model.instanceMap[key] = new Model(key); + return Model.instanceMap[key]; + } + static removeModel(key) { + delete Model.instanceMap[key]; + } + } + + export class Controller { + static MULTITON_MSG = "重复创建 Controller"; + static instanceMap = {}; + view; + commandMap; + facade_init_key; + constructor(key) { + this.view = null; + this.commandMap = null; + this.facade_init_key = null; + if (Controller.instanceMap[key]) throw Error(Controller.MULTITON_MSG); + Controller.instanceMap[key] = this; + this.facade_init_key = key; + this.commandMap = {}; + this.initializeController(); + } + initializeController() { + this.view = View.getInstance(this.facade_init_key); + } + executeCommand(notification) { + let commandClassRef = this.commandMap[notification.getName()]; + if (commandClassRef) { + let command = new commandClassRef(); + command.initializeNotifier(this.facade_init_key); + command.execute(notification); + } + } + registerCommand(notificationName, commandClassRef) { + if (!this.commandMap[notificationName]) + this.view.registerObserver(notificationName, new Observer(this.executeCommand, this)); + this.commandMap[notificationName] = commandClassRef; + } + hasCommand(notificationName) { + return this.commandMap[notificationName] != null; + } + removeCommand(notificationName) { + if (this.hasCommand(notificationName)) { + this.view.removeObserver(notificationName, this); + delete this.commandMap[notificationName]; + } + } + static getInstance(key) { + if (!Controller.instanceMap[key]) Controller.instanceMap[key] = new Controller(key); + return Controller.instanceMap[key]; + } + static removeController(key) { + delete Controller.instanceMap[key]; + } + } + + export class View { + static instanceMap = {}; + static MULTITON_MSG = "重复创建View"; + mediatorMap; + observerMap; + facade_init_key; + constructor(key) { + this.mediatorMap = null; + this.observerMap = null; + this.facade_init_key = null; + if (View.instanceMap[key]) throw Error(View.MULTITON_MSG); + View.instanceMap[key] = this; + this.facade_init_key = key; + this.mediatorMap = {}; + this.observerMap = {}; + this.initializeView(); + } + initializeView() {} + registerObserver(notificationName, observer) { + let observers = this.observerMap[notificationName]; + if (observers) observers.push(observer); + else this.observerMap[notificationName] = [observer]; + } + removeObserver(notificationName, notifyContext) { + let observers = this.observerMap[notificationName]; + let i = observers.length; + while (i--) { + let observer = observers[i]; + if (observer.compareNotifyContext(notifyContext)) { + observers.splice(i, 1); + break; + } + } + if (observers.length == 0) delete this.observerMap[notificationName]; + } + notifyObservers(notification) { + let notificationName = notification.getName(); + let observersRef = this.observerMap[notificationName]; + if (observersRef) { + let observers = observersRef.slice(0); + let len = observers.length; + for (let i = 0; i < len; i++) { + let observer = observers[i]; + observer.notifyObserver(notification); + } + } + } + registerMediator(mediator) { + let name = mediator.getMediatorName(); + if (this.mediatorMap[name]) return; + mediator.initializeNotifier(this.facade_init_key); + this.mediatorMap[name] = mediator; + let interests = mediator.listNotificationInterests(); + let len = interests.length; + if (len > 0) { + let observer = new Observer(mediator.handleNotification, mediator); + for (let i = 0; i < len; i++) this.registerObserver(interests[i], observer); + } + mediator.onRegister(); + } + retrieveMediator(mediatorName) { + return this.mediatorMap[mediatorName] || null; + } + removeMediator(mediatorName) { + let mediator = this.mediatorMap[mediatorName]; + if (!mediator) return null; + let interests = mediator.listNotificationInterests(); + let i = interests.length; + while (i--) this.removeObserver(interests[i], mediator); + delete this.mediatorMap[mediatorName]; + mediator.onRemove(); + return mediator; + } + hasMediator(mediatorName) { + return this.mediatorMap[mediatorName] != null; + } + static getInstance(key) { + if (!View.instanceMap[key]) View.instanceMap[key] = new View(key); + return View.instanceMap[key]; + } + static removeView(key) { + delete View.instanceMap[key]; + } + } + + export interface ICommand extends INotifier { + execute(notification: INotification): void; + } + + export interface IController { + executeCommand(notification: INotification): void; + registerCommand(notificationName: string, commandClassRef: Function): void; + hasCommand(notificationName: string): boolean; + removeCommand(notificationName: string): void; + } + + export interface IFacade extends INotifier { + registerCommand(notificationName: string, commandClassRef: Function): void; + removeCommand(notificationName: string): void; + hasCommand(notificationName: string): boolean; + registerProxy(proxy: IProxy): void; + retrieveProxy(proxyName: string): IProxy; + removeProxy(proxyName: string): IProxy; + hasProxy(proxyName: string): boolean; + registerMediator(mediator: IMediator): void; + retrieveMediator(mediatorName: string): IMediator; + removeMediator(mediatorName: string): IMediator; + hasMediator(mediatorName: string): boolean; + notifyObservers(notification: INotification): void; + } + + export interface IMediator extends INotifier { + getMediatorName(): string; + getViewComponent(): any; + setViewComponent(viewComponent: any): void; + listNotificationInterests(): string[]; + handleNotification(notification: INotification): void; + onRegister(): void; + onRemove(): void; + } + + export interface IModel { + registerProxy(proxy: IProxy): void; + removeProxy(proxyName: string): IProxy; + retrieveProxy(proxyName: string): IProxy; + hasProxy(proxyName: string): boolean; + } + + export interface INotification { + getName(): string; + setBody(body: any): void; + getBody(): any; + setType(type: string): void; + getType(): string; + toString(): string; + } + + export interface INotifier { + sendNotification(name: string, body?: any, type?: string): void; + initializeNotifier(key: string): void; + } + + export interface IObserver { + setNotifyMethod(notifyMethod: Function): void; + setNotifyContext(notifyContext: any): void; + notifyObserver(notification: INotification): void; + compareNotifyContext(object: any): boolean; + } + + export interface IProxy extends INotifier { + getProxyName(): string; + setData(data: any): void; + getData(): any; + onRegister(): void; + onRemove(): void; + } + + export interface IView { + registerObserver(notificationName: string, observer: IObserver): void; + removeObserver(notificationName: string, notifyContext: any): void; + notifyObservers(notification: INotification): void; + registerMediator(mediator: IMediator): void; + retrieveMediator(mediatorName: string): IMediator; + removeMediator(mediatorName: string): IMediator; + hasMediator(mediatorName: string): boolean; + } + + export class Observer { + notify; + context; + constructor(notifyMethod, notifyContext) { + this.notify = null; + this.context = null; + this.setNotifyMethod(notifyMethod); + this.setNotifyContext(notifyContext); + } + getNotifyMethod() { + return this.notify; + } + setNotifyMethod(notifyMethod) { + this.notify = notifyMethod; + } + getNotifyContext() { + return this.context; + } + setNotifyContext(notifyContext) { + this.context = notifyContext; + } + notifyObserver(notification) { + this.getNotifyMethod().call(this.getNotifyContext(), notification); + } + compareNotifyContext(object) { + return object === this.context; + } + } + + export class Notification { + name; + body; + type; + constructor(name, body, type) { + if (typeof body === "undefined") { + body = null; + } + if (typeof type === "undefined") { + type = null; + } + this.name = name; + this.body = body; + this.type = type; + } + getName() { + return this.name; + } + setBody(body) { + this.body = body; + } + getBody() { + return this.body; + } + setType(type) { + this.type = type; + } + getType() { + return this.type; + } + toString() { + let msg = "Notification Name: " + this.getName(); + msg += "\nBody:" + (this.getBody() == null ? "null" : this.getBody().toString()); + msg += "\nType:" + (this.getType() == null ? "null" : this.getType()); + return msg; + } + } + + export class Notifier { + static MULTITON_MSG = "facade_init_key for this Notifier not yet initialized!"; + facade_init_key; + constructor() { + this.facade_init_key = null; + } + initializeNotifier(key) { + this.facade_init_key = key; + } + sendNotification(name, body?, type?) { + if (typeof body === "undefined") { + body = null; + } + if (typeof type === "undefined") { + type = null; + } + if (this.facade()) this.facade().sendNotification(name, body, type); + } + facade() { + if (this.facade_init_key === null) throw Error(Notifier.MULTITON_MSG); + return Facade.getInstance(this.facade_init_key); + } + } + + export class MacroCommand extends Notifier implements ICommand, INotifier { + subCommands: Function[]; + constructor() { + super(); + this.subCommands = []; + this.initializeMacroCommand(); + } + initializeMacroCommand() {} + addSubCommand(commandClassRef) { + this.subCommands.push(commandClassRef); + } + execute(notification) { + let subCommands = this.subCommands.slice(0); + let len = this.subCommands.length; + for (let i = 0; i < len; i++) { + let commandClassRef = subCommands[i]; + let commandInstance = new (commandClassRef as any)(); + commandInstance.initializeNotifier(this.facade_init_key); + commandInstance.execute(notification); + } + this.subCommands.splice(0); + } + } + + export class SimpleCommand extends Notifier implements ICommand, INotifier { + constructor() { + super(); + } + execute(_notification) {} + } + + export class Mediator extends Notifier implements IMediator, INotifier { + static NAME = "Mediator"; + mediatorName; + viewComponent; + constructor(mediatorName, viewComponent?) { + super(); + if (typeof mediatorName === "undefined") { + mediatorName = null; + } + if (typeof viewComponent === "undefined") { + viewComponent = null; + } + this.mediatorName = mediatorName != null ? mediatorName : Mediator.NAME; + this.viewComponent = viewComponent; + } + getMediatorName() { + return this.mediatorName; + } + getViewComponent() { + return this.viewComponent; + } + setViewComponent(viewComponent) { + this.viewComponent = viewComponent; + } + listNotificationInterests(): string[] { + return []; + } + handleNotification(_notification: INotification) {} + onRegister() {} + onRemove() {} + } + + export class Proxy extends Notifier implements IProxy, INotifier { + static NAME = "Proxy"; + proxyName; + data; + constructor(proxyName, data?) { + super(); + if (typeof proxyName === "undefined") { + proxyName = null; + } + if (typeof data === "undefined") { + data = null; + } + this.proxyName = proxyName != null ? proxyName : Proxy.NAME; + if (data != null) this.setData(data); + } + getProxyName() { + return this.proxyName; + } + setData(data) { + this.data = data; + } + getData() { + return this.data; + } + onRegister() {} + onRemove() {} + } +} diff --git a/src/utils/ConfigUtils.ts b/src/utils/ConfigUtils.ts index 6b25b3d..2330a63 100644 --- a/src/utils/ConfigUtils.ts +++ b/src/utils/ConfigUtils.ts @@ -402,9 +402,34 @@ export function isAnswerDiffColor(): boolean { return getVsCodeConfig().get("answerDiffColor", false); } +const singleLineFlag = { + bash: "#", + c: "//", + cpp: "//", + csharp: "//", + golang: "//", + java: "//", + javascript: "//", + kotlin: "//", + mysql: "--", + php: "//", + python: "#", + python3: "#", + ruby: "#", + rust: "//", + scala: "//", + swift: "//", + typescript: "//", +}; + +export function includeTemplatesAuto() { + return getVsCodeConfig().get("includeTemplatesAuto", true); +} + export function getIncludeTemplate(lang: string): string { let temp_cfg = getVsCodeConfig().get("includeTemplates") || []; let result = ""; + let singleLine = singleLineFlag[lang] || ""; temp_cfg.forEach((element) => { if (element.language == lang) { result = (element.template || []).join("\n"); @@ -412,7 +437,14 @@ export function getIncludeTemplate(lang: string): string { } }); - return result; + let new_include_template: any = [ + `\n`, + `${singleLine} @lcpr-template-start`, + `${result}`, + `${singleLine} @lcpr-template-end`, + ]; + + return new_include_template.join("\n"); } // 获取清除缓存修改时间间隔