notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 259c0b677a5a5695480b992a1a733c98ea3a8e92
parent 3b7f1f1b397e175f7bc0c9724fd0d560e247e0c5
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu,  4 Sep 2025 15:19:47 -0400

add `RepostUnit` & `RepostFragment`

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck_columns/src/timeline/mod.rs | 2+-
Mcrates/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 @@ -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 @@ -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<ReactionFragment> for ReactionUnit { } } +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct RepostUnit { + pub note_reposted: NoteRef, + pub reposts: BTreeMap<NoteRef, Pubkey>, // repost note to sender + pub senders: HashSet<Pubkey>, +} + +impl RepostUnit { + pub fn get_latest_ref(&self) -> &NoteRef { + self.reposts + .first_key_value() + .map(|(r, _)| r) + .unwrap_or(&self.note_reposted) + } +} + +impl From<RepostFragment> 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); + } +}