mirror of
https://github.com/damus-io/notedeck.git
synced 2024-09-16 20:03:28 +00:00
filter: create filter from contact list
This adds a method for creating filters from contact lists. We will be using this for creating follow timelines. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
ea547a3497
commit
dd60d03407
@ -37,6 +37,7 @@ impl fmt::Display for SubscriptionError {
|
||||
pub enum Error {
|
||||
SubscriptionError(SubscriptionError),
|
||||
LoadFailed,
|
||||
EmptyContactList,
|
||||
Io(io::Error),
|
||||
Nostr(enostr::Error),
|
||||
Ndb(nostrdb::Error),
|
||||
@ -53,6 +54,9 @@ impl fmt::Display for Error {
|
||||
Self::LoadFailed => {
|
||||
write!(f, "load failed")
|
||||
}
|
||||
Self::EmptyContactList => {
|
||||
write!(f, "empty contact list")
|
||||
}
|
||||
Self::Nostr(e) => write!(f, "{e}"),
|
||||
Self::Ndb(e) => write!(f, "{e}"),
|
||||
Self::Image(e) => write!(f, "{e}"),
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::note::NoteRef;
|
||||
use nostrdb::Filter;
|
||||
use crate::{Error, Result};
|
||||
use nostrdb::{Filter, FilterBuilder, Note};
|
||||
|
||||
pub fn should_since_optimize(limit: u64, num_notes: usize) -> bool {
|
||||
// rough heuristic for bailing since optimization if we don't have enough notes
|
||||
@ -30,3 +31,65 @@ pub fn default_limit() -> u64 {
|
||||
pub fn default_remote_limit() -> u64 {
|
||||
150
|
||||
}
|
||||
|
||||
/// Create a filter from tags. This can be used to create a filter
|
||||
/// from a contact list
|
||||
pub fn filter_from_tags(note: &Note) -> Result<FilterBuilder> {
|
||||
let mut filter = Filter::new();
|
||||
let tags = note.tags();
|
||||
let mut authors: Vec<&[u8; 32]> = Vec::with_capacity(tags.count() as usize);
|
||||
let mut hashtags: Vec<&str> = vec![];
|
||||
|
||||
for tag in tags {
|
||||
if tag.count() < 2 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let t = if let Some(t) = tag.get_unchecked(0).variant().str() {
|
||||
t
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if t == "p" {
|
||||
let author = if let Some(author) = tag.get_unchecked(1).variant().id() {
|
||||
author
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
authors.push(author);
|
||||
} else if t == "t" {
|
||||
let hashtag = if let Some(hashtag) = tag.get_unchecked(1).variant().str() {
|
||||
hashtag
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
hashtags.push(hashtag);
|
||||
}
|
||||
}
|
||||
|
||||
if authors.is_empty() && hashtags.is_empty() {
|
||||
return Err(Error::EmptyContactList);
|
||||
}
|
||||
|
||||
// if we hit these ooms, we need to expand filter buffer size
|
||||
if !authors.is_empty() {
|
||||
filter.start_authors_field()?;
|
||||
for author in authors {
|
||||
filter.add_id_element(author)?;
|
||||
}
|
||||
filter.end_field();
|
||||
}
|
||||
|
||||
if !hashtags.is_empty() {
|
||||
filter.start_tags_field('t')?;
|
||||
for hashtag in hashtags {
|
||||
filter.add_str_element(hashtag)?;
|
||||
}
|
||||
filter.end_field();
|
||||
}
|
||||
|
||||
Ok(filter)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::app::{get_unknown_note_ids, UnknownId};
|
||||
use crate::error::Error;
|
||||
use crate::filter;
|
||||
use crate::note::NoteRef;
|
||||
use crate::notecache::CachedNote;
|
||||
use crate::{Damus, Result};
|
||||
@ -285,6 +286,13 @@ pub struct Timeline {
|
||||
}
|
||||
|
||||
impl Timeline {
|
||||
/// Create a timeline from a contact list
|
||||
pub fn follows(contact_list: &Note) -> Result<Self> {
|
||||
Ok(Timeline::new(vec![filter::filter_from_tags(contact_list)?
|
||||
.kinds([1])
|
||||
.build()]))
|
||||
}
|
||||
|
||||
pub fn new(filter: Vec<Filter>) -> Self {
|
||||
let subscription: Option<Subscription> = None;
|
||||
let notes = TimelineTab::new(ViewFilter::Notes);
|
||||
|
Loading…
Reference in New Issue
Block a user