scrollToEnd() unterschätzt Content-Höhe auf Android und stoppt
konsistent eine Message zu früh (verifiziert per adb-Screenshot).
scrollToOffset({offset:999999}) wird auf den echten Max-Wert geclampt
und landet immer am absoluten Ende der Liste.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The smart isNearBottomRef gating was too restrictive — own sent messages,
image-loads, and incoming partner messages were sometimes not scrolled to.
Adopt the room-chat pattern: always scroll on messages.length change and
onContentSizeChange. Drop isNearBottomRef + firstContentSizeChangeRef +
onScroll handler.
Der setTimeout(80)+onImageLoad-Ansatz war ein Timing-Hack gegen ein
strukturelles Problem (lazy Item-Measurement unter Fabric -> scrollToEnd
landet zu kurz). Stattdessen jetzt inverted FlatList: Index 0 sitzt
permanent am Bildschirmrand, neueste Nachricht immer sichtbar.
- dm.tsx: inverted + reversedMessages, Gruppen-Logik gespiegelt,
manuellen Auto-Scroll + keyboardHeight-State entfernt
- ChatBubble.tsx: onImageLoad-Prop entfernt (obsolet)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug 1 — Chat-Liste: RefreshControl nutzte React-Querys `isRefetching`,
das bei JEDEM Background-Refetch (focus-/stale-getriggert) true wird →
nach Zurück-Navigation hing der Pull-to-Refresh-Spinner endlos. Fix:
eigener `userRefreshing`-State, nur bei explizitem Pull-to-Refresh true,
im finally zurückgesetzt.
Bug 2 — Conversation scrollte nicht bis zur letzten Nachricht, wenn die
ein Bild war: onContentSizeChange-scrollToEnd feuerte vor dem Bild-Load.
Fix: ChatBubble bekommt onImageLoad-Callback, die letzte Bild-Nachricht
triggert nach dem Laden erneut scrollToBottom.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- PostCard: Bilder mit borderRadius 10 + overflow:hidden — Ecken wieder rund
- dm.tsx: myUserId synchron aus useAuthStore statt async getSession —
behebt den hängenden Lade-Spinner beim Zurück aus einer Conversation
(async getSession-Fenster auf jedem Mount → enabled-Flackern der Query)
- ChatBubble: expo-image memory-disk-Cache + 200ms-Transition für
smootheres Bild-Laden
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug: 3 Stellen hatten `behavior={Platform.OS === 'ios' ? 'padding' : undefined}`.
Auf Android = `undefined` = KeyboardAvoidingView macht NICHTS → Input wird von
Tastatur verdeckt (chat-input, profile-edit-nickname, room-chat).
Fix: switch zu react-native-keyboard-controller's KeyboardAvoidingView mit
behavior='padding' für beide Plattformen. Funktioniert sauber cross-platform
weil KeyboardProvider schon im root-layout sitzt.
Affected Files:
- components/KeyboardAwareScreen.tsx (used by profile-edit + auth-screens)
- app/dm.tsx (DM chat)
- app/room.tsx (room chat)
lyra.tsx war bereits OK (`'height'` für Android — kein Fix nötig).
iOS-Verhalten unverändert.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Android Theme parent → Theme.MaterialComponents.DayNight.NoActionBar.Bridge
(fix BadgeDrawable crash in react-native-bottom-tabs after AccessibilityService toggle)
- Plugin with-material-theme-android keeps theme idempotent across prebuilds
- Plugin with-release-signing-android wires release signingConfig from key.properties
- Splash: align native splash image with JS BrandSplash (icon.png) to eliminate
double-splash flicker on app start
- DM: reset partner/messages/replyTo state on userId change, disable cache for
history query, switch spinner condition to isLoading||isFetching so reopens
always load fresh and never show empty-state with stale partner
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Header: partner avatar left-aligned (was centered)
- ChatBubble: replace bright blue with subtle mint/brand tint, asymmetric
tail-corner radius, footer pinned bottom-right, reply-quote with green
side-bar
- New DmChatBackground: SVG hex-offset doodle pattern (stars, hearts,
clouds, dots) at 7% opacity — light-cream / dark-warm-green base
- Avatar in chat list: use resolveAvatar() consistently to handle
hero-id, https, and null cases
- Realtime subscription: stabilize deps via partnerRef to stop
re-subscribing on partner state change
- Pressable → TouchableOpacity throughout
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Consistent with chat.tsx refactor — ActivityIndicator, joinBtn, and
avatarEdit badge all now use the theme token.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>