huddle_core/app/events.rs
1use libp2p::PeerId;
2
3#[derive(Debug, Clone)]
4pub struct DiscoveredRoom {
5 pub room_id: String,
6 pub name: String,
7 pub encrypted: bool,
8 pub member_count: u32,
9 pub creator_fingerprint: String,
10 pub last_seen: i64,
11 /// True for rooms loaded from local storage that we haven't rejoined
12 /// yet this session (encrypted rooms whose passphrase key isn't in
13 /// memory). The lobby renders these with a "saved" hint; pressing
14 /// Enter goes through the join flow with passphrase prompt.
15 pub restorable: bool,
16}
17
18#[derive(Debug, Clone)]
19pub enum AppEvent {
20 /// A room was discovered (announced on the global topic).
21 RoomDiscovered(DiscoveredRoom),
22 /// A previously-discovered room hasn't been re-announced — TTL expired.
23 RoomLost { room_id: String },
24 /// We successfully joined a room (subscribed to its topic).
25 RoomJoined { room_id: String },
26 /// We left a room.
27 RoomLeft { room_id: String },
28 /// A new member appeared in a room we're in.
29 MemberJoined {
30 room_id: String,
31 fingerprint: String,
32 },
33 /// A member left a room we're in.
34 MemberLeft {
35 room_id: String,
36 fingerprint: String,
37 },
38 /// A message arrived in a room.
39 MessageReceived {
40 room_id: String,
41 sender_fingerprint: String,
42 body: String,
43 sent_at: i64,
44 },
45 /// Our own message was sent successfully.
46 MessageSent {
47 room_id: String,
48 body: String,
49 message_id: i64,
50 },
51 /// Listening on a network address.
52 ListeningOn { address: String },
53 /// A peer was discovered on the LAN.
54 PeerDiscovered { peer_id: PeerId },
55 /// We've fired a dial command — useful for the UI to show "dialing...".
56 Dialing { address: String },
57 /// A user-initiated dial completed successfully.
58 DialSucceeded { address: String, peer_id: PeerId },
59 /// A user-initiated dial failed.
60 DialFailed { address: String, error: String },
61 /// Non-fatal error.
62 Error { description: String },
63 /// Someone (us or a peer) offered a file in a room.
64 FileOffered {
65 room_id: String,
66 file_id: String,
67 name: String,
68 size_bytes: u64,
69 sender_fingerprint: String,
70 },
71 /// A chunk of an incoming transfer arrived. `total_bytes` is the
72 /// announced size from the offer.
73 FileProgress {
74 file_id: String,
75 bytes_received: u64,
76 total_bytes: u64,
77 },
78 /// All chunks of a transfer received and SHA-256 verified.
79 FileReady { file_id: String },
80 /// User saved a ready file to Downloads.
81 FileSaved { file_id: String, path: String },
82 /// A transfer failed (hash mismatch, decrypt error, IO error).
83 FileFailed { file_id: String, reason: String },
84 /// A peer initiated a key rotation in a room we're in. The UI
85 /// surfaces a modal asking the user to enter the new passphrase.
86 RotationRequested {
87 room_id: String,
88 rotator_fingerprint: String,
89 new_salt: Vec<u8>,
90 },
91 /// Someone in a room started typing. The UI re-reads typing peers
92 /// from `AppHandle::typers_in_room` on each render; the event is
93 /// just a nudge.
94 TypingChanged { room_id: String },
95 /// A received message included our fingerprint (full or short
96 /// form). The TUI uses this to ring the terminal bell, even in
97 /// muted rooms.
98 MentionReceived { room_id: String, body: String },
99}