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 //// ); //// } ////}