import React, { useState, useEffect } from 'react'; import { FaBook, FaShare } from 'react-icons/fa'; import BookList from './components/BookList'; import EpubViewer from './components/EpubViewer'; import GatewaySelector from './components/GatewaySelector'; import { parseIPFSCatalog, IPFS_GATEWAYS, buildEpubUrl } from './utils/ipfsParser'; import './App.css'; /** * Componente principal de La Biblioteca * Aplicación para visualizar documentos EPUB desde IPFS */ function App() { const [books, setBooks] = useState([]); const [selectedBook, setSelectedBook] = useState(null); const [selectedGateway, setSelectedGateway] = useState(IPFS_GATEWAYS[0].url); const [isLoading, setIsLoading] = useState(true); const [showShareDialog, setShowShareDialog] = useState(false); useEffect(() => { loadCatalog(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedGateway]); useEffect(() => { // Verificar si hay un hash IPFS en la URL al cargar la página const params = new URLSearchParams(window.location.search); const ipfsHash = params.get('epub'); const gateway = params.get('gateway'); if (ipfsHash && books.length > 0) { // Si hay un gateway en la URL, usarlo if (gateway && gateway !== selectedGateway) { setSelectedGateway(gateway); } // Cargar el EPUB directamente const book = books.find(b => b.ipfsHash === ipfsHash); if (book) { setSelectedBook(book); } else { // Si no está en el catálogo, crear un objeto básico setSelectedBook({ id: ipfsHash, ipfsHash: ipfsHash, title: 'Libro compartido', filename: `${ipfsHash}.epub`, href: '' }); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [books]); /** * Carga el catálogo de libros desde IPFS */ const loadCatalog = async () => { try { setIsLoading(true); // Cargar el catálogo desde IPFS usando el gateway seleccionado const catalogUrl = `${selectedGateway}/ipfs/QmYuyPJZs6J6LfKgVFsMPX5kApWYfSLcr1BXox8NMS7UpL/`; const response = await fetch(catalogUrl); const htmlContent = await response.text(); // Parsear el contenido y extraer los libros const parsedBooks = parseIPFSCatalog(htmlContent); setBooks(parsedBooks); setIsLoading(false); } catch (error) { console.error('Error cargando el catálogo:', error); setIsLoading(false); } }; /** * Carga un libro directamente desde su hash IPFS */ const loadBookFromHash = (ipfsHash) => { // Buscar el libro en el catálogo si ya está cargado const book = books.find(b => b.ipfsHash === ipfsHash); if (book) { setSelectedBook(book); } else { // Si no está en el catálogo, crear un objeto básico setSelectedBook({ id: ipfsHash, ipfsHash: ipfsHash, title: 'Libro compartido', filename: `${ipfsHash}.epub`, href: '' }); } }; /** * Maneja la selección de un libro */ const handleBookSelect = (book) => { // Actualizar la URL del navegador const url = new URL(window.location); url.searchParams.set('epub', book.ipfsHash); url.searchParams.set('gateway', selectedGateway); window.history.pushState({}, '', url); setSelectedBook(book); }; /** * Cierra el visor de EPUB */ const handleCloseViewer = () => { // Limpiar la URL const url = new URL(window.location); url.searchParams.delete('epub'); url.searchParams.delete('gateway'); window.history.pushState({}, '', url); setSelectedBook(null); }; /** * Genera el enlace para compartir */ const getShareUrl = () => { if (!selectedBook) return ''; const url = new URL(window.location.origin + window.location.pathname); url.searchParams.set('epub', selectedBook.ipfsHash); url.searchParams.set('gateway', selectedGateway); return url.toString(); }; /** * Copia el enlace al portapapeles */ const handleShare = async () => { const shareUrl = getShareUrl(); try { await navigator.clipboard.writeText(shareUrl); setShowShareDialog(true); setTimeout(() => setShowShareDialog(false), 3000); } catch (err) { console.error('Error al copiar:', err); alert('No se pudo copiar el enlace. URL: ' + shareUrl); } }; return (
Saltar al contenido principal {selectedBook ? ( <> {showShareDialog && (
✓ Enlace copiado al portapapeles
)} ) : ( <>

La Biblioteca

Visor de documentos EPUB accesibles desde IPFS

{books.length} libros disponibles en IPFS {' | '} ¿Qué es IPFS? {' | '} 📦 Repositorio

)}
); } export default App;