mirror of
https://github.com/damus-io/notedeck.git
synced 2024-09-16 11:53:30 +00:00
contacts: fix hashtags in filter_from_tags
split hashtag follows into a separate Filter, combining authors and hashtags doesn't work, because this is considered an AND filter, where we want an OR. We may want an option to split hashtags follows into a separate column. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
2ea6473ae2
commit
a051760fd9
@ -1,6 +1,7 @@
|
||||
use crate::note::NoteRef;
|
||||
use crate::{Error, Result};
|
||||
use nostrdb::{Filter, FilterBuilder, Note};
|
||||
use tracing::{debug, warn};
|
||||
|
||||
pub fn should_since_optimize(limit: u64, num_notes: usize) -> bool {
|
||||
// rough heuristic for bailing since optimization if we don't have enough notes
|
||||
@ -32,13 +33,45 @@ pub fn default_remote_limit() -> u64 {
|
||||
150
|
||||
}
|
||||
|
||||
pub struct FilteredTags {
|
||||
pub authors: Option<FilterBuilder>,
|
||||
pub hashtags: Option<FilterBuilder>,
|
||||
}
|
||||
|
||||
impl FilteredTags {
|
||||
// TODO: make this more general
|
||||
pub fn into_filter<I>(self, kinds: I) -> Vec<Filter>
|
||||
where
|
||||
I: IntoIterator<Item = u64> + Copy,
|
||||
{
|
||||
let mut filters: Vec<Filter> = Vec::with_capacity(2);
|
||||
|
||||
if let Some(authors) = self.authors {
|
||||
filters.push(authors.kinds(kinds).build())
|
||||
}
|
||||
|
||||
if let Some(hashtags) = self.hashtags {
|
||||
filters.push(hashtags.kinds(kinds).build())
|
||||
}
|
||||
|
||||
filters
|
||||
}
|
||||
}
|
||||
|
||||
/// 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();
|
||||
pub fn filter_from_tags(note: &Note) -> Result<FilteredTags> {
|
||||
let mut author_filter = Filter::new();
|
||||
let mut hashtag_filter = Filter::new();
|
||||
let mut author_res: Option<FilterBuilder> = None;
|
||||
let mut hashtag_res: Option<FilterBuilder> = None;
|
||||
let mut author_count = 0i32;
|
||||
let mut hashtag_count = 0i32;
|
||||
|
||||
let tags = note.tags();
|
||||
let mut authors: Vec<&[u8; 32]> = Vec::with_capacity(tags.count() as usize);
|
||||
let mut hashtags: Vec<&str> = vec![];
|
||||
|
||||
author_filter.start_authors_field()?;
|
||||
hashtag_filter.start_tags_field('t')?;
|
||||
|
||||
for tag in tags {
|
||||
if tag.count() < 2 {
|
||||
@ -58,7 +91,8 @@ pub fn filter_from_tags(note: &Note) -> Result<FilterBuilder> {
|
||||
continue;
|
||||
};
|
||||
|
||||
authors.push(author);
|
||||
author_filter.add_id_element(author)?;
|
||||
author_count += 1;
|
||||
} else if t == "t" {
|
||||
let hashtag = if let Some(hashtag) = tag.get_unchecked(1).variant().str() {
|
||||
hashtag
|
||||
@ -66,30 +100,35 @@ pub fn filter_from_tags(note: &Note) -> Result<FilterBuilder> {
|
||||
continue;
|
||||
};
|
||||
|
||||
hashtags.push(hashtag);
|
||||
hashtag_filter.add_str_element(hashtag)?;
|
||||
hashtag_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if authors.is_empty() && hashtags.is_empty() {
|
||||
author_filter.end_field();
|
||||
hashtag_filter.end_field();
|
||||
|
||||
if author_count == 0 && hashtag_count == 0 {
|
||||
warn!("no authors or hashtags found in contact list");
|
||||
return Err(Error::EmptyContactList);
|
||||
}
|
||||
|
||||
debug!(
|
||||
"adding {} authors and {} hashtags to contact filter",
|
||||
author_count, hashtag_count
|
||||
);
|
||||
|
||||
// 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 author_count > 0 {
|
||||
author_res = Some(author_filter)
|
||||
}
|
||||
|
||||
if !hashtags.is_empty() {
|
||||
filter.start_tags_field('t')?;
|
||||
for hashtag in hashtags {
|
||||
filter.add_str_element(hashtag)?;
|
||||
}
|
||||
filter.end_field();
|
||||
if hashtag_count > 0 {
|
||||
hashtag_res = Some(hashtag_filter)
|
||||
}
|
||||
|
||||
Ok(filter)
|
||||
Ok(FilteredTags {
|
||||
authors: author_res,
|
||||
hashtags: hashtag_res,
|
||||
})
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ pub struct Timeline {
|
||||
impl Timeline {
|
||||
/// Create a timeline from a contact list
|
||||
pub fn contact_list(contact_list: &Note) -> Result<Self> {
|
||||
let filter = vec![filter::filter_from_tags(contact_list)?.kinds([1]).build()];
|
||||
let filter = filter::filter_from_tags(contact_list)?.into_filter([1]);
|
||||
let pk_src = PubkeySource::Explicit(Pubkey::new(contact_list.pubkey()));
|
||||
|
||||
Ok(Timeline::new(
|
||||
|
Loading…
Reference in New Issue
Block a user