Add extension management service

This commit is contained in:
2025-06-24 14:16:53 +08:00
parent ea025e3f5d
commit f3bcb87828
31 changed files with 1682 additions and 176 deletions

View File

@@ -8,13 +8,16 @@ import {useThemeStore} from './themeStore';
import {SystemThemeType} from '@/../bindings/voidraft/internal/models/models';
import {DocumentService} from '@/../bindings/voidraft/internal/services';
import {ensureSyntaxTree} from "@codemirror/language"
import {createBasicSetup} from '@/views/editor/extensions/basicSetup';
import {createThemeExtension, updateEditorTheme} from '@/views/editor/extensions/themeExtension';
import {getTabExtensions, updateTabConfig} from '@/views/editor/extensions/tabExtension';
import {createFontExtensionFromBackend, updateFontConfig} from '@/views/editor/extensions/fontExtension';
import {createStatsUpdateExtension} from '@/views/editor/extensions/statsExtension';
import {createAutoSavePlugin, createSaveShortcutPlugin} from '@/views/editor/extensions/autoSaveExtension';
import {createDynamicKeymapExtension} from '@/views/editor/extensions/keymap';
import {createBasicSetup} from '@/views/editor/basic/basicSetup';
import {createThemeExtension, updateEditorTheme} from '@/views/editor/basic/themeExtension';
import {getTabExtensions, updateTabConfig} from '@/views/editor/basic/tabExtension';
import {createFontExtensionFromBackend, updateFontConfig} from '@/views/editor/basic/fontExtension';
import {createStatsUpdateExtension} from '@/views/editor/basic/statsExtension';
import {createAutoSavePlugin, createSaveShortcutPlugin} from '@/views/editor/basic/autoSaveExtension';
import {createDynamicKeymapExtension} from '@/views/editor/keymap';
import { createDynamicExtensions, setExtensionManagerView, getExtensionManager } from '@/views/editor/manager';
import { useExtensionStore } from './extensionStore';
import { ExtensionService } from '@/../bindings/voidraft/internal/services';
export interface DocumentStats {
lines: number;
@@ -27,6 +30,7 @@ export const useEditorStore = defineStore('editor', () => {
const configStore = useConfigStore();
const documentStore = useDocumentStore();
const themeStore = useThemeStore();
const extensionStore = useExtensionStore();
// 状态
const documentStats = ref<DocumentStats>({
@@ -130,14 +134,14 @@ export const useEditorStore = defineStore('editor', () => {
);
// 创建保存快捷键插件
const saveShortcutPlugin = createSaveShortcutPlugin(() => {
const saveShortcutExtension = createSaveShortcutPlugin(() => {
if (editorView.value) {
handleManualSave();
}
});
// 创建自动保存插件
const autoSavePlugin = createAutoSavePlugin({
const autoSaveExtension = createAutoSavePlugin({
debounceDelay: 300, // 300毫秒的输入防抖
onSave: (success) => {
if (success) {
@@ -148,6 +152,9 @@ export const useEditorStore = defineStore('editor', () => {
// 创建动态快捷键扩展
const keymapExtension = await createDynamicKeymapExtension();
// 创建动态扩展
const dynamicExtensions = await createDynamicExtensions();
// 组合所有扩展
const extensions: Extension[] = [
@@ -157,8 +164,9 @@ export const useEditorStore = defineStore('editor', () => {
...tabExtensions,
fontExtension,
statsExtension,
saveShortcutPlugin,
autoSavePlugin
saveShortcutExtension,
autoSaveExtension,
...dynamicExtensions
];
// 创建编辑器状态
@@ -175,6 +183,9 @@ export const useEditorStore = defineStore('editor', () => {
// 将编辑器实例保存到store
setEditorView(view);
// 设置编辑器视图到扩展管理器
setExtensionManagerView(view);
isEditorInitialized.value = true;
@@ -257,6 +268,23 @@ export const useEditorStore = defineStore('editor', () => {
}
});
// 扩展管理方法
const updateExtension = async (id: any, enabled: boolean, config?: any) => {
try {
// 更新后端配置
await ExtensionService.UpdateExtensionState(id, enabled, config || {})
// 更新前端编辑器
const manager = getExtensionManager()
manager.updateExtension(id, enabled, config || {})
// 重新加载扩展配置
await extensionStore.loadExtensions()
} catch (error) {
console.error('Failed to update extension:', error)
}
}
return {
// 状态
documentStats,
@@ -272,5 +300,6 @@ export const useEditorStore = defineStore('editor', () => {
handleManualSave,
destroyEditor,
scrollEditorToBottom,
updateExtension
};
});

View File

@@ -0,0 +1,76 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { Extension, ExtensionID, ExtensionCategory, ExtensionSettings } from '@/../bindings/voidraft/internal/models/models'
import { ExtensionService } from '@/../bindings/voidraft/internal/services'
export const useExtensionStore = defineStore('extension', () => {
// 扩展配置数据
const extensions = ref<Extension[]>([])
const settings = ref<ExtensionSettings | null>(null)
// 获取启用的扩展
const enabledExtensions = computed(() =>
extensions.value.filter(ext => ext.enabled)
)
// 根据分类获取扩展
const getExtensionsByCategory = computed(() =>
(category: ExtensionCategory) =>
extensions.value.filter(ext => ext.category === category)
)
// 获取启用的扩展按分类分组
const enabledExtensionsByCategory = computed(() => {
const grouped = new Map<ExtensionCategory, Extension[]>()
enabledExtensions.value.forEach(ext => {
if (!grouped.has(ext.category)) {
grouped.set(ext.category, [])
}
grouped.get(ext.category)!.push(ext)
})
return grouped
})
/**
* 从后端加载扩展配置
*/
const loadExtensions = async (): Promise<void> => {
try {
extensions.value = await ExtensionService.GetAllExtensions()
} catch (err) {
console.error('Failed to load extensions:', err)
}
}
/**
* 检查扩展是否启用
*/
const isExtensionEnabled = (id: ExtensionID): boolean => {
const extension = extensions.value.find(ext => ext.id === id)
return extension?.enabled ?? false
}
/**
* 获取扩展配置
*/
const getExtensionConfig = (id: ExtensionID): any => {
const extension = extensions.value.find(ext => ext.id === id)
return extension?.config ?? {}
}
return {
// 状态
extensions,
settings,
enabledExtensions,
// 计算属性
getExtensionsByCategory,
enabledExtensionsByCategory,
// 方法
loadExtensions,
isExtensionEnabled,
getExtensionConfig
}
})

View File

@@ -3,98 +3,64 @@ import {computed, ref} from 'vue';
import * as runtime from '@wailsio/runtime';
export interface SystemEnvironment {
OS: string;
Arch: string;
Debug: boolean;
OSInfo: {
Name: string;
Branding: string;
Version: string;
ID: string;
};
PlatformInfo?: Record<string, string>;
OS: string;
Arch: string;
Debug: boolean;
OSInfo: {
Name: string;
Branding: string;
Version: string;
ID: string;
};
PlatformInfo?: Record<string, string>;
}
export const useSystemStore = defineStore('system', () => {
// 状态
const environment = ref<SystemEnvironment | null>(null);
const isLoading = ref(false);
const error = ref<string | null>(null);
// 计算属性
const isWindows = computed(() => environment.value?.OS === 'windows');
const isMacOS = computed(() => environment.value?.OS === 'darwin');
const isLinux = computed(() => environment.value?.OS === 'linux');
// 获取操作系统名称
const osName = computed(() => {
if (!environment.value) return 'Unknown';
return environment.value.OSInfo?.Name || environment.value.OS || 'Unknown';
});
// 获取架构信息
const architecture = computed(() => environment.value?.Arch || 'Unknown');
// 获取标题栏高度
const titleBarHeight = computed(() => {
if (isWindows.value) return '32px';
if (isMacOS.value) return '28px';
return '34px'; // Linux 默认
});
// 初始化系统信息
const initializeSystemInfo = async (): Promise<void> => {
if (isLoading.value) return;
isLoading.value = true;
error.value = null;
try {
environment.value = await runtime.System.Environment();
} catch (err) {
error.value = 'Failed to get system environment';
environment.value = null;
} finally {
isLoading.value = false;
}
};
// 获取平台特定信息
const getPlatformInfo = () => {
return environment.value?.PlatformInfo || {};
};
// 检查是否支持某项功能(基于操作系统)
const supportsFeature = (feature: string): boolean => {
switch (feature) {
case 'systemTray':
return true; // 所有平台都支持
case 'globalHotkeys':
return !isLinux.value; // Linux 支持可能有限
case 'transparency':
return isWindows.value || isMacOS.value;
default:
return false;
}
};
return {
// 状态
environment,
isLoading,
error,
const environment = ref<SystemEnvironment | null>(null);
const isLoading = ref(false);
// 计算属性
isWindows,
isMacOS,
isLinux,
osName,
architecture,
titleBarHeight,
const isWindows = computed(() => environment.value?.OS === 'windows');
const isMacOS = computed(() => environment.value?.OS === 'darwin');
const isLinux = computed(() => environment.value?.OS === 'linux');
// 方法
initializeSystemInfo,
getPlatformInfo,
supportsFeature
};
// 获取标题栏高度
const titleBarHeight = computed(() => {
if (isWindows.value) return '32px';
if (isMacOS.value) return '28px';
return '34px'; // Linux 默认
});
// 初始化系统信息
const initializeSystemInfo = async (): Promise<void> => {
if (isLoading.value) return;
isLoading.value = true;
try {
environment.value = await runtime.System.Environment();
} catch (err) {
environment.value = null;
} finally {
isLoading.value = false;
}
};
return {
// 状态
environment,
isLoading,
// 计算属性
isWindows,
isMacOS,
isLinux,
titleBarHeight,
// 方法
initializeSystemInfo,
};
});