gui/modules/desktop/electron/libs/ipc.ts

209 lines
5.3 KiB
TypeScript

import { ipcMain, app, BrowserWindow } from "electron";
import { createReadStream, statSync } from "fs";
import { getInstalledPackages } from "./tea-dir";
import { readSessionData, writeSessionData } from "./auth";
import type { Packages, Session } from "../../src/libs/types";
import * as log from "electron-log";
import { post } from "./v1-client";
import { deepReadDir, deletePackageFolder } from "./tea-dir";
import path from "path";
import { installPackage, openTerminal, syncPantry } from "./cli";
import initializeTeaCli from "./initialize";
import { getUpdater } from "./auto-updater";
import fetch from "node-fetch";
import { loadPackageCache, writePackageCache } from "./package";
let teaProtocolPath = ""; // this should be empty string
export const setProtocolPath = (path: string) => {
teaProtocolPath = path;
};
export default function initializeHandlers() {
ipcMain.handle("get-installed-packages", async () => {
try {
log.info("getting installed packages");
const pkgs = await getInstalledPackages();
log.info(`got installed packages: ${pkgs.length}`);
return pkgs;
} catch (error) {
log.error(error);
return [];
}
});
ipcMain.handle("get-session", async () => {
try {
log.info("getting session");
const session = await readSessionData();
log.debug(session ? "found session data" : "no session data found");
return session;
} catch (error) {
log.error(error);
return {};
}
});
ipcMain.handle("update-session", async (_, data) => {
try {
log.info("updating session data with", data); // rm this
await writeSessionData(data as Session);
} catch (error) {
log.error(error);
}
});
ipcMain.handle("install-package", async (_, data) => {
try {
log.info("installing package:", data.full_name);
const result = await installPackage(data.full_name);
return result;
} catch (error) {
log.error(error);
return error;
}
});
ipcMain.handle("sync-pantry", async () => {
try {
return await syncPantry();
} catch (error) {
log.error(error);
return error;
}
});
ipcMain.handle("open-terminal", async (_, data) => {
const { cmd } = data as { cmd: string };
try {
// TODO: detect if mac or linux
// current openTerminal is only design for Mac
log.info("open terminal w/ cmd:", cmd);
await openTerminal(cmd);
} catch (error) {
log.error(error);
}
});
ipcMain.handle("relaunch", async () => {
try {
const autoUpdater = getUpdater();
await autoUpdater.quitAndInstall();
} catch (error) {
log.error(error);
}
});
ipcMain.handle("get-protocol-path", async () => {
const path = teaProtocolPath;
teaProtocolPath = "";
return path;
});
ipcMain.handle("submit-logs", async () => {
try {
log.info("syncing logs");
const logDir = path.join(app.getPath("home"), "Library/Logs/tea");
// ['/Users/neil/Library/Logs/tea/main.log']
const logFiles = await deepReadDir({ dir: logDir });
let deviceId = "";
const files = logFiles.map((p) => {
const paths = p.split("/");
deviceId = paths[2]; // temp hack use developers username instead of gui_id
return paths.pop();
});
const signedUrls = await post<{ [key: string]: string }>(`/gui/${deviceId}/sync-log-files`, {
files
});
if (signedUrls) {
for (const key in signedUrls) {
const fileIndex = files.indexOf(key);
const filePath = logFiles[fileIndex];
if (filePath) {
const payload = createReadStream(filePath);
const response = await fetch(signedUrls[key], {
method: "PUT",
body: payload,
headers: {
"Content-Length": statSync(filePath).size.toString()
}
});
log.info("uploading log:", key, response.status);
}
}
}
return `log files(${logFiles.length}) has been uploaded to S3 logs/${deviceId}`;
} catch (error) {
log.error(error);
return error.message;
}
});
ipcMain.handle("set-badge-count", async (_, { count }) => {
console.log("set badge count:", count);
if (count) {
app.dock.setBadge(count.toString());
} else {
app.dock.setBadge("");
}
});
ipcMain.handle(
"delete-package",
async (_, { fullName, version }: { fullName: string; version: string }) => {
let error = "";
try {
log.info("deleting package:", fullName);
await deletePackageFolder(fullName, version);
} catch (e) {
log.error(e);
error = e.message;
}
return error;
}
);
ipcMain.handle("write-package-cache", async (_, data) => {
try {
await writePackageCache(data as Packages);
} catch (error) {
log.error(error);
}
});
ipcMain.handle("load-package-cache", async () => {
try {
return await loadPackageCache();
} catch (error) {
log.error(error);
return { version: "1", packages: {} };
}
});
ipcMain.handle("get-tea-version", async () => {
try {
log.info("installing tea cli");
const version = await initializeTeaCli();
if (!version) {
throw new Error("failed to install tea cli");
}
return { version, message: "" };
} catch (error) {
log.error(error);
return { version: "", message: error.message };
}
});
ipcMain.handle("topbar-double-click", async (event: Electron.IpcMainInvokeEvent) => {
const mainWindow = BrowserWindow.fromWebContents(event.sender);
if (mainWindow) {
mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize();
}
});
}