Added settings page and alternate provider support.

This commit is contained in:
Cameron Redmore 2025-05-21 10:51:53 +01:00
parent b022bca449
commit bc62e0d059
6 changed files with 364 additions and 12 deletions

135
main.js
View file

@ -1,6 +1,6 @@
if (require('electron-squirrel-startup')) return;
const { app, BrowserWindow, globalShortcut, Tray, Menu, nativeImage, screen, clipboard, desktopCapturer } = require('electron');
const { app, BrowserWindow, globalShortcut, Tray, Menu, nativeImage, screen, clipboard, desktopCapturer, ipcMain } = require('electron');
const path = require('path');
const settingsManager = require('./src/settingsManager');
const { handleSquirrelEvent } = require('./src/squirrelEvents');
@ -15,6 +15,7 @@ if (handleSquirrelEvent()) {
let tray = null;
let isQuitting = false; // Flag to differentiate between closing the window and quitting the app
let settingsWindow = null;
async function captureAndPaste() {
const mainWindow = getMainWindow();
@ -95,6 +96,33 @@ function createAppWindow() {
}
});
}
return mainWindow; // Ensure mainWindow is returned
}
function createSettingsWindow() {
if (settingsWindow) {
settingsWindow.focus();
return;
}
settingsWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // Optional: if you need preload for settings
nodeIntegration: true, // Required for ipcRenderer in settingsRenderer.js
contextIsolation: false, // Required for ipcRenderer in settingsRenderer.js
},
parent: getMainWindow(), // Optional: makes it a child of the main window
modal: false, // Set to true if you want it to be a modal dialog
autoHideMenuBar: true,
});
settingsWindow.loadFile(path.join(__dirname, 'settings.html'));
settingsWindow.on('closed', () => {
settingsWindow = null;
});
}
function createTray() {
@ -203,7 +231,34 @@ function createTray() {
});
},
},
{ type: 'separator' }, // Optional: adds a line before the build time and Quit
{ type: 'separator' },
{
label: 'Select Provider',
submenu: settingsManager.getAllSettings().providers.map(provider => ({
label: provider.name,
type: 'radio',
checked: settingsManager.getSetting('currentProvider') === provider.name,
click: () => {
settingsManager.updateSetting('currentProvider', provider.name);
const mainWindow = getMainWindow();
if (mainWindow) {
mainWindow.loadURL(provider.url);
}
// Rebuild tray to reflect change (important for radio button state)
if (tray) {
tray.destroy();
createTray();
}
}
}))
},
{ type: 'separator' },
{
label: 'Settings',
click: () => {
createSettingsWindow();
}
},
{ label: buildTime, enabled: false },
{
label: 'Quit',
@ -233,6 +288,66 @@ Menu.setApplicationMenu(null)
app.on('ready', () => {
console.log(process.argv);
// IPC Handlers for settings
ipcMain.on('get-all-settings', (event) => {
event.returnValue = settingsManager.getAllSettings();
});
ipcMain.on('update-setting', (event, { key, value }) => {
settingsManager.updateSetting(key, value);
// Optionally, notify other windows if needed, e.g., main window for 'isAlwaysOnTop'
if (key === 'isAlwaysOnTop') {
const mainWindow = getMainWindow();
if (mainWindow) {
mainWindow.setAlwaysOnTop(value);
}
}
if (key === 'launchOnStartup') {
app.setLoginItemSettings({
openAtLogin: value,
path: app.getPath('exe'),
});
}
// If currentProvider changes, update the main window URL
if (key === 'currentProvider') {
const mainWindow = getMainWindow();
if (mainWindow) {
const providerUrl = settingsManager.getCurrentProviderUrl();
mainWindow.loadURL(providerUrl);
}
// Rebuild tray to reflect change in provider selection
if (tray) {
tray.destroy();
createTray(); // This will rebuild the menu with the correct checked state
}
}
// Notify settings window to reload if changes can affect it directly
if (settingsWindow) {
settingsWindow.webContents.send('settings-updated');
}
});
ipcMain.on('add-provider', (event, provider) => {
settingsManager.addProvider(provider);
if (settingsWindow) {
settingsWindow.webContents.send('settings-updated'); // Refresh provider list
}
});
ipcMain.on('delete-provider', (event, index) => {
settingsManager.deleteProvider(index);
if (settingsWindow) {
settingsWindow.webContents.send('settings-updated'); // Refresh provider list
}
});
ipcMain.on('update-provider', (event, { index, name, url }) => {
settingsManager.updateProvider(index, { name, url });
if (settingsWindow) {
settingsWindow.webContents.send('settings-updated'); // Refresh provider list
}
});
let firstRunWindow = null;
// Check for Squirrel events (like first run)
@ -284,6 +399,15 @@ app.on('ready', () => {
});
createTray();
// Listen for current-provider-changed event to update the main window URL
ipcMain.on('current-provider-changed', () => {
const mainWindow = getMainWindow();
if (mainWindow) {
const providerUrl = settingsManager.getCurrentProviderUrl();
mainWindow.loadURL(providerUrl);
}
});
});
app.on('will-quit', () => {
@ -311,13 +435,6 @@ app.on('activate', () => {
});
app.on('web-contents-created', (event, webContents) => {
webContents.on('will-navigate', (event) => {
// Only allow navigation to `google.com` or subdomains
const url = new URL(webContents.getURL());
if (url.hostname !== 'google.com' && !url.hostname.endsWith('.google.com')) {
event.preventDefault();
}
});
});
const assetsDir = path.join(__dirname, 'assets');