From 607b1cd3973f8aeec60bd3f3ae37008e0efbfe0d Mon Sep 17 00:00:00 2001 From: JustIceO7 Date: Thu, 27 Feb 2025 04:48:21 +0000 Subject: [PATCH] FIX: Fixed infinite scrolling for all categories page --- frontend/src/pages/AllCategoriesPage.tsx | 82 +++++++++++------------- frontend/src/pages/CategoryPage.tsx | 14 ++-- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/frontend/src/pages/AllCategoriesPage.tsx b/frontend/src/pages/AllCategoriesPage.tsx index 6ad6689..1b082d6 100644 --- a/frontend/src/pages/AllCategoriesPage.tsx +++ b/frontend/src/pages/AllCategoriesPage.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, useEffect } from "react"; +import React, { useEffect, useState, useRef } from "react"; import { useNavigate } from "react-router-dom"; import ListRow from "../components/Layout/ListRow"; import DynamicPageContent from "../components/Layout/DynamicPageContent"; @@ -7,97 +7,93 @@ import LoadingScreen from "../components/Layout/LoadingScreen"; import { CategoryType } from "../types/CategoryType"; const AllCategoriesPage: React.FC = () => { + const [categories, setCategories] = useState([]); const navigate = useNavigate(); - const [allCategories, setAllCategories] = useState([]); const [categoryOffset, setCategoryOffset] = useState(0); + const [noCategories, setNoCategories] = useState(12); const [hasMoreData, setHasMoreData] = useState(true); - const [isLoading, setIsLoading] = useState(true); + const listRowRef = useRef(null); - + const isLoading = useRef(false); + const fetchCategories = async () => { - if (isLoading && categoryOffset > 0) return []; + // If already loading, skip this fetch + if (isLoading.current) return; + + isLoading.current = true; try { - console.log(`Fetching categories with offset: ${categoryOffset}`); - const response = await fetch( - `/api/categories/popular/12/${categoryOffset}` - ); - if (!response.ok) throw new Error("Failed to fetch categories"); - + const response = await fetch(`/api/categories/popular/${noCategories}/${categoryOffset}`); + if (!response.ok) { + throw new Error("Failed to fetch categories"); + } const data = await response.json(); - console.log("Categories fetched:", data.length); - + if (data.length === 0) { setHasMoreData(false); return []; } - setCategoryOffset(categoryOffset + data.length); + setCategoryOffset(prev => prev + data.length); - const newCategories = data.map((category: any) => ({ + const processedCategories = data.map((category: any) => ({ type: "category" as const, id: category.category_id, title: category.category_name, - viewers: category.num_viewers || 0, + viewers: category.num_viewers, thumbnail: `/images/category_thumbnails/${category.category_name .toLowerCase() .replace(/ /g, "_")}.webp`, })); - return newCategories; - } catch (err) { - console.error("Error fetching categories:", err); - setHasMoreData(false); + setCategories(prev => [...prev, ...processedCategories]); + return processedCategories; + } catch (error) { + console.error("Error fetching categories:", error); return []; } finally { - setIsLoading(false); + isLoading.current = false; } }; - // Initial load useEffect(() => { - const initialLoad = async () => { - const initialCategories = await fetchCategories(); - setAllCategories(initialCategories); - }; - - initialLoad(); + fetchCategories(); }, []); - const loadMoreCategories = async () => { - if (!hasMoreData || (isLoading && categoryOffset > 0)) return; - - const newCategories = await fetchCategories(); - if (newCategories.length > 0) { - setAllCategories(prev => [...prev, ...newCategories]); - if (listRowRef.current && listRowRef.current.addMoreItems) { + const loadOnScroll = async () => { + if (hasMoreData && listRowRef.current) { + const newCategories = await fetchCategories(); + if (newCategories?.length > 0) { listRowRef.current.addMoreItems(newCategories); } } }; - // Set up infinite scroll - fetchContentOnScroll(loadMoreCategories, hasMoreData); + fetchContentOnScroll(loadOnScroll, hasMoreData); + + if (hasMoreData && !categories.length) return ; const handleCategoryClick = (categoryName: string) => { + console.log(categoryName); navigate(`/category/${categoryName}`); }; - if (isLoading && allCategories.length === 0) return ; - return ( - + - {!hasMoreData && allCategories.length > 0 && ( + {!hasMoreData && !categories.length && (
No more categories to load
diff --git a/frontend/src/pages/CategoryPage.tsx b/frontend/src/pages/CategoryPage.tsx index a87ad07..a1af124 100644 --- a/frontend/src/pages/CategoryPage.tsx +++ b/frontend/src/pages/CategoryPage.tsx @@ -50,7 +50,7 @@ const CategoryPage: React.FC = () => { setStreamOffset((prev) => prev + data.length); - const processedStreams: StreamType[] = data.map((stream: any) => ({ + const processedStreams = data.map((stream: any) => ({ type: "stream", id: stream.user_id, title: stream.title, @@ -78,16 +78,16 @@ const CategoryPage: React.FC = () => { fetchCategoryStreams(); }, []); - const logOnScroll = async () => { + const loadOnScroll = async () => { if (hasMoreData && listRowRef.current) { - const newCategories = await fetchCategoryStreams(); - if (newCategories && newCategories.length > 0) { - listRowRef.current.addMoreItems(newCategories); + const newStreams = await fetchCategoryStreams(); + if (newStreams?.length > 0) { + listRowRef.current.addMoreItems(newStreams); } else console.log("No more data to fetch"); } }; - fetchContentOnScroll(logOnScroll, hasMoreData); + fetchContentOnScroll(loadOnScroll, hasMoreData); const handleStreamClick = (streamerName: string) => { window.location.href = `/${streamerName}`; @@ -99,6 +99,7 @@ const CategoryPage: React.FC = () => {
{ wrap={true} onItemClick={handleStreamClick} extraClasses="bg-[var(--recommend)]" + itemExtraClasses="w-[20vw]" > {isLoggedIn && (