commit 8f8ff42156c7c046ca0ae9a255a9a8c51d07f0b0
parent 3a95ba05a84f64a74e981899f1832ce77f953501
Author: kernelkind <kernelkind@gmail.com>
Date: Thu, 4 Sep 2025 14:54:12 -0400
NoteUnits: use `UnitKey` instead of just `NoteKey`
in preparation for multiple composite types
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
4 files changed, 58 insertions(+), 19 deletions(-)
diff --git a/crates/notedeck_columns/src/timeline/mod.rs b/crates/notedeck_columns/src/timeline/mod.rs
@@ -36,7 +36,7 @@ mod unit;
pub use cache::TimelineCache;
pub use kind::{ColumnTitle, PubkeySource, ThreadSelection, TimelineKind};
-pub use note_units::{InsertionResponse, NoteUnits};
+pub use note_units::{CompositeType, InsertionResponse, NoteUnits};
pub use timeline_units::{TimelineUnits, UnknownPks};
pub use unit::{CompositeUnit, NoteUnit, ReactionUnit};
diff --git a/crates/notedeck_columns/src/timeline/note_units.rs b/crates/notedeck_columns/src/timeline/note_units.rs
@@ -17,7 +17,7 @@ type StorageIndex = usize;
pub struct NoteUnits {
reversed: bool,
storage: Vec<NoteUnit>,
- lookup: HashMap<NoteKey, StorageIndex>, // `NoteKey` to index in `NoteUnits::storage`
+ lookup: HashMap<UnitKey, StorageIndex>, // the key to index in `NoteUnits::storage`
order: Vec<StorageIndex>, // the sorted order of the `NoteUnit`s in `NoteUnits::storage`
}
@@ -30,7 +30,7 @@ impl NoteUnits {
}
}
- pub fn contains_key(&self, k: &NoteKey) -> bool {
+ pub fn contains_key(&self, k: &UnitKey) -> bool {
self.lookup.contains_key(k)
}
@@ -163,7 +163,7 @@ impl NoteUnits {
/// if `NoteUnitFragment::Composite` exists already, it will fold the fragment into the `CompositeUnit`
/// otherwise, it will generate the `NoteUnit::CompositeUnit` from the `NoteUnitFragment::Composite`
pub fn merge_fragments(&mut self, frags: Vec<NoteUnitFragment>) -> InsertManyResponse {
- let mut to_build: HashMap<NoteKey, CompositeUnit> = HashMap::new(); // new composites by key
+ let mut to_build: HashMap<CompositeKey, CompositeUnit> = HashMap::new(); // new composites by key
let mut singles_to_build: Vec<NoteRef> = Vec::new();
let mut singles_seen: HashSet<NoteKey> = HashSet::new();
@@ -172,7 +172,7 @@ impl NoteUnits {
match frag {
NoteUnitFragment::Single(note_ref) => {
let key = note_ref.key;
- if self.lookup.contains_key(&key) {
+ if self.lookup.contains_key(&UnitKey::Single(key)) {
continue;
}
if singles_seen.insert(key) {
@@ -181,8 +181,9 @@ impl NoteUnits {
}
NoteUnitFragment::Composite(c_frag) => {
let key = c_frag.get_underlying_noteref().key;
+ let composite_type = c_frag.get_type();
- if let Some(&storage_idx) = self.lookup.get(&key) {
+ if let Some(&storage_idx) = self.lookup.get(&UnitKey::Composite(c_frag.key())) {
if let Some(NoteUnit::Composite(c_unit)) = self.storage.get_mut(storage_idx)
{
if c_frag.get_latest_ref() < c_unit.get_latest_ref() {
@@ -194,7 +195,10 @@ impl NoteUnits {
}
// aggregate for new composite
use std::collections::hash_map::Entry;
- match to_build.entry(key) {
+ match to_build.entry(CompositeKey {
+ key,
+ composite_type,
+ }) {
Entry::Occupied(mut o) => {
c_frag.fold_into(o.get_mut());
}
@@ -234,6 +238,23 @@ impl NoteUnits {
}
}
+#[derive(Hash, PartialEq, Eq, Debug)]
+pub struct CompositeKey {
+ pub key: NoteKey,
+ pub composite_type: CompositeType,
+}
+
+#[derive(Hash, PartialEq, Eq, Debug)]
+pub enum CompositeType {
+ Reaction,
+}
+
+#[derive(Hash, PartialEq, Eq, Debug)]
+pub enum UnitKey {
+ Single(NoteKey),
+ Composite(CompositeKey),
+}
+
pub enum InsertManyResponse {
Zero,
Some {
diff --git a/crates/notedeck_columns/src/timeline/thread.rs b/crates/notedeck_columns/src/timeline/thread.rs
@@ -8,7 +8,11 @@ use notedeck::{NoteCache, NoteRef, UnknownIds};
use crate::{
actionbar::{process_thread_notes, NewThreadNotes},
multi_subscriber::ThreadSubs,
- timeline::{note_units::NoteUnits, unit::NoteUnit, InsertionResponse},
+ timeline::{
+ note_units::{NoteUnits, UnitKey},
+ unit::NoteUnit,
+ InsertionResponse,
+ },
};
use super::ThreadSelection;
@@ -417,6 +421,6 @@ impl SingleNoteUnits {
}
pub fn contains_key(&self, k: &NoteKey) -> bool {
- self.units.contains_key(k)
+ self.units.contains_key(&UnitKey::Single(*k))
}
}
diff --git a/crates/notedeck_columns/src/timeline/unit.rs b/crates/notedeck_columns/src/timeline/unit.rs
@@ -1,9 +1,13 @@
use std::collections::{BTreeMap, HashSet};
use enostr::Pubkey;
-use nostrdb::NoteKey;
use notedeck::NoteRef;
+use crate::timeline::{
+ note_units::{CompositeKey, UnitKey},
+ CompositeType,
+};
+
/// A `NoteUnit` represents a cohesive piece of data derived from notes
#[derive(Debug, Clone)]
pub enum NoteUnit {
@@ -12,10 +16,10 @@ pub enum NoteUnit {
}
impl NoteUnit {
- pub fn key(&self) -> NoteKey {
+ pub fn key(&self) -> UnitKey {
match self {
- NoteUnit::Single(note_ref) => note_ref.key,
- NoteUnit::Composite(clustered_entry) => clustered_entry.key(),
+ NoteUnit::Single(note_ref) => UnitKey::Single(note_ref.key),
+ NoteUnit::Composite(clustered_entry) => UnitKey::Composite(clustered_entry.key()),
}
}
@@ -79,9 +83,12 @@ impl PartialEq for CompositeUnit {
}
impl CompositeUnit {
- pub fn key(&self) -> NoteKey {
+ pub fn key(&self) -> CompositeKey {
match self {
- CompositeUnit::Reaction(reaction_entry) => reaction_entry.note_reacted_to.key,
+ CompositeUnit::Reaction(reaction_entry) => CompositeKey {
+ key: reaction_entry.note_reacted_to.key,
+ composite_type: CompositeType::Reaction,
+ },
}
}
}
@@ -150,11 +157,12 @@ impl CompositeFragment {
}
}
- pub fn key(&self) -> NoteKey {
+ pub fn key(&self) -> CompositeKey {
match self {
- CompositeFragment::Reaction(reaction_fragment) => {
- reaction_fragment.reaction_note_ref.key
- }
+ CompositeFragment::Reaction(reaction) => CompositeKey {
+ key: reaction.noteref_reacted_to.key,
+ composite_type: CompositeType::Reaction,
+ },
}
}
@@ -169,6 +177,12 @@ impl CompositeFragment {
CompositeFragment::Reaction(reaction_fragment) => &reaction_fragment.reaction_note_ref,
}
}
+
+ pub fn get_type(&self) -> CompositeType {
+ match self {
+ CompositeFragment::Reaction(_) => CompositeType::Reaction,
+ }
+ }
}
/// A singluar reaction to a note