diff --git a/src/server/app.py b/src/server/app.py index 7947aba..d409df1 100644 --- a/src/server/app.py +++ b/src/server/app.py @@ -1,7 +1,9 @@ -from flask import Flask, jsonify, request +from flask import Flask, jsonify, request, send_from_directory +from flask_cors import CORS import os app = Flask(__name__) +CORS(app) # Enable CORS for all routes # Get the directory where this script is located script_dir = os.path.dirname(os.path.abspath(__file__)) @@ -13,6 +15,18 @@ from parse_archive import ArchiveParser archive_parser = ArchiveParser() +# Serve static files from the website directory +@app.route("/") +def serve_static(filename): + return send_from_directory("../website", filename) + + +# Serve the main index.html page +@app.route("/") +def serve_index(): + return send_from_directory("../website", "index.html") + + @app.route("/posts", methods=["GET"]) def get_initial_posts(): """Get the first 10 posts for initial load""" @@ -20,7 +34,8 @@ def get_initial_posts(): # Use archive parser to fetch posts posts = archive_parser.get_posts(count=10, start_index=0) return jsonify(posts) - except Exception: + except Exception as e: + print(f"Error: {e}") return jsonify({"error": "Failed to fetch posts"}), 500 @@ -35,7 +50,8 @@ def get_more_posts(): posts = archive_parser.get_posts(count=10, start_index=count) return jsonify(posts) - except Exception: + except Exception as e: + print(f"Error: {e}") return jsonify({"error": "Failed to fetch more posts"}), 500 @@ -47,10 +63,11 @@ def get_total_posts(): total = archive_parser.get_total_posts() return jsonify({"total": total}) except Exception as e: + print(f"Error: {e}") return jsonify({"error": "Failed to fetch total count"}), 500 -@app.route("/") +@app.route("/api") def home(): """Home endpoint to verify server is running""" return jsonify( diff --git a/src/server/requirements.txt b/src/server/requirements.txt index 597ce19..7210db7 100644 --- a/src/server/requirements.txt +++ b/src/server/requirements.txt @@ -1 +1,2 @@ Flask==2.3.3 +Flask-CORS==4.0.0 diff --git a/src/website/app.js b/src/website/app.js index 4db8724..c444d2a 100644 --- a/src/website/app.js +++ b/src/website/app.js @@ -1,123 +1,6 @@ -// Mock Reddit data for demonstration purposes - in real app this would come from an API -const mockRedditPosts = [ - { - id: "1", - title: "This is a sample Reddit post title", - url: "https://example.com/sample-post", - image: "https://picsum.photos/400/300?random=1", - }, - { - id: "2", - title: "Another interesting Reddit post about technology", - url: "https://example.com/tech-post", - image: "https://picsum.photos/400/300?random=2", - }, - { - id: "3", - title: "Amazing landscape photography from nature", - url: "https://example.com/nature-photography", - image: "https://picsum.photos/400/300?random=3", - }, - { - id: "4", - title: "How to build a React application from scratch", - url: "https://example.com/react-guide", - image: "https://picsum.photos/400/300?random=4", - }, - { - id: "5", - title: "The future of artificial intelligence in 2023", - url: "https://example.com/ai-future", - image: "https://picsum.photos/400/300?random=5", - }, - { - id: "6", - title: "Delicious recipes for vegetarian meals", - url: "https://example.com/vegetarian-recipes", - image: "https://picsum.photos/400/300?random=6", - }, - { - id: "7", - title: "Top programming languages to learn in 2023", - url: "https://example.com/programming-languages", - image: "https://picsum.photos/400/300?random=7", - }, - { - id: "8", - title: "Space exploration updates from NASA", - url: "https://example.com/space-exploration", - image: "https://picsum.photos/400/300?random=8", - }, - { - id: "9", - title: "Tips for improving your sleep quality", - url: "https://example.com/sleep-tips", - image: "https://picsum.photos/400/300?random=9", - }, - { - id: "10", - title: "Latest trends in web development", - url: "https://example.com/web-development-trends", - image: "https://picsum.photos/400/300?random=10", - }, - { - id: "11", - title: "Health benefits of daily exercise", - url: "https://example.com/health-exercise", - image: "https://picsum.photos/400/300?random=11", - }, - { - id: "12", - title: "Understanding blockchain technology explained", - url: "https://example.com/blockchain-explained", - image: "https://picsum.photos/400/300?random=12", - }, - { - id: "13", - title: "Best travel destinations for summer 2023", - url: "https://example.com/travel-destinations", - image: "https://picsum.photos/400/300?random=13", - }, - { - id: "14", - title: "Cooking tips from professional chefs", - url: "https://example.com/chef-tips", - image: "https://picsum.photos/400/300?random=14", - }, - { - id: "15", - title: "The history of the internet and its evolution", - url: "https://example.com/internet-history", - image: "https://picsum.photos/400/300?random=15", - }, -]; - -// For the real implementation, this would be replaced with an actual API call -function fetchRedditPosts() { - return new Promise((resolve) => { - // Simulate network delay - setTimeout(() => { - // Return first 10 posts for initial load - resolve(mockRedditPosts.slice(0, 10)); - }, 500); - }); -} - -// For the real implementation, this would be replaced with an actual API call for more posts -function fetchMorePosts(currentCount) { - return new Promise((resolve) => { - // Simulate network delay - setTimeout(() => { - // Return next 10 posts - const start = currentCount; - const end = start + 10; - resolve(mockRedditPosts.slice(start, end)); - }, 500); - }); -} - +// Global variables let isLoading = false; -let currentPostCount = 10; +let currentPostCount = 0; function createPostElement(post) { const postElement = document.createElement("div"); @@ -128,7 +11,7 @@ function createPostElement(post) { imageContainer.className = "post-image-container"; const image = document.createElement("img"); - image.src = post.image; + image.src = post.image || "/Reddit_Logo.webp"; image.alt = post.title; image.className = "post-image"; image.loading = "lazy"; @@ -164,18 +47,57 @@ function renderPosts(posts) { }); } +// Fetch the initial 10 posts from our API +async function fetchRedditPosts() { + try { + const response = await fetch("/posts"); + if (!response.ok) { + throw new Error("Failed to fetch posts"); + } + const posts = await response.json(); + return posts; + } catch (error) { + console.error("Error fetching initial posts:", error); + // Return empty array on error + return []; + } +} + +// Fetch more posts from our API +async function fetchMorePosts(currentCount) { + try { + const response = await fetch(`/posts/more?count=${currentCount}`); + if (!response.ok) { + throw new Error("Failed to fetch more posts"); + } + const posts = await response.json(); + return posts; + } catch (error) { + console.error("Error fetching more posts:", error); + // Return empty array on error + return []; + } +} + async function loadInitialPosts() { try { const posts = await fetchRedditPosts(); renderPosts(posts); currentPostCount = posts.length; + + // Check if we have more posts or not + const totalResponse = await fetch("/posts/total"); + const totalData = await totalResponse.json(); + if (totalData.total <= 10) { + document.getElementById("no-more").classList.remove("hidden"); + } } catch (error) { console.error("Failed to load initial posts:", error); } } async function loadMorePosts() { - if (isLoading || currentPostCount >= mockRedditPosts.length) { + if (isLoading) { return; } @@ -208,11 +130,7 @@ function setupInfiniteScroll() { // Use Intersection Observer API for efficient infinite scrolling const observer = new IntersectionObserver( (entries) => { - if ( - entries[0].isIntersecting && - !isLoading && - currentPostCount < mockRedditPosts.length - ) { + if (entries[0].isIntersecting && !isLoading) { loadMorePosts(); } }, @@ -241,8 +159,7 @@ document.addEventListener("DOMContentLoaded", () => { if ( window.innerHeight + window.scrollY >= document.body.offsetHeight - 1000 && - !isLoading && - currentPostCount < mockRedditPosts.length + !isLoading ) { loadMorePosts(); }