Four issues from the screenshot review plus one new affordance:
1. Modal overflowing on small devices — capped at maxHeight: '85%'. Header
(handle bar + Lyra avatar + title + subtitle) stays fixed above a
ScrollView body; action buttons stay fixed below with a border separator.
Stat cards, star rating, and TextInput now live inside the scrollable body.
2. Keyboard pushed the TextInput out of sight — replaced the bespoke
Keyboard.addListener + Animated.multiply lift hack (Easing, keyboardLiftY,
the whole apparatus) with a plain KeyboardAvoidingView wrapper
(behavior="padding" iOS / "height" Android). ScrollView already had
keyboardShouldPersistTaps="handled" so taps on Posten/Abbrechen still
work while the keyboard is up.
3. All four action buttons (Nochmal, Beenden, Abbrechen, Posten) plus the
inner Save-Rating CTA now route through components/Button.tsx — picks
up the slimmer paddingVertical:12 default from the central component.
Posten gets the paper-plane icon. Nochmal + Posten = primary, Beenden +
Abbrechen = secondary.
4. New "Neuer Vorschlag" regenerate button (ghost variant, sm size,
refresh-outline icon) sits between the TextInput and the Abbrechen/
Posten row. Reuses POST /api/games/share-text — no new endpoint. Tracks
the last Lyra-generated text in a ref so we can detect user edits; if
the user has modified the suggestion, taps go through an Alert.alert
confirm before overwrite. Spinner during the regen call, Posten /
Abbrechen stay active. i18n keys gameOver.regen_* across DE/EN/FR.
Alle <Pressable style={({pressed}) => ({...})}> ersetzt — style-Funktion
droppt auf Android (New Arch) intermittierend width/height, führt zu 0×0
unsichtbaren Elementen. TouchableOpacity mit activeOpacity ist stabil.
Außerdem übrige Pressables (plain style) aus components/ und app/
migriert sowie zwei überschüssige </View>-Tags in chat.tsx + RoomCard.tsx
entfernt die TS-Fehler verursacht haben.
64 Dateien, typecheck sauber.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- upsertMailConnection: bei Update lastConnectError + lastConnectErrorAt auf
null — User aktualisiert App-Passwort → UI zeigt sofort wieder Live (statt
stale Auth-Fehler-Status bis nächstem IDLE/Scan-Cycle)
- /api/mail/status: liefert lastConnectError, lastConnectErrorAt,
lastIdleHeartbeatAt mit (waren bisher nicht im Response → Frontend hat den
Status nie korrekt rendern können)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>