From c7b03e5efc3b5f68a80e0453ef5fc2df3b0a28a4 Mon Sep 17 00:00:00 2001 From: eondrcode <2106626532@qq.com> Date: Fri, 10 Jul 2026 11:42:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=BF=87=E9=95=BF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.ts | 201 +++++++++++++++++++++++++++++----------------- src/migrations.ts | 8 +- 2 files changed, 134 insertions(+), 75 deletions(-) diff --git a/src/main.ts b/src/main.ts index b598f58..c655bd4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -89,15 +89,20 @@ export default class Manager extends Plugin { this.appPlugins = (this.app as ObsidianAppWithInternals).plugins; this.appWorkspace = this.app.workspace; - console.log(`%c ${this.manifest.name} %c v${this.manifest.version} `, `padding: 2px; border-radius: 2px 0 0 2px; color: #fff; background: #5B5B5B;`, `padding: 2px; border-radius: 0 2px 2px 0; color: #fff; background: #409EFF;`); - await this.loadSettings(); - await runMigrations(this); - // 首次安装或未设置语言时,自动跟随 Obsidian 语言 - if (!this.settings.LANGUAGE_INITIALIZED || !this.settings.LANGUAGE) { - this.settings.LANGUAGE = this.getAppLanguage(); - this.settings.LANGUAGE_INITIALIZED = true; - await this.saveSettings(); - } + console.log(`%c ${this.manifest.name} %c v${this.manifest.version} `, `padding: 2px; border-radius: 2px 0 0 2px; color: #fff; background: #5B5B5B;`, `padding: 2px; border-radius: 0 2px 2px 0; color: #fff; background: #409EFF;`); + await this.loadSettings(); + let settingsDirty = false; + const markSettingsDirty = () => { + settingsDirty = true; + }; + + await runMigrations(this); + // 首次安装或未设置语言时,自动跟随 Obsidian 语言 + if (!this.settings.LANGUAGE_INITIALIZED || !this.settings.LANGUAGE) { + this.settings.LANGUAGE = this.getAppLanguage(); + this.settings.LANGUAGE_INITIALIZED = true; + markSettingsDirty(); + } // 初始化语言系统 this.translator = new Translator(this); let builtinTagsChanged = false; @@ -121,10 +126,10 @@ export default class Manager extends Plugin { color: "#B36BFF", }); builtinTagsChanged = true; - } - this.ensureBpmTagAndRecords(); - this.ensureSelfPluginRecord(); - if (this.normalizeBuiltinTagNames() || builtinTagsChanged) await this.saveSettings(); + } + const bpmRecordsChanged = this.ensureBpmTagAndRecords(); + const selfRecordChanged = this.ensureSelfPluginRecord({ save: false }); + if (this.normalizeBuiltinTagNames() || builtinTagsChanged || bpmRecordsChanged || selfRecordChanged) markSettingsDirty(); this.repoResolver = new RepoResolver(this); @@ -136,16 +141,19 @@ export default class Manager extends Plugin { // 初始化侧边栏图标 this.addRibbonIcon('folder-cog', this.translator.t('通用_管理器_文本'), () => { this.managerModal = new ManagerModal(this.app, this); this.managerModal.open(); }); - // 初始化设置界面 - this.addSettingTab(new ManagerSettingTab(this.app, this)); - if (this.settings.DELAY) { - this.enableDelay(); - } else { - this.disableDelay(); - } - Commands(this.app, this); - - this.agreement = new Agreement(this); + // 初始化设置界面 + this.addSettingTab(new ManagerSettingTab(this.app, this)); + const pluginsChanged = this.settings.DELAY + ? this.enableDelay({ save: false }) + : this.disableDelay({ save: false }); + if (pluginsChanged) markSettingsDirty(); + Commands(this.app, this); + + if (settingsDirty) { + await this.saveSettings(); + } + + this.agreement = new Agreement(this); void this.startupCheckForUpdates(); void this.startupMaintainBetaSources(); @@ -695,15 +703,24 @@ export default class Manager extends Plugin { await this.saveSettings(); } - public ensureBpmTagAndRecords() { - ensureBpmTagExists(this); - // 确保 BPM 安装的插件拥有标签 - this.settings.BPM_INSTALLED.forEach((id) => { - const mp = this.settings.Plugins.find(p => p.id === id); - if (mp && !mp.tags.includes(BPM_TAG_ID)) mp.tags.push(BPM_TAG_ID); - }); - this.settings.Plugins.forEach((plugin) => this.applySpecialPluginTags(plugin)); - } + public ensureBpmTagAndRecords(): boolean { + const previousStateJson = JSON.stringify({ + TAGS: this.settings.TAGS, + Plugins: this.settings.Plugins, + }); + ensureBpmTagExists(this); + // 确保 BPM 安装的插件拥有标签 + this.settings.BPM_INSTALLED.forEach((id) => { + const mp = this.settings.Plugins.find(p => p.id === id); + if (mp && !mp.tags.includes(BPM_TAG_ID)) mp.tags.push(BPM_TAG_ID); + }); + this.settings.Plugins.forEach((plugin) => this.applySpecialPluginTags(plugin)); + const nextStateJson = JSON.stringify({ + TAGS: this.settings.TAGS, + Plugins: this.settings.Plugins, + }); + return previousStateJson !== nextStateJson; + } private isEondrPlugin(pluginId: string): boolean { const normalizedId = pluginId.trim().toLowerCase(); @@ -756,31 +773,56 @@ export default class Manager extends Plugin { } // 确保 BPM 自身也存在于插件记录中(用于面板显示) - public ensureSelfPluginRecord() { - const id = this.manifest.id; - const existing = this.settings.Plugins.find(p => p.id === id); - if (this.settings.HIDES?.includes(id)) { - this.settings.HIDES = this.settings.HIDES.filter(x => x !== id); - } - if (!existing) { - this.settings.Plugins.push({ - id, - name: this.manifest.name, + public ensureSelfPluginRecord(options: { save?: boolean } = {}): boolean { + const shouldSave = options.save !== false; + let changed = false; + if (!Array.isArray(this.settings.Plugins)) { + this.settings.Plugins = []; + changed = true; + } + if (!Array.isArray(this.settings.HIDES)) { + this.settings.HIDES = []; + changed = true; + } + const id = this.manifest.id; + const existing = this.settings.Plugins.find(p => p.id === id); + if (this.settings.HIDES?.includes(id)) { + this.settings.HIDES = this.settings.HIDES.filter(x => x !== id); + changed = true; + } + if (!existing) { + this.settings.Plugins.push({ + id, + name: this.manifest.name, desc: this.manifest.description, group: "", tags: [], enabled: true, - delay: "", - note: "", - }); - void this.saveSettings(); - return; - } - existing.name = existing.name || this.manifest.name; - existing.desc = existing.desc || this.manifest.description; - existing.enabled = true; - existing.delay = ""; - } + delay: "", + note: "", + }); + if (shouldSave) void this.saveSettings(); + return true; + } + if (!existing.name) { + existing.name = this.manifest.name; + changed = true; + } + if (!existing.desc) { + existing.desc = this.manifest.description; + changed = true; + } + if (existing.enabled !== true) { + existing.enabled = true; + changed = true; + } + if (existing.delay !== "") { + existing.delay = ""; + changed = true; + } + if (changed && shouldSave) void this.saveSettings(); + return changed; + } private reloadIfCurrentModal() { try { void this.managerModal?.reloadShowData(); } catch { /* ignore */ } @@ -810,10 +852,10 @@ export default class Manager extends Plugin { } // 关闭延时 调用 - public disableDelay() { + public disableDelay(options: { save?: boolean } = {}): boolean { const plugins = Object.values(this.appPlugins.manifests).filter((pm: PluginManifest) => pm.id !== this.manifest.id); - this.synchronizePlugins(plugins); - } + return this.synchronizePlugins(plugins, options); + } // 开启延时 调用 private isBpmIgnoredPlugin(pluginId: string): boolean { @@ -825,13 +867,14 @@ export default class Manager extends Plugin { .filter((pm: PluginManifest) => pm.id !== this.manifest.id && !this.isBpmIgnoredPlugin(pm.id)); } - public enableDelay() { + public enableDelay(options: { save?: boolean } = {}): boolean { const plugins = Object.values(this.appPlugins.manifests).filter((pm: PluginManifest) => pm.id !== this.manifest.id); - // 同步插件 - this.synchronizePlugins(plugins); - // 开始延时启动插件 - this.getDelayManagedPluginManifests().forEach((plugin: PluginManifest) => this.startPluginWithDelay(plugin.id)); - } + // 同步插件 + const changed = this.synchronizePlugins(plugins, options); + // 开始延时启动插件 + this.getDelayManagedPluginManifests().forEach((plugin: PluginManifest) => this.startPluginWithDelay(plugin.id)); + return changed; + } // 为所有插件启动延迟 public async enableDelaysForAllPlugins() { @@ -890,12 +933,17 @@ export default class Manager extends Plugin { } // 同步插件到配置文件 - public synchronizePlugins(p1: PluginManifest[]) { - const manifestIds = new Set(p1.map((plugin) => plugin.id)); - const bpmInstalledIds = new Set(this.settings.BPM_INSTALLED || []); - const nextPlugins = this.settings.Plugins.filter((plugin) => { - return plugin.id === this.manifest.id || manifestIds.has(plugin.id); - }); + public synchronizePlugins(p1: PluginManifest[], options: { save?: boolean } = {}): boolean { + const previousStateJson = JSON.stringify({ + Plugins: this.settings.Plugins, + HIDES: this.settings.HIDES, + }); + const shouldSave = options.save !== false; + const manifestIds = new Set(p1.map((plugin) => plugin.id)); + const bpmInstalledIds = new Set(this.settings.BPM_INSTALLED || []); + const nextPlugins = this.settings.Plugins.filter((plugin) => { + return plugin.id === this.manifest.id || manifestIds.has(plugin.id); + }); const pluginSettingsById = new Map(nextPlugins.map((plugin) => [plugin.id, plugin])); p1.forEach(p1Item => { @@ -920,12 +968,17 @@ export default class Manager extends Plugin { } this.applySpecialPluginTags(mp); }); - this.settings.Plugins = nextPlugins; - // BPM 自身保持启用且不允许延迟 - this.ensureSelfPluginRecord(); - // 保存设置 - void this.saveSettings(); - } + this.settings.Plugins = nextPlugins; + // BPM 自身保持启用且不允许延迟 + this.ensureSelfPluginRecord({ save: false }); + const nextStateJson = JSON.stringify({ + Plugins: this.settings.Plugins, + HIDES: this.settings.HIDES, + }); + const changed = previousStateJson !== nextStateJson; + if (changed && shouldSave) void this.saveSettings(); + return changed; + } // 工具函数 public createTag(text: string, color: string, type: string) { diff --git a/src/migrations.ts b/src/migrations.ts index 5f971ae..05acf0a 100644 --- a/src/migrations.ts +++ b/src/migrations.ts @@ -225,6 +225,8 @@ export const runMigrations = async (manager: Manager): Promise => { .filter((migration) => compareVersions(migration.version, lastMigrationVersion) > 0) .sort((a, b) => compareVersions(a.version, b.version)); + let anyChange = false; + for (const migration of pendingMigrations) { if (manager.settings.DEBUG) { console.log("[BPM] Running migration", migration.version); @@ -239,7 +241,7 @@ export const runMigrations = async (manager: Manager): Promise => { * 否则下次启动会重复执行已经完成的迁移。 */ if (settingsChanged || manager.settings.MIGRATION_VERSION !== previousMigrationVersion) { - await manager.saveSettings(); + anyChange = true; } } @@ -251,6 +253,10 @@ export const runMigrations = async (manager: Manager): Promise => { */ if (!manager.settings.MIGRATION_VERSION || compareVersions(manager.settings.MIGRATION_VERSION, currentVersion) < 0) { manager.settings.MIGRATION_VERSION = currentVersion; + anyChange = true; + } + + if (anyChange) { await manager.saveSettings(); } };