Electron side

This commit is contained in:
Manav Rathi 2024-05-15 13:08:21 +05:30
parent 96cd6b3759
commit 176431ba1f
No known key found for this signature in database
8 changed files with 70 additions and 60 deletions

View file

@ -17,7 +17,11 @@ import { existsSync } from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { attachFSWatchIPCHandlers, attachIPCHandlers } from "./main/ipc";
import {
attachFSWatchIPCHandlers,
attachIPCHandlers,
attachLogoutIPCHandler,
} from "./main/ipc";
import log, { initLogging } from "./main/log";
import { createApplicationMenu, createTrayContextMenu } from "./main/menu";
import { setupAutoUpdater } from "./main/services/app-update";
@ -377,8 +381,12 @@ const main = () => {
void (async () => {
// Create window and prepare for the renderer.
mainWindow = createMainWindow();
// Setup IPC and streams.
const watcher = createWatcher(mainWindow);
attachIPCHandlers();
attachFSWatchIPCHandlers(createWatcher(mainWindow));
attachFSWatchIPCHandlers(watcher);
attachLogoutIPCHandler(watcher);
registerStreamProtocol();
// Configure the renderer's environment.

View file

@ -41,16 +41,13 @@ import {
fsWriteFile,
} from "./services/fs";
import { convertToJPEG, generateImageThumbnail } from "./services/image";
import { logout } from "./services/logout";
import {
clipImageEmbedding,
clipTextEmbeddingIfAvailable,
} from "./services/ml-clip";
import { detectFaces, faceEmbedding } from "./services/ml-face";
import {
clearStores,
encryptionKey,
saveEncryptionKey,
} from "./services/store";
import { encryptionKey, saveEncryptionKey } from "./services/store";
import {
clearPendingUploads,
listZipItems,
@ -65,11 +62,9 @@ import {
watchFindFiles,
watchGet,
watchRemove,
watchReset,
watchUpdateIgnoredFiles,
watchUpdateSyncedFiles,
} from "./services/watch";
import { clearConvertToMP4Results } from "./stream";
/**
* Listen for IPC events sent/invoked by the renderer process, and route them to
@ -107,10 +102,6 @@ export const attachIPCHandlers = () => {
ipcMain.handle("selectDirectory", () => selectDirectory());
ipcMain.on("clearStores", () => clearStores());
ipcMain.on("clearConvertToMP4Results", () => clearConvertToMP4Results());
ipcMain.handle("saveEncryptionKey", (_, encryptionKey: string) =>
saveEncryptionKey(encryptionKey),
);
@ -265,6 +256,12 @@ export const attachFSWatchIPCHandlers = (watcher: FSWatcher) => {
ipcMain.handle("watchFindFiles", (_, folderPath: string) =>
watchFindFiles(folderPath),
);
ipcMain.handle("watchReset", () => watchReset(watcher));
};
/**
* Sibling of {@link attachIPCHandlers} specifically for use with the logout
* event with needs access to the {@link FSWatcher} instance.
*/
export const attachLogoutIPCHandler = (watcher: FSWatcher) => {
ipcMain.handle("logout", () => logout(watcher));
};

View file

@ -0,0 +1,30 @@
import type { FSWatcher } from "chokidar";
import log from "../log";
import { clearConvertToMP4Results } from "../stream";
import { clearStores } from "./store";
import { watchReset } from "./watch";
/**
* Perform the native side logout sequence.
*
* This function is guaranteed not to throw any errors.
*
* See: [Note: Do not throw during logout].
*/
export const logout = (watcher: FSWatcher) => {
try {
watchReset(watcher);
} catch (e) {
log.error("Ignoring error when resetting native folder watches", e);
}
try {
clearConvertToMP4Results();
} catch (e) {
log.error("Ignoring error when clearing convert-to-mp4 results", e);
}
try {
clearStores();
} catch (e) {
log.error("Ignoring error when clearing native stores", e);
}
}

View file

@ -151,6 +151,15 @@ export const watchFindFiles = async (dirPath: string) => {
return paths;
};
/**
* Stop watching all existing folder watches and remove any callbacks.
*
* This function is meant to be called when the user logs out. It stops
* all existing folder watches and forgets about any "on*" callback
* functions that have been registered.
*
* The persisted state itself gets cleared via {@link clearStores}.
*/
export const watchReset = (watcher: FSWatcher) => {
watcher.unwatch(folderWatches().map((watch) => watch.folderPath));
};

View file

@ -63,10 +63,10 @@ const openLogDirectory = () => ipcRenderer.invoke("openLogDirectory");
const selectDirectory = () => ipcRenderer.invoke("selectDirectory");
const clearStores = () => ipcRenderer.send("clearStores");
const clearConvertToMP4Results = () =>
ipcRenderer.send("clearConvertToMP4Results");
const logout = () => {
watchRemoveListeners();
ipcRenderer.send("logout");
};
const encryptionKey = () => ipcRenderer.invoke("encryptionKey");
@ -212,11 +212,10 @@ const watchOnRemoveDir = (f: (path: string, watch: FolderWatch) => void) => {
const watchFindFiles = (folderPath: string) =>
ipcRenderer.invoke("watchFindFiles", folderPath);
const watchReset = async () => {
const watchRemoveListeners = () => {
ipcRenderer.removeAllListeners("watchAddFile");
ipcRenderer.removeAllListeners("watchRemoveFile");
ipcRenderer.removeAllListeners("watchRemoveDir");
await ipcRenderer.invoke("watchReset");
};
// - Upload
@ -308,8 +307,7 @@ contextBridge.exposeInMainWorld("electron", {
openDirectory,
openLogDirectory,
selectDirectory,
clearStores,
clearConvertToMP4Results,
logout,
encryptionKey,
saveEncryptionKey,
onMainWindowFocus,
@ -360,7 +358,6 @@ contextBridge.exposeInMainWorld("electron", {
onRemoveFile: watchOnRemoveFile,
onRemoveDir: watchOnRemoveDir,
findFiles: watchFindFiles,
reset: watchReset,
},
// - Upload

View file

@ -101,7 +101,7 @@ type AppContextType = {
setDialogBoxAttributesV2: SetDialogBoxAttributesV2;
isCFProxyDisabled: boolean;
setIsCFProxyDisabled: (disabled: boolean) => void;
logout: () => Promise<void>;
logout: () => void;
};
export const AppContext = createContext<AppContextType>(null);

View file

@ -15,19 +15,9 @@ export const photosLogout = async () => {
const electron = globalThis.electron;
if (electron) {
try {
await electron.watch.reset();
await electron?.logout();
} catch (e) {
log.error("Ignoring error when resetting native folder watches", e);
}
try {
await electron.clearConvertToMP4Results();
} catch (e) {
log.error("Ignoring error when clearing convert-to-mp4 results", e);
}
try {
await electron.clearStores();
} catch (e) {
log.error("Ignoring error when clearing native stores", e);
log.error("Ignoring error in native side logout sequence", e);
}
}
try {

View file

@ -64,19 +64,9 @@ export interface Electron {
selectDirectory: () => Promise<string | undefined>;
/**
* Clear any stored data.
*
* This is a coarse single shot cleanup, meant for use in clearing any
* persisted Electron side state during logout.
* Perform any logout related cleanup of native side state.
*/
clearStores: () => Promise<void>;
/**
* Clear an state corresponding to in-flight convert-to-mp4 requests.
*
* This is meant for use during logout.
*/
clearConvertToMP4Results: () => Promise<void>;
logout: () => Promise<void>;
/**
* Return the previously saved encryption key from persistent safe storage.
@ -487,17 +477,6 @@ export interface Electron {
* The returned paths are guaranteed to use POSIX separators ('/').
*/
findFiles: (folderPath: string) => Promise<string[]>;
/**
* Stop watching all existing folder watches and remove any callbacks.
*
* This function is meant to be called when the user logs out. It stops
* all existing folder watches and forgets about any "on*" callback
* functions that have been registered.
*
* The persisted state itself gets cleared via {@link clearStores}.
*/
reset: () => Promise<void>;
};
// - Upload