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, ) -> Result> { 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 = 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> { // 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 = 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) }