From 7ef4eefc554ddce5bc3d161459be945c59db039a Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 7 Mar 2026 13:53:26 +0100 Subject: [PATCH] Add: Update-Dialog fuer Electron Auto-Updater - main.js: IPC-Events an Renderer senden wenn Update bereit - main.js: install-update IPC Handler (quitAndInstall) - App.tsx: Update-Banner "Neues Update verfuegbar!" mit Restart-Button - styles.css: Update-Bar Styling passend zum Design-System Co-Authored-By: Claude Opus 4.6 --- electron/main.js | 8 +++++++- web/src/App.tsx | 17 +++++++++++++++++ web/src/styles.css | 28 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/electron/main.js b/electron/main.js index 6d707bd..6f9a69b 100644 --- a/electron/main.js +++ b/electron/main.js @@ -1,4 +1,4 @@ -const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater, dialog } = require('electron'); +const { app, BrowserWindow, session, shell, desktopCapturer, autoUpdater, dialog, ipcMain } = require('electron'); const path = require('path'); const { setupAdBlocker } = require('./ad-blocker'); @@ -28,6 +28,12 @@ function setupAutoUpdater() { autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => { console.log('[AutoUpdater] Update downloaded:', releaseName || 'new version'); + if (mainWindow) mainWindow.webContents.send('update-ready'); + }); + + // Handle install-update request from renderer + ipcMain.on('install-update', () => { + autoUpdater.quitAndInstall(); }); autoUpdater.on('update-not-available', () => { diff --git a/web/src/App.tsx b/web/src/App.tsx index 27ae508..f951ef7 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -27,6 +27,7 @@ export function registerTab(pluginName: string, component: React.FC<{ data: any export default function App() { const [connected, setConnected] = useState(false); const [plugins, setPlugins] = useState([]); + const [updateReady, setUpdateReady] = useState(false); const [activeTab, setActiveTabRaw] = useState(() => localStorage.getItem('hub_activeTab') ?? ''); const setActiveTab = (tab: string) => { @@ -93,6 +94,13 @@ export default function App() { const version = (import.meta as any).env?.VITE_APP_VERSION ?? '1.5.0'; + // Listen for Electron auto-update events + useEffect(() => { + const api = (window as any).electronAPI; + if (!api?.onUpdateReady) return; + api.onUpdateReady(() => setUpdateReady(true)); + }, []); + // Tab icon mapping const tabIcons: Record = { radio: '\u{1F30D}', @@ -145,6 +153,15 @@ export default function App() { + {updateReady && ( +
+ Neues Update verfügbar! + +
+ )} +
{plugins.length === 0 ? (
diff --git a/web/src/styles.css b/web/src/styles.css index a7eaea6..ed5bd67 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -226,6 +226,34 @@ html, body { border-radius: 4px; } +/* ── Update Banner ── */ +.hub-update-bar { + display: flex; + align-items: center; + justify-content: center; + gap: 12px; + padding: 8px 16px; + background: rgba(var(--accent-rgb), 0.15); + border-bottom: 1px solid rgba(var(--accent-rgb), 0.3); + font-size: 13px; + font-weight: 500; + color: var(--accent); +} +.hub-update-bar button { + padding: 4px 14px; + font-size: 12px; + font-weight: 600; + border: none; + border-radius: var(--radius); + background: var(--accent); + color: #fff; + cursor: pointer; + transition: opacity var(--transition); +} +.hub-update-bar button:hover { + opacity: 0.85; +} + /* ── Main Content Area ── */ .hub-content { flex: 1;