fix(ui): Dialoge schliessen nicht mehr beim Markieren von Text
Ampel / ampel (push) Successful in 2m18s

Commander: "es gibt einen kleinen bug im UI wenn man selbst den titel
sucht das suchfenster schliesst sich dann einfach."

Bekannte Falle bei Dialogen mit klickbarer Hintergrundflaeche: Wer im
Eingabefeld Text markiert und dabei ueber den Dialogrand hinauszieht,
drueckt INNEN und laesst AUSSEN los. Der Browser meldet als Ziel des
Klicks dann den gemeinsamen Vorfahren — die Hintergrundflaeche. Der
onClick-Horcher darauf schloss den Dialog also mitten im Tippen.

Neu useHintergrundKlick(): merkt sich, WO der Klick begann. Nur wenn
Druecken UND Loslassen auf der Flaeche selbst passierten, ist es ein
Klick daneben. Gilt fuer beide Dialoge (Titelwahl und "Aendern ...").

Gegengeprueft und VERWORFEN wurde eine andere Vermutung: Die Kachelliste
haengt an `laufwerke.length === 0`, ein einziger leerer Takt der
Laufwerks-Wache wuerde die Kachel samt Dialog abraeumen. Gemessen: 20 von
20 Abfragen liefern das Laufwerk, keine leere Antwort. Die Fragilitaet
bleibt als Risiko notiert (SAVEPOINT), ist aber nicht die Ursache.

261 Tests gruen. NICHT veroeffentlicht — der Kanal steht auf 5.3.2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-01 20:48:19 +02:00
co-authored by Claude Opus 5
parent 1f678c036d
commit 7c489f8404
+34 -3
View File
@@ -7,7 +7,7 @@
// Erst-Einrichtung, Dialoge). Die Regeln bleiben: EINE Einstellungs-Quelle
// über den Kern (§ 6.7), R2 (nichts verschwindet ohne Auskunft), R4
// (Fehler stehen im Fenster — bei Systemfehlern als rote Karte).
import { useEffect, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import type {
DiscInfoStand,
DiscTitelVorschlag,
@@ -272,6 +272,35 @@ function SegmentBalken({ prozent }: { prozent: number }) {
}
// § 5 Schritt 4: „nein → fragen" — Suche + Auswahl der richtigen Metadaten.
/** Nur ein Klick, der WIRKLICH auf der Hintergrundfläche begann, schließt
* einen Dialog.
*
* Commander-Fund (01.09.2026): „es gibt einen kleinen bug im UI wenn man
* selbst den titel sucht das suchfenster schließt sich dann einfach."
* Der Grund ist eine bekannte Falle: Wer im Eingabefeld Text markiert und
* dabei über den Dialogrand hinauszieht, drückt INNEN und lässt AUSSEN
* los. Der Browser meldet als Ziel des Klicks dann den gemeinsamen
* Vorfahren — die Hintergrundfläche. Ein reiner onClick-Horcher darauf
* schließt den Dialog also mitten im Tippen.
*
* Deshalb wird der Anfang gemerkt: Nur wenn Drücken UND Loslassen auf der
* Fläche selbst passierten, ist es ein Klick daneben. */
function useHintergrundKlick(schliessen: () => void): {
onMouseDown: (e: React.MouseEvent) => void
onClick: (e: React.MouseEvent) => void
} {
const begannDraussen = useRef(false)
return {
onMouseDown: (e) => {
begannDraussen.current = e.target === e.currentTarget
},
onClick: (e) => {
if (begannDraussen.current && e.target === e.currentTarget) schliessen()
},
}
}
function AendernDialog({
id,
startText,
@@ -284,6 +313,7 @@ function AendernDialog({
schliessen: () => void
}) {
const [text, setText] = useState(startText)
const hintergrund = useHintergrundKlick(schliessen)
useEffect(() => {
metadatenSuchen(id, startText)
// Nur beim Öffnen — weitere Suchen löst der Knopf aus.
@@ -292,7 +322,7 @@ function AendernDialog({
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6 backdrop-blur-sm"
onClick={schliessen}
{...hintergrund}
>
<div
className="max-h-[80vh] w-full max-w-lg overflow-y-auto rounded-2xl border border-white/12 bg-buehne p-5 shadow-2xl shadow-black/60"
@@ -383,6 +413,7 @@ function TitelWahlDialog({
stand: TitelStand | undefined
schliessen: () => void
}) {
const hintergrund = useHintergrundKlick(schliessen)
const [gewaehlt, setGewaehlt] = useState<Set<number> | null>(null)
// Eigene Rollen-Wahl je Titel; was hier nicht drinsteht, behaelt Rippys
// Vorschlag ('hauptfilm' beim Film, 'folge' bei der Serie, sonst 'extra').
@@ -402,7 +433,7 @@ function TitelWahlDialog({
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 p-6 backdrop-blur-sm"
onClick={schliessen}
{...hintergrund}
>
<div
className="max-h-[80vh] w-full max-w-2xl overflow-y-auto rounded-2xl border border-white/12 bg-buehne p-5 shadow-2xl shadow-black/60"