mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-06-09 15:13:32 -07:00
fix(update): separate in-flight dedup keys for manual check vs install
- manual:check and manual:install now tracked independently; install no longer reuses a check's in-flight promise - add toggleNotificationHistory (Ctrl+N) shortcut to config example and docs
This commit is contained in:
@@ -208,7 +208,8 @@
|
||||
"openSessionHelp": "CommandOrControl+Slash", // Accelerator that opens the session help / keybinding cheatsheet.
|
||||
"openControllerSelect": "Alt+C", // Accelerator that opens the controller selection and learn-mode modal.
|
||||
"openControllerDebug": "Alt+Shift+C", // Accelerator that opens the controller debug modal with live axis/button readouts.
|
||||
"toggleSubtitleSidebar": "Backslash" // Accelerator that toggles the subtitle sidebar visibility.
|
||||
"toggleSubtitleSidebar": "Backslash", // Accelerator that toggles the subtitle sidebar visibility.
|
||||
"toggleNotificationHistory": "Ctrl+N" // Accelerator that toggles the overlay notification history panel.
|
||||
}, // Overlay keyboard shortcuts. Set a shortcut to null to disable.
|
||||
|
||||
// ==========================================
|
||||
|
||||
@@ -82,6 +82,7 @@ Mouse-hover playback behavior is configured separately from shortcuts: `subtitle
|
||||
| `Ctrl/Cmd+Shift+O` | Open runtime options palette | `shortcuts.openRuntimeOptions` |
|
||||
| `Ctrl/Cmd+/` | Open session help modal | `shortcuts.openSessionHelp` |
|
||||
| `Ctrl+Shift+J` | Open Jimaku subtitle search modal | `shortcuts.openJimaku` |
|
||||
| `Ctrl+N` | Toggle overlay notification history panel | `shortcuts.toggleNotificationHistory` |
|
||||
| `Ctrl+Alt+C` | Open the manual YouTube subtitle picker | `keybindings` |
|
||||
| `Ctrl+Alt+S` | Open subtitle sync (subsync) modal | `shortcuts.triggerSubsync` |
|
||||
| `\` | Toggle subtitle sidebar | `subtitleSidebar.toggleKey` |
|
||||
|
||||
@@ -293,6 +293,28 @@ test('concurrent update checks share one in-flight check', async () => {
|
||||
assert.equal(checkCount, 1);
|
||||
});
|
||||
|
||||
test('manual install request does not reuse in-flight manual check', async () => {
|
||||
let checkCount = 0;
|
||||
const resolveChecks: Array<(value: { available: boolean; version: string }) => void> = [];
|
||||
const { deps } = createDeps({
|
||||
checkAppUpdate: () =>
|
||||
new Promise((resolve) => {
|
||||
checkCount += 1;
|
||||
resolveChecks.push(resolve);
|
||||
}),
|
||||
});
|
||||
const service = createUpdateService(deps);
|
||||
const manualCheck = service.checkForUpdates({ source: 'manual' });
|
||||
const manualInstall = service.checkForUpdates({ source: 'manual', installWhenAvailable: true });
|
||||
|
||||
await Promise.resolve();
|
||||
assert.equal(checkCount, 2);
|
||||
for (const resolve of resolveChecks) {
|
||||
resolve({ available: false, version: '0.14.0' });
|
||||
}
|
||||
await Promise.all([manualCheck, manualInstall]);
|
||||
});
|
||||
|
||||
test('manual update check does not reuse in-flight automatic check', async () => {
|
||||
let checkCount = 0;
|
||||
const resolveChecks: Array<(value: { available: boolean; version: string }) => void> = [];
|
||||
|
||||
@@ -108,7 +108,14 @@ function summarizeError(error: unknown): string {
|
||||
}
|
||||
|
||||
export function createUpdateService(deps: UpdateServiceDeps) {
|
||||
const inFlightBySource = new Map<UpdateCheckSource, Promise<UpdateCheckResult>>();
|
||||
const inFlightBySource = new Map<string, Promise<UpdateCheckResult>>();
|
||||
|
||||
function getInFlightKey(request: UpdateCheckRequest): string {
|
||||
if (request.source === 'manual') {
|
||||
return request.installWhenAvailable ? 'manual:install' : 'manual:check';
|
||||
}
|
||||
return request.source;
|
||||
}
|
||||
|
||||
async function runCheck(request: UpdateCheckRequest): Promise<UpdateCheckResult> {
|
||||
const now = deps.now();
|
||||
@@ -206,12 +213,13 @@ export function createUpdateService(deps: UpdateServiceDeps) {
|
||||
|
||||
return {
|
||||
checkForUpdates(request: UpdateCheckRequest): Promise<UpdateCheckResult> {
|
||||
const inFlight = inFlightBySource.get(request.source);
|
||||
const key = getInFlightKey(request);
|
||||
const inFlight = inFlightBySource.get(key);
|
||||
if (inFlight) return inFlight;
|
||||
const nextInFlight = runCheck(request).finally(() => {
|
||||
inFlightBySource.delete(request.source);
|
||||
inFlightBySource.delete(key);
|
||||
});
|
||||
inFlightBySource.set(request.source, nextInFlight);
|
||||
inFlightBySource.set(key, nextInFlight);
|
||||
return nextInFlight;
|
||||
},
|
||||
startAutomaticChecks(options: { startupDelayMs?: number; pollIntervalMs?: number } = {}): void {
|
||||
|
||||
Reference in New Issue
Block a user