1use db_rs::View;
2pub use tokio::sync::broadcast::{self, Receiver, Sender};
3use tracing::*;
4use uuid::Uuid;
5
6use crate::io::CoreV5;
7use crate::{Lb, LbErrKind};
8
9#[derive(Clone)]
10pub struct EventSubs {
11 tx: Sender<Event>,
12}
13
14#[derive(Clone, Debug)]
15pub enum Event {
16 MetadataChanged(Actor),
20
21 DocumentWritten(Uuid, Actor),
24
25 IpcChangesApplied,
28
29 PendingSharesChanged,
30
31 Sync(SyncIncrement),
32
33 StatusUpdated,
34
35 UserSignedIn,
36}
37
38#[derive(Debug, Clone, PartialEq)]
39pub enum Actor {
40 User(Option<Uuid>),
44 Sync,
45}
46
47impl Default for EventSubs {
48 fn default() -> Self {
49 let (tx, _) = broadcast::channel::<Event>(10000);
50 Self { tx }
51 }
52}
53
54impl EventSubs {
55 pub(crate) fn pending_shares_changed(&self) {
56 self.queue(Event::PendingSharesChanged);
57 }
58
59 pub(crate) fn meta_changed(&self, actor: Actor) {
60 self.queue(Event::MetadataChanged(actor));
61 }
62
63 pub(crate) fn doc_written(&self, id: Uuid, actor: Actor) {
64 self.queue(Event::DocumentWritten(id, actor));
65 }
66
67 pub(crate) fn sync_update(&self, s: SyncIncrement) {
68 self.queue(Event::Sync(s));
69 }
70
71 pub(crate) fn status_updated(&self) {
72 self.queue(Event::StatusUpdated);
73 }
74
75 pub(crate) fn signed_in(&self) {
77 self.queue(Event::UserSignedIn);
78 }
79
80 fn queue(&self, evt: Event) {
81 if let Err(e) = self.tx.send(evt.clone()) {
82 error!(?evt, ?e, "could not queue");
83 }
84 }
85}
86
87impl Lb {
88 pub(crate) async fn notify_catch_up(&self, db: &CoreV5, previous_seq: u64) {
89 if db.account.last_modified() > previous_seq && self.get_account().is_err() {
90 if let Some(account) = db.account.as_ref() {
91 self.keychain.cache_account(account.clone()).await.unwrap();
92 self.events.signed_in();
93 }
94 }
95
96 let changed = [
97 db.account.last_modified(),
98 db.root.last_modified(),
99 db.base_metadata.last_modified(),
100 db.local_metadata.last_modified(),
101 db.pub_key_lookup.last_modified(),
102 db.pinned_files.last_modified(),
103 db.last_synced.last_modified(),
104 ]
105 .into_iter()
106 .any(|seq| seq > previous_seq);
107
108 if changed {
111 self.events.queue(Event::IpcChangesApplied);
112 }
113 }
114
115 pub fn subscribe(&self) -> Receiver<Event> {
116 self.events.tx.subscribe()
117 }
118}
119
120#[derive(Debug, Clone)]
121pub enum SyncIncrement {
122 SyncStarted,
123 PullingDocument(Uuid, bool),
124 PushingDocument(Uuid, bool),
125 SyncFinished(Option<LbErrKind>),
126}