Switch to unified timeline cache via TimelineKinds

This is a fairly large rewrite which unifies our threads, timelines and
profiles. Now all timelines have a MultiSubscriber, and can be added
and removed to columns just like Threads and Profiles.

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2025-01-22 15:59:21 -08:00
parent d46e526a45
commit 0cc1d8a600
39 changed files with 1395 additions and 2055 deletions

View File

@@ -414,6 +414,12 @@ impl Accounts {
.or_else(|| self.accounts.iter().find_map(|a| a.to_full()))
}
/// Get the selected account's pubkey as bytes. Common operation so
/// we make it a helper here.
pub fn selected_account_pubkey_bytes(&self) -> Option<&[u8; 32]> {
self.get_selected_account().map(|kp| kp.pubkey.bytes())
}
pub fn get_selected_account(&self) -> Option<&UserAccount> {
if let Some(account_index) = self.currently_selected_account {
if let Some(account) = self.get_account(account_index) {

View File

@@ -35,6 +35,9 @@ impl From<String> for Error {
pub enum FilterError {
#[error("empty contact list")]
EmptyContactList,
#[error("filter not ready")]
FilterNotReady,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, thiserror::Error)]

View File

@@ -1,6 +1,5 @@
use crate::error::{Error, FilterError};
use crate::note::NoteRef;
use crate::Result;
use nostrdb::{Filter, FilterBuilder, Note, Subscription};
use std::collections::HashMap;
use tracing::{debug, warn};
@@ -24,7 +23,7 @@ pub struct FilterStates {
}
impl FilterStates {
pub fn get(&mut self, relay: &str) -> &FilterState {
pub fn get_mut(&mut self, relay: &str) -> &FilterState {
// if our initial state is ready, then just use that
if let FilterState::Ready(_) = self.initial_state {
&self.initial_state
@@ -195,7 +194,7 @@ pub fn last_n_per_pubkey_from_tags(
note: &Note,
kind: u64,
notes_per_pubkey: u64,
) -> Result<Vec<Filter>> {
) -> Result<Vec<Filter>, Error> {
let mut filters: Vec<Filter> = vec![];
for tag in note.tags() {
@@ -250,7 +249,7 @@ pub fn filter_from_tags(
note: &Note,
add_pubkey: Option<&[u8; 32]>,
with_hashtags: bool,
) -> Result<FilteredTags> {
) -> Result<FilteredTags, Error> {
let mut author_filter = Filter::new();
let mut hashtag_filter = Filter::new();
let mut author_res: Option<FilterBuilder> = None;
@@ -338,3 +337,11 @@ pub fn filter_from_tags(
hashtags: hashtag_res,
})
}
pub fn make_filters_since(raw: &[Filter], since: u64) -> Vec<Filter> {
let mut filters = Vec::with_capacity(raw.len());
for builder in raw {
filters.push(Filter::copy_from(builder).since(since).build());
}
filters
}

View File

@@ -3,6 +3,7 @@ use enostr::NoteId;
use nostrdb::{Ndb, Note, NoteKey, QueryResult, Transaction};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt;
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub struct NoteRef {
@@ -10,9 +11,15 @@ pub struct NoteRef {
pub created_at: u64,
}
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct RootNoteIdBuf([u8; 32]);
impl fmt::Debug for RootNoteIdBuf {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "RootNoteIdBuf({})", self.hex())
}
}
#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)]
pub struct RootNoteId<'a>(&'a [u8; 32]);