Files
peerspeak/Cargo.toml
T
molluskandClaude Opus 4.8 3007002b1b feat(avatars): 6 selectable preset avatars over presence — W4 Phase 2
Adds bundled preset avatars on top of the monogram foundation.

- New `Avatar` enum (Monogram | Preset(u8)) in the avatar module, serde-encoded;
  6 preset PNGs embedded via include_bytes! (placeholder art in assets/avatars/
  — swap for real designs later). +3 unit tests.
- `PeerState` gains `avatar` (rides the gossip presence plane like `sharing`);
  `AppConfig` gains `avatar` (persisted). Avatar choice flows app → core (Join +
  new SetAvatar command) → every self-state announce, so it reaches the room incl.
  late joiners, and changing it mid-call re-announces live.
- Settings "Avatar" section: monogram + 6 preset tiles, applied live + persisted.
- Rendering: `avatar_view` draws the chosen preset image (iced `image` feature,
  now enabled) else the monogram, in the self card, peer rows, and chat (chat
  looks up the sender's avatar from presence by id).

⚠️ BREAKING gossip wire change: presence Announce is signed (S2) and the
signature is recomputed by re-serializing the parsed struct, so a new PeerState
field means old and new builds can't verify each other's presence — ALL peers
must run a build >= this one (same as the S2 change). Redeploy dopedart before
2-machine testing.

Build + clippy clean, 222 lib + integration tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 16:43:24 -04:00

44 lines
1.0 KiB
TOML

[package]
name = "peerspeak"
version = "0.1.0"
edition = "2024"
[lib]
name = "peerspeak"
path = "src/lib.rs"
[[bin]]
name = "peerspeak"
path = "src/main.rs"
[[bin]]
name = "test_net"
path = "src/bin/test_net.rs"
[[bin]]
name = "specview"
path = "src/bin/specview.rs"
[dependencies]
anyhow = "1.0.102"
async-trait = "0.1.89"
base64 = "0.22.1"
bytes = "1.11.1"
dirs = "6.0.0"
iced = { version = "0.14.0", features = ["canvas", "image"] }
iroh = "1.0.0-rc.0"
iroh-gossip = "0.99.0"
opus = "0.3.1"
# v0_3_49 exposes `Buffer::requested()` (the graph's per-cycle quantum), used by
# the playback RT callback to fill exactly what the device asks for instead of
# pinning the buffer to a hard-coded 1024-frame quantum (crackle on non-1024
# hardware). The field has existed in libpipewire since 0.3.49 (2022).
pipewire = { version = "0.9", features = ["v0_3_49"] }
rand = "0.10.1"
ringbuf = "0.5.0"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.150"
thiserror = "2.0.18"
tokio = { version = "1.52.3", features = ["full"] }
tokio-stream = "0.1.18"