diff --git a/src/commands.ts b/src/commands.ts index 9de033d..5297513 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -2,7 +2,7 @@ import * as vscode from "vscode"; import { getDependencyTreeData } from "./data-dependencyTree/data-dependencyTree"; import { StatusCallBack } from "./data-dependencyTree/getDataStatusCallBack"; import { createView } from "./web-dependencyTree/openWebView"; -import { postMessage } from "./utils/message/messagePoster"; +import { messagePoster } from "./utils/message/messagePoster"; import { reOpenWebView } from "./web-dependencyTree/openWebView"; import { renderTreeView } from "./view-dependencyTree/renderTreeView"; import { @@ -36,7 +36,7 @@ const refreshFile = async (): Promise => { let refresh = true; if (global.webViewPanel) { postedMessage = true; - postMessage({ + messagePoster.newMsg({ key: MESSAGE_UPDATE_WEBVIEW, value: stringRandom(), }); @@ -53,7 +53,7 @@ const refreshFile = async (): Promise => { global.dependencyTreeData = data; renderTreeView(global.dependencyTreeData.dependencyTreeData); if (global.webViewPanel) { - postMessage({ + messagePoster.newMsg({ key: MESSAGE_DEPENDENCY_TREE_DATA, value: { data: data.transportsData, @@ -71,7 +71,7 @@ const saveData = () => { if (global?.dependencyTreeData?.transportsData) { setData(global.dependencyTreeData.transportsData); if (global.webViewPanel) { - msgGetSavedData.post(); + msgGetSavedData(); } } else { //TODO no data error @@ -81,7 +81,7 @@ const saveData = () => { export const command_focusOnNode = vscode.commands.registerCommand( "dependencygraph.focusOnNode", (fileName, fileData) => { - postMessage({ + messagePoster.newMsg({ key: MESSAGE_FOCUS_ON_NODE, value: { fileName, fileData }, }); diff --git a/src/data-dependencyTree/getDataStatusCallBack.ts b/src/data-dependencyTree/getDataStatusCallBack.ts index cf67409..10138cb 100644 --- a/src/data-dependencyTree/getDataStatusCallBack.ts +++ b/src/data-dependencyTree/getDataStatusCallBack.ts @@ -51,7 +51,7 @@ export class StatusCallBack { // this.postMessage ? await msgGetSavedData.post() : null; } async checkGetDataFromFileSuccess() { - this.postMessage ? await msgGetSavedData.post() : null; + this.postMessage ? msgGetSavedData() : null; } async checkGetDataFromAnalyserError() { onError(NO_DEPENDENCY); diff --git a/src/processMessage.ts b/src/processMessage.ts index 4810f99..70d4de3 100644 --- a/src/processMessage.ts +++ b/src/processMessage.ts @@ -37,9 +37,9 @@ const actionSetSetting = async function (msg: Msg) { // msgRunCommandStatus("waiting", msg.value.key, true).post(); try { await setSetting(msg.value.key, msg.value.value); - msgRunCommandStatus("setting", msg.value.key, true).post(); + msgRunCommandStatus("setting", msg.value.key, true) } catch (e) { - msgRunCommandStatus("setting", msg.value.key, false).post(); + msgRunCommandStatus("setting", msg.value.key, false); onError(NO_FOLDER, e); } if (msg.value.key === SETTING_KEY_ENTRY_FILE_PATH) { @@ -51,9 +51,9 @@ const actionExportSvg = async function (msg: Msg) { // msgRunCommandStatus("waiting", msg.key, true).post(); try { await exportSvg(msg.value); - msgRunCommandStatus("command", msg.key, true).post(); + msgRunCommandStatus("command", msg.key, true) } catch (e) { - msgRunCommandStatus("command", msg.key, false).post(); + msgRunCommandStatus("command", msg.key, false) } }; const actionExportPng = async function (msg: Msg) { @@ -61,9 +61,9 @@ const actionExportPng = async function (msg: Msg) { // msgRunCommandStatus("waiting", msg.key, true).post(); try { await exportPng(msg.value); - msgRunCommandStatus("command", msg.key, true).post(); + msgRunCommandStatus("command", msg.key, true) } catch (e) { - msgRunCommandStatus("command", msg.key, false).post(); + msgRunCommandStatus("command", msg.key, false) } }; const actionSaveData = async function (msg: Msg) { @@ -71,9 +71,9 @@ const actionSaveData = async function (msg: Msg) { // msgRunCommandStatus("waiting", msg.key, true).post(); try { await vscode.commands.executeCommand("dependencygraph.saveData"); - msgRunCommandStatus("command", msg.key, true).post(); + msgRunCommandStatus("command", msg.key, true) } catch (e) { - msgRunCommandStatus("command", msg.key, false).post(); + msgRunCommandStatus("command", msg.key, false) } }; const actionUpDateData = async function (msg: Msg) { @@ -81,23 +81,30 @@ const actionUpDateData = async function (msg: Msg) { // msgRunCommandStatus("waiting", msg.key, true).post(); try { await vscode.commands.executeCommand("dependencygraph.upDateData"); - msgRunCommandStatus("command", msg.key, true).post(); + msgRunCommandStatus("command", msg.key, true) } catch (e) { - msgRunCommandStatus("command", msg.key, false).post(); + msgRunCommandStatus("command", msg.key, false) } }; const actionLogToLocal = function (msg: Msg) { switch (msg.value) { case 'debug': { - logger.debug(msg.description) + logger.debug({'WEBVIEW_LOG': msg.description }) return } case 'info': { - logger.info(msg.description) + logger.info({'WEBVIEW_LOG': msg.description }) + return + } + case 'error': { + logger.error({'WEBVIEW_LOG': msg.description }) return } } } +const actionWebViewReady = function () { + global.webViewReady = true +} const messageCase = () => { return new Map([ [MESSAGES.MESSAGE_OPEN_FILE_FROM_WEBVIEW, actionOpenFile], @@ -107,7 +114,8 @@ const messageCase = () => { [MESSAGES.MESSAGE_UPDATE_DATA, actionUpDateData], [MESSAGES.MESSAGE_EXPORT_SVG, actionExportSvg], [MESSAGES.MESSAGE_EXPORT_PNG, actionExportPng], - [MESSAGES.MESSAGE_WEBVIEW_LOG, actionLogToLocal] + [MESSAGES.MESSAGE_WEBVIEW_LOG, actionLogToLocal], + [MESSAGES.MESSAGE_WEBVIEW_READY, actionWebViewReady] ]); }; diff --git a/src/utils/message/messagePoster.ts b/src/utils/message/messagePoster.ts index 78c5549..f388693 100644 --- a/src/utils/message/messagePoster.ts +++ b/src/utils/message/messagePoster.ts @@ -9,45 +9,52 @@ const waitTime = function (waitTime: number) { setTimeout(resolve, waitTime || 0); }) } -const messagesQueue = [] as Msg[]; -export const postMessage = async function (msg: Msg) { - if (global.webViewPanel) { - messagesQueue.push(msg) - await waitTime(500) - while (messagesQueue.length) { - let ms = messagesQueue.pop(); - // postMessage is not real async just wait more 500ms - logger.debug({ - "POST-MESSAGE-TO-WEBVIEW-KEY": ms.key, - "POST-MESSAGE-TO-WEBVIEW-VALUE": ms.value - }) - const postMessageStatus = await global.webViewPanel.webview.postMessage(ms); - await waitTime(500) - if (!postMessageStatus) { - onError(NO_WEBVIEW_PANEL); - } - } - } else { - onError(NO_WEBVIEW_PANEL); +class MessagePoster { + messagesQueue: Msg[]; + status: 'posting' | 'emptyMessagesQueue' | 'waitingWebViewPanel' | 'waitingWebViewReady'; + constructor() { + this.messagesQueue = []; } -}; -export class MessagePoster { - msg: { - key: MsgKey; - value: any; - description: string | undefined; - }; - constructor(key: MsgKey, value: any, description?: string) { - this.msg = { - key: key, - value: value, - description: description, - }; + newMsg(msg: Msg) { + this.messagesQueue.push(msg); + this.startPost(); } - async post() { - await postMessage(this.msg); + clearMessagesQueue() { + this.messagesQueue = []; + } + async startPost() { + if (this.status !== 'posting') { + this.status = 'posting'; + while (this.messagesQueue.length) { + if (global.webViewPanel) { + if (global.webViewReady) { + let ms = this.messagesQueue.pop(); + logger.debug({ + "POST-MESSAGE-TO-WEBVIEW-KEY": ms.key, + "POST-MESSAGE-TO-WEBVIEW-VALUE": ms.value + }) + const postMessageStatus = await global.webViewPanel.webview.postMessage(ms); + if (!postMessageStatus) { + logger.error("NO_WEBVIEW_PANEL") + onError(NO_WEBVIEW_PANEL); + } + } else { + logger.debug("webView is not ready") + await waitTime(500) + this.status = 'waitingWebViewReady'; + } + } + else { + logger.error("webview panel is not ready") + this.status = 'waitingWebViewPanel'; + break; + } + } + this.status = 'emptyMessagesQueue'; + } } } +export const messagePoster = new MessagePoster(); export class StatusMessagePoster { msg: { key: MsgKey; @@ -69,10 +76,10 @@ export class StatusMessagePoster { } async postSuccess() { this.msg.value.status = "success"; - await postMessage(this.msg); + messagePoster.newMsg(this.msg); } async postError() { this.msg.value.status = "error"; - await postMessage(this.msg); + messagePoster.newMsg(this.msg); } } diff --git a/src/utils/message/messages.ts b/src/utils/message/messages.ts index 6f6cae7..4683f79 100644 --- a/src/utils/message/messages.ts +++ b/src/utils/message/messages.ts @@ -1,8 +1,6 @@ -import { MessagePoster, StatusMessagePoster } from "./messagePoster"; -import { getActiveTheme } from "../fileSystem/setting/setting"; +import { messagePoster, StatusMessagePoster } from "./messagePoster"; import * as STATUS from "../../data-dependencyTree/statusType"; import * as MSG from "./messagesKeys"; -import * as vscode from "vscode"; export const statusMsgGetFolderPath = new StatusMessagePoster( STATUS.STATUS_GET_DEPENDENCY_DATA_GET_FOLDER ); @@ -19,24 +17,19 @@ export const statusMsgGetDependencyProcessData = new StatusMessagePoster( STATUS.STATUS_GET_DEPENDENCY_DATA_PROCESS_DATA ); -export const msgGetLanguage = new MessagePoster( - MSG.MESSAGE_GET_LANGUAGE, - vscode.env.language -); -export const msgGetActiveThemeKind = new MessagePoster( - MSG.MESSAGE_GET_ACTIVE_THEME_KIND, - getActiveTheme() -); -export const msgRunCommandStatus = ( +export const msgRunCommandStatus = function ( type: "setting" | "command" | "waiting", key: string, value: boolean -) => new MessagePoster(MSG.MESSAGE_RUN_COMMAND_STATUS, { type, key, value }); -export const msgGetSavedData = new MessagePoster( - MSG.MESSAGE_IS_SAVED_DATA, - true -); +) { + messagePoster.newMsg({ key: MSG.MESSAGE_RUN_COMMAND_STATUS, value: { type, key, value } }) +} +export const msgGetSavedData = function () { + messagePoster.newMsg({ + key: MSG.MESSAGE_IS_SAVED_DATA, + value: true + }); +} export const postSetting = function (setting: object) { - const poster = new MessagePoster(MSG.MESSAGE_GET_ENTRY_FILE, setting); - poster.post(); + messagePoster.newMsg({ key: MSG.MESSAGE_GET_ENTRY_FILE, value: setting }); }; diff --git a/src/utils/message/messagesKeys.ts b/src/utils/message/messagesKeys.ts index c36c511..3209979 100644 --- a/src/utils/message/messagesKeys.ts +++ b/src/utils/message/messagesKeys.ts @@ -24,3 +24,4 @@ export const MESSAGE_EXPORT_SVG = "MESSAGE_EXPORT_SVG" as MsgKey; export const MESSAGE_EXPORT_PNG = "MESSAGE_EXPORT_PNG" as MsgKey; export const MESSAGE_RUN_COMMAND_STATUS = "MESSAGE_RUN_COMMAND_STATUS" as MsgKey; export const MESSAGE_WEBVIEW_LOG = "MESSAGE_WEBVIEW_LOG" as MsgKey; +export const MESSAGE_WEBVIEW_READY = "MESSAGE_WEBVIEW_READY" as MsgKey; diff --git a/src/web-dependencyTree/openWebView.ts b/src/web-dependencyTree/openWebView.ts index 4ff7d22..ae761c1 100644 --- a/src/web-dependencyTree/openWebView.ts +++ b/src/web-dependencyTree/openWebView.ts @@ -7,23 +7,23 @@ import * as path from "path"; import * as fs from "fs"; import { webViewHTMLPath } from "../paths"; import { getBaseWebViewUri } from "../utils/getWebViewUri"; -import { postMessage } from "../utils/message/messagePoster"; +import { messagePoster } from "../utils/message/messagePoster"; import { MESSAGE_ASSETS_BASE_URL, MESSAGE_DEPENDENCY_TREE_DATA, MESSAGE_FOLDER_PATH, + MESSAGE_GET_LANGUAGE, + MESSAGE_GET_ACTIVE_THEME_KIND } from "../utils/message/messagesKeys"; import { DependencyTreeData } from "../data-dependencyTree/dependencyTreeData"; import { createWebviewPanel } from "../initExtension"; import { getCurrentFolderPath } from "../utils/getCurrentFolderPath"; -import { getAllSettingFromSettingFile } from "../utils/fileSystem/setting/setting"; +import { getAllSettingFromSettingFile, getActiveTheme } from "../utils/fileSystem/setting/setting"; import { SETTING_KEY_ENTRY_FILE_PATH } from "../utils/fileSystem/settingKey"; import { statusMsgGetFolderPath, statusMsgGetEntryFile, statusMsgGetDependencyData, - msgGetLanguage, - msgGetActiveThemeKind, postSetting, msgGetSavedData, } from "../utils/message/messages"; @@ -32,6 +32,7 @@ import { isPathExists } from "../utils/utils"; import { onError } from "../utils/error/onError"; import { GET_DEPENDENCY_TREE_FAIL, NO_WEBVIEW_PANEL } from "../utils/error/errorKey"; import { isSavedData } from "../utils/fileSystem/data"; +import { logger } from "../utils/logger"; /** * 从某个HTML文件读取能被Webview加载的HTML内容 @@ -86,12 +87,18 @@ export const createView = function (): void { */ export const postNecessaryMessageWhenCreateView = function (): void { // post language - msgGetLanguage.post(); + messagePoster.newMsg({ + key: MESSAGE_GET_LANGUAGE, + value: vscode.env.language, + }); const folderPath = getCurrentFolderPath(); - postMessage({ key: MESSAGE_FOLDER_PATH, value: folderPath }); - msgGetActiveThemeKind.post(); + messagePoster.newMsg({ key: MESSAGE_FOLDER_PATH, value: folderPath }); + messagePoster.newMsg({ + key: MESSAGE_GET_ACTIVE_THEME_KIND, + value: getActiveTheme() + }) const baseWebViewUri = getBaseWebViewUri() - postMessage({ + messagePoster.newMsg({ key: MESSAGE_ASSETS_BASE_URL, value: baseWebViewUri, }); @@ -103,6 +110,8 @@ export const reOpenWebView = function ( const columnToShowIn = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined; + logger.info("reopen webView"); + messagePoster.clearMessagesQueue(); if (global.webViewPanel) { // 如果我们已经有了一个面板,那就把它显示到目标列布局中 global.webViewPanel.reveal(columnToShowIn); @@ -118,7 +127,7 @@ export const reOpenWebView = function ( statusMsgGetFolderPath.postError(); } if (isSavedData()) { - msgGetSavedData.post(); + msgGetSavedData; } if ( entryFilePath && @@ -134,6 +143,7 @@ export const reOpenWebView = function ( export const openWebView = function ( dependencyTreeData: DependencyTreeData | undefined ) { + logger.info("open webView"); const folderPath = getCurrentFolderPath(); if (!dependencyTreeData || !Object.keys(dependencyTreeData).length) { onError(GET_DEPENDENCY_TREE_FAIL); @@ -142,7 +152,7 @@ export const openWebView = function ( } const setting = getAllSettingFromSettingFile(); postSetting(setting); - postMessage({ + messagePoster.newMsg({ key: MESSAGE_DEPENDENCY_TREE_DATA, value: { data: global.dependencyTreeData?.transportsData, diff --git a/src/webView/src/index.js b/src/webView/src/index.js index 8938612..9eaffb9 100644 --- a/src/webView/src/index.js +++ b/src/webView/src/index.js @@ -3,7 +3,7 @@ import ReactDOM from "react-dom"; import { App } from "./app"; import { processMessage } from "./processMessage"; - +import { msgWebViewReady, msgWebViewLog } from "./utils/messages.js"; import "./index.css"; const removeLoading = function () { @@ -21,4 +21,6 @@ window.addEventListener("message", (event) => { }); const root = window.document.getElementById("root"); ReactDOM.render(, root); +msgWebViewReady.post(); +msgWebViewLog("info", "web view ready") removeLoading(); diff --git a/typings/module.d.ts b/typings/module.d.ts index fd172ff..2651baa 100644 --- a/typings/module.d.ts +++ b/typings/module.d.ts @@ -14,15 +14,16 @@ declare global { namespace NodeJS { interface Global { webViewPanel: vscode.WebviewPanel | undefined; + webViewReady: boolean | undefined; dependencyTreeData: - | { - dependencyTreeData: DependencyTreeData; - transportsData: { - dependencyTree: DependencyTree; - dependencyNodes: DependencyNodes; - }; - } - | undefined; + | { + dependencyTreeData: DependencyTreeData; + transportsData: { + dependencyTree: DependencyTree; + dependencyNodes: DependencyNodes; + }; + } + | undefined; } } }