Organized all the code

Updated the update notification to check periodically every 5 minutes
Added in headless browser support for extensions (check the extensions repo to see an example)
Added in DiscordRPC support
This commit is contained in:
2025-11-19 16:28:33 -05:00
parent 2f556c2ddc
commit 5f3020ca6e
24 changed files with 1077 additions and 815 deletions

View File

@@ -0,0 +1,67 @@
const { BrowserWindow } = require('electron');
class HeadlessBrowser {
async scrape(url, evalFunc, options = {}) {
const { waitSelector = null, timeout = 15000 } = options;
const win = new BrowserWindow({
show: false,
width: 800,
height: 600,
webPreferences: {
offscreen: true,
contextIsolation: false,
nodeIntegration: false,
images: true,
webgl: false,
},
});
try {
const userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
win.webContents.setUserAgent(userAgent);
await win.loadURL(url, { userAgent });
if (waitSelector) {
await this.waitForSelector(win, waitSelector, timeout);
}
const result = await win.webContents.executeJavaScript(`(${evalFunc.toString()})()`);
return result;
} catch (error) {
console.error('Headless Scrape Error:', error.message);
throw error;
} finally {
if (!win.isDestroyed()) {
win.destroy();
}
}
}
async waitForSelector(win, selector, timeout) {
const script = `
new Promise((resolve, reject) => {
const timer = setTimeout(() => {
reject(new Error('Timeout waiting for selector: ${selector}'));
}, ${timeout});
const check = () => {
if (document.querySelector('${selector}')) {
clearTimeout(timer);
resolve(true);
} else {
// FIX: Use setTimeout because requestAnimationFrame stops in hidden windows
setTimeout(check, 100);
}
};
check();
});
`;
await win.webContents.executeJavaScript(script);
}
}
module.exports = new HeadlessBrowser();