From c1db917210ffe36c99d3709b4146c9b2c7f030b1 Mon Sep 17 00:00:00 2001 From: sudacode Date: Thu, 23 Jul 2026 22:20:14 -0700 Subject: [PATCH] feat(settings): group Anki maturity fields under Known Words - Add maturityEnabled, matureThresholdDays, and per-tier maturity colors to Known Words subsection - Order maturity color fields new -> learning -> young -> mature - Route knownWordMaturityColors.* paths through the color control - Add registry tests for subsection grouping and field ordering --- src/config/settings/registry.test.ts | 26 ++++++++++++++++++++++++++ src/config/settings/registry.ts | 10 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/config/settings/registry.test.ts b/src/config/settings/registry.test.ts index e8390dba..f965e8e3 100644 --- a/src/config/settings/registry.test.ts +++ b/src/config/settings/registry.test.ts @@ -125,6 +125,32 @@ test('settings registry groups annotation display fields by config group', () => assert.equal(field('subtitleStyle.jlptColors.N1').control, 'color'); }); +test('settings registry groups maturity settings under Known Words with color controls', () => { + assert.equal(field('ankiConnect.knownWords.maturityEnabled').subsection, 'Known Words'); + assert.equal(field('ankiConnect.knownWords.matureThresholdDays').subsection, 'Known Words'); + for (const tier of ['new', 'learning', 'young', 'mature']) { + const tierField = field(`subtitleStyle.knownWordMaturityColors.${tier}`); + assert.equal(tierField.subsection, 'Known Words'); + assert.equal(tierField.control, 'color'); + } +}); + +test('settings registry orders maturity colors from least mature to mature', () => { + const knownWordsPaths = fields + .filter((candidate) => candidate.subsection === 'Known Words') + .map((candidate) => candidate.configPath); + assert.deepEqual(knownWordsPaths, [ + 'ankiConnect.knownWords.highlightEnabled', + 'ankiConnect.knownWords.maturityEnabled', + 'subtitleStyle.knownWordColor', + 'ankiConnect.knownWords.matureThresholdDays', + 'subtitleStyle.knownWordMaturityColors.new', + 'subtitleStyle.knownWordMaturityColors.learning', + 'subtitleStyle.knownWordMaturityColors.young', + 'subtitleStyle.knownWordMaturityColors.mature', + ]); +}); + test('settings registry routes known words sync, n+1, and frequency config to behavior', () => { assert.equal(field('ankiConnect.knownWords.addMinedWordsImmediately').category, 'behavior'); assert.equal(field('ankiConnect.knownWords.addMinedWordsImmediately').section, 'Known Words'); diff --git a/src/config/settings/registry.ts b/src/config/settings/registry.ts index b82e15f8..63b4df26 100644 --- a/src/config/settings/registry.ts +++ b/src/config/settings/registry.ts @@ -163,6 +163,12 @@ const PATH_ORDER = new Map( 'ankiConnect.proxy.enabled', 'ankiConnect.isLapis.enabled', 'ankiConnect.isKiku.enabled', + 'subtitleStyle.knownWordColor', + 'ankiConnect.knownWords.matureThresholdDays', + 'subtitleStyle.knownWordMaturityColors.new', + 'subtitleStyle.knownWordMaturityColors.learning', + 'subtitleStyle.knownWordMaturityColors.young', + 'subtitleStyle.knownWordMaturityColors.mature', 'subtitleStyle.fontColor', 'subtitleStyle.backgroundColor', 'subtitleStyle.hoverTokenColor', @@ -517,6 +523,7 @@ function controlForPath(path: string, value: unknown): ConfigSettingsControl { return 'key-code'; } if (path.startsWith('subtitleStyle.jlptColors.')) return 'color'; + if (path.startsWith('subtitleStyle.knownWordMaturityColors.')) return 'color'; if (path === 'subtitleStyle.frequencyDictionary.bandedColors') return 'color-list'; if (OPTION_BY_PATH.get(path)?.enumValues?.length) return 'select'; if (JSON_OBJECT_FIELDS.has(path)) return 'json'; @@ -534,6 +541,9 @@ function controlForPath(path: string, value: unknown): ConfigSettingsControl { function subsectionForPath(path: string): string | undefined { if (path === 'ankiConnect.knownWords.highlightEnabled') return 'Known Words'; + if (path === 'ankiConnect.knownWords.maturityEnabled') return 'Known Words'; + if (path === 'ankiConnect.knownWords.matureThresholdDays') return 'Known Words'; + if (path.startsWith('subtitleStyle.knownWordMaturityColors.')) return 'Known Words'; if (path === 'ankiConnect.nPlusOne.enabled') return 'N+1'; if (path === 'subtitleStyle.knownWordColor') return 'Known Words'; if (path === 'subtitleStyle.nPlusOneColor') return 'N+1';