Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2025-04-15 14:40:45 +01:00
parent c023ec6f69
commit 221ed97062
No known key found for this signature in database
GPG Key ID: A2B008A5F49F5D0D
7 changed files with 37 additions and 33 deletions

View File

@ -9,7 +9,6 @@ import { type BrowserWindow } from "electron";
import type AutoLaunch from "auto-launch"; import type AutoLaunch from "auto-launch";
import { type AppLocalization } from "../language-helper.js"; import { type AppLocalization } from "../language-helper.js";
import { type Store } from "../store.js";
// global type extensions need to use var for whatever reason // global type extensions need to use var for whatever reason
/* eslint-disable no-var */ /* eslint-disable no-var */
@ -24,6 +23,5 @@ declare global {
icon_path: string; icon_path: string;
brand: string; brand: string;
}; };
var store: Store;
} }
/* eslint-enable no-var */ /* eslint-enable no-var */

View File

@ -24,7 +24,7 @@ import "./ipc.js";
import "./seshat.js"; import "./seshat.js";
import "./settings.js"; import "./settings.js";
import * as tray from "./tray.js"; import * as tray from "./tray.js";
import { Store } from "./store.js"; import store from "./store.js";
import { buildMenuTemplate } from "./vectormenu.js"; import { buildMenuTemplate } from "./vectormenu.js";
import webContentsHandler from "./webcontents-handler.js"; import webContentsHandler from "./webcontents-handler.js";
import * as updater from "./updater.js"; import * as updater from "./updater.js";
@ -262,8 +262,6 @@ async function moveAutoLauncher(): Promise<void> {
} }
} }
global.store = new Store();
global.appQuitting = false; global.appQuitting = false;
const exitShortcuts: Array<(input: Input, platform: string) => boolean> = [ const exitShortcuts: Array<(input: Input, platform: string) => boolean> = [
@ -274,7 +272,7 @@ const exitShortcuts: Array<(input: Input, platform: string) => boolean> = [
]; ];
const warnBeforeExit = (event: Event, input: Input): void => { const warnBeforeExit = (event: Event, input: Input): void => {
const shouldWarnBeforeExit = global.store.get("warnBeforeExit", true); const shouldWarnBeforeExit = store.get("warnBeforeExit", true);
const exitShortcutPressed = const exitShortcutPressed =
input.type === "keyDown" && exitShortcuts.some((shortcutFn) => shortcutFn(input, process.platform)); input.type === "keyDown" && exitShortcuts.some((shortcutFn) => shortcutFn(input, process.platform));
@ -356,7 +354,7 @@ app.enableSandbox();
app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling,MediaSessionService"); app.commandLine.appendSwitch("disable-features", "HardwareMediaKeyHandling,MediaSessionService");
// Disable hardware acceleration if the setting has been set. // Disable hardware acceleration if the setting has been set.
if (global.store.get("disableHardwareAcceleration") === true) { if (store.get("disableHardwareAcceleration") === true) {
console.log("Disabling hardware acceleration."); console.log("Disabling hardware acceleration.");
app.disableHardwareAcceleration(); app.disableHardwareAcceleration();
} }
@ -467,7 +465,7 @@ app.on("ready", async () => {
icon: global.trayConfig.icon_path, icon: global.trayConfig.icon_path,
show: false, show: false,
autoHideMenuBar: global.store.get("autoHideMenuBar"), autoHideMenuBar: store.get("autoHideMenuBar"),
x: mainWindowState.x, x: mainWindowState.x,
y: mainWindowState.y, y: mainWindowState.y,
@ -489,10 +487,10 @@ app.on("ready", async () => {
// Handle spellchecker // Handle spellchecker
// For some reason spellCheckerEnabled isn't persisted, so we have to use the store here // For some reason spellCheckerEnabled isn't persisted, so we have to use the store here
global.mainWindow.webContents.session.setSpellCheckerEnabled(global.store.get("spellCheckerEnabled", true)); global.mainWindow.webContents.session.setSpellCheckerEnabled(store.get("spellCheckerEnabled", true));
// Create trayIcon icon // Create trayIcon icon
if (global.store.get("minimizeToTray")) tray.create(global.trayConfig); if (store.get("minimizeToTray")) tray.create(global.trayConfig);
global.mainWindow.once("ready-to-show", () => { global.mainWindow.once("ready-to-show", () => {
if (!global.mainWindow) return; if (!global.mainWindow) return;
@ -545,7 +543,6 @@ app.on("ready", async () => {
webContentsHandler(global.mainWindow.webContents); webContentsHandler(global.mainWindow.webContents);
global.appLocalization = new AppLocalization({ global.appLocalization = new AppLocalization({
store: global.store,
components: [(): void => tray.initApplicationMenu(), (): void => Menu.setApplicationMenu(buildMenuTemplate())], components: [(): void => tray.initApplicationMenu(), (): void => Menu.setApplicationMenu(buildMenuTemplate())],
}); });

View File

@ -112,11 +112,11 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
if (typeof args[0] !== "boolean") return; if (typeof args[0] !== "boolean") return;
global.mainWindow.webContents.session.setSpellCheckerEnabled(args[0]); global.mainWindow.webContents.session.setSpellCheckerEnabled(args[0]);
global.store.set("spellCheckerEnabled", args[0]); store.set("spellCheckerEnabled", args[0]);
break; break;
case "getSpellCheckEnabled": case "getSpellCheckEnabled":
ret = global.store.get("spellCheckerEnabled"); ret = store.get("spellCheckerEnabled");
break; break;
case "setSpellCheckLanguages": case "setSpellCheckLanguages":
@ -140,7 +140,7 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
case "getPickleKey": case "getPickleKey":
try { try {
ret = await global.store.getSecret(`${args[0]}|${args[1]}`); ret = await store.getSecret(`${args[0]}|${args[1]}`);
} catch { } catch {
// if an error is thrown (e.g. keytar can't connect to the keychain), // if an error is thrown (e.g. keytar can't connect to the keychain),
// then return null, which means the default pickle key will be used // then return null, which means the default pickle key will be used
@ -151,7 +151,7 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
case "createPickleKey": case "createPickleKey":
try { try {
const pickleKey = await randomArray(32); const pickleKey = await randomArray(32);
await global.store.setSecret(`${args[0]}|${args[1]}`, pickleKey); await store.setSecret(`${args[0]}|${args[1]}`, pickleKey);
ret = pickleKey; ret = pickleKey;
} catch (e) { } catch (e) {
console.error("Failed to create pickle key", e); console.error("Failed to create pickle key", e);
@ -161,7 +161,7 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
case "destroyPickleKey": case "destroyPickleKey":
try { try {
await global.store.deleteSecret(`${args[0]}|${args[1]}`); await store.deleteSecret(`${args[0]}|${args[1]}`);
} catch (e) { } catch (e) {
console.error("Failed to destroy pickle key", e); console.error("Failed to destroy pickle key", e);
} }
@ -180,7 +180,7 @@ ipcMain.on("ipcCall", async function (_ev: IpcMainEvent, payload) {
break; break;
case "clearStorage": case "clearStorage":
global.store.clear(); store.clear();
global.mainWindow.webContents.session.flushStorageData(); global.mainWindow.webContents.session.flushStorageData();
await global.mainWindow.webContents.session.clearStorageData(); await global.mainWindow.webContents.session.clearStorageData();
relaunchApp(); relaunchApp();

View File

@ -12,7 +12,7 @@ import { fileURLToPath } from "node:url";
import type EN from "./i18n/strings/en_EN.json"; import type EN from "./i18n/strings/en_EN.json";
import { loadJsonFile } from "./utils.js"; import { loadJsonFile } from "./utils.js";
import { type Store } from "./store.js"; import store from "./store.js";
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));
@ -62,10 +62,9 @@ type Component = () => void;
export class AppLocalization { export class AppLocalization {
private static readonly STORE_KEY = "locale"; private static readonly STORE_KEY = "locale";
private readonly store: Store;
private readonly localizedComponents?: Set<Component>; private readonly localizedComponents?: Set<Component>;
public constructor({ store, components = [] }: { store: Store; components: Component[] }) { public constructor({ components = [] }: { components: Component[] }) {
counterpart.registerTranslations(FALLBACK_LOCALE, this.fetchTranslationJson("en_EN")); counterpart.registerTranslations(FALLBACK_LOCALE, this.fetchTranslationJson("en_EN"));
counterpart.setFallbackLocale(FALLBACK_LOCALE); counterpart.setFallbackLocale(FALLBACK_LOCALE);
counterpart.setSeparator("|"); counterpart.setSeparator("|");
@ -74,9 +73,8 @@ export class AppLocalization {
this.localizedComponents = new Set(components); this.localizedComponents = new Set(components);
} }
this.store = store; if (store.has(AppLocalization.STORE_KEY)) {
if (this.store.has(AppLocalization.STORE_KEY)) { const locales = store.get(AppLocalization.STORE_KEY);
const locales = this.store.get(AppLocalization.STORE_KEY);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
this.setAppLocale(locales!); this.setAppLocale(locales!);
} }
@ -122,7 +120,7 @@ export class AppLocalization {
}); });
counterpart.setLocale(loadedLocales[0]); counterpart.setLocale(loadedLocales[0]);
this.store.set(AppLocalization.STORE_KEY, locales); store.set(AppLocalization.STORE_KEY, locales);
this.resetLocalizedUI(); this.resetLocalizedUI();
} }

View File

@ -41,12 +41,12 @@ let eventIndex: SeshatType | null = null;
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE"; const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
async function getOrCreatePassphrase(key: string): Promise<string> { async function getOrCreatePassphrase(key: string): Promise<string> {
try { try {
const storedPassphrase = await global.store.getSecret(key); const storedPassphrase = await store.getSecret(key);
if (storedPassphrase !== null) { if (storedPassphrase !== null) {
return storedPassphrase; return storedPassphrase;
} else { } else {
const newPassphrase = await randomArray(32); const newPassphrase = await randomArray(32);
await global.store.setSecret(key, newPassphrase); await store.setSecret(key, newPassphrase);
return newPassphrase; return newPassphrase;
} }
} catch (e) { } catch (e) {

View File

@ -27,10 +27,10 @@ export const Settings: Record<string, Setting> = {
}, },
"Electron.warnBeforeExit": { "Electron.warnBeforeExit": {
async read(): Promise<any> { async read(): Promise<any> {
return global.store.get("warnBeforeExit"); return store.get("warnBeforeExit");
}, },
async write(value: any): Promise<void> { async write(value: any): Promise<void> {
global.store.set("warnBeforeExit", value); store.set("warnBeforeExit", value);
}, },
}, },
"Electron.alwaysShowMenuBar": { "Electron.alwaysShowMenuBar": {
@ -39,7 +39,7 @@ export const Settings: Record<string, Setting> = {
return !global.mainWindow!.autoHideMenuBar; return !global.mainWindow!.autoHideMenuBar;
}, },
async write(value: any): Promise<void> { async write(value: any): Promise<void> {
global.store.set("autoHideMenuBar", !value); store.set("autoHideMenuBar", !value);
global.mainWindow!.autoHideMenuBar = !value; global.mainWindow!.autoHideMenuBar = !value;
global.mainWindow!.setMenuBarVisibility(value); global.mainWindow!.setMenuBarVisibility(value);
}, },
@ -56,15 +56,15 @@ export const Settings: Record<string, Setting> = {
} else { } else {
tray.destroy(); tray.destroy();
} }
global.store.set("minimizeToTray", value); store.set("minimizeToTray", value);
}, },
}, },
"Electron.enableHardwareAcceleration": { "Electron.enableHardwareAcceleration": {
async read(): Promise<any> { async read(): Promise<any> {
return !global.store.get("disableHardwareAcceleration"); return !store.get("disableHardwareAcceleration");
}, },
async write(value: any): Promise<void> { async write(value: any): Promise<void> {
global.store.set("disableHardwareAcceleration", !value); store.set("disableHardwareAcceleration", !value);
}, },
}, },
}; };

View File

@ -29,7 +29,7 @@ const LEGACY_KEYTAR_SERVICE = "riot.im";
* Secrets are stored within the `safeStorage` object, encrypted with safeStorage. * Secrets are stored within the `safeStorage` object, encrypted with safeStorage.
* Any secrets operations are blocked on Electron app ready emit, and keytar migration if still needed. * Any secrets operations are blocked on Electron app ready emit, and keytar migration if still needed.
*/ */
export class Store extends ElectronStore<{ class Store extends ElectronStore<{
warnBeforeExit: boolean; warnBeforeExit: boolean;
minimizeToTray: boolean; minimizeToTray: boolean;
spellCheckerEnabled: boolean; spellCheckerEnabled: boolean;
@ -174,3 +174,14 @@ export class Store extends ElectronStore<{
await keytar.deletePassword(namespace, key); await keytar.deletePassword(namespace, key);
} }
} }
declare global {
// eslint-disable-next-line no-var
var store: Store;
}
if (!global.store) {
global.store = new Store();
}
export default global.store;