Electron side
This commit is contained in:
parent
96cd6b3759
commit
176431ba1f
8 changed files with 70 additions and 60 deletions
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
};
|
||||
|
|
30
desktop/src/main/services/logout.ts
Normal file
30
desktop/src/main/services/logout.ts
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue