import type { Article } from '@/types/nostr' import type { ArticleFilters, SortOption } from '@/components/ArticleFilters' /** * Filter articles based on search query */ export function filterArticlesBySearch(articles: Article[], searchQuery: string): Article[] { if (!searchQuery.trim()) { return articles } const query = searchQuery.toLowerCase().trim() return articles.filter((article) => { const titleMatch = article.title.toLowerCase().includes(query) const previewMatch = article.preview.toLowerCase().includes(query) const contentMatch = article.content.toLowerCase().includes(query) return titleMatch || previewMatch || contentMatch }) } /** * Filter articles based on filters (author, category) */ export function filterArticles(articles: Article[], filters: ArticleFilters): Article[] { let filtered = articles // Exclude presentation articles from standard article lists filtered = filtered.filter((article) => !article.isPresentation) // Only show articles with valid categories (science-fiction or scientific-research) filtered = filtered.filter((article) => { return article.category === 'science-fiction' || article.category === 'scientific-research' }) // Filter by category if (filters.category && filters.category !== 'all') { filtered = filtered.filter((article) => article.category === filters.category) } // Filter by author if (filters.authorPubkey) { filtered = filtered.filter((article) => article.pubkey === filters.authorPubkey) } return filtered } /** * Get author sponsoring from their presentation article * We need to look up the sponsoring from presentation articles * For now, we'll use a cache or extract from already loaded articles */ function getAuthorSponsoringFromCache( pubkey: string, presentationArticles: Map ): number { const presentation = presentationArticles.get(pubkey) return presentation?.isPresentation ? presentation.totalSponsoring ?? 0 : 0 } /** * Sort articles based on sort option * Default sort: by sponsoring (descending) then by date (newest first) */ export function sortArticles( articles: Article[], sortBy: SortOption, presentationArticles?: Map ): Article[] { const sorted = [...articles] const presentationMap = presentationArticles ?? new Map() switch (sortBy) { case 'oldest': return sorted.sort((a, b) => a.createdAt - b.createdAt) case 'newest': default: // Default: sort by sponsoring (descending) then by date (newest first) return sorted.sort((a, b) => { const sponsoringA = getAuthorSponsoringFromCache(a.pubkey, presentationMap) const sponsoringB = getAuthorSponsoringFromCache(b.pubkey, presentationMap) // First sort by sponsoring (descending) if (sponsoringA !== sponsoringB) { return sponsoringB - sponsoringA } // Then sort by date (newest first) return b.createdAt - a.createdAt }) } } /** * Apply all filters and sorting to articles */ export function applyFiltersAndSort( articles: Article[], searchQuery: string, filters: ArticleFilters, presentationArticles?: Map ): Article[] { let result = articles // First apply search filter result = filterArticlesBySearch(result, searchQuery) // Then apply other filters result = filterArticles(result, filters) // Finally apply sorting (with presentation articles for sponsoring lookup) result = sortArticles(result, filters.sortBy, presentationArticles) return result }