diff --git a/apps/web/src/components/bug-report/bug-report-button.tsx b/apps/web/src/components/bug-report/bug-report-button.tsx index 6e466cf..b9cc8d8 100644 --- a/apps/web/src/components/bug-report/bug-report-button.tsx +++ b/apps/web/src/components/bug-report/bug-report-button.tsx @@ -66,7 +66,11 @@ export function BugReportButton() { - setOpen(false)} /> + {/* Nur eingehaengt, solange offen (quick-260921-ldf): so startet jedes + Oeffnen mit frischem Zustand — Haekchen, Text und Status stimmen + schon im ersten Commit, statt einen Commit spaeter nachgezogen zu + werden. */} + {open && setOpen(false)} />} ); } diff --git a/apps/web/src/components/bug-report/bug-report-dialog.tsx b/apps/web/src/components/bug-report/bug-report-dialog.tsx index 0572920..9235ecd 100644 --- a/apps/web/src/components/bug-report/bug-report-dialog.tsx +++ b/apps/web/src/components/bug-report/bug-report-dialog.tsx @@ -13,9 +13,13 @@ import { formatErrorsForReport } from '@/lib/error-buffer'; * `marketplace/components/ActivationDialog.tsx` (Overlay, `role="dialog"`, * Escape, Fokus). Bekommt das bereits aufgenommene Bild als Data-URL — * die Aufnahme passiert im Knopf, BEVOR dieser Dialog erscheint. + * + * Der Dialog wird nur eingehaengt, solange er offen ist (quick-260921-ldf): + * jedes Oeffnen ist ein frischer Mount, damit gilt der Anfangszustand schon + * im ERSTEN Commit. Vorher zog ein Effekt den Zustand erst einen Commit + * spaeter nach — dazwischen stand sichtbar "Bild da, Haekchen aus" im DOM. */ interface BugReportDialogProps { - open: boolean; screenshot: string | null; isAdmin: boolean; onClose: () => void; @@ -23,35 +27,29 @@ interface BugReportDialogProps { type Status = 'ready' | 'sending' | 'sent' | 'failed'; -export function BugReportDialog({ open, screenshot, isAdmin, onClose }: BugReportDialogProps) { +export function BugReportDialog({ screenshot, isAdmin, onClose }: BugReportDialogProps) { const t = useTranslations('bugReport'); const textareaRef = useRef(null); const [status, setStatus] = useState('ready'); const [failedStatus, setFailedStatus] = useState(0); const [description, setDescription] = useState(''); - const [attach, setAttach] = useState(screenshot !== null); - - // Bei jedem Oeffnen frisch beginnen. - useEffect(() => { - if (open) { - setStatus('ready'); - setFailedStatus(0); - setDescription(''); - setAttach(screenshot !== null); - textareaRef.current?.focus(); - } - }, [open, screenshot]); + // Das Haekchen wird beim Rendern aus `screenshot` abgeleitet, nicht per + // Effekt nachgezogen: gibt es ein Bild, ist es an. `attachChoice` haelt + // allein die bewusste Abwahl des Nutzers. + const [attachChoice, setAttachChoice] = useState(null); + const attach = screenshot !== null && (attachChoice ?? true); + + useEffect(() => { + textareaRef.current?.focus(); + }, []); useEffect(() => { - if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === 'Escape' && status !== 'sending') onClose(); }; document.addEventListener('keydown', handler); return () => document.removeEventListener('keydown', handler); - }, [open, status, onClose]); - - if (!open) return null; + }, [status, onClose]); const handleSend = async () => { setStatus('sending'); @@ -144,7 +142,7 @@ export function BugReportDialog({ open, screenshot, isAdmin, onClose }: BugRepor className="h-4 w-4" checked={attach} disabled={screenshot === null || busy} - onChange={(e) => setAttach(e.target.checked)} + onChange={(e) => setAttachChoice(e.target.checked)} />