diff --git a/crates/notedeck_columns/src/timeline/mod.rs b/crates/notedeck_columns/src/timeline/mod.rs index 718c8dae..9fc17926 100644 --- a/crates/notedeck_columns/src/timeline/mod.rs +++ b/crates/notedeck_columns/src/timeline/mod.rs @@ -38,7 +38,7 @@ pub use cache::TimelineCache; pub use kind::{ColumnTitle, PubkeySource, ThreadSelection, TimelineKind}; pub use note_units::{CompositeType, InsertionResponse, NoteUnits}; pub use timeline_units::{TimelineUnits, UnknownPks}; -pub use unit::{CompositeUnit, NoteUnit, ReactionUnit}; +pub use unit::{CompositeUnit, NoteUnit, ReactionUnit, RepostUnit}; #[derive(Copy, Clone, Eq, PartialEq, Debug, Default)] pub enum ViewFilter { diff --git a/crates/notedeck_columns/src/timeline/unit.rs b/crates/notedeck_columns/src/timeline/unit.rs index ed64fca6..4c4a47fa 100644 --- a/crates/notedeck_columns/src/timeline/unit.rs +++ b/crates/notedeck_columns/src/timeline/unit.rs @@ -3,10 +3,7 @@ use std::collections::{BTreeMap, HashSet}; use enostr::Pubkey; use notedeck::NoteRef; -use crate::timeline::{ - note_units::{CompositeKey, UnitKey}, - CompositeType, -}; +use crate::timeline::note_units::{CompositeKey, CompositeType, UnitKey}; /// A `NoteUnit` represents a cohesive piece of data derived from notes #[derive(Debug, Clone)] @@ -136,6 +133,38 @@ impl From for ReactionUnit { } } +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct RepostUnit { + pub note_reposted: NoteRef, + pub reposts: BTreeMap, // repost note to sender + pub senders: HashSet, +} + +impl RepostUnit { + pub fn get_latest_ref(&self) -> &NoteRef { + self.reposts + .first_key_value() + .map(|(r, _)| r) + .unwrap_or(&self.note_reposted) + } +} + +impl From for RepostUnit { + fn from(value: RepostFragment) -> Self { + let mut reposts = BTreeMap::new(); + reposts.insert(value.repost_noteref, value.reposter); + + let mut senders = HashSet::new(); + senders.insert(value.reposter); + + Self { + note_reposted: value.reposted_noteref, + reposts, + senders, + } + } +} + #[derive(Clone)] pub enum NoteUnitFragment { Single(NoteRef), @@ -215,3 +244,27 @@ pub struct Reaction { pub reaction: String, // can't use char because some emojis are 'grapheme clusters' pub sender: Pubkey, } + +/// Represents a singular repost +#[derive(Debug, Clone)] +pub struct RepostFragment { + pub reposted_noteref: NoteRef, + pub repost_noteref: NoteRef, + pub reposter: Pubkey, +} + +impl RepostFragment { + pub fn fold_into(self, unit: &mut RepostUnit) { + if self.reposted_noteref != unit.note_reposted { + tracing::error!("Attempting to fold a repost fragment into a RepostUnit which has a different note reposted: {:?} != {:?}. This should never occur", self.reposted_noteref, unit.note_reposted); + return; + } + + if unit.senders.contains(&self.reposter) { + return; + } + + unit.senders.insert(self.reposter); + unit.reposts.insert(self.repost_noteref, self.reposter); + } +}