mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
feat: Windows NSIS installer, embedded icons, GUI auto-launch backend
- Add package/installer.nsi (Full/Server/Client) and toolchain.nsi
- Embed icon.ico (rounded corners) into homed.exe/waiter.exe via .syso
- GUI auto-launches homed.exe from parent dir (Windows only)
- GUI fallback connections.json from app resource dir
- Add initconfig command for config.db seeding
- Replace waiter rawmode* with raw_{unix,windows,other}.go
- Fix .gitignore: /homed instead of homed, add login.json
- Update icon.svg with rounded rect, new mascot.svg
This commit is contained in:
101
cmd/gui/main.js
101
cmd/gui/main.js
@ -1,9 +1,14 @@
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
|
||||
const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { spawn } = require('child_process');
|
||||
const http = require('http');
|
||||
|
||||
const CONNECTIONS_FILE = path.join(app.getPath('userData'), 'connections.json');
|
||||
|
||||
let homedProcess = null;
|
||||
let mainWindow;
|
||||
|
||||
function loadConnections() {
|
||||
try {
|
||||
if (fs.existsSync(CONNECTIONS_FILE)) {
|
||||
@ -12,6 +17,18 @@ function loadConnections() {
|
||||
} catch (e) {
|
||||
console.error('Failed to load connections:', e);
|
||||
}
|
||||
// Fallback: check app resource dir (installer writes fallback copy there)
|
||||
try {
|
||||
const fallback = path.join(__dirname, 'connections.json');
|
||||
if (fs.existsSync(fallback)) {
|
||||
const data = JSON.parse(fs.readFileSync(fallback, 'utf-8'));
|
||||
saveConnections(data);
|
||||
console.log('Imported connections from app resource dir');
|
||||
return data;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Fallback connections load failed:', e);
|
||||
}
|
||||
return { connections: [], currentId: null };
|
||||
}
|
||||
|
||||
@ -23,9 +40,69 @@ function saveConnections(data) {
|
||||
}
|
||||
}
|
||||
|
||||
let mainWindow;
|
||||
function findHomed() {
|
||||
if (process.platform !== 'win32') return null;
|
||||
const exeDir = path.dirname(app.getPath('exe'));
|
||||
const p = path.resolve(exeDir, '..', 'homed.exe');
|
||||
return fs.existsSync(p) ? p : null;
|
||||
}
|
||||
|
||||
function isServerRunning() {
|
||||
return new Promise((resolve) => {
|
||||
const req = http.get('http://localhost:8080/', () => resolve(true));
|
||||
req.on('error', () => resolve(false));
|
||||
req.setTimeout(2000, () => { req.destroy(); resolve(false); });
|
||||
});
|
||||
}
|
||||
|
||||
function waitForServer(maxWait = 8000) {
|
||||
return new Promise((resolve) => {
|
||||
const start = Date.now();
|
||||
const check = () => {
|
||||
isServerRunning().then((running) => {
|
||||
if (running) return resolve(true);
|
||||
if (Date.now() - start > maxWait) return resolve(false);
|
||||
setTimeout(check, 300);
|
||||
});
|
||||
};
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
function startHomed() {
|
||||
const homedBin = findHomed();
|
||||
if (!homedBin) {
|
||||
console.log('homed.exe not found near GUI, skipping auto-launch');
|
||||
return;
|
||||
}
|
||||
const dataDir = path.resolve(path.dirname(homedBin), 'data');
|
||||
console.log('Starting homed:', homedBin, '-data', dataDir);
|
||||
homedProcess = spawn(homedBin, ['-data', dataDir], {
|
||||
stdio: 'ignore',
|
||||
detached: false,
|
||||
windowsHide: true,
|
||||
});
|
||||
homedProcess.on('error', (err) => {
|
||||
console.error('homed start failed:', err.message);
|
||||
homedProcess = null;
|
||||
});
|
||||
homedProcess.on('exit', (code) => {
|
||||
console.log('homed exited with code', code);
|
||||
homedProcess = null;
|
||||
});
|
||||
}
|
||||
|
||||
function stopHomed() {
|
||||
if (homedProcess) {
|
||||
homedProcess.kill();
|
||||
homedProcess = null;
|
||||
}
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
const menu = Menu.buildFromTemplate([]);
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 860,
|
||||
@ -93,12 +170,28 @@ ipcMain.handle('connections:setCurrent', (_, id) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
app.whenReady().then(createWindow);
|
||||
app.whenReady().then(async () => {
|
||||
const running = await isServerRunning();
|
||||
if (!running) {
|
||||
startHomed();
|
||||
const started = await waitForServer();
|
||||
if (started) {
|
||||
console.log('homed started successfully');
|
||||
} else {
|
||||
console.error('homed failed to start within timeout');
|
||||
}
|
||||
}
|
||||
createWindow();
|
||||
});
|
||||
|
||||
app.on('before-quit', stopHomed);
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit();
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
if (mainWindow === null) createWindow();
|
||||
if (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user