mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-13 08:12:54 -07:00
fix: address coderabbit subtitle follow-ups
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
id: TASK-345
|
||||||
|
title: Address PR 57 latest CodeRabbit review comments
|
||||||
|
status: Done
|
||||||
|
assignee:
|
||||||
|
- codex
|
||||||
|
created_date: '2026-05-12 06:35'
|
||||||
|
updated_date: '2026-05-12 06:38'
|
||||||
|
labels:
|
||||||
|
- pr-review
|
||||||
|
- coderabbit
|
||||||
|
dependencies: []
|
||||||
|
references:
|
||||||
|
- 'https://github.com/ksyasuda/SubMiner/pull/57'
|
||||||
|
priority: medium
|
||||||
|
---
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||||
|
Assess the 2026-05-11 CodeRabbit review on PR #57 and address still-valid actionable comments with minimal changes. Current comments cover mpv subtitle playback unpause behavior, parser-selection empty reading handling, and overlay focus selector accessibility.
|
||||||
|
<!-- SECTION:DESCRIPTION:END -->
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
<!-- AC:BEGIN -->
|
||||||
|
- [x] #1 Still-valid CodeRabbit comments from the latest PR #57 review are fixed or explicitly documented as skipped with rationale.
|
||||||
|
- [x] #2 Regression coverage is added for behavior-affecting fixes where practical before production code changes.
|
||||||
|
- [x] #3 Relevant targeted checks pass locally.
|
||||||
|
<!-- AC:END -->
|
||||||
|
|
||||||
|
## Implementation Plan
|
||||||
|
|
||||||
|
<!-- SECTION:PLAN:BEGIN -->
|
||||||
|
1. Inspect current code and nearby tests for the three latest CodeRabbit comments on PR #57.
|
||||||
|
2. Add regression tests first for behavior-impacting findings: mpv playNextSubtitle unpauses when pause state is unknown, and parser selection preserves combined reading for empty segment readings.
|
||||||
|
3. Apply minimal production fixes plus the CSS :focus-visible selector change.
|
||||||
|
4. Run targeted test commands for touched areas and update task notes/final status.
|
||||||
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
<!-- SECTION:NOTES:BEGIN -->
|
||||||
|
Added red tests for the two behavior comments. `bun test src/core/services/mpv.test.ts` fails because playNextSubtitle skips unpause when pause state is null. `bun test src/core/services/tokenizer/parser-selection-stage.test.ts` fails because empty grammar-ending reading clears preceding combined reading.
|
||||||
|
|
||||||
|
Implemented all three latest CodeRabbit findings. Added regressions for mpv unknown pause state and parser-selection empty reading handling; changed overlay focus selectors to :focus-visible. Also fixed existing Prettier failure in src/core/services/stats-window.ts. Verification passed: targeted tests, typecheck, test:fast, test:env, format:check:src, build, test:smoke:dist, changelog:lint, changelog:pr-check.
|
||||||
|
<!-- SECTION:NOTES:END -->
|
||||||
|
|
||||||
|
## Final Summary
|
||||||
|
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||||
|
Addressed the latest CodeRabbit comments on PR #57.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
- `playNextSubtitle` now sends `pause=false` unless mpv is explicitly known to be playing, covering startup/reconnect unknown pause state.
|
||||||
|
- Parser selection no longer slices combined readings for empty grammar-ending readings, preserving preceding token readings.
|
||||||
|
- Overlay focus suppression now targets `:focus-visible` selectors.
|
||||||
|
- Applied Prettier to `src/core/services/stats-window.ts` to clear the existing formatting gate failure.
|
||||||
|
|
||||||
|
Verification:
|
||||||
|
- `bun test src/core/services/mpv.test.ts`
|
||||||
|
- `bun test src/core/services/tokenizer/parser-selection-stage.test.ts`
|
||||||
|
- `bun run typecheck`
|
||||||
|
- `bun run test:fast`
|
||||||
|
- `bun run test:env`
|
||||||
|
- `bun run format:check:src`
|
||||||
|
- `bun run build`
|
||||||
|
- `bun run test:smoke:dist`
|
||||||
|
- `bun run changelog:lint`
|
||||||
|
- `bun run changelog:pr-check`
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||||
@@ -515,6 +515,23 @@ test('MpvIpcClient playNextSubtitle starts playback from paused state and auto-p
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('MpvIpcClient playNextSubtitle starts playback when pause state is unknown', () => {
|
||||||
|
const commands: unknown[] = [];
|
||||||
|
const client = new MpvIpcClient('/tmp/mpv.sock', makeDeps());
|
||||||
|
(client as any).send = (payload: unknown) => {
|
||||||
|
commands.push(payload);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
client.playNextSubtitle();
|
||||||
|
|
||||||
|
assert.equal((client as any).pendingPauseAtSubEnd, true);
|
||||||
|
assert.deepEqual(commands, [
|
||||||
|
{ command: ['sub-seek', 1] },
|
||||||
|
{ command: ['set_property', 'pause', false] },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
test('MpvIpcClient playNextSubtitle still auto-pauses at end while already playing', async () => {
|
test('MpvIpcClient playNextSubtitle still auto-pauses at end while already playing', async () => {
|
||||||
const commands: unknown[] = [];
|
const commands: unknown[] = [];
|
||||||
const client = new MpvIpcClient('/tmp/mpv.sock', makeDeps());
|
const client = new MpvIpcClient('/tmp/mpv.sock', makeDeps());
|
||||||
|
|||||||
@@ -525,7 +525,7 @@ export class MpvIpcClient implements MpvClient {
|
|||||||
this.pendingPauseAtSubEnd = true;
|
this.pendingPauseAtSubEnd = true;
|
||||||
this.pauseAtTime = null;
|
this.pauseAtTime = null;
|
||||||
this.send({ command: ['sub-seek', 1] });
|
this.send({ command: ['sub-seek', 1] });
|
||||||
if (this.playbackPaused === true) {
|
if (this.playbackPaused !== false) {
|
||||||
this.send({ command: ['set_property', 'pause', false] });
|
this.send({ command: ['set_property', 'pause', false] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ function showStatsWindow(window: BrowserWindow, options: StatsWindowOptions): vo
|
|||||||
promoteStatsWindowLevel(window);
|
promoteStatsWindowLevel(window);
|
||||||
window.show();
|
window.show();
|
||||||
placementBounds = syncStatsWindowBounds(window, bounds) ?? placementBounds;
|
placementBounds = syncStatsWindowBounds(window, bounds) ?? placementBounds;
|
||||||
if (!ensureHyprlandWindowFloatingByTitle({ title: STATS_WINDOW_TITLE, bounds: placementBounds })) {
|
if (
|
||||||
|
!ensureHyprlandWindowFloatingByTitle({ title: STATS_WINDOW_TITLE, bounds: placementBounds })
|
||||||
|
) {
|
||||||
placementBounds = syncStatsWindowBounds(window, bounds) ?? placementBounds;
|
placementBounds = syncStatsWindowBounds(window, bounds) ?? placementBounds;
|
||||||
}
|
}
|
||||||
window.focus();
|
window.focus();
|
||||||
|
|||||||
@@ -187,6 +187,38 @@ test('splits trailing grammar endings when later segments are standalone words',
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('keeps preceding reading when standalone grammar ending has empty reading', () => {
|
||||||
|
const parseResults = [
|
||||||
|
makeParseItem('scanning-parser', [
|
||||||
|
[
|
||||||
|
{ text: '猫', reading: 'ねこ', headword: '猫' },
|
||||||
|
{ text: 'です', reading: '', headword: 'です' },
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
const tokens = selectYomitanParseTokens(parseResults, () => false, 'headword');
|
||||||
|
assert.deepEqual(
|
||||||
|
tokens?.map((token) => ({
|
||||||
|
surface: token.surface,
|
||||||
|
reading: token.reading,
|
||||||
|
headword: token.headword,
|
||||||
|
})),
|
||||||
|
[
|
||||||
|
{
|
||||||
|
surface: '猫',
|
||||||
|
reading: 'ねこ',
|
||||||
|
headword: '猫',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
surface: 'です',
|
||||||
|
reading: '',
|
||||||
|
headword: 'です',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('splits trailing ja-nai grammar endings from preceding content', () => {
|
test('splits trailing ja-nai grammar endings from preceding content', () => {
|
||||||
const parseResults = [
|
const parseResults = [
|
||||||
makeParseItem('scanning-parser', [
|
makeParseItem('scanning-parser', [
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ export function mapYomitanParseResultItemToMergedTokens(
|
|||||||
const segmentHeadword = extractYomitanHeadword(segment);
|
const segmentHeadword = extractYomitanHeadword(segment);
|
||||||
if (isStandaloneGrammarEndingSegment(segment)) {
|
if (isStandaloneGrammarEndingSegment(segment)) {
|
||||||
combinedSurface = combinedSurface.slice(0, -segmentText.length);
|
combinedSurface = combinedSurface.slice(0, -segmentText.length);
|
||||||
if (typeof segment.reading === 'string') {
|
if (typeof segment.reading === 'string' && segment.reading.length > 0) {
|
||||||
combinedReading = combinedReading.slice(0, -segment.reading.length);
|
combinedReading = combinedReading.slice(0, -segment.reading.length);
|
||||||
}
|
}
|
||||||
flushCombinedToken(segmentStart);
|
flushCombinedToken(segmentStart);
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ body {
|
|||||||
'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Arial Unicode MS', Arial, sans-serif;
|
'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Arial Unicode MS', Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
html:focus,
|
html:focus-visible,
|
||||||
body:focus,
|
body:focus-visible,
|
||||||
#overlay:focus {
|
#overlay:focus-visible {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user