76 lines
2.3 KiB
Rust
76 lines
2.3 KiB
Rust
use crate::nips::nip01::Post;
|
|
use anyhow::{Context, Result};
|
|
use nostr_sdk::prelude::*;
|
|
use std::time::Duration;
|
|
|
|
/// Fetches a timeline/feed of posts from specific users (Followed users).
|
|
///
|
|
/// # Arguments
|
|
/// * `client` - The Nostr client.
|
|
/// * `followed_pubkeys` - A list of hex strings (bech32 also works if parsed correctly, but we assume hex or wait for parsing) representing the users to follow.
|
|
///
|
|
/// The function parses the keys, creates a filter, and returns a list of sorted Posts.
|
|
pub async fn get_followed_feed(
|
|
client: &Client,
|
|
followed_pubkeys: Vec<String>,
|
|
) -> Result<Vec<Post>> {
|
|
let mut keys = Vec::new();
|
|
for key in followed_pubkeys {
|
|
// We try to parse each key. If one fails, we just ignore it or log it (here we context it).
|
|
let pk = PublicKey::parse(&key).context(format!("Invalid public key: {}", key))?;
|
|
keys.push(pk);
|
|
}
|
|
|
|
if keys.is_empty() {
|
|
return Ok(Vec::new());
|
|
}
|
|
|
|
// Create a filter for Text Notes (Kind 1) from these authors
|
|
let filter = Filter::new().kind(Kind::TextNote).authors(keys).limit(50); // Limit to 50 posts for now
|
|
|
|
let timeout = Duration::from_secs(10);
|
|
let events = client.fetch_events(filter, timeout).await?;
|
|
|
|
// Convert Events to our Post struct
|
|
let mut posts: Vec<Post> = events
|
|
.into_iter()
|
|
.map(|e| Post {
|
|
id: e.id,
|
|
author: e.pubkey,
|
|
content: e.content.clone(),
|
|
created_at: e.created_at,
|
|
})
|
|
.collect();
|
|
|
|
// Sort by created_at descending (newest first)
|
|
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
|
|
|
|
Ok(posts)
|
|
}
|
|
|
|
/// Fetches random (recent) posts from the connected Relays (Global Feed).
|
|
///
|
|
/// This is useful for discovery.
|
|
pub async fn get_random_posts(client: &Client) -> Result<Vec<Post>> {
|
|
// Filter for any Text Note, limit 20
|
|
let filter = Filter::new().kind(Kind::TextNote).limit(20);
|
|
|
|
let timeout = Duration::from_secs(10);
|
|
let events = client.fetch_events(filter, timeout).await?;
|
|
|
|
let mut posts: Vec<Post> = events
|
|
.into_iter()
|
|
.map(|e| Post {
|
|
id: e.id,
|
|
author: e.pubkey,
|
|
content: e.content.clone(),
|
|
created_at: e.created_at,
|
|
})
|
|
.collect();
|
|
|
|
// Sort by newest first
|
|
posts.sort_by(|a, b| b.created_at.cmp(&a.created_at));
|
|
|
|
Ok(posts)
|
|
}
|