mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
refactor: extract tray runtime handler wiring
This commit is contained in:
96
src/main/runtime/tray-runtime-handlers.test.ts
Normal file
96
src/main/runtime/tray-runtime-handlers.test.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { createTrayRuntimeHandlers } from './tray-runtime-handlers';
|
||||
|
||||
test('tray runtime handlers compose resolve/menu/ensure/destroy handlers', () => {
|
||||
let tray: { destroyed: boolean } | null = null;
|
||||
let overlayInitialized = false;
|
||||
let visibleOverlay = false;
|
||||
const calls: string[] = [];
|
||||
|
||||
const runtime = createTrayRuntimeHandlers({
|
||||
resolveTrayIconPathDeps: {
|
||||
resolveTrayIconPathRuntime: () => '/tmp/SubMiner.png',
|
||||
platform: 'darwin',
|
||||
resourcesPath: '/resources',
|
||||
appPath: '/app',
|
||||
dirname: '/dirname',
|
||||
joinPath: (...parts) => parts.join('/'),
|
||||
fileExists: () => true,
|
||||
},
|
||||
buildTrayMenuTemplateDeps: {
|
||||
buildTrayMenuTemplateRuntime: () => [{ label: 'Open Overlay' }],
|
||||
initializeOverlayRuntime: () => {
|
||||
overlayInitialized = true;
|
||||
},
|
||||
isOverlayRuntimeInitialized: () => overlayInitialized,
|
||||
setVisibleOverlayVisible: (visible) => {
|
||||
visibleOverlay = visible;
|
||||
},
|
||||
openYomitanSettings: () => {},
|
||||
openRuntimeOptionsPalette: () => {},
|
||||
openJellyfinSetupWindow: () => {},
|
||||
openAnilistSetupWindow: () => {},
|
||||
quitApp: () => {},
|
||||
},
|
||||
ensureTrayDeps: {
|
||||
getTray: () => tray as never,
|
||||
setTray: (next) => {
|
||||
tray = next as { destroyed: boolean } | null;
|
||||
},
|
||||
createImageFromPath: () => ({
|
||||
isEmpty: () => false,
|
||||
resize: () => ({
|
||||
isEmpty: () => false,
|
||||
resize: () => ({} as never),
|
||||
setTemplateImage: () => {},
|
||||
}),
|
||||
setTemplateImage: () => {},
|
||||
}),
|
||||
createEmptyImage: () => ({
|
||||
isEmpty: () => true,
|
||||
resize: () => ({} as never),
|
||||
setTemplateImage: () => {},
|
||||
}),
|
||||
createTray: () => ({
|
||||
setContextMenu: () => calls.push('setContextMenu'),
|
||||
setToolTip: () => calls.push('setToolTip'),
|
||||
on: (_event: 'click', handler: () => void) => {
|
||||
calls.push('on-click');
|
||||
handler();
|
||||
},
|
||||
destroy: () => {
|
||||
calls.push('destroy');
|
||||
if (tray) tray.destroyed = true;
|
||||
},
|
||||
}),
|
||||
trayTooltip: 'SubMiner',
|
||||
platform: 'darwin',
|
||||
logWarn: (message) => calls.push(`warn:${message}`),
|
||||
initializeOverlayRuntime: () => {
|
||||
overlayInitialized = true;
|
||||
},
|
||||
isOverlayRuntimeInitialized: () => overlayInitialized,
|
||||
setVisibleOverlayVisible: (visible) => {
|
||||
visibleOverlay = visible;
|
||||
},
|
||||
},
|
||||
destroyTrayDeps: {
|
||||
getTray: () => tray as never,
|
||||
setTray: (next) => {
|
||||
tray = next as { destroyed: boolean } | null;
|
||||
},
|
||||
},
|
||||
buildMenuFromTemplate: (template) => ({ template }),
|
||||
});
|
||||
|
||||
assert.equal(runtime.resolveTrayIconPath(), '/tmp/SubMiner.png');
|
||||
assert.deepEqual(runtime.buildTrayMenu(), { template: [{ label: 'Open Overlay' }] });
|
||||
runtime.ensureTray();
|
||||
assert.equal(overlayInitialized, true);
|
||||
assert.equal(visibleOverlay, true);
|
||||
assert.ok(tray);
|
||||
runtime.destroyTray();
|
||||
assert.equal(tray, null);
|
||||
assert.deepEqual(calls, ['setToolTip', 'setContextMenu', 'on-click', 'destroy']);
|
||||
});
|
||||
48
src/main/runtime/tray-runtime-handlers.ts
Normal file
48
src/main/runtime/tray-runtime-handlers.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { createDestroyTrayHandler, createEnsureTrayHandler } from './tray-lifecycle';
|
||||
import { createBuildDestroyTrayMainDepsHandler, createBuildEnsureTrayMainDepsHandler } from './app-runtime-main-deps';
|
||||
import { createBuildTrayMenuTemplateHandler, createResolveTrayIconPathHandler } from './tray-main-actions';
|
||||
import {
|
||||
createBuildResolveTrayIconPathMainDepsHandler,
|
||||
createBuildTrayMenuTemplateMainDepsHandler,
|
||||
} from './tray-main-deps';
|
||||
|
||||
type ResolveTrayIconPathMainDeps = Parameters<typeof createBuildResolveTrayIconPathMainDepsHandler>[0];
|
||||
type BuildTrayMenuTemplateMainDeps<TMenuItem> = Parameters<
|
||||
typeof createBuildTrayMenuTemplateMainDepsHandler<TMenuItem>
|
||||
>[0];
|
||||
type EnsureTrayMainDeps = Parameters<typeof createBuildEnsureTrayMainDepsHandler>[0];
|
||||
type DestroyTrayMainDeps = Parameters<typeof createBuildDestroyTrayMainDepsHandler>[0];
|
||||
|
||||
export function createTrayRuntimeHandlers<TMenuItem, TMenu>(deps: {
|
||||
resolveTrayIconPathDeps: ResolveTrayIconPathMainDeps;
|
||||
buildTrayMenuTemplateDeps: BuildTrayMenuTemplateMainDeps<TMenuItem>;
|
||||
ensureTrayDeps: Omit<EnsureTrayMainDeps, 'buildTrayMenu' | 'resolveTrayIconPath'>;
|
||||
destroyTrayDeps: DestroyTrayMainDeps;
|
||||
buildMenuFromTemplate: (template: TMenuItem[]) => TMenu;
|
||||
}) {
|
||||
const resolveTrayIconPath = createResolveTrayIconPathHandler(
|
||||
createBuildResolveTrayIconPathMainDepsHandler(deps.resolveTrayIconPathDeps)(),
|
||||
);
|
||||
const buildTrayMenuTemplate = createBuildTrayMenuTemplateHandler(
|
||||
createBuildTrayMenuTemplateMainDepsHandler(deps.buildTrayMenuTemplateDeps)(),
|
||||
);
|
||||
const buildTrayMenu = () => deps.buildMenuFromTemplate(buildTrayMenuTemplate());
|
||||
|
||||
const ensureTray = createEnsureTrayHandler(
|
||||
createBuildEnsureTrayMainDepsHandler({
|
||||
...deps.ensureTrayDeps,
|
||||
buildTrayMenu: () => buildTrayMenu(),
|
||||
resolveTrayIconPath: () => resolveTrayIconPath(),
|
||||
})(),
|
||||
);
|
||||
const destroyTray = createDestroyTrayHandler(
|
||||
createBuildDestroyTrayMainDepsHandler(deps.destroyTrayDeps)(),
|
||||
);
|
||||
|
||||
return {
|
||||
resolveTrayIconPath,
|
||||
buildTrayMenu,
|
||||
ensureTray,
|
||||
destroyTray,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user