From 6596c13d4d26ad23b2fe96a24917130cadb17a56 Mon Sep 17 00:00:00 2001 From: Andrew Zambazos Date: Mon, 11 Aug 2025 10:49:32 +1200 Subject: [PATCH] Add detailed About panel to settings page Introduces an About tab in the settings page displaying app, runtime, and system diagnostics. Adds IPC and preload bridge for about info, clipboard copy functionality, and external navigation for GitHub and Help links. Updates site-history.json with relevant links. --- main.js | 27 ++++++++++++ preload.js | 7 ++- renderer/settings.html | 79 +++++++++++++++++++++++++++++++++- renderer/settings.js | 98 ++++++++++++++++++++++++++++++++++++++++++ site-history.json | 5 +++ 5 files changed, 213 insertions(+), 3 deletions(-) diff --git a/main.js b/main.js index 45b12e1..4b77b9d 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,7 @@ const { app, BrowserWindow, ipcMain, session, screen, shell } = require('electron'); const fs = require('fs'); const path = require('path'); +const os = require('os'); const PerformanceMonitor = require('./performance-monitor'); const GPUFallback = require('./gpu-fallback'); const GPUConfig = require('./gpu-config'); @@ -443,3 +444,29 @@ ipcMain.handle('apply-gpu-fallback', (event, level) => { return { error: err.message }; } }); + +// About/info handler +ipcMain.handle('get-about-info', () => { + try { + return { + appName: app.getName(), + appVersion: app.getVersion(), + isPackaged: app.isPackaged, + appPath: app.getAppPath(), + userDataPath: app.getPath('userData'), + electronVersion: process.versions.electron, + chromeVersion: process.versions.chrome, + nodeVersion: process.versions.node, + v8Version: process.versions.v8, + platform: process.platform, + arch: process.arch, + osType: os.type(), + osRelease: os.release(), + cpu: os.cpus()?.[0]?.model || 'Unknown CPU', + totalMemGB: Math.round((os.totalmem() / (1024 ** 3)) * 10) / 10, + }; + } catch (err) { + console.error('Error building about info:', err); + return { error: err.message }; + } +}); diff --git a/preload.js b/preload.js index ccf7d7d..330a46c 100644 --- a/preload.js +++ b/preload.js @@ -84,4 +84,9 @@ const bookmarksAPI = { // Expose APIs to main world contextBridge.exposeInMainWorld('electronAPI', electronAPI); -contextBridge.exposeInMainWorld('bookmarksAPI', bookmarksAPI); \ No newline at end of file +contextBridge.exposeInMainWorld('bookmarksAPI', bookmarksAPI); + +// Minimal about API for settings page +contextBridge.exposeInMainWorld('aboutAPI', { + getInfo: () => ipcRenderer.invoke('get-about-info') +}); \ No newline at end of file diff --git a/renderer/settings.html b/renderer/settings.html index f5fee0f..8f097d9 100644 --- a/renderer/settings.html +++ b/renderer/settings.html @@ -237,6 +237,36 @@ background: var(--accent); border-radius: 8px; } + + /* About actions */ + .about-actions { + display: flex; + gap: 10px; + align-items: center; + flex-wrap: wrap; + } + .github-btn, .help-btn { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 12px; + background: var(--primary); + color: #fff; + border: none; + border-radius: 6px; + text-decoration: none; + cursor: pointer; + transition: background 0.2s ease; + } + .github-btn:hover, .help-btn:hover { + background: var(--accent); + } + .github-btn svg, .help-btn svg { + width: 18px; + height: 18px; + fill: currentColor; + display: block; + } @@ -437,8 +467,53 @@

About

-

Nebula Browser Experimental Settings

-

Version info and links can go here.

+
+

Application

+
    +
  • Name: Loading...
  • +
  • Version: Loading...
  • +
  • Packaged: Loading...
  • +
  • User data: Loading...
  • +
+
+ +
+

Runtime

+
    +
  • Electron: Loading...
  • +
  • Chromium: Loading...
  • +
  • Node.js: Loading...
  • +
  • V8: Loading...
  • +
+
+ +
+

System

+
    +
  • OS: Loading...
  • +
  • CPU: Loading...
  • +
  • Architecture: Loading...
  • +
  • Memory: Loading...
  • +
+
+ +
diff --git a/renderer/settings.js b/renderer/settings.js index 4b7d0d7..9ab0647 100644 --- a/renderer/settings.js +++ b/renderer/settings.js @@ -137,3 +137,101 @@ function initTabs() { window.addEventListener('DOMContentLoaded', () => { initTabs(); }); + +// About tab population +async function populateAbout() { + try { + const info = (window.aboutAPI && typeof window.aboutAPI.getInfo === 'function') + ? await window.aboutAPI.getInfo() + : null; + if (!info || info.error) { + console.warn('[ABOUT] Unable to load about info', info && info.error); + return; + } + const byId = (id) => document.getElementById(id); + byId('about-app-name').textContent = info.appName; + byId('about-app-version').textContent = info.appVersion; + byId('about-packaged').textContent = info.isPackaged ? 'Yes' : 'No'; + byId('about-userdata').textContent = info.userDataPath; + + byId('about-electron').textContent = info.electronVersion; + byId('about-chrome').textContent = info.chromeVersion; + byId('about-node').textContent = info.nodeVersion; + byId('about-v8').textContent = info.v8Version; + + byId('about-os').textContent = `${info.osType} ${info.osRelease}`; + byId('about-cpu').textContent = info.cpu; + byId('about-arch').textContent = info.arch; + byId('about-mem').textContent = `${info.totalMemGB} GB`; + + const copyBtn = document.getElementById('copy-about-btn'); + if (copyBtn) { + copyBtn.addEventListener('click', async () => { + const payload = [ + `Nebula ${info.appVersion} (${info.isPackaged ? 'packaged' : 'dev'})`, + `Electron ${info.electronVersion} | Chromium ${info.chromeVersion} | Node ${info.nodeVersion} | V8 ${info.v8Version}`, + `${info.osType} ${info.osRelease} ${info.arch}`, + `CPU: ${info.cpu}`, + `RAM: ${info.totalMemGB} GB`, + `UserData: ${info.userDataPath}` + ].join('\n'); + try { + await navigator.clipboard.writeText(payload); + showStatus('Diagnostics copied'); + } catch (err) { + console.error('Clipboard error:', err); + showStatus('Failed to copy diagnostics'); + } + }); + } + } catch (err) { + console.error('[ABOUT] Error populating about info:', err); + } +} + +// Populate about info after DOM is ready +window.addEventListener('DOMContentLoaded', () => { + populateAbout(); +}); + +// Keep settings open when clicking GitHub by asking host to open externally/new tab +window.addEventListener('DOMContentLoaded', () => { + const gh = document.getElementById('github-link'); + if (gh) { + gh.addEventListener('click', (e) => { + try { + e.preventDefault(); + const url = gh.getAttribute('href'); + if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') { + window.electronAPI.sendToHost('navigate', url, { newTab: true }); + } else if (window.parent) { + window.parent.postMessage({ type: 'navigate', url, newTab: true }, '*'); + } else { + window.open(url, '_blank', 'noopener'); + } + } catch (err) { + console.error('Failed to open GitHub link:', err); + window.open(gh.getAttribute('href'), '_blank'); + } + }); + } + const help = document.getElementById('help-link'); + if (help) { + help.addEventListener('click', (e) => { + try { + e.preventDefault(); + const url = help.getAttribute('href'); + if (window.electronAPI && typeof window.electronAPI.sendToHost === 'function') { + window.electronAPI.sendToHost('navigate', url, { newTab: true }); + } else if (window.parent) { + window.parent.postMessage({ type: 'navigate', url, newTab: true }, '*'); + } else { + window.open(url, '_blank', 'noopener'); + } + } catch (err) { + console.error('Failed to open Help link:', err); + window.open(help.getAttribute('href'), '_blank'); + } + }); + } +}); diff --git a/site-history.json b/site-history.json index 1e23822..46ab1e1 100644 --- a/site-history.json +++ b/site-history.json @@ -1,3 +1,8 @@ [ + "https://nebula.zambazosmedia.group/roadmap.html", + "https://nebula.zambazosmedia.group/index.html", + "https://nebula.zambazosmedia.group/wiki/index.html", + "https://nebula.zambazosmedia.group/", + "https://github.com/Bobbybear007/NebulaBrowser", "https://www.youtube.com/" ] \ No newline at end of file