Skip to main content

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}