diff --git a/src/app/mod.rs b/src/app/mod.rs index d606d23..1ed7cc5 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1006,6 +1006,10 @@ fn update(state: &mut AppState, message: AppMessage) -> Task { let output_device = state.selected_output.as_ref().map(|d| d.name.clone()); if !state.ticket_input.is_empty() { state.status_message = "Joining room...".to_string(); + // Clear any prior room's UI state now, at initiation, so an early + // `PeerJoined` for the new room (which can beat `RoomJoined`) isn't + // wiped. From Home this is a no-op (already cleared on leave). + state.reset_room_state(); // Remember this nickname for next launch. state.config.username = state.name.clone(); state.config.save(); @@ -1026,6 +1030,8 @@ fn update(state: &mut AppState, message: AppMessage) -> Task { let input_device = state.selected_input.as_ref().map(|d| d.name.clone()); let output_device = state.selected_output.as_ref().map(|d| d.name.clone()); state.status_message = "Creating room...".to_string(); + // Clear any prior room's UI state at initiation (see JoinPressed). + state.reset_room_state(); // Remember this nickname for next launch. state.config.username = state.name.clone(); state.config.save(); @@ -1065,7 +1071,12 @@ fn update(state: &mut AppState, message: AppMessage) -> Task { AppMessage::UiEventReceived(event) => { match event { UiEvent::RoomJoined { ticket, self_id } => { - state.reset_room_state(); + // NB: do NOT clear peers here. `PeerJoined` rides a separate + // channel sender (the gossip event task) and routinely arrives + // BEFORE this `RoomJoined` (which the core emits only after audio + // + echo-cancel setup), so clearing here would wipe a peer that + // already announced → an empty roster. Room-scoped state is reset + // at join *initiation* instead (see the Join* handlers). // Remember this gathering for one-click rejoin (W7 P5). The // emitted ticket is the canonical room door (topic + member // addr + label); push_recent de-dupes by topic and persists. @@ -1423,6 +1434,8 @@ fn update(state: &mut AppState, message: AppMessage) -> Task { let input_device = state.selected_input.as_ref().map(|d| d.name.clone()); let output_device = state.selected_output.as_ref().map(|d| d.name.clone()); state.status_message = "Joining your friend's room...".to_string(); + // Clear any prior room's UI state at initiation (see JoinPressed). + state.reset_room_state(); state.config.username = state.name.clone(); state.config.save(); state.mic_test_active = false; @@ -1442,6 +1455,8 @@ fn update(state: &mut AppState, message: AppMessage) -> Task { let input_device = state.selected_input.as_ref().map(|d| d.name.clone()); let output_device = state.selected_output.as_ref().map(|d| d.name.clone()); state.status_message = "Rejoining a recent room...".to_string(); + // Clear any prior room's UI state at initiation (see JoinPressed). + state.reset_room_state(); state.config.username = state.name.clone(); state.config.save(); state.mic_test_active = false;