diff --git a/src/events.rs b/src/events.rs new file mode 100644 index 00000000..83450ed1 --- /dev/null +++ b/src/events.rs @@ -0,0 +1,41 @@ +use dashmap::{DashMap, DashSet}; +use nostr_types::{Event, Id}; + +pub struct Events { + events: DashMap, + new_events: DashSet, +} + +impl Events { + pub fn new() -> Events { + Events { + events: DashMap::new(), + new_events: DashSet::new(), + } + } + + pub fn insert(&self, event: Event) { + let _ = self.new_events.insert(event.id); + let _ = self.events.insert(event.id, event); + } + + pub fn contains_key(&self, id: &Id) -> bool { + self.events.contains_key(id) + } + + pub fn get(&self, id: &Id) -> Option { + self.events.get(id).map(|e| e.value().to_owned()) + } + + pub fn is_new(&self, id: &Id) -> bool { + self.new_events.contains(id) + } + + pub fn clear_new(&self) { + self.new_events.clear(); + } + + pub fn iter(&self) -> dashmap::iter::Iter { + self.events.iter() + } +} diff --git a/src/feed.rs b/src/feed.rs index 566ac7e2..973c64cc 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -95,7 +95,7 @@ impl Feed { } pub fn get_thread_parent(&self, id: Id) -> Id { - let mut event = match GLOBALS.events.get(&id).map(|r| r.value().to_owned()) { + let mut event = match GLOBALS.events.get(&id) { None => return id, Some(e) => e, }; diff --git a/src/globals.rs b/src/globals.rs index 6e3da532..1a8dbba0 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -1,12 +1,12 @@ use crate::comms::{ToMinionMessage, ToOverlordMessage}; use crate::db::DbRelay; +use crate::events::Events; use crate::feed::Feed; use crate::fetcher::Fetcher; use crate::people::People; use crate::relationship::Relationship; use crate::settings::Settings; use crate::signer::Signer; -use dashmap::DashMap; use nostr_types::{Event, Id, PublicKeyHex, Url}; use rusqlite::Connection; use std::collections::{HashMap, HashSet}; @@ -31,8 +31,9 @@ pub struct Globals { /// and stolen away when the Overlord is created. pub tmp_overlord_receiver: Mutex>>, - /// All nostr events, keyed by the event Id - pub events: DashMap, + /// All nostr events currently in memory, keyed by the event Id, as well as + /// information about if they are new or not, and functions + pub events: Events, /// Events coming in from relays that are not processed yet /// stored with Url they came from and Subscription they came in on @@ -63,9 +64,6 @@ pub struct Globals { /// Dismissed Events pub dismissed: RwLock>, - /// Event is new - pub event_is_new: RwLock>, - /// Feed pub feed: Feed, @@ -95,7 +93,7 @@ lazy_static! { to_minions, to_overlord, tmp_overlord_receiver: Mutex::new(Some(tmp_overlord_receiver)), - events: DashMap::new(), + events: Events::new(), incoming_events: RwLock::new(Vec::new()), relationships: RwLock::new(HashMap::new()), people: People::new(), @@ -105,7 +103,6 @@ lazy_static! { settings: RwLock::new(Settings::default()), signer: RwLock::new(Signer::default()), dismissed: RwLock::new(Vec::new()), - event_is_new: RwLock::new(Vec::new()), feed: Feed::new(), fetcher: Fetcher::new(), failed_avatars: RwLock::new(HashSet::new()), @@ -116,6 +113,18 @@ lazy_static! { } impl Globals { + /* + pub async fn get_local_event(id: Id) -> Option { + // Try memory + if let Some(e) = GLOBALS.events.get(&id) { + return Some(e.to_owned()) + } + + // Try the database + + } + */ + pub async fn add_relationship(id: Id, related: Id, relationship: Relationship) { let r = (related, relationship); let mut relationships = GLOBALS.relationships.write().await; diff --git a/src/main.rs b/src/main.rs index 4b157b6b..3ab21274 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ mod comms; mod date_ago; mod db; mod error; +mod events; mod feed; mod fetcher; mod globals; diff --git a/src/overlord/mod.rs b/src/overlord/mod.rs index c3f78d6a..53a3371f 100644 --- a/src/overlord/mod.rs +++ b/src/overlord/mod.rs @@ -439,7 +439,7 @@ impl Overlord { } ToOverlordMessage::ProcessIncomingEvents => { // Clear new events - GLOBALS.event_is_new.write().await.clear(); + GLOBALS.events.clear_new(); let _ = tokio::spawn(async move { for (event, url, sub) in GLOBALS.incoming_events.write().await.drain(..) { diff --git a/src/process.rs b/src/process.rs index 40919667..1f519b69 100644 --- a/src/process.rs +++ b/src/process.rs @@ -61,7 +61,7 @@ pub async fn process_new_event( } // Insert the event into globals map - GLOBALS.events.insert(event.id, event.clone()); + GLOBALS.events.insert(event.clone()); // Save the tags into event_tag table if from_relay { @@ -228,8 +228,5 @@ pub async fn process_new_event( // FIXME: Handle EventKind::RecommendedRelay - // Save in event_is_new (to highlight it in the feed, if feed related) - GLOBALS.event_is_new.write().await.push(event.id); - Ok(()) } diff --git a/src/ui/feed.rs b/src/ui/feed.rs index 5c82490b..cb2bbed9 100644 --- a/src/ui/feed.rs +++ b/src/ui/feed.rs @@ -39,7 +39,7 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram app.page = Page::FeedGeneral; GLOBALS.feed.set_feed_to_general(); feed_kind = FeedKind::General; - GLOBALS.event_is_new.blocking_write().clear(); + GLOBALS.events.clear_new(); } ui.separator(); if ui @@ -52,17 +52,17 @@ pub(super) fn update(app: &mut GossipUi, ctx: &Context, frame: &mut eframe::Fram app.page = Page::FeedReplies; GLOBALS.feed.set_feed_to_replies(); feed_kind = FeedKind::Replies; - GLOBALS.event_is_new.blocking_write().clear(); + GLOBALS.events.clear_new(); } if matches!(feed_kind, FeedKind::Thread(..)) { ui.separator(); ui.selectable_value(&mut app.page, Page::FeedThread, "Thread"); - GLOBALS.event_is_new.blocking_write().clear(); + GLOBALS.events.clear_new(); } if matches!(feed_kind, FeedKind::Person(..)) { ui.separator(); ui.selectable_value(&mut app.page, Page::FeedPerson, "Person"); - GLOBALS.event_is_new.blocking_write().clear(); + GLOBALS.events.clear_new(); } }); ui.separator(); @@ -274,7 +274,7 @@ fn render_post_maybe_fake( } = feed_post_params; // We always get the event even offscreen so we can estimate its height - let maybe_event = GLOBALS.events.get(&id).map(|r| r.value().to_owned()); + let maybe_event = GLOBALS.events.get(&id); if maybe_event.is_none() { return; } @@ -346,7 +346,7 @@ fn render_post_actual( threaded, } = feed_post_params; - let maybe_event = GLOBALS.events.get(&id).map(|r| r.value().to_owned()); + let maybe_event = GLOBALS.events.get(&id); if maybe_event.is_none() { return; } @@ -397,7 +397,7 @@ fn render_post_actual( // Try LayoutJob #[allow(clippy::collapsible_else_if)] - let bgcolor = if GLOBALS.event_is_new.blocking_read().contains(&event.id) { + let bgcolor = if GLOBALS.events.is_new(&event.id) { if ctx.style().visuals.dark_mode { Color32::from_rgb(60, 0, 0) } else { diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 4aa447a7..9875d24f 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -201,7 +201,7 @@ impl eframe::App for GossipUi { .clicked() { self.page = Page::FeedGeneral; - GLOBALS.event_is_new.blocking_write().clear(); + GLOBALS.events.clear_new(); } ui.separator(); if ui