feat: AudioRoomConnectionViewModel + connection chip in stage

Phase 3d-3 of the Clubhouse/nests integration. Wires the
nestsClient.connectNestsListener() facade into AudioRoomStage via a
dedicated Android ViewModel, and surfaces the listener's StateFlow
through a small assist chip so the user sees connection progress and
failure modes.

amethyst/audiorooms/room:
- New `AudioRoomConnectionViewModel` (Android `ViewModel`):
  * Owns one `NestsListener` + one `AudioRoomPlayer` per host/speaker.
  * `connect(event, signer)` resolves the room HTTP-side, opens
    WebTransport, runs MoQ SETUP, then subscribes to every host +
    speaker pubkey from the 30312 event and wires their Opus stream
    through `MediaCodecOpusDecoder` -> `AudioTrackPlayer`.
  * `disconnect()` is idempotent, also called from `onCleared()`.
  * Mirrors the underlying NestsListener.state into its own
    StateFlow so callers observe one source.
  * Audience members are skipped — they don't publish audio.
- `AudioRoomStage` now mounts the ViewModel keyed by the room
  address, auto-calls `connect()` in a LaunchedEffect, and
  disconnects in a DisposableEffect.
- New `ConnectionChip` composable renders the listener state with
  retry-on-tap for Idle / Failed / Closed, and color-codes Connected
  (primary) and Failed (error) states.

amethyst:
- Added `:nestsClient` to the project's dependencies.

res:
- New strings for the five connection-chip states.

Behavior today: on opening an audio-room, the chip will report
`Connecting (OpeningTransport)` then immediately
`Failed: WebTransport NotImplemented: ...` because the Kwik handshake
in `KwikWebTransportFactory` is the next phase. Tapping the chip
retries — same outcome until 3b-2 ships. Everything else (presence,
chat, hand-raise, mute) is unaffected.

https://claude.ai/code/session_013nVLALALKaHVgHm9u5Cg8D
This commit is contained in:
Claude
2026-04-22 07:29:42 +00:00
parent c1355f1dd8
commit 64b3367472
4 changed files with 248 additions and 0 deletions
+1
View File
@@ -247,6 +247,7 @@ dependencies {
implementation project(path: ':quartz')
implementation project(path: ':commons')
implementation project(path: ':ammolite')
implementation project(path: ':nestsClient')
implementation libs.androidx.core.ktx
implementation libs.androidx.activity.compose