presenton/electron/app/utils/setup-dependencies.ts

113 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* setup-dependencies.ts
*
* Single installer window that ensures LibreOffice, Chrome (Puppeteer), and
* ImageMagick are
* available before the user starts creating presentations. Runs checks, then
* if any are missing shows one installer that runs dependency setup steps
* in sequence (each with Install / Skip).
*/
import { BrowserWindow, ipcMain } from "electron";
import * as path from "path";
import { baseDir } from "./constants";
import { isLibreOfficeInstalled } from "./libreoffice-check";
import {
isChromeInstalled,
type SetupStatus,
} from "./puppeteer-check";
import { isImageMagickInstalled } from "./imagemagick-check";
export type { SetupStatus };
/** Set by checkDependenciesBeforeWindow; read by setup installer IPC. */
let currentSetupStatus: SetupStatus | null = null;
export function getSetupStatus(): SetupStatus | null {
return currentSetupStatus;
}
/**
* Checks LibreOffice, Chrome and ImageMagick. If all are present, returns
* immediately. If any are missing, opens one installer window that runs each
* missing setup step in sequence. Returns true only when all required dependencies
* are installed; false when the installer is closed/skipped before completion.
*/
export async function checkDependenciesBeforeWindow(): Promise<boolean> {
const [loResult, chromeInstalled, imageMagickInstalled] = await Promise.all([
isLibreOfficeInstalled(),
isChromeInstalled(),
Promise.resolve(isImageMagickInstalled()),
]);
const needsLibreOffice = !loResult.installed;
const needsChrome = !chromeInstalled;
const needsImageMagick = !imageMagickInstalled;
if (!needsLibreOffice && !needsChrome && !needsImageMagick) {
return true;
}
currentSetupStatus = {
needsLibreOffice,
needsChrome,
needsImageMagick,
};
await showSetupInstallerWindow();
// Re-check after installer closes; setup can only proceed when all
// required dependencies are actually installed.
const [postLoResult, postChromeInstalled, postImageMagickInstalled] = await Promise.all([
isLibreOfficeInstalled(),
isChromeInstalled(),
Promise.resolve(isImageMagickInstalled()),
]);
currentSetupStatus = null;
return postLoResult.installed && postChromeInstalled && postImageMagickInstalled;
}
/**
* Opens the unified setup installer window (LibreOffice then Chrome).
* Resolves when the window is closed.
*/
function showSetupInstallerWindow(): Promise<void> {
return new Promise((resolve) => {
const win = new BrowserWindow({
width: 520,
height: 600,
resizable: false,
center: true,
title: "Presenton Setup required",
icon: path.join(
baseDir,
"resources/ui/assets/images/presenton_short_filled.png"
),
webPreferences: {
webSecurity: false,
contextIsolation: true,
nodeIntegration: false,
// Keep preload runtime consistent with the main window in packaged builds.
sandbox: false,
preload: path.join(__dirname, "../preloads/setup-installer.js"),
},
});
win.setMenuBarVisibility(false);
win.loadFile(
path.join(baseDir, "resources/ui/setup-installer/index.html")
);
const onDone = () => {
if (!win.isDestroyed()) win.close();
};
ipcMain.once("setup:done", onDone);
win.on("closed", () => {
ipcMain.removeListener("setup:done", onDone);
resolve();
});
});
}