diff --git a/gui/electron/index.html b/gui/electron/index.html index 7faaa62..cf7d671 100644 --- a/gui/electron/index.html +++ b/gui/electron/index.html @@ -53,6 +53,8 @@ window.voxvera.onOnionUrl(url => { document.getElementById('onion-address').textContent = `Onion address: ${url}`; + const tear = document.getElementById('tear_off_link'); + if (tear) tear.value = url; }); window.voxvera.onLog((msg, isErr) => { diff --git a/gui/electron/main.js b/gui/electron/main.js index da471f3..8d70f9c 100644 --- a/gui/electron/main.js +++ b/gui/electron/main.js @@ -5,6 +5,7 @@ const which = require('which'); const fs = require('fs'); let mainWindow; +let onionProc; function createWindow() { mainWindow = new BrowserWindow({ @@ -17,7 +18,50 @@ function createWindow() { mainWindow.loadFile('index.html'); } -app.whenReady().then(createWindow); +function startOnionShare() { + const configPath = getConfigPath(); + const voxveraPath = which.sync('voxvera', { nothrow: true }); + if (!voxveraPath) { + dialog.showErrorBox( + 'voxvera not found', + 'Install the voxvera CLI and ensure it is in your PATH.' + ); + return; + } + const build = spawn(voxveraPath, ['--config', configPath, 'build']); + build.on('close', () => { + const args = ['--config', configPath, 'serve']; + onionProc = spawn(voxveraPath, args); + onionProc.stdout.on('data', data => { + const line = data.toString(); + process.stdout.write(line); + if (mainWindow) { + mainWindow.webContents.send('log', { text: line, isError: false }); + } + const m = line.match(/Onion URL:\s*(https?:\/\/[a-z0-9.-]+\.onion)/i); + if (m && mainWindow) { + mainWindow.webContents.send('onion-url', m[1]); + } + }); + onionProc.stderr.on('data', data => { + const line = data.toString(); + process.stderr.write(line); + if (mainWindow) { + mainWindow.webContents.send('log', { text: line, isError: true }); + } + }); + onionProc.on('close', code => { + if (code !== 0) { + dialog.showErrorBox('OnionShare error', `onionshare exited with code ${code}.`); + } + }); + }); +} + +app.whenReady().then(() => { + createWindow(); + startOnionShare(); +}); function getConfigPath() { return path.join(__dirname, '..', '..', 'voxvera', 'src', 'config.json'); @@ -43,6 +87,10 @@ ipcMain.handle('run-quickstart', async (_, config) => { return -1; } return new Promise((resolve) => { + if (onionProc) { + onionProc.kill(); + onionProc = null; + } const args = ['--config', configPath, 'quickstart', '--non-interactive']; const proc = spawn(voxveraPath, args); proc.stdout.on('data', data => { @@ -77,5 +125,9 @@ ipcMain.handle('run-quickstart', async (_, config) => { }); app.on('window-all-closed', () => { + if (onionProc) { + onionProc.kill(); + onionProc = null; + } if (process.platform !== 'darwin') app.quit(); });