From 1b35f1cbc50fcec1e1be5cc9892f41425ffd6c56 Mon Sep 17 00:00:00 2001 From: Joshua Spergel Date: Wed, 12 Feb 2025 17:39:31 -0500 Subject: [PATCH] updated merge --- frontend/src/App.tsx | 63 +++++++++++++++- frontend/src/components/WikiCard.tsx | 19 +++-- frontend/src/components/WikiViewer.tsx | 99 ++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 13 deletions(-) create mode 100644 frontend/src/components/WikiViewer.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e62fbf4..e4c4861 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -5,10 +5,14 @@ import { Analytics } from "@vercel/analytics/react"; import { LanguageSelector } from "./components/LanguageSelector"; import { useLikedArticles } from "./contexts/LikedArticlesContext"; import { useWikiArticles } from "./hooks/useWikiArticles"; +import { WikiViewer } from "./components/WikiViewer"; +import type { WikiArticle } from "./components/WikiCard"; function App() { const [showAbout, setShowAbout] = useState(false); const [showLikes, setShowLikes] = useState(false); + const [currentArticle, setCurrentArticle] = useState(null); + const [currentIndex, setCurrentIndex] = useState(-1); const { articles, loading, fetchArticles } = useWikiArticles(); const { likedArticles, toggleLike } = useLikedArticles(); const observerTarget = useRef(null); @@ -68,6 +72,44 @@ function App() { linkElement.click(); }; + const handleViewArticle = (article: WikiArticle, index: number) => { + setCurrentArticle(article); + setCurrentIndex(index); + }; + + const handleNextArticle = () => { + if (currentIndex < articles.length - 1) { + setCurrentArticle(articles[currentIndex + 1]); + setCurrentIndex(currentIndex + 1); + } + }; + + const handlePreviousArticle = () => { + if (currentIndex > 0) { + setCurrentArticle(articles[currentIndex - 1]); + setCurrentIndex(currentIndex - 1); + } + }; + + const handleShare = async () => { + if (!currentArticle) return; + + if (navigator.share) { + try { + await navigator.share({ + title: currentArticle.title, + text: currentArticle.extract, + url: currentArticle.url + }); + } catch (error) { + console.error('Error sharing:', error); + } + } else { + await navigator.clipboard.writeText(currentArticle.url); + alert('Link copied to clipboard!'); + } + }; + return (
@@ -241,8 +283,25 @@ function App() {
)} - {articles.map((article) => ( - + {currentArticle && ( + { + setCurrentArticle(null); + setCurrentIndex(-1); + }} + onNext={handleNextArticle} + onPrevious={handlePreviousArticle} + onShare={handleShare} + /> + )} + + {articles.map((article, index) => ( + handleViewArticle(article, index)} + /> ))}
{loading && ( diff --git a/frontend/src/components/WikiCard.tsx b/frontend/src/components/WikiCard.tsx index 178d6cb..b09aa25 100644 --- a/frontend/src/components/WikiCard.tsx +++ b/frontend/src/components/WikiCard.tsx @@ -16,9 +16,10 @@ export interface WikiArticle { interface WikiCardProps { article: WikiArticle; + onViewArticle: () => void; } -export function WikiCard({ article }: WikiCardProps) { +export function WikiCard({ article, onViewArticle }: WikiCardProps) { const [imageLoaded, setImageLoaded] = useState(false); const { toggleLike, isLiked } = useLikedArticles(); @@ -74,14 +75,12 @@ export function WikiCard({ article }: WikiCardProps) { {/* Content container with z-index to ensure it's above the image */}
-

{article.title}

-
+

{article.extract}

- Read more → - +
diff --git a/frontend/src/components/WikiViewer.tsx b/frontend/src/components/WikiViewer.tsx new file mode 100644 index 0000000..804f227 --- /dev/null +++ b/frontend/src/components/WikiViewer.tsx @@ -0,0 +1,99 @@ +import { ArrowLeft, ChevronUp, ChevronDown, Share2, Heart } from 'lucide-react'; +import { WikiArticle } from './WikiCard'; +import { useEffect, useState } from 'react'; +import { useLikedArticles } from '../contexts/LikedArticlesContext'; + +interface WikiViewerProps { + article: WikiArticle; + onClose: () => void; + onNext: () => void; + onPrevious: () => void; + onShare: () => void; +} + +export function WikiViewer({ article, onClose, onNext, onPrevious, onShare }: WikiViewerProps) { + const [isMobile, setIsMobile] = useState(false); + const { toggleLike, isLiked } = useLikedArticles(); + + useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth < 768); + }; + + // Check initially + checkMobile(); + + // Add resize listener + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); + + // Construct the URL based on device type + const wikiUrl = isMobile + ? article.url.replace('wikipedia.org', 'm.wikipedia.org') + : article.url; + + const handleNext = () => { + onNext(); + onClose(); + }; + + const handlePrevious = () => { + onPrevious(); + onClose(); + }; + + return ( +
+