MeshChatX/electron/closeBehavior.js

121 lines
3.2 KiB
JavaScript

const fs = require("fs");
const path = require("node:path");
const CLOSE_BEHAVIORS = new Set(["ask", "quit", "background"]);
function defaultCloseSettings() {
return {
closeBehavior: "ask",
trayEnabled: true,
};
}
function closeSettingsPath(storageDir) {
return path.join(storageDir, "desktop-close-settings.json");
}
function normalizeCloseSettings(raw) {
const defaults = defaultCloseSettings();
if (!raw || typeof raw !== "object") {
return defaults;
}
const closeBehavior = CLOSE_BEHAVIORS.has(raw.closeBehavior) ? raw.closeBehavior : defaults.closeBehavior;
const trayEnabled = typeof raw.trayEnabled === "boolean" ? raw.trayEnabled : defaults.trayEnabled;
return { closeBehavior, trayEnabled };
}
function loadCloseSettings(storageDir) {
try {
const filePath = closeSettingsPath(storageDir);
if (!fs.existsSync(filePath)) {
return defaultCloseSettings();
}
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
return normalizeCloseSettings(parsed);
} catch {
return defaultCloseSettings();
}
}
function saveCloseSettings(storageDir, partial) {
const current = loadCloseSettings(storageDir);
const next = normalizeCloseSettings({
...current,
...(partial && typeof partial === "object" ? partial : {}),
});
try {
fs.mkdirSync(storageDir, { recursive: true });
fs.writeFileSync(closeSettingsPath(storageDir), JSON.stringify(next, null, 2), "utf8");
} catch {
// ignore persistence failures; in-memory choice still applies for this session
}
return next;
}
/**
* Resolve what to do on window close.
* @returns {"ask"|"quit"|"background"|"minimize"}
*/
function resolveCloseAction(settings) {
const normalized = normalizeCloseSettings(settings);
if (normalized.closeBehavior === "ask") {
return "ask";
}
if (normalized.closeBehavior === "quit") {
return "quit";
}
if (!normalized.trayEnabled) {
return "minimize";
}
return "background";
}
/**
* Map a chosen close action + remember checkbox into persisted settings.
* Non-quit choices are stored as "background" and resolved to minimize when tray is off.
* @param {"quit"|"background"|"minimize"} action
* @param {boolean} remember
* @returns {{ closeBehavior: "quit"|"background" }|null}
*/
function rememberedCloseSettings(action, remember) {
if (!remember) {
return null;
}
if (action === "quit") {
return { closeBehavior: "quit" };
}
if (action === "background" || action === "minimize") {
return { closeBehavior: "background" };
}
return null;
}
/**
* Simple re-entrancy guard for async close handling.
*/
function createCloseRequestGuard() {
let inFlight = false;
return {
tryEnter() {
if (inFlight) {
return false;
}
inFlight = true;
return true;
},
leave() {
inFlight = false;
},
};
}
module.exports = {
CLOSE_BEHAVIORS,
defaultCloseSettings,
loadCloseSettings,
saveCloseSettings,
resolveCloseAction,
normalizeCloseSettings,
rememberedCloseSettings,
createCloseRequestGuard,
};