Befunde der Schlussdurchsicht (Attrappe des Backends, 320 x 568 bis 1440 px):
- Rueckfragen: Bei 320 x 568 lagen "Installieren"/"Abbrechen" unter dem Bildschirmrand
und liessen sich nicht erreichen (Dialog 791 px hoch, kein Scrollen). Jetzt hoechstens
Bildschirmhoehe, der Text scrollt, die Knoepfe bleiben unten stehen. Gilt fuer alle.
- Installieren: Die Rueckfrage sagt jetzt, dass llama-swap beim Eintragen sofort neu laedt
(--watch-config): laufende Antworten von Lucy/OpenChamber brechen ab, mit Rolle nach dem
Download noch einmal. Der Ersatz-Hinweis nennt, dass das bisherige Modell "heavy" behaelt.
- Abbrechen nur noch bei Downloads (eigener Prozess). Updates und die Suche laufen als
Shell-Kette, ein Abbruch stoppt dort nicht sicher alles.
- Auftragstitel in den Worten der Oberflaeche ("Update Motor (llama.cpp)" statt
"Engine-Update (llama.cpp Vulkan)"); "Laeuft seit ... min" zaehlt weiter, auch wenn der
Auftrag nichts schreibt; Ueberschriftenebene passend zum Panel.
- Updates: "Alles jetzt aktualisieren" richtet sich wie die Zeilen nach den frischen
Details (vorher nur nach dem bis zu 10 min alten Start-Stand); "Nach Neuem suchen"
sperrt, solange eine Suche laeuft (zwei apt-get update stolpern ueber die Sperre);
Rueckfragetext sagt genau, was gesichert wird.
- Nach Auftragsende nur nachladen, was betroffen ist (Download: Modelle/Platte; sonst
Versionen/Verlauf/Sicherungen) - die Update-Pruefung fragt GitHub, apt und git.
- Radar "Uebernehmen"/"Verwerfen" und "Endgueltig loeschen": Ja-Knopf gesperrt, solange
die Aktion laeuft, und ein zweiter Klick waehrend des Schliessens loest nichts mehr aus.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import type { ReactNode } from "react"
|
||
import { Button } from "@/components/ui/button"
|
||
import {
|
||
Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,
|
||
} from "@/components/ui/dialog"
|
||
|
||
/**
|
||
* Rückfrage vor Schritten, die die Box verändern (Updates, Freigeben, Zurückspielen, Neustarts,
|
||
* Installieren, Abbrechen). `gesperrt` hält den Ja-Knopf fest, solange die Aktion schon unterwegs
|
||
* ist — ein Doppelklick startet sie so nicht zweimal.
|
||
*/
|
||
export function Bestaetigen({ offen, titel, text, knopf, neinKnopf = "Abbrechen", gefahr, gesperrt, onJa, onNein, children }: {
|
||
offen: boolean
|
||
titel: string
|
||
text: string
|
||
knopf: string
|
||
neinKnopf?: string
|
||
gefahr?: boolean
|
||
gesperrt?: boolean
|
||
onJa: () => void
|
||
onNein: () => void
|
||
children?: ReactNode
|
||
}) {
|
||
return (
|
||
<Dialog open={offen} onOpenChange={(o) => !o && onNein()}>
|
||
{/* Nie höher als der Bildschirm: Auf kleinen Handys (320 × 568) lagen die Knöpfe sonst außerhalb
|
||
und ließen sich nicht erreichen. Der Text scrollt, die Knöpfe bleiben unten stehen — bündig,
|
||
darum ohne Bodenpolster (sticky rechnet das Polster ein, darunter schien sonst Text durch). */}
|
||
<DialogContent className="max-h-[calc(100dvh-2rem)] overflow-y-auto border-linie bg-panel pb-0 sm:max-w-lg">
|
||
<DialogHeader>
|
||
<DialogTitle className="schild pr-10 text-xl break-words">{titel}</DialogTitle>
|
||
<DialogDescription className="text-[15px] leading-relaxed text-text-2">{text}</DialogDescription>
|
||
</DialogHeader>
|
||
{children}
|
||
<DialogFooter className="sticky bottom-0 mb-0 gap-2 bg-erhaben sm:gap-2">
|
||
<Button variant="outline" onClick={onNein}>
|
||
{neinKnopf}
|
||
</Button>
|
||
<Button
|
||
variant={gefahr ? "gefahr" : "default"}
|
||
disabled={gesperrt}
|
||
aria-busy={gesperrt || undefined}
|
||
onClick={() => {
|
||
if (!gesperrt) onJa()
|
||
}}
|
||
>
|
||
{knopf}
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
)
|
||
}
|