mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-04-12 04:19:25 -07:00
[codex] Make Windows mpv shortcut self-contained (#40)
This commit is contained in:
@@ -38,6 +38,7 @@ export function createKeyboardHandlers(
|
||||
let pendingSelectionAnchorAfterSubtitleSeek: 'start' | 'end' | null = null;
|
||||
let pendingLookupRefreshAfterSubtitleSeek = false;
|
||||
let resetSelectionToStartOnNextSubtitleSync = false;
|
||||
let lookupScanFallbackTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
const CHORD_MAP = new Map<
|
||||
string,
|
||||
@@ -358,12 +359,10 @@ export function createKeyboardHandlers(
|
||||
});
|
||||
}
|
||||
|
||||
function isSubtitleSeekCommand(command: (string | number)[] | undefined): command is [string, number] {
|
||||
return (
|
||||
Array.isArray(command) &&
|
||||
command[0] === 'sub-seek' &&
|
||||
typeof command[1] === 'number'
|
||||
);
|
||||
function isSubtitleSeekCommand(
|
||||
command: (string | number)[] | undefined,
|
||||
): command is [string, number] {
|
||||
return Array.isArray(command) && command[0] === 'sub-seek' && typeof command[1] === 'number';
|
||||
}
|
||||
|
||||
function dispatchConfiguredMpvCommand(command: (string | number)[]): void {
|
||||
@@ -485,7 +484,9 @@ export function createKeyboardHandlers(
|
||||
});
|
||||
}
|
||||
// Fallback only if the explicit scan path did not open popup quickly.
|
||||
setTimeout(() => {
|
||||
if (lookupScanFallbackTimer !== null) clearTimeout(lookupScanFallbackTimer);
|
||||
lookupScanFallbackTimer = setTimeout(() => {
|
||||
lookupScanFallbackTimer = null;
|
||||
if (ctx.state.yomitanPopupVisible || isYomitanPopupVisible(document)) {
|
||||
return;
|
||||
}
|
||||
@@ -525,6 +526,10 @@ export function createKeyboardHandlers(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lookupScanFallbackTimer !== null) {
|
||||
clearTimeout(lookupScanFallbackTimer);
|
||||
lookupScanFallbackTimer = null;
|
||||
}
|
||||
dispatchYomitanPopupVisibility(false);
|
||||
dispatchYomitanFrontendClearActiveTextSource();
|
||||
clearNativeSubtitleSelection();
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import type {
|
||||
PlaylistBrowserDirectoryItem,
|
||||
PlaylistBrowserQueueItem,
|
||||
} from '../../types';
|
||||
import type { PlaylistBrowserDirectoryItem, PlaylistBrowserQueueItem } from '../../types';
|
||||
import type { RendererContext } from '../context';
|
||||
|
||||
type PlaylistBrowserRowRenderActions = {
|
||||
@@ -55,7 +52,7 @@ export function renderPlaylistBrowserDirectoryRow(
|
||||
? item.episodeLabel
|
||||
? `${item.episodeLabel} · Current file`
|
||||
: 'Current file'
|
||||
: item.episodeLabel ?? 'Video file';
|
||||
: (item.episodeLabel ?? 'Video file');
|
||||
main.append(label, meta);
|
||||
|
||||
const trailing = document.createElement('div');
|
||||
|
||||
@@ -236,9 +236,17 @@ function createPlaylistBrowserElectronApi(overrides?: Partial<ElectronAPI>): Ele
|
||||
notifyOverlayModalClosed: () => {},
|
||||
focusMainWindow: async () => {},
|
||||
setIgnoreMouseEvents: () => {},
|
||||
appendPlaylistBrowserFile: async () => ({ ok: true, message: 'ok', snapshot: createSnapshot() }),
|
||||
appendPlaylistBrowserFile: async () => ({
|
||||
ok: true,
|
||||
message: 'ok',
|
||||
snapshot: createSnapshot(),
|
||||
}),
|
||||
playPlaylistBrowserIndex: async () => ({ ok: true, message: 'ok', snapshot: createSnapshot() }),
|
||||
removePlaylistBrowserIndex: async () => ({ ok: true, message: 'ok', snapshot: createSnapshot() }),
|
||||
removePlaylistBrowserIndex: async () => ({
|
||||
ok: true,
|
||||
message: 'ok',
|
||||
snapshot: createSnapshot(),
|
||||
}),
|
||||
movePlaylistBrowserIndex: async () => ({ ok: true, message: 'ok', snapshot: createSnapshot() }),
|
||||
...overrides,
|
||||
} as ElectronAPI;
|
||||
@@ -348,15 +356,13 @@ test('playlist browser modal action buttons stop double-click propagation', asyn
|
||||
|
||||
await modal.openPlaylistBrowserModal();
|
||||
|
||||
const row =
|
||||
env.dom.playlistBrowserDirectoryList.children[0] as
|
||||
| ReturnType<typeof createPlaylistRow>
|
||||
| undefined;
|
||||
const row = env.dom.playlistBrowserDirectoryList.children[0] as
|
||||
| ReturnType<typeof createPlaylistRow>
|
||||
| undefined;
|
||||
const trailing = row?.children?.[1] as ReturnType<typeof createPlaylistRow> | undefined;
|
||||
const button =
|
||||
trailing?.children?.at(-1) as
|
||||
| { listeners?: Map<string, Array<(event?: unknown) => void>> }
|
||||
| undefined;
|
||||
const button = trailing?.children?.at(-1) as
|
||||
| { listeners?: Map<string, Array<(event?: unknown) => void>> }
|
||||
| undefined;
|
||||
const dblclickHandler = button?.listeners?.get('dblclick')?.[0];
|
||||
|
||||
assert.equal(typeof dblclickHandler, 'function');
|
||||
|
||||
@@ -31,7 +31,8 @@ function getDefaultDirectorySelectionIndex(snapshot: PlaylistBrowserSnapshot): n
|
||||
|
||||
function getDefaultPlaylistSelectionIndex(snapshot: PlaylistBrowserSnapshot): number {
|
||||
const playlistIndex =
|
||||
snapshot.playingIndex ?? snapshot.playlistItems.findIndex((item) => item.current || item.playing);
|
||||
snapshot.playingIndex ??
|
||||
snapshot.playlistItems.findIndex((item) => item.current || item.playing);
|
||||
return clampIndex(playlistIndex >= 0 ? playlistIndex : 0, snapshot.playlistItems.length);
|
||||
}
|
||||
|
||||
@@ -225,7 +226,10 @@ export function createPlaylistBrowserModal(
|
||||
}
|
||||
|
||||
async function removePlaylistItem(index: number): Promise<void> {
|
||||
await handleMutation(window.electronAPI.removePlaylistBrowserIndex(index), 'Removed queue item');
|
||||
await handleMutation(
|
||||
window.electronAPI.removePlaylistBrowserIndex(index),
|
||||
'Removed queue item',
|
||||
);
|
||||
}
|
||||
|
||||
async function movePlaylistItem(index: number, direction: 1 | -1): Promise<void> {
|
||||
|
||||
@@ -453,8 +453,7 @@ body {
|
||||
padding: 14px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(110, 115, 141, 0.16);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(54, 58, 79, 0.55), rgba(36, 39, 58, 0.6));
|
||||
background: linear-gradient(180deg, rgba(54, 58, 79, 0.55), rgba(36, 39, 58, 0.6));
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
@@ -496,8 +495,12 @@ body {
|
||||
}
|
||||
|
||||
.playlist-browser-row.current {
|
||||
background:
|
||||
linear-gradient(90deg, rgba(138, 173, 244, 0.12), rgba(138, 173, 244, 0.03) 28%, transparent);
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(138, 173, 244, 0.12),
|
||||
rgba(138, 173, 244, 0.03) 28%,
|
||||
transparent
|
||||
);
|
||||
box-shadow: inset 3px 0 0 #8aadf4;
|
||||
}
|
||||
|
||||
|
||||
@@ -222,8 +222,12 @@ export function resolveRendererDom(): RendererDom {
|
||||
playlistBrowserModal: getRequiredElement<HTMLDivElement>('playlistBrowserModal'),
|
||||
playlistBrowserTitle: getRequiredElement<HTMLDivElement>('playlistBrowserTitle'),
|
||||
playlistBrowserStatus: getRequiredElement<HTMLDivElement>('playlistBrowserStatus'),
|
||||
playlistBrowserDirectoryList: getRequiredElement<HTMLUListElement>('playlistBrowserDirectoryList'),
|
||||
playlistBrowserPlaylistList: getRequiredElement<HTMLUListElement>('playlistBrowserPlaylistList'),
|
||||
playlistBrowserDirectoryList: getRequiredElement<HTMLUListElement>(
|
||||
'playlistBrowserDirectoryList',
|
||||
),
|
||||
playlistBrowserPlaylistList: getRequiredElement<HTMLUListElement>(
|
||||
'playlistBrowserPlaylistList',
|
||||
),
|
||||
playlistBrowserClose: getRequiredElement<HTMLButtonElement>('playlistBrowserClose'),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user