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

+ +
+ +
+

Runtime

+ +
+ +
+

System

+ +
+ +
+ + + + + GitHub + + + + + Help + +
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