Fix JLPT underline color drift and AniList skipped-threshold sync

- Replace JLPT `text-decoration` underlines with `border-bottom` so Chromium selection/hover cannot repaint them to another annotation's color
- Lock JLPT underline color for combined annotation selectors (known, n+1, frequency) and character hover/selection states
- Trigger AniList post-watch check on every mpv time-position update to catch skipped completion thresholds
- Fall back to filename-parser season/episode when guessit omits them
This commit is contained in:
2026-05-03 20:11:24 -07:00
parent 42576d99b1
commit 12e1e783c9
11 changed files with 267 additions and 42 deletions
@@ -22,6 +22,32 @@ test('guessAnilistMediaInfo uses guessit output when available', async () => {
});
});
test('guessAnilistMediaInfo fills missing guessit episode from filename parser', async () => {
const result = await guessAnilistMediaInfo('/tmp/Guessit Title S01E09.mkv', null, {
runGuessit: async () => JSON.stringify({ title: 'Guessit Title' }),
});
assert.deepEqual(result, {
title: 'Guessit Title',
season: 1,
episode: 9,
source: 'guessit',
});
});
test('guessAnilistMediaInfo parses Little Witch Academia release filename', async () => {
const filename =
'/tmp/Little Witch Academia (2017) - S01E02 - 002 - Papiliodia [Bluray-1080p][10bit][h265][AC3 2.0][JA].mkv';
const result = await guessAnilistMediaInfo(filename, null, {
runGuessit: async () => JSON.stringify({ title: 'Little Witch Academia' }),
});
assert.deepEqual(result, {
title: 'Little Witch Academia',
season: 1,
episode: 2,
source: 'guessit',
});
});
test('guessAnilistMediaInfo falls back to parser when guessit fails', async () => {
const result = await guessAnilistMediaInfo('/tmp/My Anime S01E03.mkv', null, {
runGuessit: async () => {
@@ -54,7 +80,7 @@ test('guessAnilistMediaInfo uses basename for guessit input', async () => {
]);
assert.deepEqual(result, {
title: 'Rascal Does Not Dream of Bunny Girl Senpai',
season: null,
season: 1,
episode: 1,
source: 'guessit',
});
+3 -2
View File
@@ -236,12 +236,13 @@ export async function guessAnilistMediaInfo(
const season = firstPositiveInteger(parsed.season);
const year = firstYear(parsed.year);
if (title) {
const fallback = parseMediaInfo(target);
return {
title: buildGuessitTitle(title, alternativeTitle),
...(alternativeTitle ? { alternativeTitle } : {}),
...(year ? { year } : {}),
season,
episode,
season: season ?? fallback.season,
episode: episode ?? fallback.episode,
source: 'guessit',
};
}