pub enum AppEvent {
Show 34 variants
RoomDiscovered(DiscoveredRoom),
RoomLost {
room_id: String,
},
RoomJoined {
room_id: String,
},
RoomLeft {
room_id: String,
},
MemberJoined {
room_id: String,
fingerprint: String,
},
MemberLeft {
room_id: String,
fingerprint: String,
},
MessageReceived {
room_id: String,
sender_fingerprint: String,
body: String,
sent_at: i64,
},
MessageSent {
room_id: String,
body: String,
message_id: i64,
},
ListeningOn {
address: String,
},
PeerDiscovered {
peer_id: PeerId,
},
PeerExpired {
peer_id: PeerId,
},
Dialing {
address: String,
},
DialSucceeded {
address: String,
peer_id: PeerId,
},
DialFailed {
address: String,
error: String,
},
Error {
description: String,
},
FileOffered {
room_id: String,
file_id: String,
name: String,
size_bytes: u64,
sender_fingerprint: String,
},
FileProgress {
file_id: String,
bytes_received: u64,
total_bytes: u64,
},
FileReady {
file_id: String,
},
FileSaved {
file_id: String,
path: String,
},
FileFailed {
file_id: String,
reason: String,
},
RotationRequested {
room_id: String,
rotator_fingerprint: String,
new_salt: Vec<u8>,
},
TypingChanged {
room_id: String,
},
MentionReceived {
room_id: String,
body: String,
},
InboundDial {
peer_id: PeerId,
fingerprint: String,
address: String,
},
SasCodeReady {
room_id: String,
partner_fingerprint: String,
tx_id: String,
emoji_labels: String,
decimal: String,
},
SasVerified {
room_id: String,
partner_fingerprint: String,
},
CodeJoinTimedOut {
room_id: String,
reason: String,
},
InviteFingerprintMismatch {
address: String,
claimed: String,
actual: String,
},
NatStatusChanged {
label: String,
reachable: bool,
},
DcutrSucceeded {
peer_label: String,
},
PeerProfileUpdated {
fingerprint: String,
username: Option<String>,
},
WentDark,
AutoOpenDm {
room_id: String,
fingerprint: String,
},
ContactRequestReceived {
fingerprint: String,
display_name: Option<String>,
note: Option<String>,
},
}Variants§
RoomDiscovered(DiscoveredRoom)
A room was discovered (announced on the global topic).
RoomLost
A previously-discovered room hasn’t been re-announced — TTL expired.
RoomJoined
We successfully joined a room (subscribed to its topic).
RoomLeft
We left a room.
MemberJoined
A new member appeared in a room we’re in.
MemberLeft
A member left a room we’re in.
MessageReceived
A message arrived in a room.
MessageSent
Our own message was sent successfully.
ListeningOn
Listening on a network address.
PeerDiscovered
A peer was discovered on the LAN.
PeerExpired
A peer’s mDNS presence expired — they left the LAN or stopped announcing. The lobby refreshes its online/offline indicators.
Dialing
We’ve fired a dial command — useful for the UI to show “dialing…”.
DialSucceeded
A user-initiated dial completed successfully.
DialFailed
A user-initiated dial failed.
Error
Non-fatal error.
FileOffered
Someone (us or a peer) offered a file in a room.
FileProgress
A chunk of an incoming transfer arrived. total_bytes is the
announced size from the offer.
FileReady
All chunks of a transfer received and SHA-256 verified.
FileSaved
User saved a ready file to Downloads.
FileFailed
A transfer failed (hash mismatch, decrypt error, IO error).
RotationRequested
A peer initiated a key rotation in a room we’re in. The UI surfaces a modal asking the user to enter the new passphrase.
TypingChanged
Someone in a room started typing. The UI re-reads typing peers
from AppHandle::typers_in_room on each render; the event is
just a nudge.
MentionReceived
A received message included our fingerprint (full or short form). The TUI uses this to ring the terminal bell, even in muted rooms.
InboundDial
Phase A: an unknown peer has dialed us and Identify has
completed. The TUI shows an accept/reject/trust modal with the
peer’s short fingerprint. Routed through replace_modal_if_idle
so it doesn’t clobber whatever the user is typing.
Fields
SasCodeReady
Phase G: SAS code is ready on both sides — both ephemeral
X25519 pubkeys exchanged + ECDH derived. The TUI shows the SAS
as its word list (emoji_labels) + decimal and the
Match/Cancel buttons. huddle 0.9: the glyph form was dropped from
the UI (emoji-free), so it’s no longer carried here.
Fields
SasVerified
Phase G: SAS completed — both sides confirmed the match. The partner’s fingerprint is now verified (per-room + global).
CodeJoinTimedOut
Phase F follow-up: 30 seconds passed since we broadcast a
CodeJoinRequest and no CodeJoinResponse ever came back. The
owner either ignored us (bad/expired code), wasn’t online, or
the network dropped our packet. Fired by the timeout task
spawned in join_room_with_code once it confirms our pending
secret is still sitting in the map.
InviteFingerprintMismatch
Phase C follow-up: we dialed a peer via an invite link, the peer identified, and the fingerprint they cryptographically asserted doesn’t match the one the invite claimed. The connection has already been dropped. The TUI shows an error modal so the user knows the link is forged or stale.
NatStatusChanged
Phase D follow-up: aggregated NAT reachability state derived from the AutoNAT probe stream. The app layer maintains a small “do any probes say reachable?” tally; this event fires when that aggregate changes. The TUI renders it as a badge in the lobby header (‘reachable’ / ‘private’ / ‘detecting’).
DcutrSucceeded
Phase D follow-up: a successful DCUtR upgrade — a relay-hopped
connection became direct. The TUI shows a transient status
line (“direct connection to
PeerProfileUpdated
huddle 0.5: a peer announced or cleared their self-declared
username via a signed ProfileUpdate. username = None means
the peer is now [anonymous]. TUI consumers redraw the chat
- member list so the new label flows through.
WentDark
huddle 0.5: the local user’s go_dark call succeeded — every
joined room got a best-effort MemberLeave, the network task
shut down, and the data dir was wiped. TUI shows a final
“Goodbye” modal and exits the process.
AutoOpenDm
huddle 0.7.7: a user-initiated dial (d / a / paste-invite /
People-pane reconnect) connected, Identify completed, and we’ve
idempotently opened a DM with the freshly-identified peer. The
TUI listens for this and switches its pane to Dm(room_id) so
the user lands in a chat surface instead of having to hunt for
a way to message the peer they just dialed.
Auto-reconnects on startup do NOT fire this — we consume the
address from pending_auto_dm_addrs and only the user-initiated
paths register there in the first place.
ContactRequestReceived
huddle 1.0: a signed ContactRequest arrived on our relay inbox
from a peer we haven’t added yet (the “add by HD-ID over the
internet” path). The TUI surfaces it in the Contacts pane’s Requests
section to accept (opens a DM) or decline. Mutual requests — where we
already added the sender — auto-connect without firing this.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for AppEvent
impl RefUnwindSafe for AppEvent
impl Send for AppEvent
impl Sync for AppEvent
impl Unpin for AppEvent
impl UnsafeUnpin for AppEvent
impl UnwindSafe for AppEvent
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more