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>
This commit is contained in:
@@ -176,6 +176,9 @@ pub struct AppConfig {
|
||||
/// Chosen UI colour theme.
|
||||
#[serde(default)]
|
||||
pub theme: AppTheme,
|
||||
/// Our chosen avatar (W4): monogram fallback or a bundled preset.
|
||||
#[serde(default)]
|
||||
pub avatar: crate::avatar::Avatar,
|
||||
/// What a call recording captures (mixed / per-peer stems / both).
|
||||
#[serde(default)]
|
||||
pub recording_mode: RecordingMode,
|
||||
@@ -233,6 +236,7 @@ impl Default for AppConfig {
|
||||
chat_drawer_width: default_chat_drawer_width(),
|
||||
room_layout: RoomLayout::default(),
|
||||
theme: AppTheme::default(),
|
||||
avatar: crate::avatar::Avatar::default(),
|
||||
recording_mode: RecordingMode::default(),
|
||||
custom_sound_self_join: None,
|
||||
custom_sound_peer_join: None,
|
||||
|
||||
Reference in New Issue
Block a user