- ChatBubble: useActionSheet replaces custom Modal (native iOS popup, Android bottom sheet) - DM mode (isDM prop): hides like-count, shows Insta-style heart badge under bubble when liked - Group chat unchanged - Cleanup: remove unused Modal/Platform imports, sheet styles, actionsOpen state - deploy.sh: auto-detect ANDROID_HOME + auto-create local.properties for local Gradle - NEXT_RELEASE.md: DM reactions release note - Includes other staged work across binder-mac, marketing, ops/mdm, ios/
233 lines
7.9 KiB
Markdown
233 lines
7.9 KiB
Markdown
# 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`](../rebreak/docs/react-native-migration.md)
|
|
|
|
## Status
|
|
|
|
**Phase 1 — Foundation Skeleton** (2026-05-02)
|
|
|
|
- [x] Verzeichnisstruktur
|
|
- [x] `package.json` mit Expo SDK 53 + RN 0.76 (New Architecture)
|
|
- [x] `app.config.ts` (Expo, Bundle-ID `org.rebreak.app`)
|
|
- [x] Expo Router Skeleton
|
|
- [x] NativeWind Setup (Tailwind für RN)
|
|
- [x] Metro Config (pnpm Monorepo aware)
|
|
- [x] 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
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
## Dev-Variant (Hot-Reload parallel zur MDM-App)
|
|
|
|
Die MDM-managed Dist-App (`org.rebreak.app`) ist non-removable auf dem iPhone Air.
|
|
Der Dev-Build nutzt eine separate Bundle-ID (`org.rebreak.app.dev`) und kann parallel installiert werden.
|
|
|
|
### Erstmaliges Setup (nur einmal nötig)
|
|
|
|
```bash
|
|
# 1. Dev-Build starten — schlägt beim ersten Mal wegen Signing-Bundle fehl
|
|
REBREAK_DEV=1 ./dev-build.sh --clean
|
|
|
|
# Wenn Xcode "No profiles for 'org.rebreak.app.dev'" meldet:
|
|
# a) open ios/ReBreak.xcworkspace
|
|
# b) Targets → ReBreak → Signing & Capabilities
|
|
# c) Team auf "84BQ7MTFYK" setzen — Xcode registriert Bundle-ID automatisch
|
|
# d) Xcode schliessen, nochmal ausführen:
|
|
REBREAK_DEV=1 ./dev-build.sh --clean
|
|
```
|
|
|
|
### Täglicher Workflow
|
|
|
|
```bash
|
|
# Vollbuild (nach native-code Änderungen oder erstem Mal):
|
|
./dev-build.sh
|
|
|
|
# Nur Metro (wenn Dev-App schon auf iPhone, reine JS-Änderungen):
|
|
./dev-build.sh --metro-only
|
|
|
|
# Nuclear clean + rebuild (nach Plugin/Pod-Änderungen):
|
|
./dev-build.sh --clean
|
|
```
|
|
|
|
### Wichtige Unterschiede Dev vs. Dist
|
|
|
|
| | Dev (`org.rebreak.app.dev`) | Dist (`org.rebreak.app`) |
|
|
|---|---|---|
|
|
| App-Name | ReBreak Dev | ReBreak |
|
|
| Splash-Color | #1e3a5f (dunkles Blau) | #0f172a (schwarz) |
|
|
| URL-Scheme | `rebreak-dev://` | `rebreak://` |
|
|
| App-Group | `group.org.rebreak.app` (geteilt) | `group.org.rebreak.app` |
|
|
| Hot-Reload | via Metro | nein |
|
|
| MDM-managed | nein | ja (non-removable) |
|
|
|
|
App-Group ist bewusst geteilt — Dev-Build kann blocklist.bin lesen und
|
|
Sideload-Profile-Verhalten testen ohne MDM-Push.
|
|
|
|
### Prod-Build bleibt unverändert
|
|
|
|
`deploy-adhoc.sh` und `deploy-tf.sh` setzen `REBREAK_DEV` nicht
|
|
→ landen automatisch auf `org.rebreak.app`.
|
|
|
|
## 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.
|
|
|
|
## Release-Pipeline
|
|
|
|
### Multi-Target Deploy (`deploy-app.sh`)
|
|
|
|
Ein einziges Script baut und deployed alle drei Release-Targets:
|
|
|
|
```bash
|
|
# Default: Alle drei Targets (MDM + TestFlight + Android)
|
|
./deploy-app.sh --bump
|
|
|
|
# Nur spezifische Targets
|
|
./deploy-app.sh --mdm-only # Nur MDM (Ad-Hoc iOS)
|
|
./deploy-app.sh --tf-only # Nur TestFlight
|
|
./deploy-app.sh --android-only # Nur Android (EAS → Play-Console)
|
|
|
|
# Targets selektiv überspringen
|
|
./deploy-app.sh --skip-mdm --bump # TestFlight + Android
|
|
./deploy-app.sh --skip-android # Nur iOS (MDM + TF)
|
|
|
|
# Version-Bumping
|
|
./deploy-app.sh --bump # iOS buildNumber++, Android versionCode++
|
|
./deploy-app.sh --version 0.4.0 # Explizite SemVer
|
|
./deploy-app.sh --android-version-code 15 # Override Android versionCode
|
|
|
|
# Dry-Run (alles simulieren)
|
|
./deploy-app.sh --dry-run --bump
|
|
```
|
|
|
|
#### Was passiert pro Target
|
|
|
|
| Target | Pipeline | Output |
|
|
|---|---|---|
|
|
| **MDM** | `deploy-adhoc.sh` → xcodebuild → scp upload | MDM-Push via NanoMDM (systemd-watcher) |
|
|
| **TestFlight** | `deploy-tf.sh` → altool upload | ASC → Internal Testing (~5-15min) |
|
|
| **Android** | EAS Cloud-Build → Play-Console | Internal-Track (~10-30min Processing) |
|
|
|
|
#### Android-Vorbereitung (einmalig)
|
|
|
|
Android-Submit benötigt `serviceAccountKeyPath` in `eas.json`:
|
|
|
|
1. Google-Cloud-Service-Account erstellen (Play-Console-Zugriff)
|
|
2. JSON-Key downloaden (z.B. `~/secrets/rebreak-play-service-account.json`)
|
|
3. In `eas.json` eintragen:
|
|
```json
|
|
"submit": {
|
|
"production": {
|
|
"android": {
|
|
"serviceAccountKeyPath": "~/secrets/rebreak-play-service-account.json",
|
|
"track": "internal"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
4. **NIEMALS committen** (liegt in `.gitignore`)
|
|
|
|
Falls noch nicht konfiguriert → Script bricht mit klarer Fehlermeldung ab.
|
|
|
|
#### Changelog
|
|
|
|
Changelog-Updates erfolgen bei `--bump` automatisch für iOS (via `deploy-adhoc.sh` intern) und Android (via `deploy-app.sh`).
|
|
|
|
### Alte Scripts (weiterhin nutzbar)
|
|
|
|
- `deploy-adhoc.sh` — MDM (Ad-Hoc iOS) standalone
|
|
- `deploy-tf.sh` — TestFlight standalone (wiederverwendet xcarchive)
|
|
- `eas-release.sh` — EAS Cloud-Build (manueller Wrapper, KEIN Version-Bumping)
|
|
|
|
`deploy-app.sh` ist die empfohlene All-in-One-Lösung.
|
|
|
|
## Phasen-Tracker
|
|
|
|
Siehe Migration-Plan für Details: [`apps/rebreak/docs/react-native-migration.md`](../rebreak/docs/react-native-migration.md)
|