import { useEffect, useMemo, useRef, useState, type Dispatch, type MutableRefObject, type SetStateAction } from 'react' import { nostrService } from '@/lib/nostr' import type { Article } from '@/types/nostr' import { applyFiltersAndSort } from '@/lib/articleFiltering' import type { ArticleFilters } from '@/components/ArticleFilters' import { objectCache } from '@/lib/objectCache' /** * Hook to fetch articles published by a specific user */ export function useUserArticles( userPubkey: string, searchQuery: string = '', filters: ArticleFilters | null = null ): { articles: Article[] allArticles: Article[] loading: boolean error: string | null loadArticleContent: (articleId: string, authorPubkey: string) => Promise
} { const [articles, setArticles] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const hasArticlesRef = useRef(false) useLoadUserArticlesFromCache({ userPubkey, setArticles, setLoading, setError, hasArticlesRef, }) // Apply filters and sorting const filteredArticles = useMemo(() => { const effectiveFilters = buildDefaultFilters(filters) if (!filters && !searchQuery.trim()) { return articles } return applyFiltersAndSort(articles, searchQuery, effectiveFilters) }, [articles, searchQuery, filters]) const loadArticleContent = (articleId: string, authorPubkey: string): Promise
=> loadAndDecryptUserArticle({ articleId, authorPubkey, setArticles, setError, }) return { articles: filteredArticles, allArticles: articles, loading, error, loadArticleContent } } function useLoadUserArticlesFromCache(params: { userPubkey: string setArticles: (value: Article[]) => void setLoading: (value: boolean) => void setError: (value: string | null) => void hasArticlesRef: MutableRefObject }): void { const { userPubkey, setArticles, setLoading, setError, hasArticlesRef } = params useEffect(() => { if (!userPubkey) { setLoading(false) return } void loadUserArticlesFromCache({ userPubkey, setArticles, setLoading, setError, hasArticlesRef }) }, [userPubkey, setArticles, setLoading, setError, hasArticlesRef]) } async function loadUserArticlesFromCache(params: { userPubkey: string setArticles: (value: Article[]) => void setLoading: (value: boolean) => void setError: (value: string | null) => void hasArticlesRef: MutableRefObject }): Promise { const {hasArticlesRef} = params try { params.setLoading(true) params.setError(null) const all = (await readArticlesFromCache()).filter((a) => a.pubkey === params.userPubkey) const sorted = all.sort((a, b) => b.createdAt - a.createdAt) params.setArticles(sorted) hasArticlesRef.current = sorted.length > 0 if (sorted.length === 0) { params.setError('Aucun contenu trouvé') } } catch (e) { console.error('Error loading user articles from cache:', e) params.setError('Erreur lors du chargement des articles') } finally { params.setLoading(false) } } async function readArticlesFromCache(): Promise { const [publications, authors] = await Promise.all([ objectCache.getAll('publication'), objectCache.getAll('author'), ]) return [...publications, ...authors] as Article[] } function buildDefaultFilters(filters: ArticleFilters | null): ArticleFilters { if (filters) { return filters } return { authorPubkey: null, sortBy: 'newest', category: 'all' } } async function loadAndDecryptUserArticle(params: { articleId: string authorPubkey: string setArticles: Dispatch> setError: (value: string | null) => void }): Promise
{ try { const article = await nostrService.getArticleById(params.articleId) if (!article) { return null } const decrypted = await nostrService.getDecryptedArticleContent(params.articleId, params.authorPubkey) if (decrypted) { params.setArticles((prev) => prev.map((a) => (a.id === params.articleId ? { ...a, content: decrypted, paid: true } : a)) ) } return article } catch (e) { console.error('Error loading article content:', e) params.setError(e instanceof Error ? e.message : 'Failed to load article') return null } }