import { app, BrowserWindow, Menu, desktopCapturer, ipcMain, safeStorage } from 'electron'; import { ipcMainHandle, ipcMainOn, isDev } from './util.js'; import { getStaticData, pollResources } from './resourceManager.js'; import { getPreloadPath, getUIPath } from './pathResolver.js'; import { createTray } from './tray.js'; import { createMenu } from './menu.js'; import Store from 'electron-store'; import * as fs from "fs"; import path from "path"; import axios from 'axios'; import sharp from 'sharp'; app.on('ready', async () => { console.log("ready") const mainWindow = new BrowserWindow({ webPreferences: { preload: getPreloadPath(), }, // disables default system frame (dont do this if you want a proper working menu bar) frame: process.platform === 'darwin' ? false : true, autoHideMenuBar: true }); if (isDev()) { mainWindow.loadURL('http://localhost:5123'); mainWindow.webContents.openDevTools(); } else { mainWindow.loadFile(getUIPath()); } pollResources(mainWindow); ipcMainHandle('getStaticData', () => { return getStaticData(); }); ipcMainOn('sendFrameAction', (payload) => { switch (payload) { case 'CLOSE': mainWindow.close(); break; case 'MAXIMIZE': mainWindow.maximize(); break; case 'MINIMIZE': mainWindow.minimize(); break; } }); // createTray(mainWindow); handleCloseEvents(mainWindow); // createMenu(mainWindow); // await takeScreenshot(); }); // Blur using an offscreen canvas async function blurAndCompressBase64Image(base64: string) : Promise { const buffer = Buffer.from(base64.replace(/^data:image\/\w+;base64,/, ''), 'base64'); const outputBuffer = await sharp(buffer) .blur(8) // adjust blur radius here .jpeg({ quality: 70 }) // compress output .toBuffer(); return outputBuffer; } async function takeScreenshot() { // const sources = await desktopCapturer.getSources({ types: ["screen"] }); const sources = await desktopCapturer.getSources({ types: ['window'], thumbnailSize: { height: 768, width: 1366 } }); // Capture the first screen (you can choose others by filtering sources) const screen = sources[0]; let image = screen.thumbnail.toDataURL(); console.log("blurAndCompressBase64Image Calling") const blurredBuffer = await blurAndCompressBase64Image(image); const folderPath = "C:\\Users\\Public\\vatracker\\screenshots"; // Ensure directory exists if (!fs.existsSync(folderPath)) { fs.mkdirSync(folderPath, { recursive: true }); } const filePath = path.join(folderPath, `screenshot-${Date.now()}.png`); fs.writeFileSync(filePath, blurredBuffer); console.log(`Screenshot saved at: ${filePath}`); } ipcMain.handle('upload-screenshot', async () => { takeScreenshot() }) async function saveToken(accessToken: string, refreshToken: string | null = null) { const encryptedAccessToken = safeStorage.encryptString(accessToken); let encryptedRefreshToken = null; if (refreshToken != null) { encryptedRefreshToken = safeStorage.encryptString(refreshToken); } // Store encrypted token (example: using a file or electron-store) // For simplicity, using Electron's built-in localStorage is not available in main, so use electron-store or filesystem. // Here assume electron-store is already installed and set up: const store = new Store(); store.set("access_token", encryptedAccessToken.toString('base64')); if (encryptedRefreshToken != null) { store.set("refresh_token", encryptedRefreshToken.toString('base64')); } } async function getToken(TOKEN_KEY: string) { const store = new Store(); const encryptedBase64 = store.get(TOKEN_KEY) as string | undefined; if (!encryptedBase64) return null; const encryptedBuffer = Buffer.from(encryptedBase64, 'base64'); return safeStorage.decryptString(encryptedBuffer); } ipcMain.handle('get-token', async (event, TOKEN_KEY) => { // return decrypted token from secure storage return await getToken(TOKEN_KEY); }); ipcMain.handle('save-token', async (event, token) => { await saveToken(token); return true; }); // Handle login request from renderer ipcMain.handle('login-request', async (event, credentials: { email: string, password: string }) => { try { // Call your login API console.log("🟡 login Request received", credentials); try { console.log("➡️ Calling API..."); const response = await axios.post( 'https://wired-terminally-muskrat.ngrok-free.app/api/v1/va/login', { userDetails: { ...credentials } }, { headers: { "ngrok-skip-browser-warning": 69420 } } ); const { accessToken, refreshToken } = response.data; await saveToken(accessToken, refreshToken); return { success: true, user: response.data.user }; } catch (error) { if (error instanceof Error) { if ("response" in error && typeof (error.response) == "object" && error.response !== null && ("data" in error.response)) { console.log("❌ login API call failed:", error?.response.data); console.log("Server responded:", error?.response.data); return { success: false, error: error?.response.data || "Request failed" }; } else { return { success: false, error: error?.message || "Check you Internet connection and try again" }; } } } } catch (err) { if (err instanceof Error) { return { success: false, error: err.message }; } if (typeof err === "object" && err !== null && "response" in err) { const axiosErr = err as any; return { success: false, error: axiosErr.response?.data?.message || "Unknown error" }; } return { success: false, error: "Unexpected error occurred" }; } }); function handleCloseEvents(mainWindow: BrowserWindow) { let willClose = false; mainWindow.on('close', (e) => { if (willClose) { return; } e.preventDefault(); mainWindow.hide(); if (app.dock) { app.dock.hide(); } }); app.on('before-quit', () => { willClose = true; }); mainWindow.on('show', () => { willClose = false; }); }