🐛 Fixed extension management issues

This commit is contained in:
2025-07-01 23:25:24 +08:00
parent 3e45e6aa9b
commit 1ccee779ae
9 changed files with 290 additions and 197 deletions

View File

@@ -150,8 +150,7 @@ const saveEdit = async () => {
const trimmedTitle = editingTitle.value.trim(); const trimmedTitle = editingTitle.value.trim();
const error = validateTitle(trimmedTitle); const error = validateTitle(trimmedTitle);
if (error) { if (error) {
console.error('保存失败:', error);
// 保持编辑状态,不清除
return; return;
} }
@@ -159,8 +158,6 @@ const saveEdit = async () => {
await documentStore.updateDocumentMetadata(editingId.value, trimmedTitle); await documentStore.updateDocumentMetadata(editingId.value, trimmedTitle);
await documentStore.updateDocuments(); await documentStore.updateDocuments();
} catch (error) { } catch (error) {
console.error('保存失败:', error);
// 保持编辑状态,不清除
return; return;
} }
} }
@@ -186,7 +183,7 @@ const handleDelete = async (doc: Document, event: Event) => {
} }
} }
} catch (error) { } catch (error) {
console.error('删除失败:', error); console.error('deleted failed:', error);
} }
deleteConfirmId.value = null; deleteConfirmId.value = null;
} else { } else {

View File

@@ -4,6 +4,7 @@ import {onMounted, onUnmounted, ref, watch} from 'vue';
import {useConfigStore} from '@/stores/configStore'; import {useConfigStore} from '@/stores/configStore';
import {useEditorStore} from '@/stores/editorStore'; import {useEditorStore} from '@/stores/editorStore';
import {useUpdateStore} from '@/stores/updateStore'; import {useUpdateStore} from '@/stores/updateStore';
import {useDocumentStore} from '@/stores/documentStore';
import * as runtime from '@wailsio/runtime'; import * as runtime from '@wailsio/runtime';
import {useRouter} from 'vue-router'; import {useRouter} from 'vue-router';
import BlockLanguageSelector from './BlockLanguageSelector.vue'; import BlockLanguageSelector from './BlockLanguageSelector.vue';
@@ -14,6 +15,7 @@ import {getLanguage} from '@/views/editor/extensions/codeblock/lang-parser/langu
const editorStore = useEditorStore(); const editorStore = useEditorStore();
const configStore = useConfigStore(); const configStore = useConfigStore();
const updateStore = useUpdateStore(); const updateStore = useUpdateStore();
const documentStore = useDocumentStore();
const {t} = useI18n(); const {t} = useI18n();
const router = useRouter(); const router = useRouter();
@@ -32,7 +34,11 @@ const toggleAlwaysOnTop = async () => {
// 跳转到设置页面 // 跳转到设置页面
const goToSettings = () => { const goToSettings = () => {
router.push('/settings'); const currentDocId = documentStore.currentDocumentId;
router.push({
path: '/settings',
query: { documentId: currentDocId || undefined }
});
}; };

View File

@@ -12,13 +12,15 @@ const routes: RouteRecordRaw[] = [
{ {
path: '/', path: '/',
name: 'Editor', name: 'Editor',
component: Editor component: Editor,
props: route => ({ documentId: route.query.documentId ? Number(route.query.documentId) : null })
}, },
{ {
path: '/settings', path: '/settings',
name: 'Settings', name: 'Settings',
redirect: '/settings/general', redirect: '/settings/general',
component: Settings, component: Settings,
props: route => ({ returnDocumentId: route.query.documentId ? Number(route.query.documentId) : null }),
children: [ children: [
{ {
path: 'general', path: 'general',

View File

@@ -15,7 +15,7 @@ import {createFontExtensionFromBackend, updateFontConfig} from '@/views/editor/b
import {createStatsUpdateExtension} from '@/views/editor/basic/statsExtension'; import {createStatsUpdateExtension} from '@/views/editor/basic/statsExtension';
import {createContentChangePlugin} from '@/views/editor/basic/contentChangeExtension'; import {createContentChangePlugin} from '@/views/editor/basic/contentChangeExtension';
import {createDynamicKeymapExtension, updateKeymapExtension} from '@/views/editor/keymap'; import {createDynamicKeymapExtension, updateKeymapExtension} from '@/views/editor/keymap';
import {createDynamicExtensions, getExtensionManager, setExtensionManagerView} from '@/views/editor/manager'; import {createDynamicExtensions, getExtensionManager, setExtensionManagerView, removeExtensionManagerView} from '@/views/editor/manager';
import {useExtensionStore} from './extensionStore'; import {useExtensionStore} from './extensionStore';
import createCodeBlockExtension from "@/views/editor/extensions/codeblock"; import createCodeBlockExtension from "@/views/editor/extensions/codeblock";
@@ -197,7 +197,7 @@ export const useEditorStore = defineStore('editor', () => {
throw new Error('Operation cancelled'); throw new Error('Operation cancelled');
} }
// 快捷键扩展(异步) // 快捷键扩展
const keymapExtension = await createDynamicKeymapExtension(); const keymapExtension = await createDynamicKeymapExtension();
// 检查操作有效性 // 检查操作有效性
@@ -205,8 +205,8 @@ export const useEditorStore = defineStore('editor', () => {
throw new Error('Operation cancelled'); throw new Error('Operation cancelled');
} }
// 动态扩展(异步) // 动态扩展传递文档ID以便扩展管理器可以预初始化
const dynamicExtensions = await createDynamicExtensions(); const dynamicExtensions = await createDynamicExtensions(documentId);
// 最终检查操作有效性 // 最终检查操作有效性
if (!isOperationValid(operationId, documentId)) { if (!isOperationValid(operationId, documentId)) {
@@ -347,7 +347,7 @@ export const useEditorStore = defineStore('editor', () => {
currentEditor.value = instance.view; currentEditor.value = instance.view;
// 设置扩展管理器视图 // 设置扩展管理器视图
setExtensionManagerView(instance.view); setExtensionManagerView(instance.view, documentId);
// 更新LRU // 更新LRU
updateLRU(documentId); updateLRU(documentId);
@@ -529,6 +529,9 @@ export const useEditorStore = defineStore('editor', () => {
instance.autoSaveTimer = null; instance.autoSaveTimer = null;
} }
// 从扩展管理器中移除视图
removeExtensionManagerView(documentId);
// 移除DOM元素 // 移除DOM元素
if (instance.view && instance.view.dom && instance.view.dom.parentElement) { if (instance.view && instance.view.dom && instance.view.dom.parentElement) {
instance.view.dom.remove(); instance.view.dom.remove();
@@ -596,6 +599,7 @@ export const useEditorStore = defineStore('editor', () => {
// 应用快捷键设置 // 应用快捷键设置
const applyKeymapSettings = async () => { const applyKeymapSettings = async () => {
// 确保所有编辑器实例的快捷键都更新
await Promise.all( await Promise.all(
Object.values(editorCache.value.instances).map(instance => Object.values(editorCache.value.instances).map(instance =>
updateKeymapExtension(instance.view) updateKeymapExtension(instance.view)
@@ -614,6 +618,10 @@ export const useEditorStore = defineStore('editor', () => {
if (instance.autoSaveTimer) { if (instance.autoSaveTimer) {
clearTimeout(instance.autoSaveTimer); clearTimeout(instance.autoSaveTimer);
} }
// 从扩展管理器移除
removeExtensionManagerView(instance.documentId);
// 移除DOM元素 // 移除DOM元素
if (instance.view.dom.parentElement) { if (instance.view.dom.parentElement) {
instance.view.dom.remove(); instance.view.dom.remove();
@@ -637,19 +645,19 @@ export const useEditorStore = defineStore('editor', () => {
await ExtensionService.UpdateExtensionState(id, enabled, config); await ExtensionService.UpdateExtensionState(id, enabled, config);
} }
// 更新前端编辑器扩展 // 更新前端编辑器扩展 - 应用于所有实例
const manager = getExtensionManager(); const manager = getExtensionManager();
if (manager) { if (manager) {
manager.updateExtension(id, enabled, config || {}); // 使用立即更新模式,跳过防抖
manager.updateExtensionImmediate(id, enabled, config || {});
} }
// 重新加载扩展配置 // 重新加载扩展配置
await extensionStore.loadExtensions(); await extensionStore.loadExtensions();
// 更新快捷键映射 // 不再需要单独更新当前编辑器的快捷键映射,因为扩展管理器会更新所有实例
if (currentEditor.value) { // 但我们仍需要确保快捷键配置在所有编辑器上更新
updateKeymapExtension(currentEditor.value); await applyKeymapSettings();
}
}; };
// 监听文档切换 // 监听文档切换

View File

@@ -1,11 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import {onBeforeUnmount, onMounted, ref} from 'vue'; import {onBeforeUnmount, onMounted, ref, watch} from 'vue';
import {useEditorStore} from '@/stores/editorStore'; import {useEditorStore} from '@/stores/editorStore';
import {useDocumentStore} from '@/stores/documentStore'; import {useDocumentStore} from '@/stores/documentStore';
import {useConfigStore} from '@/stores/configStore'; import {useConfigStore} from '@/stores/configStore';
import {createWheelZoomHandler} from './basic/wheelZoomExtension'; import {createWheelZoomHandler} from './basic/wheelZoomExtension';
import Toolbar from '@/components/toolbar/Toolbar.vue'; import Toolbar from '@/components/toolbar/Toolbar.vue';
// 接收路由传入的文档ID
const props = defineProps<{
documentId?: number | null
}>();
const editorStore = useEditorStore(); const editorStore = useEditorStore();
const documentStore = useDocumentStore(); const documentStore = useDocumentStore();
const configStore = useConfigStore(); const configStore = useConfigStore();
@@ -22,6 +27,12 @@ onMounted(async () => {
if (!editorElement.value) return; if (!editorElement.value) return;
await documentStore.initialize(); await documentStore.initialize();
// 如果有指定文档ID则打开该文档
if (props.documentId) {
await documentStore.openDocument(props.documentId);
}
// 设置编辑器容器 // 设置编辑器容器
editorStore.setEditorContainer(editorElement.value); editorStore.setEditorContainer(editorElement.value);
@@ -35,6 +46,13 @@ onBeforeUnmount(() => {
editorElement.value.removeEventListener('wheel', wheelHandler); editorElement.value.removeEventListener('wheel', wheelHandler);
} }
}); });
// 监听文档ID变化
watch(() => props.documentId, async (newDocId) => {
if (newDocId && documentStore.currentDocumentId !== newDocId) {
await documentStore.openDocument(newDocId);
}
}, { immediate: true });
</script> </script>
<template> <template>

View File

@@ -29,27 +29,42 @@ export interface ExtensionFactory {
} }
/** /**
* 扩展区间信息 * 扩展状态
*/ */
interface ExtensionCompartment { interface ExtensionState {
id: ExtensionID id: ExtensionID
compartment: Compartment
factory: ExtensionFactory factory: ExtensionFactory
currentConfig?: any config: any
enabled: boolean enabled: boolean
compartment: Compartment
extension: Extension
}
/**
* 视图信息
*/
interface EditorViewInfo {
view: EditorView
documentId: number
registered: boolean
} }
/** /**
* 扩展管理器 * 扩展管理器
* 负责管理所有动态扩展的注册、启用、禁用和配置更新 * 负责管理所有动态扩展的注册、启用、禁用和配置更新
* 采用统一配置,多视图同步的设计模式
*/ */
export class ExtensionManager { export class ExtensionManager {
private view: EditorView | null = null // 统一的扩展状态存储
private compartments = new Map<ExtensionID, ExtensionCompartment>() private extensionStates = new Map<ExtensionID, ExtensionState>()
// 编辑器视图管理
private viewsMap = new Map<number, EditorViewInfo>()
private activeViewId: number | null = null
// 注册的扩展工厂
private extensionFactories = new Map<ExtensionID, ExtensionFactory>() private extensionFactories = new Map<ExtensionID, ExtensionFactory>()
private updateQueue = new Map<ExtensionID, { enabled: boolean, config: any, timestamp: number }>()
private debounceTimeout: number | null = null
/** /**
* 注册扩展工厂 * 注册扩展工厂
* @param id 扩展ID * @param id 扩展ID
@@ -57,13 +72,21 @@ export class ExtensionManager {
*/ */
registerExtension(id: ExtensionID, factory: ExtensionFactory): void { registerExtension(id: ExtensionID, factory: ExtensionFactory): void {
this.extensionFactories.set(id, factory) this.extensionFactories.set(id, factory)
this.compartments.set(id, {
id, // 创建初始状态
compartment: new Compartment(), if (!this.extensionStates.has(id)) {
factory, const compartment = new Compartment()
currentConfig: factory.getDefaultConfig(), const defaultConfig = factory.getDefaultConfig()
enabled: false
}) this.extensionStates.set(id, {
id,
factory,
config: defaultConfig,
enabled: false,
compartment,
extension: [] // 默认为空扩展(禁用状态)
})
}
} }
/** /**
@@ -82,70 +105,95 @@ export class ExtensionManager {
} }
/** /**
* 根据后端配置获取初始扩展数组 * 后端配置初始扩展状态
* @param extensionConfigs 后端扩展配置列表 * @param extensionConfigs 后端扩展配置列表
* @returns CodeMirror扩展数组
*/ */
getInitialExtensions(extensionConfigs: ExtensionConfig[]): Extension[] { initializeExtensionsFromConfig(extensionConfigs: ExtensionConfig[]): void {
const extensions: Extension[] = []
for (const config of extensionConfigs) { for (const config of extensionConfigs) {
const compartmentInfo = this.compartments.get(config.id) const factory = this.extensionFactories.get(config.id)
if (!compartmentInfo) { if (!factory) continue
continue
}
// 验证配置 // 验证配置
if (compartmentInfo.factory.validateConfig && if (factory.validateConfig && !factory.validateConfig(config.config)) {
!compartmentInfo.factory.validateConfig(config.config)) {
continue continue
} }
try { try {
const extension = config.enabled // 创建扩展实例
? compartmentInfo.factory.create(config.config) const extension = config.enabled ? factory.create(config.config) : []
: [] // 空扩展表示禁用
// 如果状态已存在则更新,否则创建新状态
extensions.push(compartmentInfo.compartment.of(extension)) if (this.extensionStates.has(config.id)) {
const state = this.extensionStates.get(config.id)!
// 更新状态 state.config = config.config
compartmentInfo.currentConfig = config.config state.enabled = config.enabled
compartmentInfo.enabled = config.enabled state.extension = extension
} else {
const compartment = new Compartment()
this.extensionStates.set(config.id, {
id: config.id,
factory,
config: config.config,
enabled: config.enabled,
compartment,
extension
})
}
} catch (error) { } catch (error) {
console.error(`[ExtensionManager] Failed to create extension ${config.id}:`, error) console.error(`Failed to initialize extension ${config.id}:`, error)
} }
} }
}
/**
* 获取初始扩展配置数组(用于创建编辑器)
* @returns CodeMirror扩展数组
*/
getInitialExtensions(): Extension[] {
const extensions: Extension[] = []
// 为每个注册的扩展添加compartment
for (const state of this.extensionStates.values()) {
extensions.push(state.compartment.of(state.extension))
}
return extensions return extensions
} }
/** /**
* 设置编辑器视图 * 设置编辑器视图
* @param view 编辑器视图实例 * @param view 编辑器视图实例
* @param documentId 文档ID
*/ */
setView(view: EditorView): void { setView(view: EditorView, documentId: number): void {
this.view = view // 保存视图信息
this.viewsMap.set(documentId, {
view,
documentId,
registered: true
})
// 设置当前活动视图
this.activeViewId = documentId
} }
/** /**
* 动态更新单个扩展(带防抖) * 获取当前活动视图
*/
private getActiveView(): EditorView | null {
if (this.activeViewId === null) return null
const viewInfo = this.viewsMap.get(this.activeViewId)
return viewInfo ? viewInfo.view : null
}
/**
* 更新单个扩展配置并应用到所有视图
* @param id 扩展ID * @param id 扩展ID
* @param enabled 是否启用 * @param enabled 是否启用
* @param config 扩展配置 * @param config 扩展配置
*/ */
updateExtension(id: ExtensionID, enabled: boolean, config: any = {}): void { updateExtension(id: ExtensionID, enabled: boolean, config: any = {}): void {
// 添加到更新队列 this.updateExtensionImmediate(id, enabled, config)
this.updateQueue.set(id, {enabled, config, timestamp: Date.now()})
// 清除之前的防抖定时器
if (this.debounceTimeout) {
clearTimeout(this.debounceTimeout)
}
// 设置新的防抖定时器
this.debounceTimeout = window.setTimeout(() => {
this.flushUpdateQueue()
}, 100) // 100ms 防抖
} }
/** /**
@@ -155,83 +203,54 @@ export class ExtensionManager {
* @param config 扩展配置 * @param config 扩展配置
*/ */
updateExtensionImmediate(id: ExtensionID, enabled: boolean, config: any = {}): void { updateExtensionImmediate(id: ExtensionID, enabled: boolean, config: any = {}): void {
if (!this.view) { // 获取扩展状态
const state = this.extensionStates.get(id)
if (!state) return
// 获取工厂
const factory = state.factory
// 验证配置
if (factory.validateConfig && !factory.validateConfig(config)) {
return return
} }
const compartmentInfo = this.compartments.get(id)
if (!compartmentInfo) {
return
}
try { try {
// 验证配置 // 创建新的扩展实例
if (compartmentInfo.factory.validateConfig && const extension = enabled ? factory.create(config) : []
!compartmentInfo.factory.validateConfig(config)) {
return // 更新内部状态
} state.config = config
state.enabled = enabled
const extension = enabled state.extension = extension
? compartmentInfo.factory.create(config)
: [] // 应用到所有视图
this.applyExtensionToAllViews(id)
this.view.dispatch({
effects: compartmentInfo.compartment.reconfigure(extension)
})
// 更新状态
compartmentInfo.currentConfig = config
compartmentInfo.enabled = enabled
} catch (error) { } catch (error) {
console.error(`[ExtensionManager] Failed to update extension ${id}:`, error) console.error(`Failed to update extension ${id}:`, error)
} }
} }
/** /**
* 处理更新队列中的所有更新 * 将指定扩展的当前状态应用到所有视图
* @param id 扩展ID
*/ */
private flushUpdateQueue(): void { private applyExtensionToAllViews(id: ExtensionID): void {
if (!this.view) { const state = this.extensionStates.get(id)
return if (!state) return
}
// 遍历所有视图并应用更改
const effects: StateEffect<any>[] = [] for (const viewInfo of this.viewsMap.values()) {
for (const [id, update] of this.updateQueue) {
const compartmentInfo = this.compartments.get(id)
if (!compartmentInfo) {
continue
}
try { try {
// 验证配置 if (!viewInfo.registered) continue
if (compartmentInfo.factory.validateConfig &&
!compartmentInfo.factory.validateConfig(update.config)) { viewInfo.view.dispatch({
continue effects: state.compartment.reconfigure(state.extension)
} })
const extension = update.enabled
? compartmentInfo.factory.create(update.config)
: []
effects.push(compartmentInfo.compartment.reconfigure(extension))
// 更新状态
compartmentInfo.currentConfig = update.config
compartmentInfo.enabled = update.enabled
} catch (error) { } catch (error) {
console.error(`[ExtensionManager] Failed to update extension ${id}:`, error) console.error(`Failed to apply extension ${id} to document ${viewInfo.documentId}:`, error)
} }
} }
if (effects.length > 0) {
this.view.dispatch({effects})
}
// 清空更新队列
this.updateQueue.clear()
this.debounceTimeout = null
} }
/** /**
@@ -243,42 +262,53 @@ export class ExtensionManager {
enabled: boolean enabled: boolean
config: any config: any
}>): void { }>): void {
if (!this.view) { // 更新所有扩展状态
console.warn('Editor view not set')
return
}
const effects: StateEffect<any>[] = []
for (const update of updates) { for (const update of updates) {
const compartmentInfo = this.compartments.get(update.id) // 获取扩展状态
if (!compartmentInfo) { const state = this.extensionStates.get(update.id)
if (!state) continue
// 获取工厂
const factory = state.factory
// 验证配置
if (factory.validateConfig && !factory.validateConfig(update.config)) {
continue continue
} }
try { try {
// 验证配置 // 创建新的扩展实例
if (compartmentInfo.factory.validateConfig && const extension = update.enabled ? factory.create(update.config) : []
!compartmentInfo.factory.validateConfig(update.config)) {
continue // 更新内部状态
} state.config = update.config
state.enabled = update.enabled
const extension = update.enabled state.extension = extension
? compartmentInfo.factory.create(update.config)
: []
effects.push(compartmentInfo.compartment.reconfigure(extension))
// 更新状态
compartmentInfo.currentConfig = update.config
compartmentInfo.enabled = update.enabled
} catch (error) { } catch (error) {
console.error(`Failed to update extension ${update.id}:`, error) console.error(`Failed to update extension ${update.id}:`, error)
} }
} }
if (effects.length > 0) { // 将更改应用到所有视图
this.view.dispatch({effects}) for (const viewInfo of this.viewsMap.values()) {
if (!viewInfo.registered) continue
const effects: StateEffect<any>[] = []
for (const update of updates) {
const state = this.extensionStates.get(update.id)
if (!state) continue
effects.push(state.compartment.reconfigure(state.extension))
}
if (effects.length > 0) {
try {
viewInfo.view.dispatch({ effects })
} catch (error) {
console.error(`Failed to apply extensions to document ${viewInfo.documentId}:`, error)
}
}
} }
} }
@@ -290,14 +320,12 @@ export class ExtensionManager {
enabled: boolean enabled: boolean
config: any config: any
} | null { } | null {
const compartmentInfo = this.compartments.get(id) const state = this.extensionStates.get(id)
if (!compartmentInfo) { if (!state) return null
return null
}
return { return {
enabled: compartmentInfo.enabled, enabled: state.enabled,
config: compartmentInfo.currentConfig config: state.config
} }
} }
@@ -306,28 +334,32 @@ export class ExtensionManager {
* @param id 扩展ID * @param id 扩展ID
*/ */
resetExtensionToDefault(id: ExtensionID): void { resetExtensionToDefault(id: ExtensionID): void {
const compartmentInfo = this.compartments.get(id) const state = this.extensionStates.get(id)
if (!compartmentInfo) { if (!state) return
return
} const defaultConfig = state.factory.getDefaultConfig()
const defaultConfig = compartmentInfo.factory.getDefaultConfig()
this.updateExtension(id, true, defaultConfig) this.updateExtension(id, true, defaultConfig)
} }
/**
* 从管理器中移除视图
* @param documentId 文档ID
*/
removeView(documentId: number): void {
if (this.activeViewId === documentId) {
this.activeViewId = null
}
this.viewsMap.delete(documentId)
}
/** /**
* 销毁管理器 * 销毁管理器
*/ */
destroy(): void { destroy(): void {
// 清除防抖定时器 this.viewsMap.clear()
if (this.debounceTimeout) { this.activeViewId = null
clearTimeout(this.debounceTimeout)
this.debounceTimeout = null
}
this.view = null
this.compartments.clear()
this.extensionFactories.clear() this.extensionFactories.clear()
this.updateQueue.clear() this.extensionStates.clear()
} }
} }

View File

@@ -1,4 +1,5 @@
import {Extension} from '@codemirror/state' import {Extension} from '@codemirror/state'
import {EditorView} from '@codemirror/view'
import {useExtensionStore} from '@/stores/extensionStore' import {useExtensionStore} from '@/stores/extensionStore'
import {ExtensionManager} from './ExtensionManager' import {ExtensionManager} from './ExtensionManager'
import {registerAllExtensions} from './factories' import {registerAllExtensions} from './factories'
@@ -11,8 +12,9 @@ const extensionManager = new ExtensionManager()
/** /**
* 异步创建动态扩展 * 异步创建动态扩展
* 确保扩展配置已加载 * 确保扩展配置已加载
* @param documentId 可选的文档ID用于提前初始化视图
*/ */
export const createDynamicExtensions = async (): Promise<Extension[]> => { export const createDynamicExtensions = async (documentId?: number): Promise<Extension[]> => {
const extensionStore = useExtensionStore() const extensionStore = useExtensionStore()
// 注册所有扩展工厂 // 注册所有扩展工厂
@@ -23,10 +25,11 @@ export const createDynamicExtensions = async (): Promise<Extension[]> => {
await extensionStore.loadExtensions() await extensionStore.loadExtensions()
} }
// 获取启用的扩展配置 // 初始化扩展管理器配置
const enabledExtensions = extensionStore.enabledExtensions extensionManager.initializeExtensionsFromConfig(extensionStore.extensions)
return extensionManager.getInitialExtensions(enabledExtensions) // 获取初始扩展配置
return extensionManager.getInitialExtensions()
} }
/** /**
@@ -40,9 +43,18 @@ export const getExtensionManager = (): ExtensionManager => {
/** /**
* 设置编辑器视图到扩展管理器 * 设置编辑器视图到扩展管理器
* @param view 编辑器视图 * @param view 编辑器视图
* @param documentId 文档ID
*/ */
export const setExtensionManagerView = (view: any): void => { export const setExtensionManagerView = (view: EditorView, documentId: number): void => {
extensionManager.setView(view) extensionManager.setView(view, documentId)
}
/**
* 从扩展管理器移除编辑器视图
* @param documentId 文档ID
*/
export const removeExtensionManagerView = (documentId: number): void => {
extensionManager.removeView(documentId)
} }
// 导出相关模块 // 导出相关模块

View File

@@ -8,6 +8,11 @@ const { t } = useI18n();
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
// 接收路由传入的参数
const props = defineProps<{
returnDocumentId?: number | null
}>();
// 导航配置 // 导航配置
const navItems = [ const navItems = [
{ id: 'general', icon: '⚙️', route: '/settings/general' }, { id: 'general', icon: '⚙️', route: '/settings/general' },
@@ -28,7 +33,15 @@ const handleNavClick = (item: typeof navItems[0]) => {
// 返回编辑器 // 返回编辑器
const goBackToEditor = async () => { const goBackToEditor = async () => {
await router.push('/'); // 如果有返回文档ID则传递参数
if (props.returnDocumentId) {
await router.push({
path: '/',
query: { documentId: props.returnDocumentId }
});
} else {
await router.push('/');
}
}; };
</script> </script>

View File

@@ -69,6 +69,9 @@ const updateExtensionConfig = async (extensionId: ExtensionID, configKey: string
// 更新配置 // 更新配置
const updatedConfig = {...extension.config, [configKey]: value} const updatedConfig = {...extension.config, [configKey]: value}
console.log(`[ExtensionsPage] 更新扩展 ${extensionId} 配置, ${configKey}=${value}`)
// 使用editorStore的updateExtension方法更新确保应用到所有编辑器实例
await editorStore.updateExtension(extensionId, extension.enabled, updatedConfig) await editorStore.updateExtension(extensionId, extension.enabled, updatedConfig)
} catch (error) { } catch (error) {
@@ -79,16 +82,18 @@ const updateExtensionConfig = async (extensionId: ExtensionID, configKey: string
// 重置扩展到默认配置 // 重置扩展到默认配置
const resetExtension = async (extensionId: ExtensionID) => { const resetExtension = async (extensionId: ExtensionID) => {
try { try {
// 重置到默认配置(后端)
await ExtensionService.ResetExtensionToDefault(extensionId) await ExtensionService.ResetExtensionToDefault(extensionId)
// 重新加载扩展状态以获取最新配置 // 重新加载扩展状态以获取最新配置
await extensionStore.loadExtensions() await extensionStore.loadExtensions()
// 获取重置后的状态,立即通知编辑器更新 // 获取重置后的状态,立即应用到所有编辑器视图
const extension = extensionStore.extensions.find(ext => ext.id === extensionId) const extension = extensionStore.extensions.find(ext => ext.id === extensionId)
if (extension) { if (extension) {
const manager = getExtensionManager() // 通过editorStore更新确保所有视图都能同步
manager.updateExtension(extensionId, extension.enabled, extension.config) await editorStore.updateExtension(extensionId, extension.enabled, extension.config)
console.log(`[ExtensionsPage] 重置扩展 ${extensionId} 配置,同步应用到所有编辑器实例`)
} }
} catch (error) { } catch (error) {
console.error('Failed to reset extension:', error) console.error('Failed to reset extension:', error)