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:
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);
+ }
+}