mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-13 08:12:54 -07:00
7c9b65db8b
* feat: inject bundled mpv plugin for managed launches, remove legacy glob - SubMiner-managed launcher and Windows shortcut launches inject the bundled plugin when no global plugin is detected - First-run setup detects and removes legacy global plugin files via OS trash before managed playback starts - Makefile `install-plugin` target and Windows config-rewrite script removed; Linux/macOS install now copies plugin to app data dir - AniList stats search and post-watch tracking now go through the shared rate limiter - Stats cover-art lookup reuses cached AniList data before issuing a new request - Closing mpv in a launcher-managed session now terminates the background Electron app * harden bootstrap version load and clean plugin on uninstall - Use pcall for version.lua in bootstrap.lua so missing version module does not crash plugin startup - Remove plugin/subminer from app-data dirs in uninstall-linux and uninstall-macos targets - Add Lua compat test asserting bootstrap uses defensive pcall for version load - Add release-workflow test asserting uninstall targets clean bundled plugin dirs - Delete completed planning document
73 lines
1.9 KiB
TypeScript
73 lines
1.9 KiB
TypeScript
import { fail, log } from '../log.js';
|
|
import {
|
|
waitForUnixSocketReady,
|
|
launchMpvIdleDetached,
|
|
resolveLauncherRuntimePluginPath,
|
|
} from '../mpv.js';
|
|
import type { LauncherCommandContext } from './context.js';
|
|
|
|
interface MpvCommandDeps {
|
|
waitForUnixSocketReady(socketPath: string, timeoutMs: number): Promise<boolean>;
|
|
launchMpvIdleDetached(
|
|
socketPath: string,
|
|
appPath: string,
|
|
args: LauncherCommandContext['args'],
|
|
runtimePluginPath?: string | null,
|
|
): Promise<void>;
|
|
}
|
|
|
|
const defaultDeps: MpvCommandDeps = {
|
|
waitForUnixSocketReady,
|
|
launchMpvIdleDetached,
|
|
};
|
|
|
|
export async function runMpvPreAppCommand(
|
|
context: LauncherCommandContext,
|
|
deps: MpvCommandDeps = defaultDeps,
|
|
): Promise<boolean> {
|
|
const { args, mpvSocketPath, processAdapter } = context;
|
|
if (args.mpvSocket) {
|
|
processAdapter.writeStdout(`${mpvSocketPath}\n`);
|
|
return true;
|
|
}
|
|
|
|
if (!args.mpvStatus) {
|
|
return false;
|
|
}
|
|
|
|
const ready = await deps.waitForUnixSocketReady(mpvSocketPath, 500);
|
|
log(
|
|
ready ? 'info' : 'warn',
|
|
args.logLevel,
|
|
`[mpv] socket ${ready ? 'ready' : 'not ready'}: ${mpvSocketPath}`,
|
|
);
|
|
processAdapter.exit(ready ? 0 : 1);
|
|
return true;
|
|
}
|
|
|
|
export async function runMpvPostAppCommand(
|
|
context: LauncherCommandContext,
|
|
deps: MpvCommandDeps = defaultDeps,
|
|
): Promise<boolean> {
|
|
const { args, appPath, scriptPath, mpvSocketPath } = context;
|
|
if (!args.mpvIdle) {
|
|
return false;
|
|
}
|
|
if (!appPath) {
|
|
fail('SubMiner app binary not found. Install to ~/.local/bin/ or set SUBMINER_APPIMAGE_PATH.');
|
|
}
|
|
|
|
await deps.launchMpvIdleDetached(
|
|
mpvSocketPath,
|
|
appPath,
|
|
args,
|
|
resolveLauncherRuntimePluginPath({ appPath, scriptPath }),
|
|
);
|
|
const ready = await deps.waitForUnixSocketReady(mpvSocketPath, 8000);
|
|
if (!ready) {
|
|
fail(`MPV IPC socket not ready after idle launch: ${mpvSocketPath}`);
|
|
}
|
|
log('info', args.logLevel, `[mpv] idle instance ready on ${mpvSocketPath}`);
|
|
return true;
|
|
}
|