Skip to main content

iris_chat_core/
updates.rs

1use crate::actions::AppAction;
2use crate::state::{AppState, MutualGroupsSnapshot, PeerProfileDebugSnapshot};
3use flume::Sender;
4use nostr_sdk::prelude::{Event, RelayStatus};
5
6#[derive(uniffi::Enum, Clone, Debug)]
7#[allow(clippy::large_enum_variant)]
8pub enum AppUpdate {
9    FullState(AppState),
10    PersistAccountBundle {
11        rev: u64,
12        owner_nsec: Option<String>,
13        owner_pubkey_hex: String,
14        device_nsec: String,
15    },
16    NearbyPublishedEvent {
17        event_id: String,
18        kind: u32,
19        created_at_secs: u64,
20        event_json: String,
21    },
22}
23
24#[derive(Debug)]
25pub(crate) enum CoreMsg {
26    Action(AppAction),
27    Internal(Box<InternalEvent>),
28    BuildNearbyPresenceEvent {
29        peer_id: String,
30        my_nonce: String,
31        their_nonce: String,
32        profile_event_id: String,
33        reply_tx: Sender<String>,
34    },
35    ExportSupportBundle(Sender<String>),
36    PeerProfileDebug {
37        owner_input: String,
38        reply_tx: Sender<Option<PeerProfileDebugSnapshot>>,
39    },
40    MutualGroups {
41        owner_input: String,
42        reply_tx: Sender<MutualGroupsSnapshot>,
43    },
44    PrepareForSuspend(Sender<()>),
45    /// Snapshot of core-internal perf counters (debug-snapshot
46    /// rebuild count etc.) — read by `FfiApp::core_perf_counters()`
47    /// so the release-gate budget tests can assert on internal hot
48    /// loops, not just FFI surface traffic.
49    CorePerfCounters(Sender<CorePerfCountersSnapshot>),
50    Shutdown(Option<Sender<()>>),
51    #[cfg(test)]
52    PanicForTest,
53}
54
55#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
56pub(crate) struct CorePerfCountersSnapshot {
57    /// `build_runtime_debug_snapshot` calls since core start.
58    pub debug_snapshot_builds: u64,
59}
60
61#[derive(Debug)]
62pub(crate) enum InternalEvent {
63    RelayEvent(Event),
64    NearbyEvent {
65        event: Event,
66        transport: String,
67    },
68    FetchTrackedPeerCatchUp {
69        token: u64,
70    },
71    ProtocolSubscriptionLivenessCheck {
72        token: u64,
73    },
74    PollPendingDeviceInvites {
75        token: u64,
76    },
77    PruneExpiredMessages {
78        token: u64,
79    },
80    FetchCatchUpEvents(Vec<Event>),
81    ProfileMetadataFetchFinished {
82        owner_pubkey_hex: String,
83        events: Vec<Event>,
84        error: Option<String>,
85    },
86    RelayStatusChanged {
87        relay_url: String,
88        status: RelayStatus,
89        generation: u64,
90    },
91    ProtocolSubscriptionReconcileCompleted {
92        generation: u64,
93        token: u64,
94        reason: String,
95        plan: Option<crate::core::ProtocolSubscriptionPlan>,
96        success: bool,
97        error: Option<String>,
98        relay_statuses: Vec<(String, RelayStatus)>,
99        connected_before: u64,
100        connected_after: u64,
101        filter_count: u64,
102    },
103    RelayTransportConnectionFinished {
104        token: u64,
105        reason: String,
106        relay_statuses: Vec<(String, RelayStatus)>,
107        connected_count: u64,
108    },
109    #[cfg(not(target_os = "ios"))]
110    DebugSnapshotWriteFinished {
111        generation: u64,
112    },
113    DebugLog {
114        category: String,
115        detail: String,
116    },
117    TypingIndicatorExpired {
118        chat_id: String,
119        author: String,
120    },
121    FlushPendingDeliveredReceipts {
122        token: u64,
123    },
124    RelayPublishDrainFinished {
125        token: u64,
126        results: Vec<RelayPublishDrainResult>,
127    },
128    RetryPendingRelayPublishes {
129        reason: String,
130    },
131    AttachmentUploadFinished {
132        chat_id: String,
133        result: Result<String, String>,
134    },
135    AttachmentUploadProgress {
136        bytes_uploaded: u64,
137        total_bytes: u64,
138    },
139    ProfilePictureUploadFinished {
140        result: Result<String, String>,
141    },
142    GroupPictureUploadFinished {
143        group_id: String,
144        result: Result<String, String>,
145    },
146    SyncComplete,
147    // Heavy tail of `open_chat` — DB page load, identity republish,
148    // persist, protocol refresh. Runs on the same event loop as a
149    // queued follow-up so subsequent UI actions (back, switch chat)
150    // can interleave between the screen flip and the load.
151    OpenChatFinalize {
152        chat_id: String,
153    },
154}
155
156#[derive(Debug)]
157pub(crate) struct RelayPublishDrainResult {
158    pub(crate) event_id: String,
159    pub(crate) message_id: Option<String>,
160    pub(crate) chat_id: Option<String>,
161    pub(crate) success: bool,
162    pub(crate) relay_urls: Vec<String>,
163    pub(crate) detail: String,
164}