feat(config): reorganize settings window and move annotation colors to subtitleStyle

- Reorganize Configuration window into Appearance, Behavior, Anki, Input, and Integration sections
- Add AnkiConnect-backed deck, note-type, and field pickers in the Anki section
- Add click-to-learn keybinding controls
- Move known-word and N+1 highlight colors to subtitleStyle.knownWordColor / subtitleStyle.nPlusOneColor; legacy ankiConnect.knownWords.color and ankiConnect.nPlusOne.nPlusOne keys still accepted with deprecation warnings
- Add deckNames, modelNames, modelFieldNames, and fieldNamesForDeck methods to AnkiConnectClient
- Mark discordPresence.presenceStyle as an enum in the config registry
This commit is contained in:
2026-05-17 02:10:16 -07:00
parent a54f03f0cd
commit 309ce6ef8f
44 changed files with 2152 additions and 321 deletions
+50
View File
@@ -155,6 +155,56 @@ test('subtitleStyle nameMatchColor accepts valid values and warns on invalid', (
);
});
test('subtitleStyle knownWordColor accepts valid values and warns on invalid', () => {
const valid = createResolveContext({
subtitleStyle: {
knownWordColor: '#ed8796',
},
});
applySubtitleDomainConfig(valid.context);
assert.equal(valid.context.resolved.subtitleStyle.knownWordColor, '#ed8796');
const invalid = createResolveContext({
subtitleStyle: {
knownWordColor: 'pink',
},
});
applySubtitleDomainConfig(invalid.context);
assert.equal(invalid.context.resolved.subtitleStyle.knownWordColor, '#a6da95');
assert.ok(
invalid.warnings.some(
(warning) =>
warning.path === 'subtitleStyle.knownWordColor' &&
warning.message === 'Expected hex color.',
),
);
});
test('subtitleStyle nPlusOneColor accepts valid values and warns on invalid', () => {
const valid = createResolveContext({
subtitleStyle: {
nPlusOneColor: '#ed8796',
},
});
applySubtitleDomainConfig(valid.context);
assert.equal(valid.context.resolved.subtitleStyle.nPlusOneColor, '#ed8796');
const invalid = createResolveContext({
subtitleStyle: {
nPlusOneColor: 'pink',
},
});
applySubtitleDomainConfig(invalid.context);
assert.equal(invalid.context.resolved.subtitleStyle.nPlusOneColor, '#c6a0f6');
assert.ok(
invalid.warnings.some(
(warning) =>
warning.path === 'subtitleStyle.nPlusOneColor' &&
warning.message === 'Expected hex color.',
),
);
});
test('subtitleStyle frequencyDictionary.matchMode accepts valid values and warns on invalid', () => {
const valid = createResolveContext({
subtitleStyle: {