# PeerSpeak Feature Inventory A capability list of what PeerSpeak **already does**, so we don't keep re-deriving it. This is the user-facing companion to `ARCHITECTURE.md` (which covers internals). When you ship a feature, add it here. **Field-test status legend:** - โœ… **Verified** โ€” confirmed working on a real call (usually desktop โ†” dopedart). - ๐Ÿงช **Tests-green** โ€” unit-tested and/or smoke-tested locally, but **not** yet exercised on a real 2-machine call. Treat as unproven. - โš™๏ธ **Plumbing** โ€” wiring/persistence that has no separate field test of its own. --- ## Rooms & sessions | Feature | Status | Notes | |---|---|---| | Create a room โ†’ shareable join ticket | โœ… | Ticket carries host addr + topic id. | | Join a room via ticket | โœ… | Paste ticket on the launch screen. | | Leave a room | โœ… | | | Multi-peer rooms (mesh) | โœ… | Presence over the iroh gossip plane. | | Copy ticket to clipboard | โœ… | Button on the room screen. | | Remembered nickname | โœ… | `config.username` pre-fills the launch field, saved on join/create. | | In-call duration timer | โœ… | `call_started` drives the header clock. | ## Audio I/O & codec | Feature | Status | Notes | |---|---|---| | PipeWire capture + playback | โœ… | `src/audio/pipewire_impl.rs`. | | Input device selection | โœ… | | | Output device selection | โœ… | | | App-internal input (mic) gain slider | โœ… | Unity default; applied pre-gate/encode. | | App-internal output gain slider | โœ… | Unity default; applied on the mixed output. | | Opus codec | โœ… | 48 kHz mono, `Application::Voip`, 20 ms / 960-sample frames. | | Adaptive jitter buffer + Opus PLC | ๐Ÿงช | `src/core/jitter.rs`; reorders by seq, adaptive playout delay, conceals drops. Not field-tested. | ## Voice controls | Feature | Status | Notes | |---|---|---| | Self mute | โœ… | | | Deafen | โœ… | | | Push-to-talk + rebindable hotkey | โœ… | `TogglePtt` / `StartSettingHotkey`; gate ahead of the encoder. | | Noise gate (hysteresis + attack/release/hangover) | โœ… | `src/audio/gate.rs`. | | Draggable gate threshold on the mic meter | โœ… | Discord/OBS-style `GateMeter` canvas widget. | | Mic level meter โ€” in-call | โœ… | | | Mic level meter โ€” off-call "Test mic" | โœ… | `SetMicMonitor` / standalone capture stream. | | Mix-bus soft limiter | ๐Ÿงช | `src/audio/limiter.rs`; A/B never confirmed on a real call. | | Echo cancellation (opt-in) | ๐Ÿงช | `src/audio/echo_cancel.rs`; PipeWire `module-echo-cancel` (WebRTC AEC+NS+AGC) via RAII pactl guard. **Needs a 2-machine call through speakers, not headphones.** | ## Per-peer controls | Feature | Status | Notes | |---|---|---| | Per-peer volume | โœ… | `SetPeerVolume`. | | Per-peer local mute | โœ… | Still decoded (levels show) but not mixed. | | Per-peer speaking indicator | โœ… | `audio_levels` per `EndpointId`. | ## Text chat | Feature | Status | Notes | |---|---|---| | In-room text chat | ๐Ÿงช | Over the gossip plane; full-width bottom-dock UI. 2-machine delivery not confirmed. | | Outgoing + incoming sanitization | โœ… | `sanitize_chat`: strips control chars, collapses whitespace, caps 2000. | | History cap | โš™๏ธ | `CHAT_HISTORY_MAX = 300`. | | Local echo of own messages | โœ… | | ## Recording | Feature | Status | Notes | |---|---|---| | Local call recording (mic + incoming mix โ†’ WAV) | ๐Ÿงช | `src/audio/recorder.rs`; writes to `~/peerspeak-recordings/`. Solo + 2-machine recording not confirmed. Header REC timer present. | ## Notifications & sounds | Feature | Status | Notes | |---|---|---| | Desktop notifications toggle | โœ… | `notifications_enabled`. | | Event chimes | โœ… | 8 events: self-join, peer-join, peer-leave, reconnect-attempt, reconnected, self-leave, mic-toggle, reconnect-failed. | | Per-event custom sound override | โœ… | `custom_sound_*` paths in config. | ## Networking & privacy | Feature | Status | Notes | |---|---|---| | iroh QUIC transport | โœ… | | | Network mode picker | โœ… | `RelayNoDiscovery` (default), `N0Full`, `DirectOnly`. Takes effect next join. | | Retained-address reconnect | โœ… | Dials last-known full addr before falling back to bare id. | | Reconnect + eviction model | โœ… | Incl. two-outage reconnect-eviction fix + regression test. | | Self-hosted relay | โŒ | Decided against โ€” rely on n0 relays, `RelayNoDiscovery` default. | ## UI & layout | Feature | Status | Notes | |---|---|---| | Selectable room layouts | โœ… | 3-Column, Bottom Dock (default), Drawer. | | Layout picker popup w/ canvas thumbnails | โœ… | `LayoutThumb`, no image dependency. | | Draggable + persisted panel dividers | โœ… | Per-layout, clamped to window; saved on drag-release. | | Chat drawer toggle (drawer layout) | ๐Ÿงช | Toggle + restart-persistence not explicitly confirmed. | | Responsive full-window Settings screen | โœ… | | ## Persistence | Feature | Status | Notes | |---|---|---| | Config file | โœ… | `~/.config/peerspeak/config.json`. | | Backward-compatible loading | โœ… | serde `default`s fill missing fields; unknown fields tolerated. | --- ## Known field-test debt (the ๐Ÿงช rows above, collected) Re-run on a real desktop โ†” dopedart call before calling these done: 1. **Echo cancellation** โ€” 2-machine call *through speakers* (the only path that actually exercises AEC). 2. **Mix-bus soft limiter** โ€” A/B a hot signal. 3. **Local call recording** โ€” solo + 2-machine, verify the WAV. 4. **In-room text chat** โ€” 2-machine delivery. 5. **Adaptive jitter buffer** โ€” behaviour under real packet loss/jitter. 6. **Chat drawer** โ€” toggle + persistence across restart. ## Not built (candidate features) Things that came up but **do not** exist yet: - Soundboard (play short clips into the call mix). - Video / screen share. - Invite links beyond the raw ticket / room persistence.