pub enum AppEvent {
Show 32 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_string: 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,
}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
code (emoji + decimal) and the Match/Cancel buttons.
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.
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