Skip to content

Repository files navigation

Cruise

A convoy app for a group of friends driving in separate cars on a long road trip. Two features, nothing else:

  1. Live map — everyone sees everyone else's position in real time, so if the cars get separated they can still follow the same route. Each phone sets its own name and picks a colour from a palette of eight; both ride along with the position packets, so everybody's map agrees without a server-side roster.
  2. Walkie-talkie — push-to-talk voice between all cars, played through the car audio (Bluetooth or CarPlay/Android Auto), whether or not the phone is on silent and whether or not the app is foregrounded — or even in the recent apps list at all.

Reference points: TenTen for the walkie-talkie, Bump for the map.

The one thing to read first

Push-to-talk is half-duplex because it has to be, not because it is nicer. Any always-hot microphone forces a Bluetooth link from A2DP (stereo, good) to HFP (mono, narrowband, "phone call music") for as long as the mic is open — for the entire drive. Keeping the mic closed until somebody holds the button is the only way the music sounds normal.

Almost every non-obvious decision in this repo follows from that. They are written down in docs/DESIGN.md, which is worth reading before changing anything under src/lib/audio.ts or modules/expo-ptt.

Stack

  • Expo (managed workflow + config plugins), React Native, TypeScript
  • Development builds, not Expo Go — Expo Go cannot load custom native code
  • LiveKit, self-hosted, for both the audio room (Opus over WebRTC) and position broadcast over the data channel, which deliberately avoids standing up a second realtime backend
  • expo-location + expo-task-manager for background location
  • react-native-maps
  • A small Node token server issuing LiveKit JWTs and sending APNs PushToTalk wakeups

Layout

App.tsx, index.ts        entry point; registerGlobals and the audio-session regime decision
app.json                 the single source of truth for entitlements, background modes,
                         Info.plist keys and Android permissions
app.config.ts            overlays the two values that differ per machine
src/
  config.ts              one hardcoded room, one hardcoded channel, one shared secret
  lib/audio.ts           the audio configuration, which is the design
  lib/room.ts            LiveKit room creation and connection
  lib/location.ts        background location task
  lib/positions.ts       the position packet format
  lib/palette.ts         the eight convoy colours
  ptt/usePushToTalk.ts   binds the OS push-to-talk session to the LiveKit mic track
  state/ConvoyProvider   everything the two screens need
modules/expo-ptt/        the native module: PTChannelManager on iOS, a foreground service on
                         Android, one JS API over both
server/                  LiveKit JWTs + APNs PushToTalk sender
infra/                   docker-compose for the SFU, Caddy and the token server
docs/                    RUNBOOK, DESIGN, SETUP, SERVER, ROADMAP

Getting started

docs/RUNBOOK.md is the one to follow first — fresh clone to both phones running, with the server on your Mac and no TLS, domain or APNs needed on day one.

cp .env.example .env      # LiveKit URL, token server URL, shared secret
npm install
npx expo prebuild --clean --platform android
npx expo run:android      # a physical device — the emulator has no Bluetooth

docs/SETUP.md covers the repo rules that make the Windows/Mac split work, and the Push to Talk entitlement including the license-agreement trap that blocks it.

The server is in docs/SERVER.md — including why the TLS certificate must not be a Cloudflare Origin CA one.

Where the project actually stands, phase by phase, is in docs/ROADMAP.md.

Status

Alpha, for one trip with a handful of known people. No invites, no accounts, no onboarding, no group management — the room is hardcoded and the auth is a shared secret. That is deliberate.

About

Cruise companion app

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages