Skip to content

Add Expo/React Native mobile prototype for iOS, Android, and web - #42

Open
srctl wants to merge 5 commits into
mainfrom
claude/project-thread-y7mv3u
Open

srctl wants to merge 5 commits into
mainfrom
claude/project-thread-y7mv3u

Conversation

@srctl

@srctl srctl commented Sep 26, 2026

Copy link
Copy Markdown
Owner

This PR introduces a complete Expo (SDK 57, React Native 0.86) prototype of the Roost mobile application, enabling evaluation of React Native viability against the existing SwiftUI implementation.

Summary

A new apps/mobile-expo application that ports four core screens from the SwiftUI app (apps/ios) to run on iOS, Android, and web platforms. The prototype connects to the same /api/mobile/v1 API using device tokens, allowing it to run against a real Roost server or the native UI fixture.

Key Changes

  • Connect Screen: Server and token validation, session/agents check, secure storage via expo-secure-store (Keychain on iOS, SecureStore on Android, localStorage on web)
  • Agents Screen: Native large-title list with search, pull-to-refresh, and 15-second foreground refresh polling
  • Chat Screen: Full conversation management with revision-based polling (1s busy / 4s idle / 8s error), idempotent message sending with retry, stop functionality, approval cards, reply threads, and swipe-to-reply gestures
  • Feed Screen: Story list with filtering (all/saved), pull-to-refresh, and native reader sheet
  • API Layer (lib/api.ts): Complete port of the Swift API client with bearer token auth, error handling, and user-facing error messages
  • Conversation State (lib/conversation.ts): Revision-based polling, pending payload reuse after network failures, and message deduplication
  • Session Management (lib/session.tsx): Secure connection storage and agent list caching
  • UI Components:
    • Typing indicator with staggered dot animation
    • Message composer with glass effect (iOS 26+) and attachment placeholder
    • Message rows with swipe-to-reply, context menus, and markdown rendering
    • Native buttons using SwiftUI on iOS, Material Design on Android/web
    • Character pixel art renderer (shared with SwiftUI app)
    • Markdown parser supporting headings, lists, code blocks, and inline formatting
  • Theme System: Shared color palette with the SwiftUI app via Themes.json
  • Keyboard Handling: Keyboard-aware chat scrolling that lifts content only when newest message is visible
  • Animations: React Native Reanimated for smooth transitions, spring physics, and gesture-driven interactions

Notable Implementation Details

  • Platform-specific code uses .ios.tsx and .tsx suffixes for SwiftUI integration on iOS while maintaining Android/web compatibility
  • Shared JSON resources (Characters.json, Themes.json) imported from the iOS app via Metro config
  • Gesture handling with react-native-gesture-handler for swipe-to-reply with haptic feedback
  • Secure token storage with platform-appropriate backends (Keychain, SecureStore, localStorage)
  • Comprehensive TypeScript types matching the Swift API models
  • Accessibility labels and roles throughout for screen reader support

https://claude.ai/code/session_01N4Td1Sf9cr1ZvAJ3uowaNJ

claude and others added 5 commits September 26, 2026 19:16
Ports Connect, Agents, Chat and Feed from the SwiftUI app to Expo SDK 57
against the same mobile API. Lives outside the pnpm workspace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4Td1Sf9cr1ZvAJ3uowaNJ
Header buttons become Stack.Toolbar items and menus, buttons render as
SwiftUI glass buttons through @expo/ui, the composer sits in a GlassView,
and message long-press uses the SwiftUI context menu. Android and web keep
React Native fallbacks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4Td1Sf9cr1ZvAJ3uowaNJ
- Install expo-updates with a fingerprint runtimeVersion so JS-only changes
  can ship to iOS and Android without store review, and add eas.json with
  preview and production channels. No update server is configured yet.
- Add a config plugin that adopts Expo's ExpoAppSceneDelegate. Apps built
  with the iOS 27 SDK are killed at launch without the UIScene life cycle,
  and the generated AppDelegate doesn't use it.
- Point the ios/android scripts at development builds, which prebuild
  switched them to.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 01M3FNHDC0WP1BCHNMEZCNPJY0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants