From 94e0ad9c2c335979645e107147686e236de440e1 Mon Sep 17 00:00:00 2001 From: liuxuezhuo Date: Tue, 25 Aug 2026 21:26:33 +0800 Subject: [PATCH] fix(settings): refresh language row labels on live locale switch Obsidian's declarative reconciler re-renders every settings row except the one whose control triggered the change, so after switching the display language the language row kept the previous locale's name and description until the tab was reopened. Patch the row's leaf text nodes directly after update(); any later full render produces the same strings, so this cannot conflict with the reconciler. Co-authored-by: QoderAI (Qwen 3.8 Max) --- .gitignore | 1 + CHANGELOG.md | 3 +++ src/features/settings/settings-tab.ts | 23 +++++++++++++++++++++++ tests/__mocks__/obsidian.ts | 1 + 4 files changed, 28 insertions(+) diff --git a/.gitignore b/.gitignore index a0521ba..9c771f9 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ coverage/ # Temporary screenshots from automated UI verification /.cu_crop_*.png +/.verify-shots/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ae03ec..d633edf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,9 @@ version with its date and start a fresh empty `[Unreleased]` above it. mentions just like notes (chipified, no attachment preview); mixed drags combine note, folder, and image mentions, and only truly unsupported file types are reported as ignored. +- The settings language row now updates its own label and description + immediately when the display language is changed, instead of keeping + the previous language's text until the settings tab is reopened. ## [1.0.5] - 2026-08-18 diff --git a/src/features/settings/settings-tab.ts b/src/features/settings/settings-tab.ts index d249c12..f2afd65 100644 --- a/src/features/settings/settings-tab.ts +++ b/src/features/settings/settings-tab.ts @@ -438,8 +438,11 @@ export class QoderianSettingTab extends PluginSettingTab { await this.plugin.saveSettings(); if (key === 'locale') { + const previousName = t('settings.language.name'); + const previousDesc = t('settings.language.desc'); setLocale(this.plugin.settings.locale as Locale); this.update(); + this.refreshLocalizedLanguageRow(previousName, previousDesc); this.refreshViewChrome(); } else if (key === 'maxTabs') { for (const view of this.plugin.getAllViews()) { @@ -460,6 +463,26 @@ export class QoderianSettingTab extends PluginSettingTab { } } + /** + * Obsidian's declarative reconciler refreshes every row except the one + * whose control triggered the change, so after a live language switch the + * language row would keep the previous locale's labels until the tab is + * reopened. Patch its leaf text nodes directly; any later full render + * produces the same strings, so this cannot conflict. + */ + private refreshLocalizedLanguageRow(previousName: string, previousDesc: string): void { + const newName = t('settings.language.name'); + const newDesc = t('settings.language.desc'); + for (const el of Array.from(this.containerEl.querySelectorAll('*'))) { + if (el.children.length !== 0) continue; + if (el.textContent === previousName) { + el.setText(newName); + } else if (el.textContent === previousDesc) { + el.setText(newDesc); + } + } + } + /** * The declarative renderer reconciles `group.listEl` synchronously after * every `render` callback returns, removing children it does not own. diff --git a/tests/__mocks__/obsidian.ts b/tests/__mocks__/obsidian.ts index 0cf7c23..df7c678 100644 --- a/tests/__mocks__/obsidian.ts +++ b/tests/__mocks__/obsidian.ts @@ -24,6 +24,7 @@ export class PluginSettingTab { empty: jest.fn(), createEl: jest.fn().mockReturnValue({ createEl: jest.fn(), createDiv: jest.fn() }), createDiv: jest.fn().mockReturnValue({ createEl: jest.fn(), createDiv: jest.fn() }), + querySelectorAll: jest.fn().mockReturnValue([]), }; constructor(app: any, plugin: any) {