mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-19 11:43:43 +00:00
PART 4 of globals/process revamp: strip out feed_event and feed_event map from globals; get_feed rewritten
This commit is contained in:
parent
b544603d5e
commit
7e18d33f71
@ -1,90 +0,0 @@
|
||||
use crate::db::DbEvent;
|
||||
use crate::error::Error;
|
||||
use nostr_types::{Event, EventKind, Id};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct Reactions {
|
||||
pub upvotes: u64,
|
||||
pub downvotes: u64,
|
||||
pub emojis: Vec<(char, u64)>,
|
||||
}
|
||||
|
||||
/// This contains event-related data that is relevant at the time of
|
||||
/// rendering the event, most of which is gathered from other related
|
||||
/// events.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct FeedEvent {
|
||||
pub id: Id,
|
||||
pub event: Option<Event>,
|
||||
pub feed_related: bool,
|
||||
pub replies: Vec<Id>,
|
||||
pub in_reply_to: Option<Id>,
|
||||
pub reactions: Reactions,
|
||||
pub deleted_reason: Option<String>,
|
||||
pub client: Option<String>,
|
||||
pub hashtags: Vec<String>,
|
||||
pub subject: Option<String>,
|
||||
pub urls: Vec<String>,
|
||||
pub last_reply_at: Option<i64>,
|
||||
}
|
||||
|
||||
impl FeedEvent {
|
||||
#[allow(dead_code)]
|
||||
pub fn new(id: Id) -> FeedEvent {
|
||||
FeedEvent {
|
||||
id,
|
||||
event: None,
|
||||
feed_related: false,
|
||||
replies: Vec::new(),
|
||||
in_reply_to: None,
|
||||
reactions: Default::default(),
|
||||
deleted_reason: None,
|
||||
client: None,
|
||||
hashtags: Vec::new(),
|
||||
subject: None,
|
||||
urls: Vec::new(),
|
||||
last_reply_at: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Event> for FeedEvent {
|
||||
fn from(event: &Event) -> FeedEvent {
|
||||
FeedEvent {
|
||||
id: event.id,
|
||||
event: Some(event.to_owned()),
|
||||
feed_related: event.kind == EventKind::TextNote,
|
||||
replies: Vec::new(),
|
||||
in_reply_to: None,
|
||||
reactions: Default::default(),
|
||||
deleted_reason: None,
|
||||
client: None,
|
||||
hashtags: Vec::new(),
|
||||
subject: None,
|
||||
urls: Vec::new(),
|
||||
last_reply_at: Some(event.created_at.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&DbEvent> for FeedEvent {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(dbevent: &DbEvent) -> Result<FeedEvent, Error> {
|
||||
Ok(FeedEvent {
|
||||
id: dbevent.id.clone().try_into()?,
|
||||
event: serde_json::from_str(&dbevent.raw)?,
|
||||
feed_related: dbevent.kind == 1,
|
||||
replies: Vec::new(),
|
||||
in_reply_to: None,
|
||||
reactions: Default::default(),
|
||||
deleted_reason: None,
|
||||
client: None,
|
||||
hashtags: Vec::new(),
|
||||
subject: None,
|
||||
urls: Vec::new(),
|
||||
last_reply_at: Some(dbevent.created_at),
|
||||
})
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
use crate::comms::BusMessage;
|
||||
use crate::db::{DbPerson, DbPersonRelay, DbRelay};
|
||||
use crate::error::Error;
|
||||
use crate::feed_event::FeedEvent;
|
||||
use crate::relationship::Relationship;
|
||||
use crate::settings::Settings;
|
||||
use async_recursion::async_recursion;
|
||||
@ -29,15 +28,10 @@ pub struct Globals {
|
||||
/// and stolen away when the Overlord is created.
|
||||
pub from_minions: Mutex<Option<mpsc::UnboundedReceiver<BusMessage>>>,
|
||||
|
||||
/// All nostr event related data, keyed by the event Id
|
||||
pub feed_events: Mutex<HashMap<Id, FeedEvent>>,
|
||||
|
||||
/// All nostr events, keyed by the event Id
|
||||
/// This will replace feed_events.
|
||||
pub events: Mutex<HashMap<Id, Event>>,
|
||||
|
||||
/// All relationships between events
|
||||
/// This will also replace feed_events.
|
||||
pub relationships: Mutex<HashMap<Id, Vec<(Id, Relationship)>>>,
|
||||
|
||||
/// The date of the latest reply. Only reply relationships count, not reactions,
|
||||
@ -73,7 +67,6 @@ lazy_static! {
|
||||
to_minions,
|
||||
to_overlord,
|
||||
from_minions: Mutex::new(Some(from_minions)),
|
||||
feed_events: Mutex::new(HashMap::new()),
|
||||
events: Mutex::new(HashMap::new()),
|
||||
relationships: Mutex::new(HashMap::new()),
|
||||
last_reply: Mutex::new(HashMap::new()),
|
||||
@ -88,20 +81,20 @@ lazy_static! {
|
||||
impl Globals {
|
||||
#[allow(dead_code)]
|
||||
pub async fn get_feed(threaded: bool) -> Vec<Id> {
|
||||
let feed: Vec<FeedEvent> = GLOBALS
|
||||
.feed_events
|
||||
let feed: Vec<Event> = GLOBALS
|
||||
.events
|
||||
.lock()
|
||||
.await
|
||||
.iter()
|
||||
.map(|(_, e)| e)
|
||||
.filter(|e| e.event.is_some() && e.event.as_ref().unwrap().kind == EventKind::TextNote)
|
||||
.filter(|e| e.kind == EventKind::TextNote)
|
||||
.filter(|e| {
|
||||
if threaded {
|
||||
e.in_reply_to.is_none()
|
||||
e.replies_to().is_none()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}) // only root events
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
@ -110,44 +103,36 @@ impl Globals {
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn blocking_get_feed(threaded: bool) -> Vec<Id> {
|
||||
let feed: Vec<FeedEvent> = GLOBALS
|
||||
.feed_events
|
||||
let feed: Vec<Event> = GLOBALS
|
||||
.events
|
||||
.blocking_lock()
|
||||
.iter()
|
||||
.map(|(_, e)| e)
|
||||
.filter(|e| e.event.is_some() && e.event.as_ref().unwrap().kind == EventKind::TextNote)
|
||||
.filter(|e| e.kind == EventKind::TextNote)
|
||||
.filter(|e| {
|
||||
if threaded {
|
||||
e.in_reply_to.is_none()
|
||||
e.replies_to().is_none()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}) // only root events
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
Self::sort_feed(feed, threaded)
|
||||
}
|
||||
|
||||
fn sort_feed(mut feed: Vec<FeedEvent>, threaded: bool) -> Vec<Id> {
|
||||
fn sort_feed(mut feed: Vec<Event>, threaded: bool) -> Vec<Id> {
|
||||
if threaded {
|
||||
feed.sort_unstable_by(|a, b| b.last_reply_at.cmp(&a.last_reply_at));
|
||||
} else {
|
||||
feed.sort_unstable_by(|a, b| {
|
||||
if a.event.is_some() && b.event.is_some() {
|
||||
b.event
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.created_at
|
||||
.cmp(&a.event.as_ref().unwrap().created_at)
|
||||
} else if a.event.is_some() {
|
||||
std::cmp::Ordering::Greater
|
||||
} else if b.event.is_some() {
|
||||
std::cmp::Ordering::Less
|
||||
} else {
|
||||
std::cmp::Ordering::Equal
|
||||
}
|
||||
let a_last = GLOBALS.last_reply.blocking_lock().get(&a.id).cloned();
|
||||
let b_last = GLOBALS.last_reply.blocking_lock().get(&b.id).cloned();
|
||||
let a_time = a_last.unwrap_or(a.created_at);
|
||||
let b_time = b_last.unwrap_or(b.created_at);
|
||||
b_time.cmp(&a_time)
|
||||
});
|
||||
} else {
|
||||
feed.sort_unstable_by(|a, b| b.created_at.cmp(&a.created_at));
|
||||
}
|
||||
|
||||
feed.iter().map(|e| e.id).collect()
|
||||
@ -203,13 +188,25 @@ impl Globals {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_replies_sync(id: Id) -> Vec<Id> {
|
||||
let mut output: Vec<Id> = Vec::new();
|
||||
if let Some(vec) = GLOBALS.relationships.blocking_lock().get(&id) {
|
||||
for (id, relationship) in vec.iter() {
|
||||
if *relationship == Relationship::Reply {
|
||||
output.push(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
// FIXME - this allows people to react many times to the same event, and
|
||||
// it counts them all!
|
||||
#[allow(dead_code)]
|
||||
pub async fn get_reactions(id: Id) -> HashMap<char, usize> {
|
||||
pub fn get_reactions_sync(id: Id) -> HashMap<char, usize> {
|
||||
let mut output: HashMap<char, usize> = HashMap::new();
|
||||
|
||||
if let Some(relationships) = GLOBALS.relationships.lock().await.get(&id).cloned() {
|
||||
if let Some(relationships) = GLOBALS.relationships.blocking_lock().get(&id).cloned() {
|
||||
for (_id, relationship) in relationships.iter() {
|
||||
if let Relationship::Reaction(reaction) = relationship {
|
||||
if let Some(ch) = reaction.chars().next() {
|
||||
|
@ -8,7 +8,6 @@ mod comms;
|
||||
mod date_ago;
|
||||
mod db;
|
||||
mod error;
|
||||
mod feed_event;
|
||||
mod globals;
|
||||
mod overlord;
|
||||
mod process;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::GossipUi;
|
||||
use crate::globals::Globals;
|
||||
use crate::globals::{Globals, GLOBALS};
|
||||
use eframe::egui;
|
||||
use egui::{Align, Color32, Context, Layout, RichText, ScrollArea, TextStyle, Ui, Vec2};
|
||||
use nostr_types::{EventKind, Id, PublicKey};
|
||||
@ -46,31 +46,21 @@ fn render_post(
|
||||
id: Id,
|
||||
indent: usize,
|
||||
) {
|
||||
let maybe_fevent = crate::globals::GLOBALS
|
||||
.feed_events
|
||||
.blocking_lock()
|
||||
.get(&id)
|
||||
.cloned();
|
||||
if maybe_fevent.is_none() {
|
||||
let maybe_event = GLOBALS.events.blocking_lock().get(&id).cloned();
|
||||
if maybe_event.is_none() {
|
||||
return;
|
||||
}
|
||||
let fevent = maybe_fevent.unwrap();
|
||||
|
||||
if fevent.event.is_none() {
|
||||
return;
|
||||
} // don't render related info w/o nostr event.
|
||||
let event = fevent.event.as_ref().unwrap().to_owned();
|
||||
let event = maybe_event.unwrap();
|
||||
|
||||
// Only render TextNote events
|
||||
if event.kind != EventKind::TextNote {
|
||||
return;
|
||||
}
|
||||
|
||||
let maybe_person = crate::globals::GLOBALS
|
||||
.people
|
||||
.blocking_lock()
|
||||
.get(&event.pubkey)
|
||||
.cloned();
|
||||
let maybe_person = GLOBALS.people.blocking_lock().get(&event.pubkey).cloned();
|
||||
|
||||
let reactions = Globals::get_reactions_sync(event.id);
|
||||
let replies = Globals::get_replies_sync(event.id);
|
||||
|
||||
// Person Things we can render:
|
||||
// pubkey
|
||||
@ -149,19 +139,25 @@ fn render_post(
|
||||
|
||||
// Second row
|
||||
ui.horizontal(|ui| {
|
||||
if fevent.reactions.upvotes > 0 {
|
||||
for (ch, count) in reactions.iter() {
|
||||
if *ch == '+' {
|
||||
ui.label(
|
||||
RichText::new(&format!("+{}", fevent.reactions.upvotes))
|
||||
RichText::new(&format!("{} {}", ch, count))
|
||||
.text_style(TextStyle::Name("Bold".into()))
|
||||
.color(Color32::DARK_GREEN),
|
||||
);
|
||||
}
|
||||
if fevent.reactions.downvotes > 0 {
|
||||
} else if *ch == '-' {
|
||||
ui.label(
|
||||
RichText::new(&format!("-{}", fevent.reactions.downvotes))
|
||||
RichText::new(&format!("{} {}", ch, count))
|
||||
.text_style(TextStyle::Name("Bold".into()))
|
||||
.color(Color32::DARK_RED),
|
||||
);
|
||||
} else {
|
||||
ui.label(
|
||||
RichText::new(&format!("{} {}", ch, count))
|
||||
.text_style(TextStyle::Name("Bold".into())),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -172,7 +168,7 @@ fn render_post(
|
||||
ui.separator();
|
||||
|
||||
if app.settings.view_threaded {
|
||||
for reply_id in fevent.replies {
|
||||
for reply_id in replies {
|
||||
render_post(app, _ctx, _frame, ui, reply_id, indent + 1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user