diff --git a/package.json b/package.json index 40b39fc..35592b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rapport-server-app", - "version": "0.1.1", + "version": "0.1.2", "private": true, "type": "module", "description": "Doppelklick-Self-Hosting f\u00fcr Rapport \u2014 Tauri-App, die Postgres, GoTrue, PostgREST, Realtime und Storage als Subprozesse b\u00fcndelt.", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c6d1ace..0c40874 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3567,7 +3567,7 @@ dependencies = [ [[package]] name = "rapport-server-app" -version = "0.1.1" +version = "0.1.2" dependencies = [ "axum", "axum-server", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9edda30..456729f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rapport-server-app" -version = "0.1.1" +version = "0.1.2" edition = "2021" authors = ["Karim Gabriele Varano"] license = "AGPL-3.0-or-later" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f320b72..4fc65b7 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2.0.0", "productName": "RAPPORT Server", - "version": "0.1.1", + "version": "0.1.2", "identifier": "com.rapport.server-app", "build": { "beforeDevCommand": "npm run dev", diff --git a/src/components/AppUpdateBanner.jsx b/src/components/AppUpdateBanner.jsx index 724c1e1..1a7f0a3 100644 --- a/src/components/AppUpdateBanner.jsx +++ b/src/components/AppUpdateBanner.jsx @@ -1,17 +1,16 @@ -// Background-Check fuer App-Updates. Im Tauri-Kontext: nutzt das offizielle -// @tauri-apps/plugin-updater. Im Browser (Web-UI): kein App-Update moeglich -// (Browser kann nicht die Server-Mac-App neu installieren) — Banner versteckt. +// Auto-Update-Banner. Pollt latest.json alle 6h. +// Bei Klick: Modal-Overlay mit Live-Fortschritt + sichtbare Errors. import { useEffect, useState } from 'react' -import { runtime } from '../api.js' -import { api } from '../api.js' +import { runtime, api } from '../api.js' const CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000 export default function AppUpdateBanner() { const [update, setUpdate] = useState(null) - const [busy, setBusy] = useState(false) + const [showModal, setShowModal] = useState(false) + const [step, setStep] = useState('idle') // idle|backup|download|install|done|error + const [progress, setProgress] = useState({ downloaded: 0, total: 0 }) const [error, setError] = useState(null) - const [progress, setProgress] = useState(null) useEffect(() => { if (runtime !== 'tauri') return @@ -24,10 +23,7 @@ export default function AppUpdateBanner() { const u = await check() if (alive) setUpdate(u) } catch (e) { - if (alive) { - console.warn('updater check:', e) - setError(String(e)) - } + if (alive) console.warn('updater check:', e) } } @@ -38,53 +34,149 @@ export default function AppUpdateBanner() { async function install() { if (!update) return - const ok = window.confirm( - `Update auf v${update.version} installieren?\n\n` + - 'Ablauf:\n' + - ' 1. pg_dumpall Pre-Backup (auto)\n' + - ' 2. Neue Binary herunterladen + Signatur pruefen\n' + - ' 3. App-Restart mit neuer Version\n\n' + - 'Container laufen waehrend Restart weiter — keine Downtime\n' + - 'auf der Service-Seite. Admin-UI ist ~10s nicht verfuegbar.' - ) - if (!ok) return + setShowModal(true) + setError(null) + setProgress({ downloaded: 0, total: 0 }) - setBusy(true); setError(null); setProgress('Pre-Backup...') try { - // 1) Pre-Backup - await api.backupNow() - setProgress('Update wird heruntergeladen...') + setStep('backup') + console.log('[update] starting pre-backup') + const backup = await api.backupNow() + console.log('[update] backup ok:', backup) - // 2) Download + Install (Tauri plugin uebernimmt restart) + setStep('download') + console.log('[update] starting download + install') + let totalBytes = 0 + let downloaded = 0 await update.downloadAndInstall((event) => { - // event.event: 'Started' | 'Progress' | 'Finished' - if (event.event === 'Progress') { - setProgress(`Download: ${event.data.chunkLength} Bytes`) + console.log('[update] event:', event.event, event.data ?? '') + if (event.event === 'Started') { + totalBytes = event.data?.contentLength ?? 0 + setProgress({ downloaded: 0, total: totalBytes }) + } else if (event.event === 'Progress') { + downloaded += event.data?.chunkLength ?? 0 + setProgress({ downloaded, total: totalBytes }) } else if (event.event === 'Finished') { - setProgress('Installiert — Restart...') + setStep('install') + setProgress({ downloaded: totalBytes, total: totalBytes }) } }) - // Tauri startet die App automatisch neu, dieser Code-Pfad erreicht's nie + // Tauri restartet automatisch — sollten wir nie sehen + setStep('done') } catch (e) { - setError(String(e)) - setBusy(false) - setProgress(null) + console.error('[update] failed:', e) + setStep('error') + setError(String(e?.message ?? e)) + } + } + + function close() { + if (step === 'idle' || step === 'error' || step === 'done') { + setShowModal(false) + setStep('idle') + setError(null) } } if (!update) return null return ( -
Ablauf:
++ Container laufen waehrend Restart weiter — keine Downtime auf der + Service-Seite. Admin-UI ist ~10s nicht verfuegbar. +
++ Fehler: +
+{error}
+ App restartet jetzt mit der neuen Version ...
+ )} +