@@ -917,6 +917,9 @@ impl App for Skrepka {
917 if let Some(c) = model.contacts.get_mut(&peer) {
917 if let Some(c) = model.contacts.get_mut(&peer) {
918 c.blocked = blocked;
918 c.blocked = blocked;
920+ // Clear a stale error (e.g. "cannot send to a blocked contact")
921+ // when the user unblocks — the block that caused it is now lifted.
920 if blocked {
923 if blocked {
921 // Gating *ingest* on the block only stops the acks we have not
924 // Gating *ingest* on the block only stops the acks we have not
922 // queued yet. Anything already sitting in the outbox for this
925 // queued yet. Anything already sitting in the outbox for this
@@ -3442,6 +3445,30 @@ mod tests {
3442 assert!(vm.contacts.iter().any(|c| c.pubkey == peer && c.blocked));
3445 assert!(vm.contacts.iter().any(|c| c.pubkey == peer && c.blocked));
3448+ /// Unblocking clears a stale "cannot send to a blocked contact" error, so the
3449+ /// chat error display does not persist after the user lifts the block.
3451+ fn unblocking_clears_the_stale_send_error() {
3453+ let mut m = with_identity();
3454+ let peer = peer_hex(9);
3455+ let mut contact = Contact::new(peer.clone(), "Bob".into(), 0);
3456+ contact.blocked = true;
3457+ m.contacts.insert(peer.clone(), contact);
3458+ m.error = Some("cannot send to a blocked contact".into());
3460+ let _ = app.update(
3461+ Event::SetBlocked {
3462+ peer: peer.clone(),
3468+ assert!(!m.contacts[&peer].blocked);
3469+ assert!(m.error.is_none(), "unblocking clears the stale error");
3445 /// Gating ingest stops the acks we have not queued yet — but the ack for the
3472 /// Gating ingest stops the acks we have not queued yet — but the ack for the
3446 /// message that made the user hit "block" is already in the outbox, and an ack
3473 /// message that made the user hit "block" is already in the outbox, and an ack
3447 /// is exactly the "we are online and reading you" signal the block exists to
3474 /// is exactly the "we are online and reading you" signal the block exists to