🎨 Change configuration structure
This commit is contained in:
@@ -10,23 +10,33 @@ import {Create as $Create} from "@wailsio/runtime";
|
||||
import * as time$0 from "../../../time/models.js";
|
||||
|
||||
/**
|
||||
* AppConfig 应用配置 - 包含业务配置和路径配置
|
||||
* AppConfig 应用配置 - 按照前端设置页面分类组织
|
||||
*/
|
||||
export class AppConfig {
|
||||
/**
|
||||
* 编辑器配置
|
||||
* 通用设置
|
||||
*/
|
||||
"editor": EditorConfig;
|
||||
"general": GeneralConfig;
|
||||
|
||||
/**
|
||||
* 文档配置
|
||||
* 编辑设置
|
||||
*/
|
||||
"document": DocumentConfig;
|
||||
"editing": EditingConfig;
|
||||
|
||||
/**
|
||||
* 路径配置
|
||||
* 外观设置
|
||||
*/
|
||||
"paths": PathsConfig;
|
||||
"appearance": AppearanceConfig;
|
||||
|
||||
/**
|
||||
* 快捷键设置
|
||||
*/
|
||||
"keyBindings": KeyBindingsConfig;
|
||||
|
||||
/**
|
||||
* 更新设置
|
||||
*/
|
||||
"updates": UpdatesConfig;
|
||||
|
||||
/**
|
||||
* 配置元数据
|
||||
@@ -35,14 +45,20 @@ export class AppConfig {
|
||||
|
||||
/** Creates a new AppConfig instance. */
|
||||
constructor($$source: Partial<AppConfig> = {}) {
|
||||
if (!("editor" in $$source)) {
|
||||
this["editor"] = (new EditorConfig());
|
||||
if (!("general" in $$source)) {
|
||||
this["general"] = (new GeneralConfig());
|
||||
}
|
||||
if (!("document" in $$source)) {
|
||||
this["document"] = (new DocumentConfig());
|
||||
if (!("editing" in $$source)) {
|
||||
this["editing"] = (new EditingConfig());
|
||||
}
|
||||
if (!("paths" in $$source)) {
|
||||
this["paths"] = (new PathsConfig());
|
||||
if (!("appearance" in $$source)) {
|
||||
this["appearance"] = (new AppearanceConfig());
|
||||
}
|
||||
if (!("keyBindings" in $$source)) {
|
||||
this["keyBindings"] = (new KeyBindingsConfig());
|
||||
}
|
||||
if (!("updates" in $$source)) {
|
||||
this["updates"] = (new UpdatesConfig());
|
||||
}
|
||||
if (!("metadata" in $$source)) {
|
||||
this["metadata"] = (new ConfigMetadata());
|
||||
@@ -59,23 +75,58 @@ export class AppConfig {
|
||||
const $$createField1_0 = $$createType1;
|
||||
const $$createField2_0 = $$createType2;
|
||||
const $$createField3_0 = $$createType3;
|
||||
const $$createField4_0 = $$createType4;
|
||||
const $$createField5_0 = $$createType5;
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
if ("editor" in $$parsedSource) {
|
||||
$$parsedSource["editor"] = $$createField0_0($$parsedSource["editor"]);
|
||||
if ("general" in $$parsedSource) {
|
||||
$$parsedSource["general"] = $$createField0_0($$parsedSource["general"]);
|
||||
}
|
||||
if ("document" in $$parsedSource) {
|
||||
$$parsedSource["document"] = $$createField1_0($$parsedSource["document"]);
|
||||
if ("editing" in $$parsedSource) {
|
||||
$$parsedSource["editing"] = $$createField1_0($$parsedSource["editing"]);
|
||||
}
|
||||
if ("paths" in $$parsedSource) {
|
||||
$$parsedSource["paths"] = $$createField2_0($$parsedSource["paths"]);
|
||||
if ("appearance" in $$parsedSource) {
|
||||
$$parsedSource["appearance"] = $$createField2_0($$parsedSource["appearance"]);
|
||||
}
|
||||
if ("keyBindings" in $$parsedSource) {
|
||||
$$parsedSource["keyBindings"] = $$createField3_0($$parsedSource["keyBindings"]);
|
||||
}
|
||||
if ("updates" in $$parsedSource) {
|
||||
$$parsedSource["updates"] = $$createField4_0($$parsedSource["updates"]);
|
||||
}
|
||||
if ("metadata" in $$parsedSource) {
|
||||
$$parsedSource["metadata"] = $$createField3_0($$parsedSource["metadata"]);
|
||||
$$parsedSource["metadata"] = $$createField5_0($$parsedSource["metadata"]);
|
||||
}
|
||||
return new AppConfig($$parsedSource as Partial<AppConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AppearanceConfig 外观设置配置
|
||||
*/
|
||||
export class AppearanceConfig {
|
||||
/**
|
||||
* 界面语言
|
||||
*/
|
||||
"language": LanguageType;
|
||||
|
||||
/** Creates a new AppearanceConfig instance. */
|
||||
constructor($$source: Partial<AppearanceConfig> = {}) {
|
||||
if (!("language" in $$source)) {
|
||||
this["language"] = ("" as LanguageType);
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AppearanceConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): AppearanceConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new AppearanceConfig($$parsedSource as Partial<AppearanceConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ConfigMetadata 配置元数据
|
||||
*/
|
||||
@@ -141,7 +192,7 @@ export class Document {
|
||||
* Creates a new Document instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): Document {
|
||||
const $$createField0_0 = $$createType4;
|
||||
const $$createField0_0 = $$createType6;
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
if ("meta" in $$parsedSource) {
|
||||
$$parsedSource["meta"] = $$createField0_0($$parsedSource["meta"]);
|
||||
@@ -150,49 +201,6 @@ export class Document {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DocumentConfig 定义文档配置
|
||||
*/
|
||||
export class DocumentConfig {
|
||||
/**
|
||||
* 自动保存延迟(毫秒)- 内容变更后多久自动保存
|
||||
*/
|
||||
"autoSaveDelay": number;
|
||||
|
||||
/**
|
||||
* 变更字符阈值,超过此阈值立即触发保存
|
||||
*/
|
||||
"changeThreshold": number;
|
||||
|
||||
/**
|
||||
* 最小保存间隔(毫秒)- 两次保存之间的最小时间间隔,避免频繁IO
|
||||
*/
|
||||
"minSaveInterval": number;
|
||||
|
||||
/** Creates a new DocumentConfig instance. */
|
||||
constructor($$source: Partial<DocumentConfig> = {}) {
|
||||
if (!("autoSaveDelay" in $$source)) {
|
||||
this["autoSaveDelay"] = 0;
|
||||
}
|
||||
if (!("changeThreshold" in $$source)) {
|
||||
this["changeThreshold"] = 0;
|
||||
}
|
||||
if (!("minSaveInterval" in $$source)) {
|
||||
this["minSaveInterval"] = 0;
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DocumentConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): DocumentConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new DocumentConfig($$parsedSource as Partial<DocumentConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DocumentMeta 文档元数据
|
||||
*/
|
||||
@@ -245,10 +253,11 @@ export class DocumentMeta {
|
||||
}
|
||||
|
||||
/**
|
||||
* EditorConfig 定义编辑器配置
|
||||
* EditingConfig 编辑设置配置
|
||||
*/
|
||||
export class EditorConfig {
|
||||
export class EditingConfig {
|
||||
/**
|
||||
* 字体设置
|
||||
* 字体大小
|
||||
*/
|
||||
"fontSize": number;
|
||||
@@ -269,6 +278,7 @@ export class EditorConfig {
|
||||
"lineHeight": number;
|
||||
|
||||
/**
|
||||
* Tab设置
|
||||
* 是否启用Tab缩进
|
||||
*/
|
||||
"enableTabIndent": boolean;
|
||||
@@ -284,17 +294,23 @@ export class EditorConfig {
|
||||
"tabType": TabType;
|
||||
|
||||
/**
|
||||
* 界面语言
|
||||
* 保存选项
|
||||
* 自动保存延迟(毫秒)
|
||||
*/
|
||||
"language": LanguageType;
|
||||
"autoSaveDelay": number;
|
||||
|
||||
/**
|
||||
* 窗口是否置顶
|
||||
* 变更字符阈值
|
||||
*/
|
||||
"alwaysOnTop": boolean;
|
||||
"changeThreshold": number;
|
||||
|
||||
/** Creates a new EditorConfig instance. */
|
||||
constructor($$source: Partial<EditorConfig> = {}) {
|
||||
/**
|
||||
* 最小保存间隔(毫秒)
|
||||
*/
|
||||
"minSaveInterval": number;
|
||||
|
||||
/** Creates a new EditingConfig instance. */
|
||||
constructor($$source: Partial<EditingConfig> = {}) {
|
||||
if (!("fontSize" in $$source)) {
|
||||
this["fontSize"] = 0;
|
||||
}
|
||||
@@ -316,22 +332,80 @@ export class EditorConfig {
|
||||
if (!("tabType" in $$source)) {
|
||||
this["tabType"] = ("" as TabType);
|
||||
}
|
||||
if (!("language" in $$source)) {
|
||||
this["language"] = ("" as LanguageType);
|
||||
if (!("autoSaveDelay" in $$source)) {
|
||||
this["autoSaveDelay"] = 0;
|
||||
}
|
||||
if (!("alwaysOnTop" in $$source)) {
|
||||
this["alwaysOnTop"] = false;
|
||||
if (!("changeThreshold" in $$source)) {
|
||||
this["changeThreshold"] = 0;
|
||||
}
|
||||
if (!("minSaveInterval" in $$source)) {
|
||||
this["minSaveInterval"] = 0;
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EditorConfig instance from a string or object.
|
||||
* Creates a new EditingConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): EditorConfig {
|
||||
static createFrom($$source: any = {}): EditingConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new EditorConfig($$parsedSource as Partial<EditorConfig>);
|
||||
return new EditingConfig($$parsedSource as Partial<EditingConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GeneralConfig 通用设置配置
|
||||
*/
|
||||
export class GeneralConfig {
|
||||
/**
|
||||
* 窗口是否置顶
|
||||
*/
|
||||
"alwaysOnTop": boolean;
|
||||
|
||||
/**
|
||||
* 数据存储路径
|
||||
*/
|
||||
"dataPath": string;
|
||||
|
||||
/** Creates a new GeneralConfig instance. */
|
||||
constructor($$source: Partial<GeneralConfig> = {}) {
|
||||
if (!("alwaysOnTop" in $$source)) {
|
||||
this["alwaysOnTop"] = false;
|
||||
}
|
||||
if (!("dataPath" in $$source)) {
|
||||
this["dataPath"] = "";
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new GeneralConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): GeneralConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new GeneralConfig($$parsedSource as Partial<GeneralConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* KeyBindingsConfig 快捷键设置配置
|
||||
*/
|
||||
export class KeyBindingsConfig {
|
||||
|
||||
/** Creates a new KeyBindingsConfig instance. */
|
||||
constructor($$source: Partial<KeyBindingsConfig> = {}) {
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new KeyBindingsConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): KeyBindingsConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new KeyBindingsConfig($$parsedSource as Partial<KeyBindingsConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,33 +429,6 @@ export enum LanguageType {
|
||||
LangEnUS = "en-US",
|
||||
};
|
||||
|
||||
/**
|
||||
* PathsConfig 路径配置集合
|
||||
*/
|
||||
export class PathsConfig {
|
||||
/**
|
||||
* 数据存储路径
|
||||
*/
|
||||
"dataPath": string;
|
||||
|
||||
/** Creates a new PathsConfig instance. */
|
||||
constructor($$source: Partial<PathsConfig> = {}) {
|
||||
if (!("dataPath" in $$source)) {
|
||||
this["dataPath"] = "";
|
||||
}
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PathsConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): PathsConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new PathsConfig($$parsedSource as Partial<PathsConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TabType 定义了制表符类型
|
||||
*/
|
||||
@@ -402,9 +449,31 @@ export enum TabType {
|
||||
TabTypeTab = "tab",
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdatesConfig 更新设置配置
|
||||
*/
|
||||
export class UpdatesConfig {
|
||||
|
||||
/** Creates a new UpdatesConfig instance. */
|
||||
constructor($$source: Partial<UpdatesConfig> = {}) {
|
||||
|
||||
Object.assign(this, $$source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UpdatesConfig instance from a string or object.
|
||||
*/
|
||||
static createFrom($$source: any = {}): UpdatesConfig {
|
||||
let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
|
||||
return new UpdatesConfig($$parsedSource as Partial<UpdatesConfig>);
|
||||
}
|
||||
}
|
||||
|
||||
// Private type creation functions
|
||||
const $$createType0 = EditorConfig.createFrom;
|
||||
const $$createType1 = DocumentConfig.createFrom;
|
||||
const $$createType2 = PathsConfig.createFrom;
|
||||
const $$createType3 = ConfigMetadata.createFrom;
|
||||
const $$createType4 = DocumentMeta.createFrom;
|
||||
const $$createType0 = GeneralConfig.createFrom;
|
||||
const $$createType1 = EditingConfig.createFrom;
|
||||
const $$createType2 = AppearanceConfig.createFrom;
|
||||
const $$createType3 = KeyBindingsConfig.createFrom;
|
||||
const $$createType4 = UpdatesConfig.createFrom;
|
||||
const $$createType5 = ConfigMetadata.createFrom;
|
||||
const $$createType6 = DocumentMeta.createFrom;
|
||||
|
@@ -61,7 +61,7 @@ export function GetDiffInfo(oldText: string, newText: string): Promise<$models.D
|
||||
/**
|
||||
* GetSaveSettings 获取文档保存设置
|
||||
*/
|
||||
export function GetSaveSettings(): Promise<models$0.DocumentConfig | null> & { cancel(): void } {
|
||||
export function GetSaveSettings(): Promise<models$0.EditingConfig | null> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(4257471801) as any;
|
||||
let $typingPromise = $resultPromise.then(($result: any) => {
|
||||
return $$createType4($result);
|
||||
@@ -129,7 +129,7 @@ export function UpdateActiveDocumentContent(content: string): Promise<void> & {
|
||||
/**
|
||||
* UpdateSaveSettings 更新文档保存设置
|
||||
*/
|
||||
export function UpdateSaveSettings(docConfig: models$0.DocumentConfig): Promise<void> & { cancel(): void } {
|
||||
export function UpdateSaveSettings(docConfig: models$0.EditingConfig): Promise<void> & { cancel(): void } {
|
||||
let $resultPromise = $Call.ByID(1245479534, docConfig) as any;
|
||||
return $resultPromise;
|
||||
}
|
||||
@@ -138,5 +138,5 @@ export function UpdateSaveSettings(docConfig: models$0.DocumentConfig): Promise<
|
||||
const $$createType0 = models$0.Document.createFrom;
|
||||
const $$createType1 = $Create.Nullable($$createType0);
|
||||
const $$createType2 = $models.DiffResult.createFrom;
|
||||
const $$createType3 = models$0.DocumentConfig.createFrom;
|
||||
const $$createType3 = models$0.EditingConfig.createFrom;
|
||||
const $$createType4 = $Create.Nullable($$createType3);
|
||||
|
@@ -1,75 +1,79 @@
|
||||
<script setup lang="ts">
|
||||
import {useEditorStore} from '@/stores/editorStore';
|
||||
import {useConfigStore, SUPPORTED_LOCALES, type SupportedLocaleType} from '@/stores/configStore';
|
||||
import {useLogStore} from '@/stores/logStore';
|
||||
import { useErrorHandler } from '@/utils/errorHandler';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ref, onMounted, watch } from 'vue';
|
||||
import { useConfigStore } from '@/stores/configStore';
|
||||
import { useEditorStore } from '@/stores/editorStore';
|
||||
import { useErrorHandler } from '@/utils/errorHandler';
|
||||
import * as runtime from '@wailsio/runtime';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const editorStore = useEditorStore();
|
||||
const configStore = useConfigStore();
|
||||
const logStore = useLogStore();
|
||||
const { safeCall } = useErrorHandler();
|
||||
const { t, locale } = useI18n();
|
||||
const router = useRouter();
|
||||
|
||||
// 语言下拉菜单
|
||||
const showLanguageMenu = ref(false);
|
||||
|
||||
// 切换语言
|
||||
const changeLanguage = async (localeCode: SupportedLocaleType) => {
|
||||
await safeCall(
|
||||
() => configStore.setLocale(localeCode),
|
||||
'config.languageChangeFailed'
|
||||
);
|
||||
showLanguageMenu.value = false;
|
||||
};
|
||||
const supportedLanguages = [
|
||||
{ code: 'zh-CN', name: '简体中文' },
|
||||
{ code: 'en-US', name: 'English' }
|
||||
];
|
||||
|
||||
// 切换语言菜单显示
|
||||
const toggleLanguageMenu = () => {
|
||||
showLanguageMenu.value = !showLanguageMenu.value;
|
||||
};
|
||||
|
||||
// 窗口置顶控制
|
||||
const closeLanguageMenu = () => {
|
||||
showLanguageMenu.value = false;
|
||||
};
|
||||
|
||||
const changeLanguage = async (langCode: string) => {
|
||||
await safeCall(() => configStore.setLanguage(langCode as any), 'language.changeFailed');
|
||||
closeLanguageMenu();
|
||||
};
|
||||
|
||||
// 设置窗口置顶
|
||||
const setWindowAlwaysOnTop = async (isTop: boolean) => {
|
||||
await safeCall(async () => {
|
||||
await runtime.Window.SetAlwaysOnTop(isTop);
|
||||
}, 'window.setTopFailed');
|
||||
};
|
||||
|
||||
// 切换窗口置顶
|
||||
const toggleAlwaysOnTop = async () => {
|
||||
await safeCall(async () => {
|
||||
await configStore.toggleAlwaysOnTop();
|
||||
// 使用Window.SetAlwaysOnTop方法设置窗口置顶状态
|
||||
await runtime.Window.SetAlwaysOnTop(configStore.config.alwaysOnTop);
|
||||
await runtime.Window.SetAlwaysOnTop(configStore.config.general.alwaysOnTop);
|
||||
}, 'config.alwaysOnTopFailed');
|
||||
};
|
||||
|
||||
// 打开设置页面
|
||||
const openSettings = () => {
|
||||
// 跳转到设置页面
|
||||
const goToSettings = () => {
|
||||
router.push('/settings');
|
||||
};
|
||||
|
||||
// 设置窗口置顶状态的通用函数
|
||||
const setWindowAlwaysOnTop = async (alwaysOnTop: boolean) => {
|
||||
await safeCall(
|
||||
() => runtime.Window.SetAlwaysOnTop(alwaysOnTop),
|
||||
'config.alwaysOnTopFailed'
|
||||
);
|
||||
};
|
||||
const isLoaded = ref(false);
|
||||
|
||||
// 初始化配置
|
||||
onMounted(async () => {
|
||||
// 加载配置
|
||||
if (!configStore.configLoaded) {
|
||||
await configStore.initConfig();
|
||||
}
|
||||
|
||||
// 设置窗口置顶状态
|
||||
if (configStore.config.alwaysOnTop) {
|
||||
await setWindowAlwaysOnTop(true);
|
||||
}
|
||||
onMounted(() => {
|
||||
isLoaded.value = true;
|
||||
});
|
||||
|
||||
// 监听配置加载完成
|
||||
watch(() => configStore.configLoaded, (isLoaded) => {
|
||||
if (isLoaded && configStore.config.alwaysOnTop) {
|
||||
setWindowAlwaysOnTop(true);
|
||||
// 监听置顶设置变化
|
||||
watch(
|
||||
() => configStore.config.general.alwaysOnTop,
|
||||
async (newValue) => {
|
||||
if (!isLoaded.value) return;
|
||||
await runtime.Window.SetAlwaysOnTop(newValue);
|
||||
}
|
||||
);
|
||||
|
||||
// 在组件加载完成后应用置顶设置
|
||||
watch(isLoaded, async (newLoaded) => {
|
||||
if (newLoaded && configStore.config.general.alwaysOnTop) {
|
||||
await setWindowAlwaysOnTop(true);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -86,34 +90,30 @@ watch(() => configStore.configLoaded, (isLoaded) => {
|
||||
<span class="stat-item" :title="t('toolbar.editor.selected')" v-if="editorStore.documentStats.selectedCharacters > 0">
|
||||
{{ t('toolbar.editor.selected') }}: <span class="stat-value">{{ editorStore.documentStats.selectedCharacters }}</span>
|
||||
</span>
|
||||
<span v-if="logStore.showLog && logStore.latestLog" class="log-item" :class="'log-' + logStore.latestLog.level"
|
||||
@click="logStore.hideCurrentLog()">
|
||||
{{ logStore.latestLog.message }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<span class="font-size" :title="t('toolbar.fontSizeTooltip')" @click="() => configStore.resetFontSize()">
|
||||
{{ configStore.config.fontSize }}px
|
||||
{{ configStore.config.editing.fontSize }}px
|
||||
</span>
|
||||
<span class="tab-settings">
|
||||
<label :title="t('toolbar.tabLabel')" class="tab-toggle">
|
||||
<input type="checkbox" :checked="configStore.config.enableTabIndent" @change="() => configStore.toggleTabIndent()"/>
|
||||
<input type="checkbox" :checked="configStore.config.editing.enableTabIndent" @change="() => configStore.toggleTabIndent()"/>
|
||||
<span>{{ t('toolbar.tabLabel') }}</span>
|
||||
</label>
|
||||
<span class="tab-type" :title="t('toolbar.tabType.' + (configStore.config.tabType === 'spaces' ? 'spaces' : 'tab'))" @click="() => configStore.toggleTabType()">
|
||||
{{ t('toolbar.tabType.' + (configStore.config.tabType === 'spaces' ? 'spaces' : 'tab')) }}
|
||||
<span class="tab-type" :title="t('toolbar.tabType.' + (configStore.config.editing.tabType === 'spaces' ? 'spaces' : 'tab'))" @click="() => configStore.toggleTabType()">
|
||||
{{ t('toolbar.tabType.' + (configStore.config.editing.tabType === 'spaces' ? 'spaces' : 'tab')) }}
|
||||
</span>
|
||||
<span class="tab-size" title="Tab大小" v-if="configStore.config.tabType === 'spaces'">
|
||||
<button class="tab-btn" @click="() => configStore.decreaseTabSize()" :disabled="configStore.config.tabSize <= configStore.tabSize.min">-</button>
|
||||
<span>{{ configStore.config.tabSize }}</span>
|
||||
<button class="tab-btn" @click="() => configStore.increaseTabSize()" :disabled="configStore.config.tabSize >= configStore.tabSize.max">+</button>
|
||||
<span class="tab-size" title="Tab大小" v-if="configStore.config.editing.tabType === 'spaces'">
|
||||
<button class="tab-btn" @click="() => configStore.decreaseTabSize()" :disabled="configStore.config.editing.tabSize <= configStore.tabSize.min">-</button>
|
||||
<span>{{ configStore.config.editing.tabSize }}</span>
|
||||
<button class="tab-btn" @click="() => configStore.increaseTabSize()" :disabled="configStore.config.editing.tabSize >= configStore.tabSize.max">+</button>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<!-- 窗口置顶图标按钮 -->
|
||||
<div
|
||||
class="pin-button"
|
||||
:class="{ 'active': configStore.config.alwaysOnTop }"
|
||||
:class="{ 'active': configStore.config.general.alwaysOnTop }"
|
||||
:title="t('toolbar.alwaysOnTop')"
|
||||
@click="toggleAlwaysOnTop"
|
||||
>
|
||||
@@ -130,7 +130,7 @@ watch(() => configStore.configLoaded, (isLoaded) => {
|
||||
</button>
|
||||
<div class="selector-menu" v-if="showLanguageMenu">
|
||||
<div
|
||||
v-for="lang in SUPPORTED_LOCALES"
|
||||
v-for="lang in supportedLanguages"
|
||||
:key="lang.code"
|
||||
class="selector-option"
|
||||
:class="{ active: locale === lang.code }"
|
||||
@@ -141,7 +141,7 @@ watch(() => configStore.configLoaded, (isLoaded) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="settings-btn" :title="t('toolbar.settings')" @click="openSettings">
|
||||
<button class="settings-btn" :title="t('toolbar.settings')" @click="goToSettings">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="12" cy="12" r="3"></circle>
|
||||
@@ -177,24 +177,6 @@ watch(() => configStore.configLoaded, (isLoaded) => {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
}
|
||||
|
||||
.log-item {
|
||||
cursor: default;
|
||||
font-size: 12px;
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
&.log-info {
|
||||
color: rgba(177, 176, 176, 0.8);
|
||||
}
|
||||
|
||||
&.log-warning {
|
||||
color: rgba(240, 230, 140, 0.8);
|
||||
}
|
||||
|
||||
&.log-error {
|
||||
color: rgba(255, 107, 107, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
|
@@ -3,7 +3,7 @@ import {computed, reactive} from 'vue';
|
||||
import {
|
||||
ConfigService
|
||||
} from '@/../bindings/voidraft/internal/services';
|
||||
import {EditorConfig, TabType, LanguageType} from '@/../bindings/voidraft/internal/models/models';
|
||||
import {AppConfig, GeneralConfig, EditingConfig, AppearanceConfig, TabType, LanguageType} from '@/../bindings/voidraft/internal/models';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useErrorHandler } from '@/utils/errorHandler';
|
||||
import { ConfigUtils } from '@/utils/configUtils';
|
||||
@@ -24,26 +24,41 @@ export const SUPPORTED_LOCALES = [
|
||||
] as const;
|
||||
|
||||
// 配置键映射和限制的类型定义
|
||||
type ConfigKeyMap = {
|
||||
readonly [K in keyof EditorConfig]: string;
|
||||
type GeneralConfigKeyMap = {
|
||||
readonly [K in keyof GeneralConfig]: string;
|
||||
};
|
||||
|
||||
type EditingConfigKeyMap = {
|
||||
readonly [K in keyof EditingConfig]: string;
|
||||
};
|
||||
|
||||
type AppearanceConfigKeyMap = {
|
||||
readonly [K in keyof AppearanceConfig]: string;
|
||||
};
|
||||
|
||||
type NumberConfigKey = 'fontSize' | 'tabSize' | 'lineHeight';
|
||||
type StringConfigKey = 'fontFamily' | 'fontWeight';
|
||||
type BooleanConfigKey = 'enableTabIndent' | 'alwaysOnTop';
|
||||
type EnumConfigKey = 'tabType' | 'language';
|
||||
|
||||
// 配置键映射
|
||||
const CONFIG_KEY_MAP: ConfigKeyMap = {
|
||||
fontSize: 'editor.font_size',
|
||||
fontFamily: 'editor.font_family',
|
||||
fontWeight: 'editor.font_weight',
|
||||
lineHeight: 'editor.line_height',
|
||||
enableTabIndent: 'editor.enable_tab_indent',
|
||||
tabSize: 'editor.tab_size',
|
||||
tabType: 'editor.tab_type',
|
||||
language: 'editor.language',
|
||||
alwaysOnTop: 'editor.always_on_top'
|
||||
const GENERAL_CONFIG_KEY_MAP: GeneralConfigKeyMap = {
|
||||
alwaysOnTop: 'general.always_on_top',
|
||||
dataPath: 'general.data_path'
|
||||
} as const;
|
||||
|
||||
const EDITING_CONFIG_KEY_MAP: EditingConfigKeyMap = {
|
||||
fontSize: 'editing.font_size',
|
||||
fontFamily: 'editing.font_family',
|
||||
fontWeight: 'editing.font_weight',
|
||||
lineHeight: 'editing.line_height',
|
||||
enableTabIndent: 'editing.enable_tab_indent',
|
||||
tabSize: 'editing.tab_size',
|
||||
tabType: 'editing.tab_type',
|
||||
autoSaveDelay: 'editing.auto_save_delay',
|
||||
changeThreshold: 'editing.change_threshold',
|
||||
minSaveInterval: 'editing.min_save_interval'
|
||||
} as const;
|
||||
|
||||
const APPEARANCE_CONFIG_KEY_MAP: AppearanceConfigKeyMap = {
|
||||
language: 'appearance.language'
|
||||
} as const;
|
||||
|
||||
// 配置限制
|
||||
@@ -80,16 +95,32 @@ const getBrowserLanguage = (): SupportedLocaleType => {
|
||||
};
|
||||
|
||||
// 默认配置
|
||||
const DEFAULT_CONFIG: EditorConfig = {
|
||||
fontSize: CONFIG_LIMITS.fontSize.default,
|
||||
fontFamily: FONT_OPTIONS[0].value,
|
||||
fontWeight: 'normal',
|
||||
lineHeight: CONFIG_LIMITS.lineHeight.default,
|
||||
enableTabIndent: true,
|
||||
tabSize: CONFIG_LIMITS.tabSize.default,
|
||||
tabType: CONFIG_LIMITS.tabType.default,
|
||||
language: LanguageType.LangZhCN,
|
||||
alwaysOnTop: false
|
||||
const DEFAULT_CONFIG: AppConfig = {
|
||||
general: {
|
||||
alwaysOnTop: false,
|
||||
dataPath: './data'
|
||||
},
|
||||
editing: {
|
||||
fontSize: CONFIG_LIMITS.fontSize.default,
|
||||
fontFamily: FONT_OPTIONS[0].value,
|
||||
fontWeight: 'normal',
|
||||
lineHeight: CONFIG_LIMITS.lineHeight.default,
|
||||
enableTabIndent: true,
|
||||
tabSize: CONFIG_LIMITS.tabSize.default,
|
||||
tabType: CONFIG_LIMITS.tabType.default,
|
||||
autoSaveDelay: 5000,
|
||||
changeThreshold: 500,
|
||||
minSaveInterval: 1000
|
||||
},
|
||||
appearance: {
|
||||
language: LanguageType.LangZhCN
|
||||
},
|
||||
keyBindings: {},
|
||||
updates: {},
|
||||
metadata: {
|
||||
version: '1.0.0',
|
||||
lastUpdated: null
|
||||
}
|
||||
};
|
||||
|
||||
export const useConfigStore = defineStore('config', () => {
|
||||
@@ -98,7 +129,7 @@ export const useConfigStore = defineStore('config', () => {
|
||||
|
||||
// 响应式状态
|
||||
const state = reactive({
|
||||
config: { ...DEFAULT_CONFIG } as EditorConfig,
|
||||
config: { ...DEFAULT_CONFIG } as AppConfig,
|
||||
isLoading: false,
|
||||
configLoaded: false
|
||||
});
|
||||
@@ -110,19 +141,49 @@ export const useConfigStore = defineStore('config', () => {
|
||||
) as Record<NumberConfigKey, ReturnType<typeof createLimitComputed>>;
|
||||
|
||||
// 通用配置更新方法
|
||||
const updateConfig = async <K extends keyof EditorConfig>(key: K, value: EditorConfig[K]): Promise<void> => {
|
||||
const updateGeneralConfig = async <K extends keyof GeneralConfig>(key: K, value: GeneralConfig[K]): Promise<void> => {
|
||||
// 确保配置已加载
|
||||
if (!state.configLoaded && !state.isLoading) {
|
||||
await initConfig();
|
||||
}
|
||||
|
||||
const backendKey = CONFIG_KEY_MAP[key];
|
||||
const backendKey = GENERAL_CONFIG_KEY_MAP[key];
|
||||
if (!backendKey) {
|
||||
throw new Error(`No backend key mapping found for ${key.toString()}`);
|
||||
throw new Error(`No backend key mapping found for general.${key.toString()}`);
|
||||
}
|
||||
|
||||
await ConfigService.Set(backendKey, value);
|
||||
state.config[key] = value;
|
||||
state.config.general[key] = value;
|
||||
};
|
||||
|
||||
const updateEditingConfig = async <K extends keyof EditingConfig>(key: K, value: EditingConfig[K]): Promise<void> => {
|
||||
// 确保配置已加载
|
||||
if (!state.configLoaded && !state.isLoading) {
|
||||
await initConfig();
|
||||
}
|
||||
|
||||
const backendKey = EDITING_CONFIG_KEY_MAP[key];
|
||||
if (!backendKey) {
|
||||
throw new Error(`No backend key mapping found for editing.${key.toString()}`);
|
||||
}
|
||||
|
||||
await ConfigService.Set(backendKey, value);
|
||||
state.config.editing[key] = value;
|
||||
};
|
||||
|
||||
const updateAppearanceConfig = async <K extends keyof AppearanceConfig>(key: K, value: AppearanceConfig[K]): Promise<void> => {
|
||||
// 确保配置已加载
|
||||
if (!state.configLoaded && !state.isLoading) {
|
||||
await initConfig();
|
||||
}
|
||||
|
||||
const backendKey = APPEARANCE_CONFIG_KEY_MAP[key];
|
||||
if (!backendKey) {
|
||||
throw new Error(`No backend key mapping found for appearance.${key.toString()}`);
|
||||
}
|
||||
|
||||
await ConfigService.Set(backendKey, value);
|
||||
state.config.appearance[key] = value;
|
||||
};
|
||||
|
||||
// 加载配置
|
||||
@@ -133,8 +194,14 @@ export const useConfigStore = defineStore('config', () => {
|
||||
try {
|
||||
const appConfig = await ConfigService.GetConfig();
|
||||
|
||||
if (appConfig?.editor) {
|
||||
Object.assign(state.config, appConfig.editor);
|
||||
if (appConfig) {
|
||||
// 合并配置
|
||||
if (appConfig.general) Object.assign(state.config.general, appConfig.general);
|
||||
if (appConfig.editing) Object.assign(state.config.editing, appConfig.editing);
|
||||
if (appConfig.appearance) Object.assign(state.config.appearance, appConfig.appearance);
|
||||
if (appConfig.keyBindings) Object.assign(state.config.keyBindings, appConfig.keyBindings);
|
||||
if (appConfig.updates) Object.assign(state.config.updates, appConfig.updates);
|
||||
if (appConfig.metadata) Object.assign(state.config.metadata, appConfig.metadata);
|
||||
}
|
||||
|
||||
state.configLoaded = true;
|
||||
@@ -149,23 +216,26 @@ export const useConfigStore = defineStore('config', () => {
|
||||
const clamp = (value: number) => ConfigUtils.clamp(value, limit.min, limit.max);
|
||||
|
||||
return {
|
||||
increase: () => safeCall(() => updateConfig(key, clamp(state.config[key] + 1)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
decrease: () => safeCall(() => updateConfig(key, clamp(state.config[key] - 1)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
set: (value: number) => safeCall(() => updateConfig(key, clamp(value)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
reset: () => safeCall(() => updateConfig(key, limit.default), 'config.saveFailed', 'config.saveSuccess')
|
||||
increase: () => safeCall(() => updateEditingConfig(key, clamp(state.config.editing[key] + 1)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
decrease: () => safeCall(() => updateEditingConfig(key, clamp(state.config.editing[key] - 1)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
set: (value: number) => safeCall(() => updateEditingConfig(key, clamp(value)), 'config.saveFailed', 'config.saveSuccess'),
|
||||
reset: () => safeCall(() => updateEditingConfig(key, limit.default), 'config.saveFailed', 'config.saveSuccess')
|
||||
};
|
||||
};
|
||||
|
||||
// 通用布尔值切换器
|
||||
const createToggler = <T extends BooleanConfigKey>(key: T) =>
|
||||
() => safeCall(() => updateConfig(key, !state.config[key]), 'config.saveFailed', 'config.saveSuccess');
|
||||
const createGeneralToggler = <T extends keyof GeneralConfig>(key: T) =>
|
||||
() => safeCall(() => updateGeneralConfig(key, !state.config.general[key] as GeneralConfig[T]), 'config.saveFailed', 'config.saveSuccess');
|
||||
|
||||
const createEditingToggler = <T extends keyof EditingConfig>(key: T) =>
|
||||
() => safeCall(() => updateEditingConfig(key, !state.config.editing[key] as EditingConfig[T]), 'config.saveFailed', 'config.saveSuccess');
|
||||
|
||||
// 枚举值切换器
|
||||
const createEnumToggler = <T extends TabType>(key: 'tabType', values: readonly T[]) =>
|
||||
() => {
|
||||
const currentIndex = values.indexOf(state.config[key] as T);
|
||||
const currentIndex = values.indexOf(state.config.editing[key] as T);
|
||||
const nextIndex = (currentIndex + 1) % values.length;
|
||||
return safeCall(() => updateConfig(key, values[nextIndex]), 'config.saveFailed', 'config.saveSuccess');
|
||||
return safeCall(() => updateEditingConfig(key, values[nextIndex]), 'config.saveFailed', 'config.saveSuccess');
|
||||
};
|
||||
|
||||
// 重置配置
|
||||
@@ -184,8 +254,7 @@ export const useConfigStore = defineStore('config', () => {
|
||||
// 语言设置方法
|
||||
const setLanguage = async (language: LanguageType): Promise<void> => {
|
||||
await safeCall(async () => {
|
||||
await ConfigService.Set(CONFIG_KEY_MAP.language, language);
|
||||
state.config.language = language;
|
||||
await updateAppearanceConfig('language', language);
|
||||
|
||||
// 同步更新前端语言
|
||||
const frontendLocale = ConfigUtils.backendLanguageToFrontend(language);
|
||||
@@ -193,12 +262,6 @@ export const useConfigStore = defineStore('config', () => {
|
||||
}, 'config.languageChangeFailed', 'config.languageChanged');
|
||||
};
|
||||
|
||||
// 通过前端语言代码设置语言
|
||||
const setLocale = async (localeCode: SupportedLocaleType): Promise<void> => {
|
||||
const backendLanguage = ConfigUtils.frontendLanguageToBackend(localeCode);
|
||||
await setLanguage(backendLanguage);
|
||||
};
|
||||
|
||||
// 初始化语言设置
|
||||
const initializeLanguage = async (): Promise<void> => {
|
||||
try {
|
||||
@@ -208,7 +271,7 @@ export const useConfigStore = defineStore('config', () => {
|
||||
}
|
||||
|
||||
// 同步前端语言设置
|
||||
const frontendLocale = ConfigUtils.backendLanguageToFrontend(state.config.language);
|
||||
const frontendLocale = ConfigUtils.backendLanguageToFrontend(state.config.appearance.language);
|
||||
locale.value = frontendLocale as any;
|
||||
} catch (error) {
|
||||
const browserLang = getBrowserLanguage();
|
||||
@@ -225,15 +288,16 @@ export const useConfigStore = defineStore('config', () => {
|
||||
|
||||
// 创建切换器实例
|
||||
const togglers = {
|
||||
tabIndent: createToggler('enableTabIndent'),
|
||||
alwaysOnTop: createToggler('alwaysOnTop'),
|
||||
tabIndent: createEditingToggler('enableTabIndent'),
|
||||
alwaysOnTop: createGeneralToggler('alwaysOnTop'),
|
||||
tabType: createEnumToggler('tabType', CONFIG_LIMITS.tabType.values)
|
||||
};
|
||||
|
||||
// 字符串配置设置器
|
||||
const setters = {
|
||||
fontFamily: (value: string) => safeCall(() => updateConfig('fontFamily', value), 'config.saveFailed', 'config.saveSuccess'),
|
||||
fontWeight: (value: string) => safeCall(() => updateConfig('fontWeight', value), 'config.saveFailed', 'config.saveSuccess')
|
||||
fontFamily: (value: string) => safeCall(() => updateEditingConfig('fontFamily', value), 'config.saveFailed', 'config.saveSuccess'),
|
||||
fontWeight: (value: string) => safeCall(() => updateEditingConfig('fontWeight', value), 'config.saveFailed', 'config.saveSuccess'),
|
||||
dataPath: (value: string) => safeCall(() => updateGeneralConfig('dataPath', value), 'config.saveFailed', 'config.saveSuccess')
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -248,11 +312,9 @@ export const useConfigStore = defineStore('config', () => {
|
||||
// 核心方法
|
||||
initConfig: () => safeCall(() => initConfig(), 'config.loadFailed', 'config.loadSuccess'),
|
||||
resetConfig,
|
||||
updateConfig: (key: keyof EditorConfig, value: any) => safeCall(() => updateConfig(key, value), 'config.saveFailed', 'config.saveSuccess'),
|
||||
|
||||
// 语言相关方法
|
||||
setLanguage,
|
||||
setLocale,
|
||||
initializeLanguage,
|
||||
|
||||
// 字体大小操作
|
||||
@@ -279,6 +341,9 @@ export const useConfigStore = defineStore('config', () => {
|
||||
// 字体操作
|
||||
setFontFamily: setters.fontFamily,
|
||||
setFontWeight: setters.fontWeight,
|
||||
|
||||
// 路径操作
|
||||
setDataPath: setters.dataPath,
|
||||
};
|
||||
},{
|
||||
persist: true,
|
||||
|
@@ -33,7 +33,7 @@ export const useEditorStore = defineStore('editor', () => {
|
||||
// 更新编辑器的字体大小
|
||||
const editorDOM = editorView.value.dom;
|
||||
if (editorDOM) {
|
||||
editorDOM.style.fontSize = `${configStore.config.fontSize}px`;
|
||||
editorDOM.style.fontSize = `${configStore.config.editing.fontSize}px`;
|
||||
editorView.value?.requestMeasure();
|
||||
}
|
||||
}
|
||||
|
@@ -53,17 +53,17 @@ const createEditor = async () => {
|
||||
|
||||
// 获取Tab相关扩展
|
||||
const tabExtensions = getTabExtensions(
|
||||
configStore.config.tabSize,
|
||||
configStore.config.enableTabIndent,
|
||||
configStore.config.tabType
|
||||
configStore.config.editing.tabSize,
|
||||
configStore.config.editing.enableTabIndent,
|
||||
configStore.config.editing.tabType
|
||||
);
|
||||
|
||||
// 创建字体扩展
|
||||
const fontExtension = createFontExtensionFromBackend({
|
||||
fontFamily: configStore.config.fontFamily,
|
||||
fontSize: configStore.config.fontSize,
|
||||
lineHeight: configStore.config.lineHeight,
|
||||
fontWeight: configStore.config.fontWeight
|
||||
fontFamily: configStore.config.editing.fontFamily,
|
||||
fontSize: configStore.config.editing.fontSize,
|
||||
lineHeight: configStore.config.editing.lineHeight,
|
||||
fontWeight: configStore.config.editing.fontWeight
|
||||
});
|
||||
|
||||
// 创建统计信息更新扩展
|
||||
@@ -148,9 +148,9 @@ const reconfigureTabSettings = () => {
|
||||
if (!editorStore.editorView) return;
|
||||
updateTabConfig(
|
||||
editorStore.editorView as EditorView,
|
||||
configStore.config.tabSize,
|
||||
configStore.config.enableTabIndent,
|
||||
configStore.config.tabType
|
||||
configStore.config.editing.tabSize,
|
||||
configStore.config.editing.enableTabIndent,
|
||||
configStore.config.editing.tabType
|
||||
);
|
||||
};
|
||||
|
||||
@@ -158,33 +158,33 @@ const reconfigureTabSettings = () => {
|
||||
const reconfigureFontSettings = () => {
|
||||
if (!editorStore.editorView) return;
|
||||
updateFontConfig(editorStore.editorView as EditorView, {
|
||||
fontFamily: configStore.config.fontFamily,
|
||||
fontSize: configStore.config.fontSize,
|
||||
lineHeight: configStore.config.lineHeight,
|
||||
fontWeight: configStore.config.fontWeight
|
||||
fontFamily: configStore.config.editing.fontFamily,
|
||||
fontSize: configStore.config.editing.fontSize,
|
||||
lineHeight: configStore.config.editing.lineHeight,
|
||||
fontWeight: configStore.config.editing.fontWeight
|
||||
});
|
||||
};
|
||||
|
||||
// 监听Tab设置变化
|
||||
watch(() => configStore.config.tabSize, reconfigureTabSettings);
|
||||
watch(() => configStore.config.enableTabIndent, reconfigureTabSettings);
|
||||
watch(() => configStore.config.tabType, reconfigureTabSettings);
|
||||
watch([
|
||||
() => configStore.config.editing.tabSize,
|
||||
() => configStore.config.editing.enableTabIndent,
|
||||
() => configStore.config.editing.tabType,
|
||||
], () => {
|
||||
reconfigureTabSettings();
|
||||
});
|
||||
|
||||
// 监听字体大小变化
|
||||
watch(() => configStore.config.fontSize, () => {
|
||||
watch([
|
||||
() => configStore.config.editing.fontFamily,
|
||||
() => configStore.config.editing.fontSize,
|
||||
() => configStore.config.editing.lineHeight,
|
||||
() => configStore.config.editing.fontWeight,
|
||||
], () => {
|
||||
reconfigureFontSettings();
|
||||
editorStore.applyFontSize();
|
||||
});
|
||||
|
||||
// 监听字体族变化
|
||||
watch(() => configStore.config.fontFamily, reconfigureFontSettings);
|
||||
|
||||
// 监听字体粗细变化
|
||||
watch(() => configStore.config.fontWeight, reconfigureFontSettings);
|
||||
|
||||
// 监听行高变化
|
||||
watch(() => configStore.config.lineHeight, reconfigureFontSettings);
|
||||
|
||||
onMounted(() => {
|
||||
// 创建编辑器
|
||||
createEditor();
|
||||
|
@@ -47,7 +47,7 @@ const selectTheme = (themeId: string) => {
|
||||
<div class="settings-page">
|
||||
<SettingSection :title="t('settings.language')">
|
||||
<SettingItem :title="t('settings.language')" :description="t('settings.restartRequired')">
|
||||
<select class="select-input" :value="configStore.config.language" @change="updateLanguage">
|
||||
<select class="select-input" :value="configStore.config.appearance.language" @change="updateLanguage">
|
||||
<option v-for="option in languageOptions" :key="option.value" :value="option.value">
|
||||
{{ option.label }}
|
||||
</option>
|
||||
|
@@ -22,7 +22,7 @@ onMounted(async () => {
|
||||
|
||||
// 字体选择选项
|
||||
const fontFamilyOptions = FONT_OPTIONS;
|
||||
const currentFontFamily = computed(() => configStore.config.fontFamily);
|
||||
const currentFontFamily = computed(() => configStore.config.editing.fontFamily);
|
||||
|
||||
// 字体选择
|
||||
const handleFontFamilyChange = async (event: Event) => {
|
||||
@@ -60,7 +60,7 @@ const handleFontWeightChange = async (event: Event) => {
|
||||
|
||||
// 行高控制
|
||||
const increaseLineHeight = async () => {
|
||||
const newLineHeight = Math.min(3.0, configStore.config.lineHeight + 0.1);
|
||||
const newLineHeight = Math.min(3.0, configStore.config.editing.lineHeight + 0.1);
|
||||
await safeCall(
|
||||
() => configStore.setLineHeight(Math.round(newLineHeight * 10) / 10),
|
||||
'config.lineHeightIncreaseFailed'
|
||||
@@ -68,7 +68,7 @@ const increaseLineHeight = async () => {
|
||||
};
|
||||
|
||||
const decreaseLineHeight = async () => {
|
||||
const newLineHeight = Math.max(1.0, configStore.config.lineHeight - 0.1);
|
||||
const newLineHeight = Math.max(1.0, configStore.config.editing.lineHeight - 0.1);
|
||||
await safeCall(
|
||||
() => configStore.setLineHeight(Math.round(newLineHeight * 10) / 10),
|
||||
'config.lineHeightDecreaseFailed'
|
||||
@@ -92,7 +92,7 @@ const decreaseFontSize = async () => {
|
||||
|
||||
// Tab类型切换
|
||||
const tabTypeText = computed(() => {
|
||||
return configStore.config.tabType === TabType.TabTypeSpaces
|
||||
return configStore.config.editing.tabType === TabType.TabTypeSpaces
|
||||
? t('settings.spaces')
|
||||
: t('settings.tabs');
|
||||
});
|
||||
@@ -156,7 +156,7 @@ const handleToggleTabType = async () => {
|
||||
>
|
||||
<div class="number-control">
|
||||
<button @click="decreaseFontSize" class="control-button">-</button>
|
||||
<span>{{ configStore.config.fontSize }}px</span>
|
||||
<span>{{ configStore.config.editing.fontSize }}px</span>
|
||||
<button @click="increaseFontSize" class="control-button">+</button>
|
||||
</div>
|
||||
</SettingItem>
|
||||
@@ -167,7 +167,7 @@ const handleToggleTabType = async () => {
|
||||
>
|
||||
<select
|
||||
class="font-weight-select"
|
||||
:value="configStore.config.fontWeight"
|
||||
:value="configStore.config.editing.fontWeight"
|
||||
@change="handleFontWeightChange"
|
||||
>
|
||||
<option
|
||||
@@ -186,16 +186,16 @@ const handleToggleTabType = async () => {
|
||||
>
|
||||
<div class="number-control">
|
||||
<button @click="decreaseLineHeight" class="control-button">-</button>
|
||||
<span>{{ configStore.config.lineHeight.toFixed(1) }}</span>
|
||||
<span>{{ configStore.config.editing.lineHeight.toFixed(1) }}</span>
|
||||
<button @click="increaseLineHeight" class="control-button">+</button>
|
||||
</div>
|
||||
</SettingItem>
|
||||
|
||||
<div class="font-preview" :style="{
|
||||
fontSize: `${configStore.config.fontSize}px`,
|
||||
fontFamily: configStore.config.fontFamily,
|
||||
fontWeight: configStore.config.fontWeight,
|
||||
lineHeight: configStore.config.lineHeight
|
||||
fontSize: `${configStore.config.editing.fontSize}px`,
|
||||
fontFamily: configStore.config.editing.fontFamily,
|
||||
fontWeight: configStore.config.editing.fontWeight,
|
||||
lineHeight: configStore.config.editing.lineHeight
|
||||
}">
|
||||
<div class="preview-label">字体预览</div>
|
||||
<div class="preview-text">
|
||||
@@ -210,9 +210,9 @@ const handleToggleTabType = async () => {
|
||||
<SettingSection :title="t('settings.tabSettings')">
|
||||
<SettingItem :title="t('settings.tabSize')">
|
||||
<div class="number-control">
|
||||
<button @click="decreaseTabSize" class="control-button" :disabled="configStore.config.tabSize <= configStore.tabSize.min">-</button>
|
||||
<span>{{ configStore.config.tabSize }}</span>
|
||||
<button @click="increaseTabSize" class="control-button" :disabled="configStore.config.tabSize >= configStore.tabSize.max">+</button>
|
||||
<button @click="decreaseTabSize" class="control-button" :disabled="configStore.config.editing.tabSize <= configStore.tabSize.min">-</button>
|
||||
<span>{{ configStore.config.editing.tabSize }}</span>
|
||||
<button @click="increaseTabSize" class="control-button" :disabled="configStore.config.editing.tabSize >= configStore.tabSize.max">+</button>
|
||||
</div>
|
||||
</SettingItem>
|
||||
|
||||
@@ -224,7 +224,7 @@ const handleToggleTabType = async () => {
|
||||
|
||||
<SettingItem :title="t('settings.enableTabIndent')">
|
||||
<ToggleSwitch
|
||||
v-model="configStore.config.enableTabIndent"
|
||||
v-model="configStore.config.editing.enableTabIndent"
|
||||
@update:modelValue="handleToggleTabIndent"
|
||||
/>
|
||||
</SettingItem>
|
||||
|
@@ -52,7 +52,7 @@ const resetSettings = async () => {
|
||||
<div class="settings-page">
|
||||
<SettingSection :title="t('settings.globalHotkey')">
|
||||
<SettingItem :title="t('settings.enableGlobalHotkey')">
|
||||
<ToggleSwitch v-model="configStore.config.alwaysOnTop" /> <!-- 此处使用alwaysOnTop作为示例 -->
|
||||
<ToggleSwitch v-model="configStore.config.general.alwaysOnTop" /> <!-- 此处使用alwaysOnTop作为示例 -->
|
||||
</SettingItem>
|
||||
|
||||
<div class="hotkey-selector">
|
||||
@@ -87,19 +87,19 @@ const resetSettings = async () => {
|
||||
|
||||
<SettingSection :title="t('settings.window')">
|
||||
<SettingItem :title="t('settings.showInSystemTray')">
|
||||
<ToggleSwitch v-model="configStore.config.alwaysOnTop" /> <!-- 需要后端实现 -->
|
||||
<ToggleSwitch v-model="configStore.config.general.alwaysOnTop" /> <!-- 需要后端实现 -->
|
||||
</SettingItem>
|
||||
<SettingItem :title="t('settings.alwaysOnTop')">
|
||||
<ToggleSwitch v-model="configStore.config.alwaysOnTop" @update:modelValue="configStore.toggleAlwaysOnTop" />
|
||||
<ToggleSwitch v-model="configStore.config.general.alwaysOnTop" @update:modelValue="configStore.toggleAlwaysOnTop" />
|
||||
</SettingItem>
|
||||
</SettingSection>
|
||||
|
||||
<SettingSection :title="t('settings.bufferFiles')">
|
||||
<SettingItem :title="t('settings.useCustomLocation')">
|
||||
<ToggleSwitch v-model="configStore.config.alwaysOnTop" /> <!-- 需要后端实现 -->
|
||||
<ToggleSwitch v-model="configStore.config.general.alwaysOnTop" /> <!-- 需要后端实现 -->
|
||||
</SettingItem>
|
||||
<div class="directory-selector">
|
||||
<div class="path-display">{{ configStore.config.alwaysOnTop ? 'C:/Custom/Path' : 'Default Location' }}</div>
|
||||
<div class="path-display">{{ configStore.config.general.alwaysOnTop ? 'C:/Custom/Path' : 'Default Location' }}</div>
|
||||
<button class="select-button">{{ t('settings.selectDirectory') }}</button>
|
||||
</div>
|
||||
</SettingSection>
|
||||
|
@@ -16,29 +16,6 @@ const (
|
||||
TabTypeTab TabType = "tab"
|
||||
)
|
||||
|
||||
// DocumentConfig 定义文档配置
|
||||
type DocumentConfig struct {
|
||||
// 自动保存延迟(毫秒)- 内容变更后多久自动保存
|
||||
AutoSaveDelay int `json:"autoSaveDelay" yaml:"auto_save_delay" mapstructure:"auto_save_delay"`
|
||||
// 变更字符阈值,超过此阈值立即触发保存
|
||||
ChangeThreshold int `json:"changeThreshold" yaml:"change_threshold" mapstructure:"change_threshold"`
|
||||
// 最小保存间隔(毫秒)- 两次保存之间的最小时间间隔,避免频繁IO
|
||||
MinSaveInterval int `json:"minSaveInterval" yaml:"min_save_interval" mapstructure:"min_save_interval"`
|
||||
}
|
||||
|
||||
// EditorConfig 定义编辑器配置
|
||||
type EditorConfig struct {
|
||||
FontSize int `json:"fontSize" yaml:"font_size" mapstructure:"font_size"` // 字体大小
|
||||
FontFamily string `json:"fontFamily" yaml:"font_family" mapstructure:"font_family"` // 字体族
|
||||
FontWeight string `json:"fontWeight" yaml:"font_weight" mapstructure:"font_weight"` // 字体粗细
|
||||
LineHeight float64 `json:"lineHeight" yaml:"line_height" mapstructure:"line_height"` // 行高
|
||||
EnableTabIndent bool `json:"enableTabIndent" yaml:"enable_tab_indent" mapstructure:"enable_tab_indent"` // 是否启用Tab缩进
|
||||
TabSize int `json:"tabSize" yaml:"tab_size" mapstructure:"tab_size"` // Tab大小
|
||||
TabType TabType `json:"tabType" yaml:"tab_type" mapstructure:"tab_type"` // Tab类型(空格或Tab)
|
||||
Language LanguageType `json:"language" yaml:"language" mapstructure:"language"` // 界面语言
|
||||
AlwaysOnTop bool `json:"alwaysOnTop" yaml:"always_on_top" mapstructure:"always_on_top"` // 窗口是否置顶
|
||||
}
|
||||
|
||||
// LanguageType 语言类型定义
|
||||
type LanguageType string
|
||||
|
||||
@@ -49,17 +26,54 @@ const (
|
||||
LangEnUS LanguageType = "en-US"
|
||||
)
|
||||
|
||||
// PathsConfig 路径配置集合
|
||||
type PathsConfig struct {
|
||||
DataPath string `json:"dataPath" yaml:"data_path" mapstructure:"data_path"` // 数据存储路径
|
||||
// GeneralConfig 通用设置配置
|
||||
type GeneralConfig struct {
|
||||
AlwaysOnTop bool `json:"alwaysOnTop" yaml:"always_on_top" mapstructure:"always_on_top"` // 窗口是否置顶
|
||||
DataPath string `json:"dataPath" yaml:"data_path" mapstructure:"data_path"` // 数据存储路径
|
||||
}
|
||||
|
||||
// AppConfig 应用配置 - 包含业务配置和路径配置
|
||||
// EditingConfig 编辑设置配置
|
||||
type EditingConfig struct {
|
||||
// 字体设置
|
||||
FontSize int `json:"fontSize" yaml:"font_size" mapstructure:"font_size"` // 字体大小
|
||||
FontFamily string `json:"fontFamily" yaml:"font_family" mapstructure:"font_family"` // 字体族
|
||||
FontWeight string `json:"fontWeight" yaml:"font_weight" mapstructure:"font_weight"` // 字体粗细
|
||||
LineHeight float64 `json:"lineHeight" yaml:"line_height" mapstructure:"line_height"` // 行高
|
||||
|
||||
// Tab设置
|
||||
EnableTabIndent bool `json:"enableTabIndent" yaml:"enable_tab_indent" mapstructure:"enable_tab_indent"` // 是否启用Tab缩进
|
||||
TabSize int `json:"tabSize" yaml:"tab_size" mapstructure:"tab_size"` // Tab大小
|
||||
TabType TabType `json:"tabType" yaml:"tab_type" mapstructure:"tab_type"` // Tab类型(空格或Tab)
|
||||
|
||||
// 保存选项
|
||||
AutoSaveDelay int `json:"autoSaveDelay" yaml:"auto_save_delay" mapstructure:"auto_save_delay"` // 自动保存延迟(毫秒)
|
||||
ChangeThreshold int `json:"changeThreshold" yaml:"change_threshold" mapstructure:"change_threshold"` // 变更字符阈值
|
||||
MinSaveInterval int `json:"minSaveInterval" yaml:"min_save_interval" mapstructure:"min_save_interval"` // 最小保存间隔(毫秒)
|
||||
}
|
||||
|
||||
// AppearanceConfig 外观设置配置
|
||||
type AppearanceConfig struct {
|
||||
Language LanguageType `json:"language" yaml:"language" mapstructure:"language"` // 界面语言
|
||||
}
|
||||
|
||||
// KeyBindingsConfig 快捷键设置配置
|
||||
type KeyBindingsConfig struct {
|
||||
// 预留给未来的快捷键配置
|
||||
}
|
||||
|
||||
// UpdatesConfig 更新设置配置
|
||||
type UpdatesConfig struct {
|
||||
// 预留给未来的更新配置
|
||||
}
|
||||
|
||||
// AppConfig 应用配置 - 按照前端设置页面分类组织
|
||||
type AppConfig struct {
|
||||
Editor EditorConfig `json:"editor" yaml:"editor" mapstructure:"editor"` // 编辑器配置
|
||||
Document DocumentConfig `json:"document" yaml:"document" mapstructure:"document"` // 文档配置
|
||||
Paths PathsConfig `json:"paths" yaml:"paths" mapstructure:"paths"` // 路径配置
|
||||
Metadata ConfigMetadata `json:"metadata" yaml:"metadata" mapstructure:"metadata"` // 配置元数据
|
||||
General GeneralConfig `json:"general" yaml:"general" mapstructure:"general"` // 通用设置
|
||||
Editing EditingConfig `json:"editing" yaml:"editing" mapstructure:"editing"` // 编辑设置
|
||||
Appearance AppearanceConfig `json:"appearance" yaml:"appearance" mapstructure:"appearance"` // 外观设置
|
||||
KeyBindings KeyBindingsConfig `json:"keyBindings" yaml:"key_bindings" mapstructure:"key_bindings"` // 快捷键设置
|
||||
Updates UpdatesConfig `json:"updates" yaml:"updates" mapstructure:"updates"` // 更新设置
|
||||
Metadata ConfigMetadata `json:"metadata" yaml:"metadata" mapstructure:"metadata"` // 配置元数据
|
||||
}
|
||||
|
||||
// ConfigMetadata 配置元数据
|
||||
@@ -80,24 +94,33 @@ func NewDefaultAppConfig() *AppConfig {
|
||||
dataDir := filepath.Join(currentDir, "data")
|
||||
|
||||
return &AppConfig{
|
||||
Editor: EditorConfig{
|
||||
FontSize: 13,
|
||||
FontFamily: `"HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif`,
|
||||
FontWeight: "normal",
|
||||
LineHeight: 1.5,
|
||||
General: GeneralConfig{
|
||||
AlwaysOnTop: false,
|
||||
DataPath: dataDir,
|
||||
},
|
||||
Editing: EditingConfig{
|
||||
// 字体设置
|
||||
FontSize: 13,
|
||||
FontFamily: `"HarmonyOS Sans SC", "HarmonyOS Sans", "Microsoft YaHei", "PingFang SC", "Helvetica Neue", Arial, sans-serif`,
|
||||
FontWeight: "normal",
|
||||
LineHeight: 1.5,
|
||||
// Tab设置
|
||||
EnableTabIndent: true,
|
||||
TabSize: 4,
|
||||
TabType: TabTypeSpaces,
|
||||
Language: LangZhCN,
|
||||
AlwaysOnTop: false,
|
||||
},
|
||||
Document: DocumentConfig{
|
||||
// 保存选项
|
||||
AutoSaveDelay: 5000, // 5秒后自动保存
|
||||
ChangeThreshold: 500, // 500个字符变更触发保存
|
||||
MinSaveInterval: 1000, // 最小间隔1000毫秒
|
||||
},
|
||||
Paths: PathsConfig{
|
||||
DataPath: dataDir,
|
||||
Appearance: AppearanceConfig{
|
||||
Language: LangZhCN,
|
||||
},
|
||||
KeyBindings: KeyBindingsConfig{
|
||||
// 预留给未来的快捷键配置
|
||||
},
|
||||
Updates: UpdatesConfig{
|
||||
// 预留给未来的更新配置
|
||||
},
|
||||
Metadata: ConfigMetadata{
|
||||
Version: "1.0.0",
|
||||
|
@@ -68,7 +68,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
fixed := false
|
||||
|
||||
switch key {
|
||||
case "editor.font_size":
|
||||
case "editing.font_size":
|
||||
if intVal, ok := value.(int); ok {
|
||||
if intVal < limits.FontSizeMin {
|
||||
cs.logger.Warning("Config: Font size too small, fixing", "original", intVal, "fixed", limits.FontSizeMin)
|
||||
@@ -80,7 +80,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "editor.tab_size":
|
||||
case "editing.tab_size":
|
||||
if intVal, ok := value.(int); ok {
|
||||
if intVal < limits.TabSizeMin {
|
||||
cs.logger.Warning("Config: Tab size too small, fixing", "original", intVal, "fixed", limits.TabSizeMin)
|
||||
@@ -92,7 +92,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "editor.tab_type":
|
||||
case "editing.tab_type":
|
||||
if strVal, ok := value.(string); ok {
|
||||
validTypes := []string{string(models.TabTypeSpaces), string(models.TabTypeTab)}
|
||||
isValid := false
|
||||
@@ -108,7 +108,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "editor.language":
|
||||
case "appearance.language":
|
||||
if strVal, ok := value.(string); ok {
|
||||
validLanguages := []string{string(models.LangZhCN), string(models.LangEnUS)}
|
||||
isValid := false
|
||||
@@ -124,7 +124,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "document.auto_save_delay":
|
||||
case "editing.auto_save_delay":
|
||||
if intVal, ok := value.(int); ok {
|
||||
if intVal < 1000 {
|
||||
cs.logger.Warning("Config: Auto save delay too small, fixing", "original", intVal, "fixed", 1000)
|
||||
@@ -136,7 +136,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "document.change_threshold":
|
||||
case "editing.change_threshold":
|
||||
if intVal, ok := value.(int); ok {
|
||||
if intVal < 10 {
|
||||
cs.logger.Warning("Config: Change threshold too small, fixing", "original", intVal, "fixed", 10)
|
||||
@@ -148,7 +148,7 @@ func (cs *ConfigService) validateAndFixValue(key string, value interface{}) (int
|
||||
}
|
||||
}
|
||||
|
||||
case "document.min_save_interval":
|
||||
case "editing.min_save_interval":
|
||||
if intVal, ok := value.(int); ok {
|
||||
if intVal < 100 {
|
||||
cs.logger.Warning("Config: Min save interval too small, fixing", "original", intVal, "fixed", 100)
|
||||
@@ -175,39 +175,39 @@ func (cs *ConfigService) validateAllConfig() error {
|
||||
}
|
||||
|
||||
// 验证编辑器配置
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editor.font_size", config.Editor.FontSize); fixed {
|
||||
cs.viper.Set("editor.font_size", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.font_size", config.Editing.FontSize); fixed {
|
||||
cs.viper.Set("editing.font_size", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editor.tab_size", config.Editor.TabSize); fixed {
|
||||
cs.viper.Set("editor.tab_size", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.tab_size", config.Editing.TabSize); fixed {
|
||||
cs.viper.Set("editing.tab_size", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editor.tab_type", string(config.Editor.TabType)); fixed {
|
||||
cs.viper.Set("editor.tab_type", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.tab_type", string(config.Editing.TabType)); fixed {
|
||||
cs.viper.Set("editing.tab_type", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editor.language", string(config.Editor.Language)); fixed {
|
||||
cs.viper.Set("editor.language", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("appearance.language", string(config.Appearance.Language)); fixed {
|
||||
cs.viper.Set("appearance.language", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
// 验证文档配置
|
||||
if fixedValue, fixed := cs.validateAndFixValue("document.auto_save_delay", config.Document.AutoSaveDelay); fixed {
|
||||
cs.viper.Set("document.auto_save_delay", fixedValue)
|
||||
// 验证保存选项配置
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.auto_save_delay", config.Editing.AutoSaveDelay); fixed {
|
||||
cs.viper.Set("editing.auto_save_delay", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
if fixedValue, fixed := cs.validateAndFixValue("document.change_threshold", config.Document.ChangeThreshold); fixed {
|
||||
cs.viper.Set("document.change_threshold", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.change_threshold", config.Editing.ChangeThreshold); fixed {
|
||||
cs.viper.Set("editing.change_threshold", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
if fixedValue, fixed := cs.validateAndFixValue("document.min_save_interval", config.Document.MinSaveInterval); fixed {
|
||||
cs.viper.Set("document.min_save_interval", fixedValue)
|
||||
if fixedValue, fixed := cs.validateAndFixValue("editing.min_save_interval", config.Editing.MinSaveInterval); fixed {
|
||||
cs.viper.Set("editing.min_save_interval", fixedValue)
|
||||
hasChanges = true
|
||||
}
|
||||
|
||||
@@ -280,24 +280,24 @@ func NewConfigService(logger *log.LoggerService) *ConfigService {
|
||||
func setDefaults(v *viper.Viper) {
|
||||
defaultConfig := models.NewDefaultAppConfig()
|
||||
|
||||
// 编辑器配置默认值
|
||||
v.SetDefault("editor.font_size", defaultConfig.Editor.FontSize)
|
||||
v.SetDefault("editor.font_family", defaultConfig.Editor.FontFamily)
|
||||
v.SetDefault("editor.font_weight", defaultConfig.Editor.FontWeight)
|
||||
v.SetDefault("editor.line_height", defaultConfig.Editor.LineHeight)
|
||||
v.SetDefault("editor.enable_tab_indent", defaultConfig.Editor.EnableTabIndent)
|
||||
v.SetDefault("editor.tab_size", defaultConfig.Editor.TabSize)
|
||||
v.SetDefault("editor.tab_type", defaultConfig.Editor.TabType)
|
||||
v.SetDefault("editor.language", defaultConfig.Editor.Language)
|
||||
v.SetDefault("editor.always_on_top", defaultConfig.Editor.AlwaysOnTop)
|
||||
// 通用设置默认值
|
||||
v.SetDefault("general.always_on_top", defaultConfig.General.AlwaysOnTop)
|
||||
v.SetDefault("general.data_path", defaultConfig.General.DataPath)
|
||||
|
||||
// 文档配置默认值
|
||||
v.SetDefault("document.auto_save_delay", defaultConfig.Document.AutoSaveDelay)
|
||||
v.SetDefault("document.change_threshold", defaultConfig.Document.ChangeThreshold)
|
||||
v.SetDefault("document.min_save_interval", defaultConfig.Document.MinSaveInterval)
|
||||
// 编辑设置默认值
|
||||
v.SetDefault("editing.font_size", defaultConfig.Editing.FontSize)
|
||||
v.SetDefault("editing.font_family", defaultConfig.Editing.FontFamily)
|
||||
v.SetDefault("editing.font_weight", defaultConfig.Editing.FontWeight)
|
||||
v.SetDefault("editing.line_height", defaultConfig.Editing.LineHeight)
|
||||
v.SetDefault("editing.enable_tab_indent", defaultConfig.Editing.EnableTabIndent)
|
||||
v.SetDefault("editing.tab_size", defaultConfig.Editing.TabSize)
|
||||
v.SetDefault("editing.tab_type", defaultConfig.Editing.TabType)
|
||||
v.SetDefault("editing.auto_save_delay", defaultConfig.Editing.AutoSaveDelay)
|
||||
v.SetDefault("editing.change_threshold", defaultConfig.Editing.ChangeThreshold)
|
||||
v.SetDefault("editing.min_save_interval", defaultConfig.Editing.MinSaveInterval)
|
||||
|
||||
// 路径配置默认值
|
||||
v.SetDefault("paths.data_path", defaultConfig.Paths.DataPath)
|
||||
// 外观设置默认值
|
||||
v.SetDefault("appearance.language", defaultConfig.Appearance.Language)
|
||||
|
||||
// 元数据默认值
|
||||
v.SetDefault("metadata.version", defaultConfig.Metadata.Version)
|
||||
|
@@ -147,9 +147,9 @@ func (ds *DocumentService) scheduleAutoSave() {
|
||||
|
||||
// 打印保存设置,便于调试
|
||||
ds.logger.Debug("Document: Auto save settings",
|
||||
"autoSaveDelay", config.Document.AutoSaveDelay,
|
||||
"changeThreshold", config.Document.ChangeThreshold,
|
||||
"minSaveInterval", config.Document.MinSaveInterval)
|
||||
"autoSaveDelay", config.Editing.AutoSaveDelay,
|
||||
"changeThreshold", config.Editing.ChangeThreshold,
|
||||
"minSaveInterval", config.Editing.MinSaveInterval)
|
||||
|
||||
ds.lock.Lock()
|
||||
defer ds.lock.Unlock()
|
||||
@@ -160,7 +160,7 @@ func (ds *DocumentService) scheduleAutoSave() {
|
||||
}
|
||||
|
||||
// 创建新的自动保存定时器
|
||||
autoSaveDelay := config.Document.AutoSaveDelay
|
||||
autoSaveDelay := config.Editing.AutoSaveDelay
|
||||
ds.logger.Debug("Document: Scheduling auto save", "delay", autoSaveDelay)
|
||||
ds.scheduleTimerWithDelay(autoSaveDelay)
|
||||
}
|
||||
@@ -197,7 +197,7 @@ func (ds *DocumentService) saveToStore(trigger SaveTrigger) {
|
||||
|
||||
// 如果成功获取了配置,使用配置值
|
||||
if err == nil && config != nil {
|
||||
minInterval = config.Document.MinSaveInterval
|
||||
minInterval = config.Editing.MinSaveInterval
|
||||
}
|
||||
|
||||
// 如果是自动保存,检查最小保存间隔
|
||||
@@ -305,7 +305,7 @@ func (ds *DocumentService) ensureDocumentsDir() error {
|
||||
}
|
||||
|
||||
// 创建文档目录
|
||||
docsDir := filepath.Join(config.Paths.DataPath, "docs")
|
||||
docsDir := filepath.Join(config.General.DataPath, "docs")
|
||||
err = os.MkdirAll(docsDir, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -320,7 +320,7 @@ func (ds *DocumentService) getDocumentsDir() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(config.Paths.DataPath, "docs"), nil
|
||||
return filepath.Join(config.General.DataPath, "docs"), nil
|
||||
}
|
||||
|
||||
// getDefaultDocumentPath 获取默认文档路径
|
||||
@@ -405,7 +405,7 @@ func (ds *DocumentService) UpdateActiveDocumentContent(content string) error {
|
||||
|
||||
// 如果成功获取了配置,使用配置值
|
||||
if err == nil && config != nil {
|
||||
threshold = config.Document.ChangeThreshold
|
||||
threshold = config.Editing.ChangeThreshold
|
||||
}
|
||||
|
||||
ds.lock.Lock()
|
||||
@@ -520,26 +520,26 @@ func (ds *DocumentService) GetDiffInfo(oldText, newText string) DiffResult {
|
||||
}
|
||||
|
||||
// GetSaveSettings 获取文档保存设置
|
||||
func (ds *DocumentService) GetSaveSettings() (*models.DocumentConfig, error) {
|
||||
func (ds *DocumentService) GetSaveSettings() (*models.EditingConfig, error) {
|
||||
config, err := ds.configService.GetConfig()
|
||||
if err != nil {
|
||||
return nil, &DocumentError{Operation: "get_save_settings", Err: err}
|
||||
}
|
||||
return &config.Document, nil
|
||||
return &config.Editing, nil
|
||||
}
|
||||
|
||||
// UpdateSaveSettings 更新文档保存设置
|
||||
func (ds *DocumentService) UpdateSaveSettings(docConfig models.DocumentConfig) error {
|
||||
func (ds *DocumentService) UpdateSaveSettings(docConfig models.EditingConfig) error {
|
||||
// 使用配置服务的 Set 方法更新文档配置
|
||||
if err := ds.configService.Set("document.auto_save_delay", docConfig.AutoSaveDelay); err != nil {
|
||||
if err := ds.configService.Set("editing.auto_save_delay", docConfig.AutoSaveDelay); err != nil {
|
||||
return &DocumentError{Operation: "update_save_settings_auto_save_delay", Err: err}
|
||||
}
|
||||
|
||||
if err := ds.configService.Set("document.change_threshold", docConfig.ChangeThreshold); err != nil {
|
||||
if err := ds.configService.Set("editing.change_threshold", docConfig.ChangeThreshold); err != nil {
|
||||
return &DocumentError{Operation: "update_save_settings_change_threshold", Err: err}
|
||||
}
|
||||
|
||||
if err := ds.configService.Set("document.min_save_interval", docConfig.MinSaveInterval); err != nil {
|
||||
if err := ds.configService.Set("editing.min_save_interval", docConfig.MinSaveInterval); err != nil {
|
||||
return &DocumentError{Operation: "update_save_settings_min_save_interval", Err: err}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user