UPDATE: Add LoadingScreen component to maintain consistency
This commit is contained in:
@@ -10,11 +10,12 @@ import ResetPasswordPage from "./pages/ResetPasswordPage";
|
|||||||
import CategoryPage from "./pages/CategoryPage";
|
import CategoryPage from "./pages/CategoryPage";
|
||||||
import CategoriesPage from "./pages/AllCategoriesPage";
|
import CategoriesPage from "./pages/AllCategoriesPage";
|
||||||
import ResultsPage from "./pages/ResultsPage";
|
import ResultsPage from "./pages/ResultsPage";
|
||||||
import { SidebarProvider, useSidebar } from "./context/SidebarContext";
|
import { SidebarProvider } from "./context/SidebarContext";
|
||||||
import { QuickSettingsProvider } from "./context/QuickSettingsContext";
|
import { QuickSettingsProvider } from "./context/QuickSettingsContext";
|
||||||
import StreamDashboardPage from "./pages/StreamDashboardPage";
|
import StreamDashboardPage from "./pages/StreamDashboardPage";
|
||||||
import { Brightness } from "./context/BrightnessContext";
|
import { Brightness } from "./context/BrightnessContext";
|
||||||
import Sidebar from "./components/Navigation/Sidebar";
|
import Sidebar from "./components/Navigation/Sidebar";
|
||||||
|
import LoadingScreen from "./components/Layout/LoadingScreen";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||||
@@ -40,7 +41,7 @@ function App() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <div className="flex w-full h-full">Loading...</div>;
|
return <LoadingScreen />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
17
frontend/src/components/Layout/LoadingScreen.tsx
Normal file
17
frontend/src/components/Layout/LoadingScreen.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface LoadingScreenProps {
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoadingScreen: React.FC<LoadingScreenProps> = ({
|
||||||
|
children = "Loading...",
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen flex items-center justify-center text-white">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoadingScreen;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Sidebar as SidebarIcon } from "lucide-react";
|
import { Sidebar as SidebarIcon } from "lucide-react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useAuth } from "../../context/AuthContext";
|
import { useAuth } from "../../context/AuthContext";
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { useNavigate, useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import VideoPage from "../../pages/VideoPage";
|
import VideoPage from "../../pages/VideoPage";
|
||||||
|
import LoadingScreen from "../Layout/LoadingScreen";
|
||||||
|
|
||||||
const StreamerRoute: React.FC = () => {
|
const StreamerRoute: React.FC = () => {
|
||||||
const { streamerName } = useParams();
|
const { streamerName } = useParams();
|
||||||
@@ -32,13 +33,7 @@ const StreamerRoute: React.FC = () => {
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [streamerName]);
|
}, [streamerName]);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) return <LoadingScreen />;
|
||||||
return (
|
|
||||||
<div className="h-screen w-screen flex text-6xl items-center justify-center">
|
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// streamId=0 is a special case for the streamer's latest stream
|
// streamId=0 is a special case for the streamer's latest stream
|
||||||
if (isLive) {
|
if (isLive) {
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ export function ContentProvider({ children }: { children: React.ReactNode }) {
|
|||||||
const categoriesUrl = isLoggedIn
|
const categoriesUrl = isLoggedIn
|
||||||
? "/api/categories/recommended"
|
? "/api/categories/recommended"
|
||||||
: "/api/categories/popular/4";
|
: "/api/categories/popular/4";
|
||||||
|
console.log("Fetching categories from", categoriesUrl);
|
||||||
|
|
||||||
fetch(categoriesUrl)
|
fetch(categoriesUrl)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
@@ -86,6 +87,7 @@ export function ContentProvider({ children }: { children: React.ReactNode }) {
|
|||||||
.replace(/ /g, "_")}.webp`,
|
.replace(/ /g, "_")}.webp`,
|
||||||
}));
|
}));
|
||||||
setCategories(processedCategories);
|
setCategories(processedCategories);
|
||||||
|
console.log("Categories fetched", processedCategories);
|
||||||
});
|
});
|
||||||
}, [isLoggedIn]);
|
}, [isLoggedIn]);
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import React, {
|
|||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { io, Socket } from "socket.io-client";
|
import { io, Socket } from "socket.io-client";
|
||||||
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
||||||
|
|
||||||
interface SocketContextType {
|
interface SocketContextType {
|
||||||
socket: Socket | null;
|
socket: Socket | null;
|
||||||
@@ -86,13 +87,7 @@ export const SocketProvider: React.FC<{ children: React.ReactNode }> = ({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) return <LoadingScreen>Connecting to Socket...</LoadingScreen>;
|
||||||
return (
|
|
||||||
<div className="h-screen w-screen flex items-center justify-center">
|
|
||||||
<div className="text-4xl text-white">Connecting to socket...</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SocketContext.Provider value={{ socket, isConnected }}>
|
<SocketContext.Provider value={{ socket, isConnected }}>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import ListRow from "../components/Layout/ListRow";
|
import ListRow from "../components/Layout/ListRow";
|
||||||
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
||||||
import { fetchContentOnScroll } from "../hooks/fetchContentOnScroll";
|
import { fetchContentOnScroll } from "../hooks/fetchContentOnScroll";
|
||||||
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
||||||
|
|
||||||
interface categoryData {
|
interface categoryData {
|
||||||
type: "category";
|
type: "category";
|
||||||
@@ -78,13 +79,7 @@ const AllCategoriesPage: React.FC = () => {
|
|||||||
|
|
||||||
fetchContentOnScroll(loadOnScroll, hasMoreData);
|
fetchContentOnScroll(loadOnScroll, hasMoreData);
|
||||||
|
|
||||||
if (hasMoreData && !categories.length) {
|
if (hasMoreData && !categories.length) return <LoadingScreen />;
|
||||||
return (
|
|
||||||
<div className="h-screen w-screen flex items-center justify-center text-white">
|
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleCategoryClick = (categoryName: string) => {
|
const handleCategoryClick = (categoryName: string) => {
|
||||||
console.log(categoryName);
|
console.log(categoryName);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import Button from "../components/Input/Button";
|
|||||||
import { useAuth } from "../context/AuthContext";
|
import { useAuth } from "../context/AuthContext";
|
||||||
import { useCategoryFollow } from "../hooks/useCategoryFollow";
|
import { useCategoryFollow } from "../hooks/useCategoryFollow";
|
||||||
import { ListItemProps as StreamData } from "../components/Layout/ListItem";
|
import { ListItemProps as StreamData } from "../components/Layout/ListItem";
|
||||||
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
||||||
|
|
||||||
const CategoryPage: React.FC = () => {
|
const CategoryPage: React.FC = () => {
|
||||||
const { categoryName } = useParams<{ categoryName: string }>();
|
const { categoryName } = useParams<{ categoryName: string }>();
|
||||||
@@ -92,13 +93,7 @@ const CategoryPage: React.FC = () => {
|
|||||||
window.location.href = `/${streamerName}`;
|
window.location.href = `/${streamerName}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (hasMoreData && !streams.length) {
|
if (hasMoreData && !streams.length) return <LoadingScreen />;
|
||||||
return (
|
|
||||||
<div className="h-screen w-screen flex items-center justify-center text-white">
|
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DynamicPageContent className="min-h-screen bg-gradient-radial from-[#ff00f1] via-[#0400ff] to-[#ff0000] bg-[url(/images/background-pattern.svg)]">
|
<DynamicPageContent className="min-h-screen bg-gradient-radial from-[#ff00f1] via-[#0400ff] to-[#ff0000] bg-[url(/images/background-pattern.svg)]">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { useStreams, useCategories } from "../context/ContentContext";
|
import { useStreams, useCategories } from "../context/ContentContext";
|
||||||
import Button from "../components/Input/Button";
|
import Button from "../components/Input/Button";
|
||||||
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
||||||
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
||||||
|
|
||||||
interface HomePageProps {
|
interface HomePageProps {
|
||||||
variant?: "default" | "personalised";
|
variant?: "default" | "personalised";
|
||||||
@@ -23,7 +24,7 @@ const HomePage: React.FC<HomePageProps> = ({ variant = "default" }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!categories || categories.length === 0) {
|
if (!categories || categories.length === 0) {
|
||||||
return <div>Loading categories...</div>;
|
return <LoadingScreen>Loading Categories...</LoadingScreen>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { useFollow } from "../hooks/useFollow";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import Button, { EditButton } from "../components/Input/Button";
|
import Button, { EditButton } from "../components/Input/Button";
|
||||||
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
||||||
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
||||||
|
|
||||||
interface UserProfileData {
|
interface UserProfileData {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -100,13 +101,8 @@ const UserPage: React.FC = () => {
|
|||||||
if (loggedInUsername && username) checkFollowStatus(username);
|
if (loggedInUsername && username) checkFollowStatus(username);
|
||||||
}, [username]);
|
}, [username]);
|
||||||
|
|
||||||
if (!profileData) {
|
if (!profileData) return <LoadingScreen />;
|
||||||
return (
|
|
||||||
<div className="h-screen w-screen flex items-center justify-center text-white">
|
|
||||||
Loading...
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<DynamicPageContent
|
<DynamicPageContent
|
||||||
className={`min-h-screen ${
|
className={`min-h-screen ${
|
||||||
@@ -226,7 +222,7 @@ const UserPage: React.FC = () => {
|
|||||||
id={profileData.id}
|
id={profileData.id}
|
||||||
type="stream"
|
type="stream"
|
||||||
title={profileData.currentStreamTitle || ""}
|
title={profileData.currentStreamTitle || ""}
|
||||||
streamer=""
|
username=""
|
||||||
viewers={profileData.currentStreamViewers || 0}
|
viewers={profileData.currentStreamViewers || 0}
|
||||||
thumbnail={profileData.currentStreamThumbnail}
|
thumbnail={profileData.currentStreamThumbnail}
|
||||||
onItemClick={() => {
|
onItemClick={() => {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const VideoPage: React.FC<VideoPageProps> = ({ streamerId }) => {
|
|||||||
const { showAuthModal, setShowAuthModal } = useAuthModal();
|
const { showAuthModal, setShowAuthModal } = useAuthModal();
|
||||||
const [isStripeReady, setIsStripeReady] = useState(false);
|
const [isStripeReady, setIsStripeReady] = useState(false);
|
||||||
const [showCheckout, setShowCheckout] = useState(false);
|
const [showCheckout, setShowCheckout] = useState(false);
|
||||||
const showReturn = window.location.search.includes("session_id");
|
// const showReturn = window.location.search.includes("session_id"); //! Not used
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [isSubscribed, setIsSubscribed] = useState(false);
|
const [isSubscribed, setIsSubscribed] = useState(false);
|
||||||
const [timeStarted, setTimeStarted] = useState("");
|
const [timeStarted, setTimeStarted] = useState("");
|
||||||
|
|||||||
Reference in New Issue
Block a user