Ebene/Zeichnungsebene Erzeugen: window.prompt raus (macOS WKWebView-Bug)

Symptom: erster +-Klick hat funktioniert, alle weiteren nicht (kein
APPLY im Log). Diagnose: macOS WKWebView in Rhino blockiert
WIEDERHOLTE window.prompt-Aufrufe — der erste zeigt einen Dialog,
nachfolgende returnen direkt null. Mein `if (!name) return`
beendet dann ohne Add → kein APPLY → User sieht nichts.

Plus: das nach Anlegen direkt onActiveChange(code) erzeugte einen
SET_ACTIVE_LAYER race (Layer war noch nicht durch build_layers
erstellt → Warning "Sublayer mit Code X nicht gefunden").

Beide Probleme weg durch:

- EbenenManager.addNew: silent append mit Default-Name "NEU",
  Code-Feld bekommt autoEdit-Fokus → User kann direkt tippen,
  Tab springt zum Name-Feld. Code = nextFreeAfter(activeCode) bleibt
  (eine nach der aktiven).
- GeschossManager.addQuick: silent append mit Default-Name
  "NOG" (basiert auf Anzahl Geschosse), kein onActiveChange.
  User editiert ueber den Geschoss-Settings-Cog am Row falls
  noetig.

Tradeoff: keine Dialog-Bestätigung mehr wie ursprünglich vom User
gewünscht — aber dafür funktioniert's überhaupt. Falls Dialog
wieder gewünscht, müsste ein React-Modal statt window.prompt her.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 00:43:45 +02:00
parent f14f84ca36
commit 581f366437
2 changed files with 14 additions and 16 deletions
+9 -7
View File
@@ -367,18 +367,20 @@ export default function EbenenManager({
} }
const addNew = () => { const addNew = () => {
const name = (window.prompt('Name für neue Ebene:', 'NEU') || '').trim() // KEIN window.prompt — macOS WKWebView blockiert wiederholte
if (!name) return // JavaScript-Dialoge (erster zeigt, nachfolgende returnen null).
// Silent-Append mit autoEdit damit der User direkt den Namen
// eintippen kann.
const code = nextFreeAfter(activeCode) const code = nextFreeAfter(activeCode)
const newEbene = { const newEbene = {
code, name: name.toUpperCase(), code, name: 'NEU',
color: '#888888', lw: 0.18, visible: true, locked: false, color: '#888888', lw: 0.18, visible: true, locked: false,
} }
console.log('[EBENEN-UI] addNew →', { activeCode, code, name: newEbene.name, ebenenCountBefore: ebenen.length }) console.log('[EBENEN-UI] addNew →', { activeCode, code, ebenenCountBefore: ebenen.length })
onChange([...ebenen, newEbene]) onChange([...ebenen, newEbene])
// Neue Ebene direkt als aktiv setzen → Pill-Highlight, sofort sichtbar // Code-Feld der neuen Ebene fokussieren — User kann sofort tippen
// und der User kann gleich anfangen Geometrie auf diese Ebene zu zeichnen. // (Tab springt dann zum Name-Feld).
if (onActiveChange) onActiveChange(code) setAutoEdit({ code, field: 'code', token: Date.now() })
} }
const duplicateEbene = (code) => { const duplicateEbene = (code) => {
+5 -9
View File
@@ -94,15 +94,13 @@ export default function GeschossManager({
.reduce((s, z) => s + (z.hoehe ?? 0), 0) .reduce((s, z) => s + (z.hoehe ?? 0), 0)
const addQuick = () => { const addQuick = () => {
const defaultName = `${zeichnungsebenen.filter(z => z.isGeschoss).length + 1}OG` // KEIN window.prompt — macOS WKWebView blockiert wiederholte
const name = (window.prompt( // JavaScript-Dialoge. Silent-Append mit Default-Name; User editiert
'Name für neue Zeichnungsebene (Geschoss):', // ueber den Geschoss-Settings-Dialog falls noetig.
defaultName const geschossCount = zeichnungsebenen.filter(z => z.isGeschoss).length
) || '').trim()
if (!name) return
const newZ = { const newZ = {
id: `z_${Date.now()}`, id: `z_${Date.now()}`,
name, name: `${geschossCount + 1}OG`,
isGeschoss: true, isGeschoss: true,
hoehe: 3.0, hoehe: 3.0,
schnitthoehe: 1.0, schnitthoehe: 1.0,
@@ -110,8 +108,6 @@ export default function GeschossManager({
} }
console.log('[ZEICHNUNGSEBENEN-UI] addQuick →', { newZ, countBefore: zeichnungsebenen.length }) console.log('[ZEICHNUNGSEBENEN-UI] addQuick →', { newZ, countBefore: zeichnungsebenen.length })
onChange([...zeichnungsebenen, newZ]) onChange([...zeichnungsebenen, newZ])
// Direkt als aktiv setzen → Pill-Highlight, klar sichtbar
if (onActiveChange) onActiveChange(newZ.id)
} }
const toggleVisible = (id) => { const toggleVisible = (id) => {