feat(anki): mirror mpv software volume into generated sentence audio (#155)

This commit is contained in:
2026-07-10 00:44:23 -07:00
committed by GitHub
parent 84c75f50aa
commit 7b1a005a65
31 changed files with 419 additions and 23 deletions
@@ -149,6 +149,42 @@ test('createConfigHotReloadAppliedHandler applies safe Anki, annotation, and log
assert.ok(calls.includes('broadcast:config:hot-reload'));
});
test('createConfigHotReloadAppliedHandler applies only changed Anki media options', () => {
const config = deepCloneConfig(DEFAULT_CONFIG);
config.ankiConnect.media.normalizeAudio = false;
config.ankiConnect.media.mirrorMpvVolume = false;
const ankiPatches: unknown[] = [];
const applyHotReload = createConfigHotReloadAppliedHandler({
setKeybindings: () => undefined,
setSessionBindings: () => undefined,
refreshGlobalAndOverlayShortcuts: () => undefined,
setSecondarySubMode: () => undefined,
broadcastToOverlayWindows: () => undefined,
applyAnkiRuntimeConfigPatch: (patch) => ankiPatches.push(patch),
});
applyHotReload(
{
hotReloadFields: ['ankiConnect.media.normalizeAudio'],
restartRequiredFields: [],
},
config,
);
applyHotReload(
{
hotReloadFields: ['ankiConnect.media.mirrorMpvVolume'],
restartRequiredFields: [],
},
config,
);
assert.deepEqual(ankiPatches, [
{ media: { normalizeAudio: false } },
{ media: { mirrorMpvVolume: false } },
]);
});
test('buildConfigHotReloadPayload includes independent primary subtitle mode', () => {
const config = deepCloneConfig(DEFAULT_CONFIG);
config.subtitleStyle.primaryDefaultMode = 'hover';
@@ -93,6 +93,16 @@ function buildAnkiRuntimeConfigPatch(
if (diff.hotReloadFields.includes('ankiConnect.deck')) {
patch.deck = config.ankiConnect.deck;
}
const mediaPatch: NonNullable<AnkiConnectConfig['media']> = {};
if (diff.hotReloadFields.includes('ankiConnect.media.normalizeAudio')) {
mediaPatch.normalizeAudio = config.ankiConnect.media.normalizeAudio;
}
if (diff.hotReloadFields.includes('ankiConnect.media.mirrorMpvVolume')) {
mediaPatch.mirrorMpvVolume = config.ankiConnect.media.mirrorMpvVolume;
}
if (Object.keys(mediaPatch).length > 0) {
patch.media = mediaPatch;
}
if (hasAnyHotReloadField(diff, ['ankiConnect.knownWords'])) {
patch.knownWords = config.ankiConnect.knownWords;
}