From 259c0b677a5a5695480b992a1a733c98ea3a8e92 Mon Sep 17 00:00:00 2001 From: kernelkind Date: Thu, 4 Sep 2025 15:19:47 -0400 Subject: [PATCH] add `RepostUnit` & `RepostFragment` Signed-off-by: kernelkind --- crates/notedeck_columns/src/timeline/mod.rs | 2 +- crates/notedeck_columns/src/timeline/unit.rs | 61 ++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) 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); + } +}