diff --git a/frontend/src/components/loading/LoadingScreen.vue b/frontend/src/components/loading/LoadingScreen.vue
index fec414f..cb82dfc 100644
--- a/frontend/src/components/loading/LoadingScreen.vue
+++ b/frontend/src/components/loading/LoadingScreen.vue
@@ -142,7 +142,7 @@ onBeforeUnmount(() => {
display: flex;
align-items: center;
justify-content: center;
- font-family: var(--voidraft-font-mono, SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace);
+ font-family: var(--voidraft-font-mono),serif;
}
.loading-word {
diff --git a/frontend/src/stores/editorStore.ts b/frontend/src/stores/editorStore.ts
index a7b8b93..b98fcb6 100644
--- a/frontend/src/stores/editorStore.ts
+++ b/frontend/src/stores/editorStore.ts
@@ -30,7 +30,7 @@ import {generateContentHash} from "@/common/utils/hashUtils";
import {createTimerManager, type TimerManager} from '@/common/utils/timerUtils';
import {EDITOR_CONFIG} from '@/common/constant/editor';
import {createHttpClientExtension} from "@/views/editor/extensions/httpclient";
-import {markdownPreviewExtension} from "@/views/editor/extensions/markdownPreview";
+import {markdownPreviewExtension, updateMarkdownPreviewTheme} from "@/views/editor/extensions/markdownPreview";
import {createDebounce} from '@/common/utils/debounce';
export interface DocumentStats {
@@ -642,6 +642,13 @@ export const useEditorStore = defineStore('editor', () => {
});
};
+ // 应用 Markdown 预览主题
+ const applyPreviewThemeSettings = () => {
+ editorCache.values().forEach(instance => {
+ updateMarkdownPreviewTheme(instance.view);
+ });
+ };
+
// 应用Tab设置
const applyTabSettings = () => {
editorCache.values().forEach(instance => {
@@ -783,6 +790,7 @@ export const useEditorStore = defineStore('editor', () => {
// 配置更新方法
applyFontSettings,
applyThemeSettings,
+ applyPreviewThemeSettings,
applyTabSettings,
applyKeymapSettings,
diff --git a/frontend/src/stores/themeStore.ts b/frontend/src/stores/themeStore.ts
index 55787ef..31e57da 100644
--- a/frontend/src/stores/themeStore.ts
+++ b/frontend/src/stores/themeStore.ts
@@ -141,6 +141,7 @@ export const useThemeStore = defineStore('theme', () => {
const editorStore = useEditorStore();
editorStore?.applyThemeSettings();
+ editorStore?.applyPreviewThemeSettings();
};
return {
diff --git a/frontend/src/views/editor/Editor.vue b/frontend/src/views/editor/Editor.vue
index 6213e06..8cc94e2 100644
--- a/frontend/src/views/editor/Editor.vue
+++ b/frontend/src/views/editor/Editor.vue
@@ -35,17 +35,16 @@ onMounted(async () => {
// onBeforeUnmount(() => {
// editorStore.clearAllEditors();
-//
// });
diff --git a/frontend/src/views/editor/extensions/markdownPreview/index.ts b/frontend/src/views/editor/extensions/markdownPreview/index.ts
index 1b51a50..a927001 100644
--- a/frontend/src/views/editor/extensions/markdownPreview/index.ts
+++ b/frontend/src/views/editor/extensions/markdownPreview/index.ts
@@ -2,6 +2,7 @@
* Markdown 预览扩展主入口
*/
import { EditorView } from "@codemirror/view";
+import { Compartment } from "@codemirror/state";
import { useThemeStore } from "@/stores/themeStore";
import { usePanelStore } from "@/stores/panelStore";
import { useDocumentStore } from "@/stores/documentStore";
@@ -52,11 +53,30 @@ export function toggleMarkdownPreview(view: EditorView): boolean {
/**
* 导出 Markdown 预览扩展
*/
-export function markdownPreviewExtension() {
+const previewThemeCompartment = new Compartment();
+
+const buildPreviewTheme = () => {
const themeStore = useThemeStore();
const colors = themeStore.currentColors;
-
- const theme = colors ? createMarkdownPreviewTheme(colors) : EditorView.baseTheme({});
-
- return [previewPanelState, previewPanelPlugin, theme];
+ return colors ? createMarkdownPreviewTheme(colors) : EditorView.baseTheme({});
+};
+
+export function markdownPreviewExtension() {
+ return [
+ previewPanelState,
+ previewPanelPlugin,
+ previewThemeCompartment.of(buildPreviewTheme())
+ ];
+}
+
+export function updateMarkdownPreviewTheme(view: EditorView): void {
+ if (!view?.dispatch) return;
+
+ try {
+ view.dispatch({
+ effects: previewThemeCompartment.reconfigure(buildPreviewTheme())
+ });
+ } catch (error) {
+ console.error("Failed to update markdown preview theme", error);
+ }
}
diff --git a/frontend/src/views/editor/extensions/markdownPreview/panel.ts b/frontend/src/views/editor/extensions/markdownPreview/panel.ts
index 18844fe..eaa5c57 100644
--- a/frontend/src/views/editor/extensions/markdownPreview/panel.ts
+++ b/frontend/src/views/editor/extensions/markdownPreview/panel.ts
@@ -22,7 +22,7 @@ export class MarkdownPreviewPanel {
private readonly resizeHandle: HTMLDivElement;
private readonly content: HTMLDivElement;
private view: EditorView;
- private themeUnwatch?: () => void;
+ private themeUnwatchers: Array<() => void> = [];
private lastRenderedContent: string = "";
private readonly debouncedUpdate: ReturnType;
private isDestroyed: boolean = false; // 标记面板是否已销毁
@@ -38,11 +38,22 @@ export class MarkdownPreviewPanel {
// 监听主题变化
const themeStore = useThemeStore();
- this.themeUnwatch = watch(() => themeStore.isDarkMode, (isDark) => {
- const newTheme = isDark ? "dark" : "default";
- updateMermaidTheme(newTheme);
- this.lastRenderedContent = ""; // 清空缓存,强制重新渲染
- });
+ this.themeUnwatchers.push(
+ watch(() => themeStore.isDarkMode, (isDark) => {
+ const newTheme = isDark ? "dark" : "default";
+ updateMermaidTheme(newTheme);
+ this.resetPreviewContent();
+ })
+ );
+ this.themeUnwatchers.push(
+ watch(
+ () => themeStore.currentColors,
+ () => {
+ this.resetPreviewContent();
+ },
+ { deep: true }
+ )
+ );
// 创建 DOM 结构
this.dom = document.createElement("div");
@@ -315,6 +326,16 @@ export class MarkdownPreviewPanel {
});
}
+ private resetPreviewContent(): void {
+ if (this.isDestroyed) {
+ return;
+ }
+
+ this.md = createMarkdownRenderer();
+ this.lastRenderedContent = "";
+ this.updateContentInternal();
+ }
+
/**
* 响应编辑器更新
*/
@@ -339,9 +360,14 @@ export class MarkdownPreviewPanel {
if (this.debouncedUpdate) {
this.debouncedUpdate.cancel();
}
-
+
// 清空缓存
this.lastRenderedContent = "";
+
+ if (this.themeUnwatchers.length) {
+ this.themeUnwatchers.forEach(unwatch => unwatch());
+ this.themeUnwatchers = [];
+ }
}
/**