mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-11-10 04:46:07 -08:00
feat(jimaku): auto-open modal when a video has no Japanese subtitle (#319)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Ivan Melck <ivan@spec-kitty.ai>
This commit is contained in:
24 files changed
+907
-22
No files matched your search
@@ -69,20 +69,22 @@ export function createOverlayModalsAssembly(deps: OverlayModalsAssemblyDeps) {
|
||||
openModal: (deps: ReturnType<typeof createOverlayHostedModalOpenDeps>) => Promise<boolean>,
|
||||
unavailableMessage: string,
|
||||
failureLogMessage: string,
|
||||
): void {
|
||||
void openModal(createOverlayHostedModalOpenDeps())
|
||||
): Promise<boolean> {
|
||||
return openModal(createOverlayHostedModalOpenDeps())
|
||||
.then((opened) => {
|
||||
if (!opened) {
|
||||
deps.getOverlayNotifications().showConfiguredStatusNotification(unavailableMessage, {
|
||||
variant: 'warning',
|
||||
});
|
||||
}
|
||||
return opened;
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.error(failureLogMessage, error);
|
||||
deps.getOverlayNotifications().showConfiguredStatusNotification(unavailableMessage, {
|
||||
variant: 'error',
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,8 +96,9 @@ export function createOverlayModalsAssembly(deps: OverlayModalsAssemblyDeps) {
|
||||
);
|
||||
}
|
||||
|
||||
function openJimakuOverlay(): void {
|
||||
openOverlayHostedModalWithOsd(
|
||||
/** Resolves to whether the modal acknowledged opening; failures are already reported. */
|
||||
function openJimakuOverlay(): Promise<boolean> {
|
||||
return openOverlayHostedModalWithOsd(
|
||||
openJimakuModalRuntime,
|
||||
'Jimaku overlay unavailable.',
|
||||
'Failed to open Jimaku overlay.',
|
||||
|
||||
@@ -159,6 +159,10 @@ function makeDeps(recorder: Recorder, state: FixtureState) {
|
||||
getMediaTimingReviewRuntime: spy('getMediaTimingReviewRuntime', () => ({
|
||||
dispose: spy('mediaTimingReview.dispose', resolved),
|
||||
})),
|
||||
getJimakuAutoOpenRuntime: spy('getJimakuAutoOpenRuntime', () => ({
|
||||
handleJimakuModalOpened: spy('jimakuAutoOpen.handleJimakuModalOpened', noop),
|
||||
handleJimakuModalClosed: spy('jimakuAutoOpen.handleJimakuModalClosed', noop),
|
||||
})),
|
||||
getSubtitleProcessingController: spy('getSubtitleProcessingController', () => ({
|
||||
refreshCurrentSubtitle: spy('subtitle.refreshCurrent', () => true),
|
||||
})),
|
||||
|
||||
@@ -25,6 +25,7 @@ import { createLinuxOverlayModeRuntime } from '../runtime/linux-overlay-mode-run
|
||||
import { shouldRunLinuxOverlayZOrderKeepAlive } from '../runtime/linux-overlay-zorder-keepalive';
|
||||
import { focusMacOSOverlayWindow } from '../runtime/macos-overlay-window-focus';
|
||||
import type { createMediaTimingReviewRuntime } from '../runtime/media-timing-review';
|
||||
import type { createJimakuAutoOpenRuntime } from '../runtime/jimaku-auto-open';
|
||||
import type { createOverlayModalInputState } from '../runtime/overlay-modal-input-state';
|
||||
import type { createOverlayGeometryRuntime } from '../runtime/overlay-geometry-runtime';
|
||||
import type { createOverlayNotificationsRuntime } from '../runtime/overlay-notifications-runtime';
|
||||
@@ -125,6 +126,10 @@ export interface OverlayAssemblyDeps {
|
||||
ReturnType<typeof createMediaTimingReviewRuntime>,
|
||||
'dispose'
|
||||
>;
|
||||
getJimakuAutoOpenRuntime: () => Pick<
|
||||
ReturnType<typeof createJimakuAutoOpenRuntime>,
|
||||
'handleJimakuModalOpened' | 'handleJimakuModalClosed'
|
||||
>;
|
||||
getSubtitleProcessingController: () => Pick<
|
||||
PlaybackAssembly['subtitleProcessingController'],
|
||||
'refreshCurrentSubtitle'
|
||||
@@ -331,6 +336,8 @@ export function createOverlayAssembly(deps: OverlayAssemblyDeps) {
|
||||
return;
|
||||
}
|
||||
void deps.getMediaTimingReviewRuntime().dispose();
|
||||
// A destroyed modal window never reports its modals closed.
|
||||
deps.getJimakuAutoOpenRuntime().handleJimakuModalClosed();
|
||||
overlayManager.setModalWindow(null);
|
||||
}
|
||||
},
|
||||
@@ -506,6 +513,9 @@ export function createOverlayAssembly(deps: OverlayAssemblyDeps) {
|
||||
if (modal === 'media-timing-review') {
|
||||
void deps.getMediaTimingReviewRuntime().dispose();
|
||||
}
|
||||
if (modal === 'jimaku') {
|
||||
deps.getJimakuAutoOpenRuntime().handleJimakuModalClosed();
|
||||
}
|
||||
if (modal === 'subtitle-sidebar' && senderWindow === overlayManager.getMainWindow()) {
|
||||
deps.setSubtitleSidebarRequestedOpen(false);
|
||||
}
|
||||
@@ -525,6 +535,9 @@ export function createOverlayAssembly(deps: OverlayAssemblyDeps) {
|
||||
if (modal === 'subtitle-sidebar' && senderWindow === overlayManager.getMainWindow()) {
|
||||
deps.setSubtitleSidebarRequestedOpen(true);
|
||||
}
|
||||
if (modal === 'jimaku') {
|
||||
deps.getJimakuAutoOpenRuntime().handleJimakuModalOpened();
|
||||
}
|
||||
deps.overlayModalRuntime.notifyOverlayModalOpened(modal);
|
||||
},
|
||||
onOverlayMouseInteractionChanged: (active, senderWindow) => {
|
||||
|
||||
@@ -76,6 +76,9 @@ function makeDeps(recorder: Recorder): PlaybackAssemblyDeps {
|
||||
handleMediaPathChange: spy('localSubtitles.handleMediaPathChange', noop),
|
||||
handleSubtitleTrackListChange: spy('localSubtitles.handleSubtitleTrackListChange', noop),
|
||||
},
|
||||
jimakuAutoOpenRuntime: {
|
||||
handleMediaPathChange: spy('jimakuAutoOpen.handleMediaPathChange', noop),
|
||||
},
|
||||
mediaTimingReviewRuntime: {
|
||||
deferPlaybackResume: spy('timingReview.deferPlaybackResume', () => false),
|
||||
cancelPlaybackResume: spy('timingReview.cancelPlaybackResume', noop),
|
||||
|
||||
@@ -61,6 +61,7 @@ import type { createDiscordPresenceRuntime } from '../runtime/discord-presence-r
|
||||
import type { createImmersionMediaRuntime } from '../runtime/domains/startup';
|
||||
import type { loadSubtitleSourceText } from '../runtime/internal-subtitle-extraction';
|
||||
import type { createManagedLocalSubtitleSelectionRuntime } from '../runtime/local-subtitle-selection';
|
||||
import type { createJimakuAutoOpenRuntime } from '../runtime/jimaku-auto-open';
|
||||
import type { createMediaTimingReviewRuntime } from '../runtime/media-timing-review';
|
||||
import type { createOverlayNotificationsRuntime } from '../runtime/overlay-notifications-runtime';
|
||||
import type { createStartupOsdSequencer } from '../runtime/startup-osd-sequencer';
|
||||
@@ -122,6 +123,10 @@ export interface PlaybackAssemblyDeps {
|
||||
ReturnType<typeof createManagedLocalSubtitleSelectionRuntime>,
|
||||
'handleMediaPathChange' | 'handleSubtitleTrackListChange'
|
||||
>;
|
||||
jimakuAutoOpenRuntime: Pick<
|
||||
ReturnType<typeof createJimakuAutoOpenRuntime>,
|
||||
'handleMediaPathChange'
|
||||
>;
|
||||
mediaTimingReviewRuntime: Pick<
|
||||
ReturnType<typeof createMediaTimingReviewRuntime>,
|
||||
'deferPlaybackResume' | 'cancelPlaybackResume'
|
||||
@@ -240,6 +245,7 @@ export function createPlaybackAssembly(deps: PlaybackAssemblyDeps) {
|
||||
currentMediaTokenizationGate,
|
||||
startupOsdSequencer,
|
||||
managedLocalSubtitleSelectionRuntime,
|
||||
jimakuAutoOpenRuntime,
|
||||
mediaTimingReviewRuntime,
|
||||
discordPresenceRuntime,
|
||||
immersionMediaRuntime,
|
||||
@@ -683,6 +689,7 @@ export function createPlaybackAssembly(deps: PlaybackAssemblyDeps) {
|
||||
}
|
||||
currentMediaTokenizationGate.updateCurrentMediaPath(path);
|
||||
managedLocalSubtitleSelectionRuntime.handleMediaPathChange(path);
|
||||
jimakuAutoOpenRuntime.handleMediaPathChange(path);
|
||||
startupOsdSequencer.reset();
|
||||
subtitlePrefetchRuntime.clearScheduledSubtitlePrefetchRefresh();
|
||||
if (!preserveParsedSubtitleCues) {
|
||||
|
||||
Reference in new issue
Block a user