chahinebrini b31066a04c feat(chat): native action sheet + Insta-style heart for DM messages
- 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/
2026-05-30 09:14:32 +02:00

432 lines
13 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# dev.sh — ReBreak Native Development Tooling
#
# SUBCOMMANDS:
# ./dev.sh default: ios (Metro + Xcode)
# ./dev.sh ios iOS Dev (Metro + Xcode Workspace / Simulator)
# ./dev.sh android Android Dev (Metro + Gradle build + install)
# ./dev.sh metro Nur Metro starten
# ./dev.sh clean iOS: Nuclear clean (Pods, DerivedData, Archives)
# ./dev.sh install ios Build Release + Install auf iPhone USB
# ./dev.sh install android Build Debug APK + Install auf Android Device
#
# FLAGS (ios):
# --device Build auf physisches iPhone via USB
# --simulator Build auf iOS Simulator (default)
# --xcode Nur Xcode öffnen (manueller Build)
# --wifi Metro mit --host lan (für WiFi-Dev auf iPhone)
#
# FLAGS (android):
# --no-build Skip Gradle build, nur install last APK
# --no-launch Install but don't auto-launch
#
# FLAGS (metro):
# --keep Cache behalten (kein --clear)
#
# FLAGS (clean):
# --build + iOS build am Ende
# --xcode + Xcode öffnen am Ende
#
# BEISPIELE:
# # iOS Dev auf Simulator:
# ./dev.sh ios
#
# # iOS Dev auf physischem iPhone via USB:
# ./dev.sh ios --device
#
# # iOS Dev auf iPhone via WiFi (Metro LAN):
# ./dev.sh ios --wifi
#
# # Android Dev:
# ./dev.sh android
#
# # Nur Metro starten:
# ./dev.sh metro
#
# # iOS Clean + Rebuild:
# ./dev.sh clean --build
#
# # Release-Build auf iPhone installieren:
# ./dev.sh install ios
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
IOS_DIR="$SCRIPT_DIR/ios"
ANDROID_DIR="$SCRIPT_DIR/android"
# ═══════════════════════════════════════════════════════════════════════════
# Color Output
# ═══════════════════════════════════════════════════════════════════════════
if [[ -t 1 ]]; then
BOLD=$(tput bold)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
RED=$(tput setaf 1)
BLUE=$(tput setaf 4)
RESET=$(tput sgr0)
else
BOLD="" GREEN="" YELLOW="" RED="" BLUE="" RESET=""
fi
log() { echo "${BLUE}==>${RESET} ${BOLD}$*${RESET}"; }
ok() { echo "${GREEN}${RESET} $*"; }
warn() { echo "${YELLOW}${RESET} $*" >&2; }
error() { echo "${RED}${RESET} ${BOLD}$*${RESET}" >&2; }
die() { error "$*"; exit 1; }
section() {
echo ""
echo "${BOLD}$*${RESET}"
echo "${BOLD}────────────────────────────────────────────────────────────${RESET}"
}
# ═══════════════════════════════════════════════════════════════════════════
# ENV Defaults
# ═══════════════════════════════════════════════════════════════════════════
export REBREAK_ENABLE_FAMILY_CONTROLS="${REBREAK_ENABLE_FAMILY_CONTROLS:-1}"
export EXPO_PUBLIC_ENABLE_DEBUG="${EXPO_PUBLIC_ENABLE_DEBUG:-1}"
export REBREAK_DEV="${REBREAK_DEV:-0}"
# ═══════════════════════════════════════════════════════════════════════════
# Commands
# ═══════════════════════════════════════════════════════════════════════════
cmd_ios() {
local MODE="simulator"
local WIFI=false
while [[ $# -gt 0 ]]; do
case "$1" in
--device) MODE="device"; shift ;;
--simulator) MODE="simulator"; shift ;;
--xcode) MODE="xcode"; shift ;;
--wifi) WIFI=true; shift ;;
*) die "Unbekannter Flag für 'ios': $1" ;;
esac
done
section "iOS Dev Mode"
if $WIFI; then
log "Metro: WiFi-Modus (--host lan)"
echo ""
echo "Mac LAN-IP:"
ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || echo " (kein WiFi/Ethernet detected)"
echo ""
echo "Falls dev-client Metro nicht automatisch findet:"
echo " im iPhone-Launcher → 'Enter URL manually' → http://<LAN-IP>:8081"
echo ""
log "Killing old Metro on port 8081..."
lsof -ti:8081 | xargs kill -9 2>/dev/null || true
echo ""
exec pnpm expo start --host lan --clear --dev-client
fi
case "$MODE" in
xcode)
log "Opening Xcode Workspace..."
osascript -e 'tell application "Xcode" to close every window whose name contains "Rebreak.xcodeproj"' 2>/dev/null || true
open -a Xcode "$IOS_DIR/ReBreak.xcworkspace"
ok "Xcode geöffnet — Cmd+R für Build & Run"
echo ""
echo " Metro: separat starten via './dev.sh metro' falls noch nicht läuft"
;;
device)
log "Building für physisches iPhone (USB)..."
pnpm expo run:ios --device
;;
simulator)
log "Building für iOS Simulator..."
pnpm expo run:ios
;;
esac
}
cmd_android() {
local BUILD=true
local LAUNCH=true
while [[ $# -gt 0 ]]; do
case "$1" in
--no-build) BUILD=false; shift ;;
--no-launch) LAUNCH=false; shift ;;
*) die "Unbekannter Flag für 'android': $1" ;;
esac
done
section "Android Dev Mode"
command -v adb >/dev/null 2>&1 || die "adb nicht gefunden — brew install --cask android-platform-tools"
local DEVICE_COUNT
DEVICE_COUNT=$(adb devices | grep -E '[[:space:]]device$' | grep -c '.' || true)
if [[ "$DEVICE_COUNT" -eq 0 ]]; then
warn "Kein Android-Gerät via ADB verbunden"
echo ""
adb devices
echo ""
echo "Mögliche Ursachen:"
echo " - USB nicht angeschlossen / Kabel nur Strom"
echo " - USB-Debugging auf dem Phone aus"
echo " - 'Diesem Computer vertrauen?' Dialog noch nicht bestätigt"
exit 1
fi
if $BUILD; then
log "Building Debug APK..."
(cd "$ANDROID_DIR" && ./gradlew assembleDebug --console=plain)
fi
local APK="$ANDROID_DIR/app/build/outputs/apk/debug/app-debug.apk"
[[ -f "$APK" ]] || die "APK nicht gefunden: $APK"
log "Installing APK..."
adb install -r -d "$APK"
if $LAUNCH; then
log "Launching App..."
adb shell monkey -p org.rebreak.app -c android.intent.category.LAUNCHER 1 >/dev/null 2>&1 || {
warn "Launch via monkey schlug fehl — App ist installiert, manuell öffnen"
}
fi
ok "Android Dev Build abgeschlossen"
}
cmd_metro() {
local CLEAR_FLAG="--clear"
while [[ $# -gt 0 ]]; do
case "$1" in
--keep) CLEAR_FLAG=""; shift ;;
*) die "Unbekannter Flag für 'metro': $1" ;;
esac
done
section "Metro Bundler"
log "Killing existing Metro on port 8081..."
lsof -iTCP:8081 -sTCP:LISTEN -n -P 2>/dev/null | awk 'NR>1 {print $2}' | sort -u | xargs kill -9 2>/dev/null || true
pkill -f "expo start" 2>/dev/null || true
pkill -f "react-native/cli/build" 2>/dev/null || true
if [[ -n "$CLEAR_FLAG" ]]; then
log "Starting Metro mit --clear (Cache reset)..."
else
log "Starting Metro (Cache behalten)..."
fi
exec npx expo start $CLEAR_FLAG
}
cmd_clean() {
local POST_ACTION=""
while [[ $# -gt 0 ]]; do
case "$1" in
--build) POST_ACTION="build"; shift ;;
--xcode) POST_ACTION="xcode"; shift ;;
*) die "Unbekannter Flag für 'clean': $1" ;;
esac
done
section "iOS Nuclear Clean"
log "rm -rf ios/Pods ios/Podfile.lock ios/build"
rm -rf "$IOS_DIR/Pods" "$IOS_DIR/Podfile.lock" "$IOS_DIR/build"
local DERIVED_DATA="$HOME/Library/Developer/Xcode/DerivedData"
if [[ -d "$DERIVED_DATA" ]]; then
log "rm -rf DerivedData/Rebreak-*"
rm -rf "$DERIVED_DATA"/Rebreak-* 2>/dev/null || true
fi
local ARCHIVES_DIR="$HOME/Library/Developer/Xcode/Archives"
if [[ -d "$ARCHIVES_DIR" ]]; then
local before_count
before_count=$(find "$ARCHIVES_DIR" -maxdepth 2 -type d -iname "*rebreak*.xcarchive" 2>/dev/null | wc -l | tr -d ' ')
log "Cleaning Xcode Archives (Rebreak, >24h) — vorher: $before_count Stk"
find "$ARCHIVES_DIR" -maxdepth 2 -type d -iname "*rebreak*.xcarchive" -mtime +1 -exec rm -rf {} + 2>/dev/null || true
find "$ARCHIVES_DIR" -maxdepth 1 -type d -empty -delete 2>/dev/null || true
fi
log "pnpm expo prebuild --clean"
pnpm expo prebuild --clean
log "cd ios && pod install"
(cd "$IOS_DIR" && pod install)
ok "Clean abgeschlossen"
case "$POST_ACTION" in
build)
echo ""
log "Building + Running..."
pnpm ios
;;
xcode)
echo ""
log "Opening Xcode..."
osascript -e 'tell application "Xcode" to close every window whose name contains "Rebreak.xcodeproj"' 2>/dev/null || true
open -a Xcode "$IOS_DIR/ReBreak.xcworkspace"
ok "Xcode geöffnet — Cmd+R für Build & Run"
;;
"")
echo ""
echo "Nächste Schritte:"
echo " ./dev.sh ios # Build & Run"
echo " ./dev.sh ios --xcode # Xcode öffnen"
;;
esac
}
cmd_install_ios() {
section "iOS Standalone Install"
local CONFIGURATION="Release"
command -v xcrun >/dev/null 2>&1 || die "Xcode Command-Line-Tools fehlen — xcode-select --install"
local XCTRACE_OUT
XCTRACE_OUT=$(xcrun xctrace list devices 2>&1)
local ONLINE
ONLINE=$(printf '%s\n' "$XCTRACE_OUT" \
| awk '/^== Devices ==/{f=1; next} /^== /{f=0} f' \
| grep -E "iPhone|iPad" || true)
if [[ -z "$ONLINE" ]]; then
error "Kein iPhone/iPad ONLINE"
echo ""
echo "Setup:"
echo " - iPhone via USB anschließen + entsperren"
echo " - 'Diesem Computer vertrauen?' am iPhone bestätigen"
echo " - Xcode öffnen, dort 'Use for Development' aktivieren"
exit 1
fi
log "Gerät online: $(printf '%s\n' "$ONLINE" | head -1)"
log "Building iOS Release bundle + installing on device..."
echo ""
echo "(Erster Release-Build dauert 5-10 min wegen Pod-Install + Bundle)"
echo ""
npx expo run:ios --device --configuration "$CONFIGURATION"
ok "App läuft jetzt standalone auf deinem iPhone"
echo "Backend: https://staging.rebreak.org"
echo "Free-Account: 7 Tage gültig, danach Skript erneut laufen lassen"
}
cmd_install_android() {
section "Android Standalone Install"
local SKIP_BUILD=false
local LAUNCH=true
while [[ $# -gt 0 ]]; do
case "$1" in
--no-build) SKIP_BUILD=true; shift ;;
--no-launch) LAUNCH=false; shift ;;
*) die "Unbekannter Flag für 'install android': $1" ;;
esac
done
command -v adb >/dev/null 2>&1 || die "adb nicht gefunden — brew install --cask android-platform-tools"
local DEVICE_COUNT
DEVICE_COUNT=$(adb devices | grep -E '[[:space:]]device$' | grep -c '.' || true)
if [[ "$DEVICE_COUNT" -eq 0 ]]; then
error "Kein Android-Gerät via ADB"
adb devices
exit 1
fi
local APK="$ANDROID_DIR/app/build/outputs/apk/debug/app-debug.apk"
if ! $SKIP_BUILD; then
log "Building debug APK..."
(cd "$ANDROID_DIR" && ./gradlew assembleDebug --console=plain)
fi
[[ -f "$APK" ]] || die "APK nicht gefunden: $APK"
log "Installing $APK..."
adb install -r -d "$APK"
if $LAUNCH; then
log "Launching App..."
adb shell monkey -p org.rebreak.app -c android.intent.category.LAUNCHER 1 >/dev/null 2>&1 || {
warn "Launch schlug fehl — App ist installiert, manuell öffnen"
}
fi
ok "Fertig"
}
# ═══════════════════════════════════════════════════════════════════════════
# Main
# ═══════════════════════════════════════════════════════════════════════════
COMMAND="${1:-ios}"
shift || true
case "$COMMAND" in
ios)
cmd_ios "$@"
;;
android)
cmd_android "$@"
;;
metro)
cmd_metro "$@"
;;
clean)
cmd_clean "$@"
;;
install)
local PLATFORM="${1:-}"
shift || true
case "$PLATFORM" in
ios) cmd_install_ios "$@" ;;
android) cmd_install_android "$@" ;;
*)
error "Unbekannte install-Platform: $PLATFORM"
echo "Verfügbar: ios, android"
exit 1
;;
esac
;;
-h|--help)
awk '/^#!/{next} /^#/{sub(/^# ?/, ""); print; next} {exit}' "$0"
exit 0
;;
*)
error "Unbekanntes Subcommand: $COMMAND"
echo ""
echo "Verfügbare Commands:"
echo " ios iOS Dev (Metro + Xcode/Simulator/Device)"
echo " android Android Dev (Metro + Gradle + Install)"
echo " metro Nur Metro starten"
echo " clean iOS Nuclear Clean"
echo " install ios Release-Build auf iPhone installieren"
echo " install android Debug-APK auf Android installieren"
echo ""
echo "Nutze --help für Details"
exit 1
;;
esac