6 Commits

Author SHA1 Message Date
chahinebrini
b8e4b02b88 perf(images): migrate react-native Image → expo-image (memory+disk cache)
Avatare (Dicebear-URLs), Chat-Attachments und Feed-Bilder wurden bei
jedem App-Reload neu vom Netzwerk geladen — RN Image hat nur flüchtigen
Memory-Cache. expo-image (~3.0.11) bringt persistenten Disk-Cache
(cachePolicy 'memory-disk' default).

14 Files migriert: UserAvatar, ChatBubble, RoomCard, ChatInput, PostCard,
ComposeCard, NotificationsDropdown, AppHeader, ProfileHeader,
AddDomainSheet, DomainGrid, room, profile/edit, signup.

API-Mapping: resizeMode→contentFit. PostCard onLoad las e.nativeEvent.
source — expo-image liefert e.source direkt (sonst wäre der Post-Bild-
Aspect-Ratio-Fix still gebrochen).

PostCard: nur Image-Zeilen angefasst, Like/Count/Memo-Logik unberührt
(memory/feedback_minimal_post_changes.md).

Kommt mit v0.3.3 (expo-image ist Native-Modul, braucht neuen Build).
2026-05-20 04:49:11 +02:00
chahinebrini
14452b2a46 refactor(native): Pressable → TouchableOpacity sweep (style-fn swallows Android styles)
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>
2026-05-11 15:43:10 +02:00
chahinebrini
594a43cbf9 feat(theme): Dark Theme — global color-system + Wave 1 screens
Theme-switch in Settings (System/Light/Dark) jetzt App-weit wirksam für die
Core-Screens. Wave 2 dokumentiert (siehe unten).

Color-System:
- lib/theme.ts: refactored zu colors.light + colors.dark (gleiche keys)
  Light: bg #fff, surface #fafafa, surfaceElevated #f5f5f5, border #e5e5e5,
         text #0a0a0a, textMuted #737373
  Dark:  bg #000, surface #1c1c1e, surfaceElevated #2c2c2e, border #38383a,
         text #fff, textMuted #8e8e93
  brandOrange unverändert #007AFF (iOS system blue)
  success/error variieren (light: #16a34a/#dc2626, dark: #30d158/#ff453a)
- legacy `colors` export bleibt als Light-Fallback für nicht-migrierte Files
- new `useColors()` hook → liest aktiven scheme aus useThemeStore

stores/theme.ts:
- Appearance.addChangeListener für live System-Theme-Updates (User schaltet
  iOS Dark/Light → App reagiert sofort ohne Reload)

Wave 1 — migrated Files (Core Screens):
- app/_layout.tsx + app/(app)/_layout.tsx + app/(app)/index.tsx (root + home)
- app/settings.tsx (full theme-aware inkl. TrueSheet)
- app/profile/index.tsx (bg + dividers)
- app/devices.tsx (bg, surface, border, icons)
- app/lyra.tsx (chat container, backdrop, bubbles, ThinkingDots, LoadingPulse)
- components/AppHeader (Nativewind classes ersetzt durch theme-aware Styles)
- components/header/HeaderDropdownMenu
- components/profile/* (ProfileHeader, StatsBar, StreakSection, UrgeStatsCard,
  ApprovedDomainsList, DemographicsAccordion)

Wave 2 (TODOs für separate Session):
- app/urge.tsx (~20 hardcoded colors, größter Screen)
- app/room.tsx, app/dm.tsx, app/(app)/chat.tsx, app/(app)/mail.tsx, app/(app)/coach.tsx
- app/games.tsx, app/profile/[userId].tsx
- Nativewind classes in PostCard, ComposeCard, PostCardSkeleton, NotificationsDropdown

StatusBar style dynamisch synchronisiert (light bei dark-mode, dark bei light).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 22:15:55 +02:00
chahinebrini
3c52d8869e feat(native): WIP checkpoint — Profile/Settings/Demographics + WheelPicker + Maestro
Rollback-Punkt vor Expo SDK 54 / RN 0.81 Upgrade.

UI/UX:
- Profile: ProfileHeader redesign (sign-in chip + member-since), StatsBar 3 pill cards,
  Demographics accordion completed (Geburtsjahr, Geschlecht, Familienstand, Beruf-split,
  Wohnort), Pro-Trial-Banner, Approved-Domains list, DigaMissionBanner
- Settings: section-based layout, neutral icons (matched Header dropdown style)
- Header dropdown: extended with logout + games-page link
- Notifications page: skeleton dummy data
- Locales: i18n keys for new screens

New components:
- WheelPickerModal: native iOS UIPickerView wheel for long lists (Geburtsjahr 91 items,
  Bundesland 16, Stadt 30+/Bundesland)
- OptionsBottomSheet: iOS-style options sheet (used briefly for Geschlecht, currently
  unused — kept for potential future use)
- germanCities.ts: Top-cities per Bundesland (DSGVO-clean static data)

New libs (NewArch-codegen verified):
- @react-native-menu/menu 2.0.0 (UIMenu wrapper, Apple HIG-konform)
- @lodev09/react-native-true-sheet 3.10.1 (UISheetPresentationController wrapper —
  ABER incompatible mit RN 0.79.6, Build-Error → Trigger für SDK-54-Upgrade)

Maestro E2E:
- Initial setup mit auth/community/profile/urge flows

Scripts:
- build-ios-clean.sh: Xcode DerivedData + ios/build cleanup vor expo run:ios

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 19:32:27 +02:00
chahinebrini
57dfc51d97 fix(layout): restore Profile root flex:1, harden Settings + ProfileHeader rows
ROOT CAUSE Profile-Page leer: View+ScrollView verloren beide flex:1
(experimentelle Edit). Ohne flex:1 hat root null Höhe → ScrollView
kollabiert → nur ProfileHeader sichtbar, Rest abgeschnitten.

Profile/index.tsx:
- View style={{ flex: 1, backgroundColor: '#ffffff' }} restored
- ScrollView style={{ flex: 1 }} restored
- Debug-Title "Profil DEBUG-23s00" → "Profil"
- Magenta debug-marker entfernt

Settings row (def. flex-row hardening gegen icon-stack-Bug):
- width: '100%' auf Pressable
- flexShrink:0, flexGrow:0 auf icon-Box
- minWidth:0, flexShrink:1 auf text-Container (Pflicht für RN-Wrap)
- numberOfLines={1} auf label + sublabel (verhindert column-illusion bei
  langem text)
- paddingVertical: 12 fuer breathing room

ProfileHeader hint (gleicher Pattern fix):
- width: '100%' + flexShrink:0 auf beide icons
- minWidth:0, flexShrink:1, numberOfLines={2} auf hint-text
- paddingVertical 10→12

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:27:21 +02:00
chahinebrini
e76be7ee78 feat(profile): Profile-Page komplett + Header-Dropdown + UI-Pattern-Fixes
Profile (3 Iterationen):
- app/profile/index.tsx + components/profile/* (Header, StatsBar, Approved,
  Streak, UrgeStats, Demographics, DigaMissionBanner)
- echte Live-Daten via useMe-Hook (Avatar/Nickname/Plan/Email/Provider-Pill)
- Demographics mit echten Inputs (TextInput + Bottom-Sheet-Selects),
  debounced auto-save, Pro-Trial-Reward-Banner, Mikro-Why-Texte
- Approved Domains als plain integer (KEIN Plan-Slot/Cap)
- Friendly Hint-Text statt Progress-Bar (alignSelf:'stretch' Pattern)
- StatsBar zentriert mit 3 prominenten Cards (vertikale Dividers)
- Cooldown-Timeline als Liste mit 1px-Rail
- ApprovedDomainsList: Collapse-Chevron rechts in Title-Row (Pattern-Fix)
- Eigene vs fremde Profile-Ansicht streng getrennt (DSGVO/Anonymität)

Header-Dropdown (kein 3-Punkte-Icon):
- Avatar als Trigger im AppHeader (User-Wunsch)
- Custom-Modal beide Plattformen, Card-Style
- SOS prominent oben (nur Wort 'SOS' rot, Tagline 'wir sind für dich da' klein darunter)
- Profile/Settings/Games/Debug(__DEV__)/Logout
- Logout neutral (nicht rot — Recovery-tonal)
- AppHeader: neue showBack + title Props für Sub-Routes

Routes (Stub bis Phase C):
- app/profile/[userId].tsx — anonym (nur public-Stats)
- app/settings.tsx — Coming-Soon-Skeleton
- app/games.tsx — Standalone Games-Page mit GameCard-Grid
- app/debug.tsx — __DEV__-only

Game-Picker (Migration aus Nuxt):
- components/games/{GameCard, StarRating, GameRatingStars}
- 2x2 Grid, 56pt SVG-Icons (inline aus components/urge/gameSvgs.ts)
- Live-Backend /api/games/ratings (silent-fail)
- Re-use UrgeGames.tsx ohne TTS/Cooldown-Loop

UI-Pattern-Fixes (alle aus screenshot-User-Feedback 2026-05-07):
- Snake-Bug (food-pellet React-18-StrictMode-Reducer-double-call) gefixt
- Snake-Buttons platform-native (iOS-blue / Android-ripple)
- Tetris-Margins (16px paddingHorizontal)
- PostCard-Buttons Apple-44pt-Hit-Area (Image-Select, Image-Remove,
  Cancel, Share-Pill — via hitSlop)
- ProfileHeader Demographics-Hint: alignSelf:'stretch' Pattern
- ApprovedDomainsList Collapse: Title flex:1 + Chevron rechts
- ProtectionDetailsSheet FAQ-Items: alignSelf:'stretch' defensive
- AppHeader Back-Button: neue showBack-Prop + chevron-back

Memory + Plan-Docs:
- 17 Memory-Files dokumentieren System-Wissen + Patterns
- ops/{CUTOVER, UI_MIGRATION, PROFILE_PAGE, WEBHOOK, GAMES_1V1,
  RELEASE_READINESS, TESTING_STATE, MAESTRO_HOSTING}_*.md

Backend bleibt unverändert (Tier-LLM + Nickname + sort:latency
sind seit gestern deployed).
2026-05-07 18:22:58 +02:00