chahinebrini a841b32c31 feat(rebreak-native): <FormSheet> — one reusable bottom-sheet composable (phase 1)
The custom modals each rolled their own Modal + animated-height + PanResponder +
keyboard handling, inconsistently. <FormSheet> is the single parametrized
composable, generalized from the proven PostCommentsSheet pattern:

  - standard header: centred grabber + left-aligned title — NO Fertig/Abbrechen/
    Zurück buttons (dismiss = swipe down / backdrop tap)
  - resizable via drag on handle/header; drag-down past minHeightPct (or a fast
    flick) dismisses
  - height hard-capped at 75% of the screen — drag AND keyboard-expand
  - keyboard-aware: sheet grows by the keyboard height (capped), iOS paddingBottom
    pushes the content exactly above the keyboard; Android adjustResize handles it
  - JS-driver height / native-driver translateY split (avoids the "height not
    supported by native animated module" crash)
  - props: title, initialHeightPct, minHeightPct, backdropOpacity, dismissOnBackdrop,
    safeAreaBottom, growWithKeyboard, topRadius

Migrated (phase 1 — the no-input content sheets):
  - ProtectionDetailsSheet → drops the bespoke Modal/PanResponder + the "Fertig"
    header button; was 0.9–0.95 tall, now ≤0.75
  - DeactivationExplainerSheet → was a pageSheet Modal with a "Zurück" button;
    now the standard bottom sheet, header button gone
  - PostCommentsSheet → capped its expand height 0.92 → 0.75 (TODO phase-1b: move
    it onto <FormSheet> too instead of pinning magic numbers)

Phase 2 (next): <SheetFieldStack> — progressive multi-input flow (active input
pinned above the keyboard + "→" to advance, filled fields stack above, the rest
of the form reveals after the last field) for ConnectMailSheet / AddDomainSheet /
EditMailAccountSheet / CreateRoomSheet; then the auth/edit full-screen pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:03:17 +02:00
..

Rebreak Native (React Native + Expo)

Mobile App für iOS + Android. Migration von Nuxt+Capacitor → React Native+Expo. Migration-Plan: apps/rebreak/docs/react-native-migration.md

Status

Phase 1 — Foundation Skeleton (2026-05-02)

  • Verzeichnisstruktur
  • package.json mit Expo SDK 53 + RN 0.76 (New Architecture)
  • app.config.ts (Expo, Bundle-ID org.rebreak.app)
  • Expo Router Skeleton
  • NativeWind Setup (Tailwind für RN)
  • Metro Config (pnpm Monorepo aware)
  • Supabase Client + API Wrapper
  • pnpm install — vom User auszuführen
  • expo prebuild — generiert ios/ + android/ Bare-Projekte
  • Native Module Imports (NEFilter, VpnService, A11y) — Phase 5+

Setup

# vom Monorepo-Root:
pnpm install

# Native-Projekte generieren (lokal, nicht committed)
cd apps/rebreak-native
pnpm prebuild

# Run
pnpm ios       # iOS Simulator
pnpm android   # Android Emulator

Stack

Bereich Lib
Framework React Native 0.76 (New Architecture) + Expo SDK 53
Routing Expo Router (file-based)
State Zustand
Server State TanStack Query (React Query)
Styling NativeWind 4 (Tailwind)
Forms React Hook Form + Valibot
i18n react-i18next
Auth @supabase/supabase-js + AsyncStorage
Animation react-native-reanimated, lottie-react-native
Storage react-native-mmkv (fast key-value)

Verzeichnisstruktur

apps/rebreak-native/
├── app/                  # Expo Router (file-based routes)
│   ├── _layout.tsx       # Root Stack
│   ├── index.tsx         # Landing (auth oder app entscheiden)
│   ├── (auth)/           # Auth-Flow (signin, signup, forgot-password)
│   └── (app)/            # Authenticated App (tabs)
├── components/           # Reusable UI Components
├── hooks/                # Custom React Hooks
├── stores/               # Zustand Stores
├── lib/                  # Supabase Client, API Wrapper, Utils
│   ├── supabase.ts
│   └── api.ts
├── locales/              # de.json, en.json
├── modules/              # Custom Expo Native Modules
│   ├── rebreak-ios-filter/        # NEFilter + Tunnel (Phase 5)
│   ├── rebreak-android-blocker/   # VpnService + DnsFilter (Phase 6)
│   └── rebreak-android-a11y/      # AccessibilityService (Phase 6)
├── plugins/              # Expo Config Plugins
└── assets/               # Icons, Splashscreens, Fonts

Wichtige Konfiguration

Datei Zweck
app.config.ts Expo App-Config (Bundle-ID, Permissions, Plugins)
metro.config.js Monorepo-aware Metro (Symlinks, Workspace-Folders)
babel.config.js NativeWind Preset + Reanimated Plugin
tailwind.config.js Tailwind Config — Brand-Colors aus apps/rebreak/ syncen
global.css NativeWind Tailwind-Imports

Native Module Strategie

Bestehender Native-Code aus apps/rebreak/ios/ + apps/rebreak/android/ wird in Expo Native Modules gewrappt — ohne neu zu schreiben.

iOS — modules/rebreak-ios-filter/

Wrapped:

  • RebreakURLFilter (NEFilterDataProvider) → blockt bet365 etc.
  • RebreakTunnel (NEPacketTunnelProvider) → DNS-Filter

Android — modules/rebreak-android-blocker/

Wrapped:

  • RebreakVpnService (Kotlin) → VpnService DNS-Filter
  • DnsFilter + HashList + DomainHasher

Android — modules/rebreak-android-a11y/

Wrapped:

  • RebreakAccessibilityService → Detection von Gambling-Apps

⚠️ Wichtige Hinweise

  • Schutz-Stack bleibt 1:1 erhalten — Swift- und Kotlin-Code wandert unverändert in modules/.
  • Backend bleibt in apps/rebreak/server/ — RN ruft die gleichen Endpoints.
  • Alte Capacitor-App bleibt deployed bis RN-App im Store ist.
  • Kein Auto-Commit — User entscheidet wann committet wird.

Phasen-Tracker

Siehe Migration-Plan für Details: apps/rebreak/docs/react-native-migration.md