reloadVersionsAndStatus(); $this->recompute(); if ($this->running) $this->state = 'running'; } public function render() { return view('livewire.ui.system.update-card'); } /* ========== Aktionen ========== */ public function refreshState(): void { $this->state = 'running'; $this->message = 'Prüfe auf Updates …'; $this->messagePositive = null; try { Artisan::call('mailwolt:check-updates'); } catch (\Throwable $e) { // kein fataler Abbruch } $this->reloadVersionsAndStatus(); $this->recompute(); $this->finishUiIfNoUpdate(); } public function runUpdate(): void { Cache::forget('mailwolt.update_available'); Cache::put($this->cacheStartedAtKey, time(), now()->addHour()); @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); $this->latest = null; $this->displayLatest = null; $this->hasUpdate = false; $this->state = 'running'; $this->running = true; $this->message = 'Update läuft …'; } public function tick(): void { $this->refreshLowLevelState(); $started = (int)Cache::get($this->cacheStartedAtKey, 0); if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) { $this->running = false; $this->rc ??= 0; } if (!$this->running) { Cache::forget($this->cacheStartedAtKey); $this->reloadVersionsAndStatus(); $this->recompute(); $this->finishUiIfNoUpdate(); if ($this->rc === 0) { $ver = $this->displayCurrent ?? 'aktuelle Version'; // ✅ zentraler Toastra-Toast $this->dispatch('toast', type: 'success', title: 'Update erfolgreich', text: "MailWolt wurde erfolgreich auf {$ver} aktualisiert. Die Seite wird in 5 Sekunden neu geladen …", badge: 'System', duration: 5000 ); // nach 5 Sekunden Seite neu laden $this->dispatch('reload-page', delay: 5000); } elseif ($this->rc !== null) { $this->dispatch('toast', type: 'error', title: 'Update fehlgeschlagen', text: "Update ist mit Rückgabecode {$this->rc} fehlgeschlagen. Bitte Logs prüfen.", badge: 'System', duration: 0 ); } $this->state = 'idle'; } } /* ========== Helper ========== */ protected function reloadVersionsAndStatus(): void { $this->current = $this->readCurrentVersion(); $this->latest = Cache::get('mailwolt.update_available'); $this->refreshLowLevelState(); } protected function finishUiIfNoUpdate(): void { if (!$this->hasUpdate) { $this->state = 'idle'; $cur = $this->displayCurrent ?? '–'; $this->message = "Du bist auf dem neuesten Stand ({$cur})"; $this->messagePositive = true; Cache::forget('mailwolt.update_available'); } } protected function recompute(): void { $curNorm = $this->normalizeVersion($this->current); $latNorm = $this->normalizeVersion($this->latest); $this->hasUpdate = ($curNorm && $latNorm) ? version_compare($latNorm, $curNorm, '>') : false; // Immer mit v-Präfix anzeigen $this->displayCurrent = $curNorm ? 'v' . $curNorm : null; $this->displayLatest = ($this->hasUpdate && $latNorm) ? 'v' . $latNorm : null; } protected function refreshLowLevelState(): void { $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); $this->running = ($state === 'running'); $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; } protected function readCurrentVersion(): ?string { $build = @file_get_contents('/etc/mailwolt/build.info'); if ($build) { foreach (preg_split('/\R+/', $build) as $line) { if (str_starts_with($line, 'version=')) { $v = trim(substr($line, 8)); return $v !== '' ? $v : null; } } } $v = config('app.version'); return $v !== '' ? $v : null; } protected function normalizeVersion(?string $v): ?string { if ($v === null) return null; $v = trim($v); return ltrim($v, "vV \t\n\r\0\x0B") ?: null; } } //namespace App\Livewire\Ui\System; // //use Illuminate\Support\Facades\Artisan; //use Illuminate\Support\Facades\Cache; //use Livewire\Component; // //class UpdateCard extends Component //{ // /** Rohwerte (so wie gelesen/aus Cache) */ // public ?string $current = null; // z.B. "v1.0.20" oder "1.0.20" // public ?string $latest = null; // z.B. "1.0.20" oder "v1.0.20" // // /** Anzeige (immer mit v-Präfix) */ // public ?string $displayCurrent = null; // z.B. "v1.0.20" // public ?string $displayLatest = null; // nur gesetzt, wenn wirklich neuer // // /** Status/UX */ // public bool $hasUpdate = false; // public string $state = 'idle'; // idle|running // public ?string $message = null; // public ?bool $messagePositive = null; // // /** low-level / Wrapper */ // public bool $running = false; // public ?int $rc = null; // // /** intern */ // protected string $cacheStartedAtKey = 'mw.update.started_at'; // protected int $failsafeSeconds = 20 * 60; // 20 Min // // public function mount(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // // $this->recompute(); // setzt hasUpdate + display* + ggf. message // if ($this->running) $this->state = 'running'; // } // // public function render() // { // return view('livewire.ui.system.update-card'); // } // // /* =================== Aktionen =================== */ // // public function refreshState(): void // { // $this->state = 'running'; // $this->message = 'Prüfe auf Updates …'; // $this->messagePositive = null; // // try { // Artisan::call('mailwolt:check-updates'); // } catch (\Throwable $e) { // // weich fallen // } // // $this->reloadVersionsAndStatus(); // $this->recompute(); // $this->finishUiIfNoUpdate(); // beendet progress, wenn nichts mehr offen ist // } // // public function runUpdate(): void // { // // Hinweis sofort entfernen (Badge weg) // Cache::forget('mailwolt.update_available'); // Cache::put($this->cacheStartedAtKey, time(), now()->addHour()); // // // Wrapper asynchron starten // @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); // // // UI-Status // $this->latest = null; // $this->displayLatest = null; // $this->hasUpdate = false; // // $this->state = 'running'; // $this->running = true; // $this->message = 'Update läuft …'; // $this->messagePositive = null; // } // // /** Wird nur gepollt, solange $state==='running' (wire:poll) */ // public function tick(): void // { // $this->refreshLowLevelState(); // // // Failsafe // $started = (int)Cache::get($this->cacheStartedAtKey, 0); // if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) { // $this->running = false; // } // // if (!$this->running) { // Cache::forget($this->cacheStartedAtKey); // $this->reloadVersionsAndStatus(); // $this->recompute(); // $this->finishUiIfNoUpdate(); // } // } // // /* =================== Helpers =================== */ // // protected function reloadVersionsAndStatus(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // } // // protected function finishUiIfNoUpdate(): void // { // if (!$this->hasUpdate) { // $this->state = 'idle'; // $cur = $this->displayCurrent ?? '–'; // // <<< Klammern-Fix: erst coalescen, dann in den String einsetzen // $this->message = "Du bist auf dem neuesten Stand ({$cur})"; // $this->messagePositive = true; // // // zur Sicherheit: Cache leeren // Cache::forget('mailwolt.update_available'); // } // } // // protected function recompute(): void // { // $curNorm = $this->normalizeVersion($this->current); // $latNorm = $this->normalizeVersion($this->latest); // // $this->hasUpdate = ($curNorm && $latNorm) // ? version_compare($latNorm, $curNorm, '>') // : false; // // // Anzeige immer mit v-Präfix // $this->displayCurrent = $curNorm ? 'v' . $curNorm : null; // $this->displayLatest = ($this->hasUpdate && $latNorm) ? 'v' . $latNorm : null; // // // Initiale Message (nur wenn noch nicht gesetzt) // if ($this->message === null) { // if ($this->hasUpdate) { // $this->message = "Neue Version verfügbar: {$this->displayLatest}"; // $this->messagePositive = false; // } else { // $cur = $this->displayCurrent ?? '–'; // $this->message = "Du bist auf dem neuesten Stand ({$cur})"; // $this->messagePositive = true; // } // } // } // // protected function refreshLowLevelState(): void // { // $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); // $this->running = ($state === 'running'); // // $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); // $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; // } // // protected function readCurrentVersion(): ?string // { // // bevorzugt build.info // $build = @file_get_contents('/etc/mailwolt/build.info'); // if ($build) { // foreach (preg_split('/\R+/', $build) as $line) { // if (str_starts_with($line, 'version=')) { // $v = trim(substr($line, 8)); // return $v !== '' ? $v : null; // } // } // } // $v = config('app.version'); // return $v !== '' ? $v : null; // } // // protected function normalizeVersion(?string $v): ?string // { // if ($v === null) return null; // $v = trim($v); // // führendes v/V + whitespace entfernen // $v = ltrim($v, "vV \t\n\r\0\x0B"); // return $v === '' ? null : $v; // } //} //namespace App\Livewire\Ui\System; // //use Illuminate\Support\Facades\Artisan; //use Illuminate\Support\Facades\Cache; //use Livewire\Component; // //class UpdateCard extends Component //{ // public ?string $current = null; // installierte Version // public ?string $latest = null; // verfügbare Version (oder null) // public string $state = 'idle'; // idle | running // // public ?string $message = null; // public ?bool $messagePositive = null; // // // low-level // public bool $running = false; // public ?int $rc = null; // // // intern // protected string $cacheStartedAtKey = 'mw.update.started_at'; // protected int $failsafeSeconds = 20 * 60; // 20 Min // // public function mount(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // // // initiale Message // if ($this->message === null) { // if ($this->getHasUpdateProperty()) { // $this->message = "Neue Version verfügbar: {$this->latest}"; // $this->messagePositive = false; // } else { // $cur = $this->current ?: '–'; // $this->message = "Du bist auf dem neuesten Stand ({$cur})"; // $this->messagePositive = true; // } // } // // // falls der Wrapper gerade läuft → visuell „running“ // if ($this->running) { // $this->state = 'running'; // } // } // // public function render() // { // return view('livewire.ui.system.update-card'); // } // // /* =================== Aktionen =================== */ // // public function refreshState(): void // { // $this->state = 'running'; // $this->message = 'Prüfe auf Updates …'; // $this->messagePositive = null; // // try { // Artisan::call('mailwolt:check-updates'); // } catch (\Throwable $e) { // // weich fallen // } // // $this->reloadVersionsAndStatus(); // $this->finishUiIfNoUpdate(); // } // // public function runUpdate(): void // { // // Badge „Update verfügbar“ sofort ausblenden // Cache::forget('mailwolt.update_available'); // // // Startzeit merken (Failsafe) // Cache::put($this->cacheStartedAtKey, time(), now()->addHours(1)); // // // Wrapper asynchron starten // @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); // // $this->latest = null; // $this->state = 'running'; // $this->running = true; // $this->message = 'Update läuft …'; // $this->messagePositive = null; // } // // /** // * Wird vom Blade nur während running gepollt (wire:poll="tick"). // * Bricht den Fortschritt ab, sobald der Wrapper „done“ meldet ODER // * der Failsafe greift. Lädt danach Versionen & Badge neu. // */ // public function tick(): void // { // $this->refreshLowLevelState(); // // // Failsafe: nach N Minuten Fortschritt aus // $started = (int)Cache::get($this->cacheStartedAtKey, 0); // if ($this->running && $started > 0 && (time() - $started) > $this->failsafeSeconds) { // $this->running = false; // } // // if (!$this->running) { // // abgeschlossen → Startmarke löschen // Cache::forget($this->cacheStartedAtKey); // // // Versionen/Caches neu laden // $this->reloadVersionsAndStatus(); // // // wenn erfolgreich (rc=0) und keine neue Version mehr → Done // $this->finishUiIfNoUpdate(); // } // // wenn weiterhin running: nichts tun, UI zeigt Progress weiter // } // // /* =================== Computed =================== */ // // // Blade nutzt $this->hasUpdate // public function getHasUpdateProperty(): bool // { // $cur = $this->normalizeVersion($this->current ?? null); // $lat = $this->normalizeVersion($this->latest ?? null); // if ($lat === null || $cur === null) return false; // return version_compare($lat, $cur, '>'); // } // // /* =================== Helpers =================== */ // // protected function reloadVersionsAndStatus(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // } // // protected function finishUiIfNoUpdate(): void // { // if (!$this->getHasUpdateProperty()) { // // alles aktuell → Fortschritt aus, Badge „Aktuell“, Hinweistext grün // $this->state = 'idle'; // $this->message = "Du bist auf dem neuesten Stand (" . $this->current ?? '–' . ")"; // $this->messagePositive = true; // // // zur Sicherheit Badge-Cache entfernen // Cache::forget('mailwolt.update_available'); // } // } // // protected function refreshLowLevelState(): void // { // $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); // $this->running = ($state === 'running'); // // $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); // $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; // } // // protected function readCurrentVersion(): ?string // { // $build = @file_get_contents('/etc/mailwolt/build.info'); // if ($build) { // foreach (preg_split('/\R+/', $build) as $line) { // if (str_starts_with($line, 'version=')) { // $v = trim(substr($line, 8)); // if ($v !== '') return $v; // } // } // } // $v = config('app.version'); // return $v !== '' ? $v : null; // } // // protected function normalizeVersion(?string $v): ?string // { // if ($v === null) return null; // $v = trim($v); // $v = ltrim($v, 'v'); // führt "v1.0.19" und "1.0.19" zusammen // return $v === '' ? null : $v; // } //} //namespace App\Livewire\Ui\System; // //use Illuminate\Support\Facades\Artisan; //use Illuminate\Support\Facades\Cache; //use Livewire\Component; // //class UpdateCard extends Component //{ // public ?string $current = null; // installed (pretty) // public ?string $latest = null; // available (pretty or null) // public string $state = 'idle'; // idle|running // // public ?string $message = null; // inline message // public ?bool $messagePositive = null; // // // low-level // public bool $running = false; // public ?int $rc = null; // // // ---- lifecycle --------------------------------------------------------- // // public function mount(): void // { // $this->readLowLevel(); // $this->current = $this->readCurrentVersion(); // $this->latest = $this->readCachedLatest(); // // if ($this->message === null) { // if ($this->hasUpdate()) { // $this->message = "Neue Version verfügbar: {$this->latest}"; // $this->messagePositive = false; // } else { // $cur = $this->current ?? '–'; // $this->message = "Du bist auf dem neuesten Stand ({$cur})"; // $this->messagePositive = true; // } // } // // // if wrapper is already running when page loads, reflect that // if ($this->running) { // $this->state = 'running'; // } // } // // public function render() // { // return view('livewire.ui.system.update-card'); // } // // // ---- UI actions -------------------------------------------------------- // // /** Button: „Erneut prüfen“ (no toast; shows inline progress) */ // public function refreshState(): void // { // $this->state = 'running'; // $this->message = 'Prüfe auf Updates …'; // $this->messagePositive = null; // // try { // // your checker should update the cache key below // Artisan::call('mailwolt:check-updates'); // } catch (\Throwable $e) { // // swallow but still continue to show something meaningful // } // // $this->current = $this->readCurrentVersion(); // $this->latest = $this->readCachedLatest(); // $this->readLowLevel(); // // if ($this->hasUpdate()) { // $this->message = "Neue Version verfügbar: {$this->latest}"; // $this->messagePositive = false; // } else { // $this->message = "Du bist auf dem neuesten Stand ($this->current ?? '–')"; // $this->messagePositive = true; // } // // $this->state = 'idle'; // } // // /** Button: „Jetzt aktualisieren“ (no toast; start wrapper + progress) */ // public function runUpdate(): void // { // // Hide the yellow badges immediately // Cache::forget('mailwolt.update_available'); // // // spawn wrapper in the background // @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); // // // reflect “running” in UI // $this->latest = null; // $this->state = 'running'; // $this->running = true; // $this->message = 'Update läuft …'; // $this->messagePositive = null; // } // // /** // * Called from the blade with `wire:poll.1200ms="tick"` – but **only** // * when $state === 'running'. This finishes the UX once the wrapper ends. // */ // public function tick(): void // { // if ($this->state !== 'running') return; // // $this->readLowLevel(); // // if (!$this->running) { // wrapper finished // // give build.info a split second to land on slow disks // usleep(150000); // // $this->current = $this->readCurrentVersion(); // $this->latest = $this->readCachedLatest(); // // if ($this->rc === 0) { // // success path // if ($this->hasUpdate()) { // // very unlikely right after success, but handle anyway // $this->message = "Neue Version verfügbar: {$this->latest}"; // $this->messagePositive = false; // } else { // $this->message = "Update erfolgreich – jetzt: {$this->current}"; // $this->messagePositive = true; // } // } else { // // failure path // $rc = $this->rc ?? 1; // $this->message = "Update fehlgeschlagen (rc={$rc})"; // $this->messagePositive = false; // } // // $this->state = 'idle'; // } // } // // // ---- helpers ----------------------------------------------------------- // // public function getHasUpdateProperty(): bool // { // // gleiche Logik wie in deiner Klasse: // $cur = $this->normalizeVersion($this->current ?? null); // $lat = $this->normalizeVersion($this->latest ?? null); // if ($lat === null || $cur === null) return false; // return version_compare($lat, $cur, '>'); // } // // protected function hasUpdate(): bool // { // $cur = $this->normalizeVersion($this->current); // $lat = $this->normalizeVersion($this->latest); // // if ($lat === null || $cur === null) return false; // return version_compare($lat, $cur, '>'); // } // // protected function readLowLevel(): void // { // $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); // $this->running = ($state === 'running'); // // $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); // $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; // } // // protected function readCurrentVersion(): ?string // { // // Prefer the installer/updater stamp // $build = @file_get_contents('/etc/mailwolt/build.info'); // if ($build) { // foreach (preg_split('/\R+/', $build) as $line) { // if (str_starts_with($line, 'version=')) { // $v = trim(substr($line, 8)); // if ($v !== '') return $this->prettyVersion($v); // } // } // } // $v = trim((string)config('app.version', '')); // return $v !== '' ? $this->prettyVersion($v) : null; // } // // protected function readCachedLatest(): ?string // { // $v = Cache::get('mailwolt.update_available'); // if (!is_string($v) || $v === '') return null; // return $this->prettyVersion($v); // } // // /** // * Return a “compare-safe” semver string: e.g. `v1.0.18` → `1.0.18`. // * Accepts tags like `release-1.0.18` too. // */ // protected function normalizeVersion(?string $v): ?string // { // if (!$v) return null; // // keep only the first x.y.z like portion // if (preg_match('/(\d+\.\d+\.\d+)/', $v, $m)) { // return $m[1]; // } // // fallback: bare digits (x.y) // if (preg_match('/(\d+\.\d+)/', $v, $m)) { // return $m[1]; // } // return null; // } // // /** Always render with a single leading `v` (no “vv…”) */ // protected function prettyVersion(string $v): string // { // $n = $this->normalizeVersion($v); // return $n ? 'v' . $n : $v; // } //} //namespace App\Livewire\Ui\System; // //use Livewire\Component; //use Illuminate\Support\Facades\Artisan; //use Illuminate\Support\Facades\Cache; // //class UpdateCard extends Component //{ // public ?string $current = null; // installierte Version // public ?string $latest = null; // verfügbare Version (oder null) // public string $state = 'idle'; // idle | running // // // UI-Textausgabe nach einer Prüfung / Aktion // public ?string $message = null; // z.B. "Du bist auf dem neuesten Stand (v1.0.16)" // public ?bool $messagePositive = null; // true = grün, false = neutral/weiß // // // low-level (falls du sie später brauchst) // public bool $running = false; // aus /var/lib/mailwolt/update/state // public ?int $rc = null; // // public function mount(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // // // Starttext, falls nichts geprüft wurde // if ($this->message === null) { // $this->message = $this->latest && $this->hasUpdate() // ? "Neue Version verfügbar: {$this->latest}" // : ($this->current ? "Du bist auf dem neuesten Stand ({$this->current})" : "Status unbekannt"); // $this->messagePositive = !$this->hasUpdate(); // } // } // // public function render() // { // return view('livewire.ui.system.update-card'); // } // // /** // * „Erneut prüfen“ – ohne Toast: // * - Progress anzeigen // * - Check-Command laufen lassen // * - Message in der Box aktualisieren // */ // public function refreshState(): void // { // $this->state = 'running'; // $this->message = 'Prüfe auf Updates …'; // $this->messagePositive = null; // // try { // // Passe den Namen hier an dein tatsächliches Command an: // Artisan::call('mailwolt:check-updates'); // } catch (\Throwable $e) { // // weich fallen // } // // // Daten neu einlesen // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // // if ($this->hasUpdate()) { // $this->message = "Neue Version verfügbar: {$this->latest}"; // $this->messagePositive = false; // neutral // } else { // $cur = $this->current ?: '–'; // $this->message = "Du bist auf dem neuesten Stand ({$cur})"; // $this->messagePositive = true; // grün // } // // $this->refreshLowLevelState(); // $this->state = 'idle'; // } // // /** // * „Jetzt aktualisieren“ – ohne Toast: // * - Hinweis sofort aus Cache entfernen (Badge weg) // * - Update-Wrapper starten // * - Running + Text in der Box anzeigen // */ // public function runUpdate(): void // { // Cache::forget('mailwolt.update_available'); // // @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); // // $this->latest = null; // $this->state = 'running'; // $this->running = true; // $this->message = 'Update läuft …'; // $this->messagePositive = null; // } // // /** --------------------- helpers --------------------- */ // // protected function hasUpdate(): bool // { // if (!$this->latest) return false; // $cur = $this->current ?: '0.0.0'; // return version_compare($this->latest, $cur, '>'); // } // // protected function refreshLowLevelState(): void // { // $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); // $this->running = ($state === 'running'); // // $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); // $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; // } // // protected function readCurrentVersion(): ?string // { // // bevorzugt /etc/mailwolt/build.info (wird im Installer/Updater gepflegt) // $build = @file_get_contents('/etc/mailwolt/build.info'); // if ($build) { // foreach (preg_split('/\R+/', $build) as $line) { // if (str_starts_with($line, 'version=')) { // $v = trim(substr($line, 8)); // if ($v !== '') return $v; // } // } // } // $v = config('app.version'); // return $v !== '' ? $v : null; // } //} // // //namespace App\Livewire\Ui\System; // //use Livewire\Component; //use Illuminate\Support\Facades\Artisan; //use Illuminate\Support\Facades\Cache; // //class UpdateCard extends Component //{ // public ?string $current = null; // z.B. v1.0.16 (aktuell installiert) // public ?string $latest = null; // z.B. v1.0.17 (verfügbar) oder null // public string $state = 'idle'; // idle | running // // // optional: Low-level-Infos, falls du sie irgendwo anders brauchst // public bool $running = false; // Wrapper-/Updater läuft gerade (aus State-Datei) // public string $log = ''; // public ?int $rc = null; // // public function mount(): void // { // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // $this->refreshLowLevelState(); // liest /var/lib/mailwolt/update/* // } // // public function render() // { // return view('livewire.ui.system.update-card'); // } // // /** // * „Erneut prüfen“: // * - zeigt Running-Progress // * - ruft den Checker (dein bestehendes Artisan-Command) // * - aktualisiert $latest / $current // * - dispatcht passenden Toast // */ // public function refreshState(): void // { // $this->state = 'running'; // // // Falls vorhanden: dein Command, der cache('mailwolt.update_available') setzt // // -> Namen ggf. anpassen (du hattest z.B. mailwolt:check-updates erwähnt) // try { // Artisan::call('mailwolt:check-updates'); // } catch (\Throwable $e) { // // Wenn das Command (noch) nicht existiert, nicht crashen – state einfach zurücksetzen // } // // // App-Status neu einlesen // $this->current = $this->readCurrentVersion(); // $this->latest = Cache::get('mailwolt.update_available'); // // $hasUpdate = $this->hasUpdate(); // // // Toast ausspielen // $this->dispatch('toast', // type: $hasUpdate ? 'info' : 'done', // badge: 'Update', // title: $hasUpdate ? 'Neue Version verfügbar' : 'Alles aktuell', // text: $hasUpdate // ? "Verfügbar: {$this->latest} – installiert: {$this->current}" // : "Du bist auf dem neuesten Stand ({$this->current}).", // duration: 6000 // ); // // // Low-level-State (optional) und UI-State zurücksetzen // $this->refreshLowLevelState(); // $this->state = 'idle'; // } // // /** // * „Jetzt aktualisieren“: // * - blendet die verfügbare-Version sofort aus // * - startet den Root-Wrapper im Hintergrund // * - zeigt einen Toast „Update gestartet“ // */ // public function runUpdate(): void // { // Cache::forget('mailwolt.update_available'); // Badge sofort weg // @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); // // $this->state = 'running'; // $this->running = true; // // $this->dispatch('toast', // type: 'info', // badge: 'Update', // title: 'Update gestartet', // text: 'Das System wird aktualisiert …', // duration: 6000 // ); // } // // /** ---- Helpers ------------------------------------------------------- */ // // protected function hasUpdate(): bool // { // if (!$this->latest) return false; // $cur = $this->current ?: '0.0.0'; // return version_compare($this->latest, $cur, '>'); // } // // protected function refreshLowLevelState(): void // { // $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); // $this->running = ($state === 'running'); // // $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); // $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; // // // Log bewusst NICHT angezeigt, aber verfügbar, falls du es später brauchst // $this->log = @shell_exec('tail -n 200 /var/log/mailwolt-update.log 2>/dev/null') ?? ''; // } // // protected function readCurrentVersion(): ?string // { // // bevorzugt build.info, sonst config('app.version') // $build = @file_get_contents('/etc/mailwolt/build.info'); // if ($build) { // foreach (preg_split('/\R+/', $build) as $line) { // if (str_starts_with($line, 'version=')) { // $v = trim(substr($line, 8)); // if ($v !== '') return $v; // } // } // } // $v = config('app.version'); // return $v !== '' ? $v : null; // } //} //// ////namespace App\Livewire\Ui\System; //// ////use Livewire\Component; ////use Illuminate\Support\Facades\Artisan; ////use Illuminate\Support\Facades\Cache; //// ////class UpdateCard extends Component ////{ //// public ?string $current = null; //// public ?string $latest = null; //// public string $state = 'idle'; // idle|running //// //// public bool $running = false; //// public string $log = ''; //// public ?int $rc = null; //// //// public function mount(): void //// { ////// $this->refreshState(); //// $this->latest = cache('mailwolt.update_available'); //// //// } //// //// public function render() //// { //// return view('livewire.ui.system.update-card'); //// } //// //// public function refreshState(): void //// { //// $state = @trim(@file_get_contents('/var/lib/mailwolt/update/state') ?: ''); //// $this->running = ($state === 'running'); //// //// $rcRaw = @trim(@file_get_contents('/var/lib/mailwolt/update/rc') ?: ''); //// $this->rc = is_numeric($rcRaw) ? (int)$rcRaw : null; //// //// // letzte 200 Zeilen Log //// $this->log = @shell_exec('tail -n 200 /var/log/mailwolt-update.log 2>/dev/null') ?? ''; //// } //// //// public function runUpdate(): void //// { //// // Hinweis „Update verfügbar“ ausblenden //// cache()->forget('mailwolt.update_available'); //// //// // Update im Hintergrund starten //// @shell_exec('nohup sudo -n /usr/local/sbin/mw-update >/dev/null 2>&1 &'); //// //// $this->running = true; //// $this->dispatch('toast', //// type: 'info', //// badge: 'Update', //// title: 'Update gestartet', //// text: 'Das System wird aktualisiert …', //// duration: 6000 //// ); //// } ////}