🐛 Fixed markdown preview issue
This commit is contained in:
@@ -4,6 +4,7 @@ import {EditorView} from '@codemirror/view';
|
|||||||
import {EditorState, Extension} from '@codemirror/state';
|
import {EditorState, Extension} from '@codemirror/state';
|
||||||
import {useConfigStore} from './configStore';
|
import {useConfigStore} from './configStore';
|
||||||
import {useDocumentStore} from './documentStore';
|
import {useDocumentStore} from './documentStore';
|
||||||
|
import {usePanelStore} from './panelStore';
|
||||||
import {ExtensionID} from '@/../bindings/voidraft/internal/models/models';
|
import {ExtensionID} from '@/../bindings/voidraft/internal/models/models';
|
||||||
import {DocumentService, ExtensionService} from '@/../bindings/voidraft/internal/services';
|
import {DocumentService, ExtensionService} from '@/../bindings/voidraft/internal/services';
|
||||||
import {ensureSyntaxTree} from "@codemirror/language";
|
import {ensureSyntaxTree} from "@codemirror/language";
|
||||||
@@ -686,6 +687,10 @@ export const useEditorStore = defineStore('editor', () => {
|
|||||||
instance.view.destroy();
|
instance.view.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 清理 panelStore 状态(导航离开编辑器页面时)
|
||||||
|
const panelStore = usePanelStore();
|
||||||
|
panelStore.reset();
|
||||||
|
|
||||||
currentEditor.value = null;
|
currentEditor.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ import MarkdownIt from 'markdown-it';
|
|||||||
import * as runtime from "@wailsio/runtime";
|
import * as runtime from "@wailsio/runtime";
|
||||||
import {previewPanelState} from "./state";
|
import {previewPanelState} from "./state";
|
||||||
import {createMarkdownRenderer} from "./markdownRenderer";
|
import {createMarkdownRenderer} from "./markdownRenderer";
|
||||||
import {updateMermaidTheme} from "@/common/markdown-it/plugins/markdown-it-mermaid";
|
|
||||||
import {useThemeStore} from "@/stores/themeStore";
|
|
||||||
import {watch} from "vue";
|
|
||||||
import {createDebounce} from "@/common/utils/debounce";
|
import {createDebounce} from "@/common/utils/debounce";
|
||||||
import {morphHTML} from "@/common/utils/domDiff";
|
import {morphHTML} from "@/common/utils/domDiff";
|
||||||
|
|
||||||
@@ -21,9 +18,8 @@ export class MarkdownPreviewPanel {
|
|||||||
private readonly resizeHandle: HTMLDivElement;
|
private readonly resizeHandle: HTMLDivElement;
|
||||||
private readonly content: HTMLDivElement;
|
private readonly content: HTMLDivElement;
|
||||||
private view: EditorView;
|
private view: EditorView;
|
||||||
private themeUnwatch?: () => void;
|
|
||||||
private lastRenderedContent: string = "";
|
private lastRenderedContent: string = "";
|
||||||
private debouncedUpdate: ReturnType<typeof createDebounce>;
|
private readonly debouncedUpdate: ReturnType<typeof createDebounce>;
|
||||||
private isDestroyed: boolean = false; // 标记面板是否已销毁
|
private isDestroyed: boolean = false; // 标记面板是否已销毁
|
||||||
|
|
||||||
constructor(view: EditorView) {
|
constructor(view: EditorView) {
|
||||||
@@ -33,16 +29,7 @@ export class MarkdownPreviewPanel {
|
|||||||
// 创建防抖更新函数
|
// 创建防抖更新函数
|
||||||
this.debouncedUpdate = createDebounce(() => {
|
this.debouncedUpdate = createDebounce(() => {
|
||||||
this.updateContentInternal();
|
this.updateContentInternal();
|
||||||
}, { delay: 1000 });
|
}, { delay: 500 });
|
||||||
|
|
||||||
// 监听主题变化
|
|
||||||
const themeStore = useThemeStore();
|
|
||||||
this.themeUnwatch = watch(() => themeStore.isDarkMode, (isDark) => {
|
|
||||||
const newTheme = isDark ? "dark" : "default";
|
|
||||||
updateMermaidTheme(newTheme);
|
|
||||||
this.lastRenderedContent = ""; // 清空缓存,强制重新渲染
|
|
||||||
this.updateContentInternal();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 创建 DOM 结构
|
// 创建 DOM 结构
|
||||||
this.dom = document.createElement("div");
|
this.dom = document.createElement("div");
|
||||||
@@ -340,12 +327,6 @@ export class MarkdownPreviewPanel {
|
|||||||
this.debouncedUpdate.cancel();
|
this.debouncedUpdate.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理主题监听
|
|
||||||
if (this.themeUnwatch) {
|
|
||||||
this.themeUnwatch();
|
|
||||||
this.themeUnwatch = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空缓存
|
// 清空缓存
|
||||||
this.lastRenderedContent = "";
|
this.lastRenderedContent = "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package constant
|
|||||||
// VOIDRAFT_MAIN_WINDOW_NAME is the name of the main window of the Voidcraft client.
|
// VOIDRAFT_MAIN_WINDOW_NAME is the name of the main window of the Voidcraft client.
|
||||||
const VOIDRAFT_MAIN_WINDOW_NAME = "voidraft-main-window"
|
const VOIDRAFT_MAIN_WINDOW_NAME = "voidraft-main-window"
|
||||||
|
|
||||||
const VOIDRAFT_WINDOW_TITLE = "voidraft"
|
const VOIDRAFT_APP_NAME = "voidraft"
|
||||||
|
const VOIDRAFT_APP_DESCRIPTION = "An elegant text snippet recording tool designed for developers."
|
||||||
|
|
||||||
const VOIDRAFT_WINDOW_WIDTH = 700
|
const VOIDRAFT_WINDOW_WIDTH = 700
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func (wh *WindowHelper) FocusMainWindow() bool {
|
|||||||
func (wh *WindowHelper) AutoShowMainWindow() {
|
func (wh *WindowHelper) AutoShowMainWindow() {
|
||||||
window := wh.MustGetMainWindow()
|
window := wh.MustGetMainWindow()
|
||||||
if window.IsVisible() {
|
if window.IsVisible() {
|
||||||
window.Hide()
|
window.Focus()
|
||||||
} else {
|
} else {
|
||||||
window.Show()
|
window.Show()
|
||||||
}
|
}
|
||||||
|
|||||||
8
main.go
8
main.go
@@ -39,8 +39,8 @@ func main() {
|
|||||||
// 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances.
|
// 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances.
|
||||||
// 'Mac' options tailor the application when running an macOS.
|
// 'Mac' options tailor the application when running an macOS.
|
||||||
app := application.New(application.Options{
|
app := application.New(application.Options{
|
||||||
Name: "voidraft",
|
Name: constant.VOIDRAFT_APP_NAME,
|
||||||
Description: "voidraft",
|
Description: constant.VOIDRAFT_APP_DESCRIPTION,
|
||||||
Services: serviceManager.GetServices(),
|
Services: serviceManager.GetServices(),
|
||||||
Assets: application.AssetOptions{
|
Assets: application.AssetOptions{
|
||||||
Handler: application.AssetFileServerFS(assets),
|
Handler: application.AssetFileServerFS(assets),
|
||||||
@@ -50,7 +50,7 @@ func main() {
|
|||||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||||
},
|
},
|
||||||
SingleInstance: &application.SingleInstanceOptions{
|
SingleInstance: &application.SingleInstanceOptions{
|
||||||
UniqueID: "com.voidraft",
|
UniqueID: constant.VOIDRAFT_APP_NAME,
|
||||||
EncryptionKey: encryptionKey,
|
EncryptionKey: encryptionKey,
|
||||||
OnSecondInstanceLaunch: func(data application.SecondInstanceData) {
|
OnSecondInstanceLaunch: func(data application.SecondInstanceData) {
|
||||||
if window != nil {
|
if window != nil {
|
||||||
@@ -71,7 +71,7 @@ func main() {
|
|||||||
// 'URL' is the URL that will be loaded into the webview.
|
// 'URL' is the URL that will be loaded into the webview.
|
||||||
mainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
mainWindow := app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||||
Name: constant.VOIDRAFT_MAIN_WINDOW_NAME,
|
Name: constant.VOIDRAFT_MAIN_WINDOW_NAME,
|
||||||
Title: constant.VOIDRAFT_WINDOW_TITLE,
|
Title: constant.VOIDRAFT_APP_NAME,
|
||||||
Width: constant.VOIDRAFT_WINDOW_WIDTH,
|
Width: constant.VOIDRAFT_WINDOW_WIDTH,
|
||||||
Height: constant.VOIDRAFT_WINDOW_HEIGHT,
|
Height: constant.VOIDRAFT_WINDOW_HEIGHT,
|
||||||
Hidden: false,
|
Hidden: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user