UPDATE/REFACTOR: Change how VODs are accessed & loaded;

FIX: `isLive` -> `streamerIsLive`;
FIX: `Sidebar` profile pictures;
This commit is contained in:
Chris-1010
2025-03-06 22:44:08 +00:00
parent 9c44dfe598
commit b243191b2e
7 changed files with 28 additions and 59 deletions

View File

@@ -151,7 +151,7 @@ const VodListItem: React.FC<VodListItemProps> = ({
<div className="flex justify-evenly items-stretch rounded-b-lg">
<a
className="flex justify-around w-full h-full bg-black/50 hover:bg-black/80 p-2 mx-1 font-semibold rounded-full border border-transparent hover:border-white"
href={`/vods/${username}/${vod_id}.mp4`}
href={`/vod/${username}/${vod_id}.mp4`}
download={`${username}_vod_${vod_id}.mp4`}
>
<DownloadIcon />

View File

@@ -17,7 +17,7 @@ interface ListRowProps {
description?: string;
items: ItemType[];
wrap?: boolean;
onItemClick: (itemName: string) => void;
onItemClick: (itemName: string, username?: string) => void;
titleClickable?: boolean;
extraClasses?: string;
itemExtraClasses?: string;
@@ -185,8 +185,8 @@ const ListRow = forwardRef<ListRowRef, ListRowProps>((props, ref) => {
category_name={item.category_name}
length={item.length}
views={item.views}
thumbnail={item.thumbnail}
onItemClick={() => handleVodClick(item)}
thumbnail={`/vods/${item.username}/${item.vod_id}.png`}
onItemClick={() => onItemClick(item.username, item.vod_id.toString())}
extraClasses={itemExtraClasses}
variant={variant}
/>

View File

@@ -120,7 +120,7 @@ const Sidebar: React.FC<SideBarProps> = ({ extraClasses = "" }) => {
</div>
<div id="streamers-followed" className="flex flex-col flex-grow items-center">
<h2 className="border-b-2 border-t-2 w-[125%] text-2xl cursor-default mb-5">Streamers</h2>
<div className="flex flex-col flex-grow justify-evenly w-full">
<div className="flex flex-col flex-grow justify-start w-full">
{followedStreamers.map((streamer) => (
<div
key={`${sidebarId.current}-streamer-${streamer.username}`}
@@ -131,6 +131,10 @@ const Sidebar: React.FC<SideBarProps> = ({ extraClasses = "" }) => {
>
<img
src={`/user/${streamer.username}/profile_picture`}
onError={(e) => {
e.currentTarget.src = "/images/pfps/default.png";
e.currentTarget.onerror = null;
}}
alt={`${streamer.username}'s Profile`}
className="w-10 h-10 rounded-full object-cover"
/>

View File

@@ -7,7 +7,7 @@ import { ChatProvider } from "../../context/ChatContext";
const StreamerRoute: React.FC = () => {
const { streamerName } = useParams();
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isLive, setIsLive] = useState<boolean>(false);
const [streamerIsLive, setStreamerIsLive] = useState<boolean>(false);
const [streamId, setStreamId] = useState<number>(0);
const navigate = useNavigate();
@@ -16,11 +16,11 @@ const StreamerRoute: React.FC = () => {
try {
const response = await fetch(`/api/user/${streamerName}/status`);
const data = await response.json();
setIsLive(Boolean(data.is_live));
setStreamerIsLive(Boolean(data.is_live));
setStreamId(data.user_id);
} catch (error) {
console.error("Error checking stream status:", error);
setIsLive(false);
setStreamerIsLive(false);
} finally {
setIsLoading(false);
}
@@ -36,7 +36,7 @@ const StreamerRoute: React.FC = () => {
if (isLoading) return <LoadingScreen />;
if (isLive) {
if (streamerIsLive) {
return (
<ChatProvider>
<VideoPage streamerId={streamId} />

View File

@@ -10,18 +10,6 @@ interface VodsDashboardProps {
const VodsDashboard: React.FC<VodsDashboardProps> = ({ vods }) => {
const navigate = useNavigate();
const handleVodClick = (vodId: string) => {
if (vods.length > 0) {
navigate(`/stream/${vods[0].username}/vods/${vodId}`);
}
};
// Ensure each VOD has a hardcoded thumbnail path
const thumbnails = vods.map((vod) => ({
...vod,
thumbnail: `/vods/${vod.username}/${vod.vod_id}.png`,
}));
return (
<div className="w-full">
<h2 className="text-3xl font-bold text-white mb-6">Past Broadcasts</h2>
@@ -34,9 +22,9 @@ const VodsDashboard: React.FC<VodsDashboardProps> = ({ vods }) => {
<ListRow
type="vod"
variant="vodDashboard"
items={thumbnails} // Use modified VODs with hardcoded thumbnail
items={vods}
wrap={false}
onItemClick={handleVodClick}
onItemClick={(username, vodId) => navigate(`/vods/${username}/${vodId}`) }
extraClasses="bg-black/50"
itemExtraClasses="w-[20vw]"
/>

View File

@@ -6,7 +6,6 @@ import Button from "../components/Input/Button";
import DynamicPageContent from "../components/Layout/DynamicPageContent";
import LoadingScreen from "../components/Layout/LoadingScreen";
import Footer from "../components/Layout/Footer";
import { useAuth } from "../context/AuthContext";
const HomePage: React.FC = () => {
const { streams, isLoading: isLoadingStreams } = useStreams();
@@ -14,16 +13,8 @@ const HomePage: React.FC = () => {
const { vods, isLoading: isLoadingVods } = useVods();
const navigate = useNavigate();
if (isLoadingStreams || isLoadingCategories || isLoadingVods) return <LoadingScreen>Loading Content...</LoadingScreen>;
const thumbnails = vods.map((vod) => ({
...vod,
thumbnail: `/vods/${vod.username}/${vod.vod_id}.png`,
video: `/vods/${vod.username}/${vod.vod_id}.mp4`,
}));
return (
<DynamicPageContent navbarVariant="home" className="relative min-h-screen animate-moving_bg" contentClassName="pb-[12vh]">
{/* Streams Section */}
@@ -60,9 +51,9 @@ const HomePage: React.FC = () => {
type="vod"
title="Recent VODs"
description="Watch the latest recorded streams!"
items={thumbnails}
items={vods}
wrap={false}
onItemClick={() => null}
onItemClick={(username, vodId) => navigate(`/vods/${username}/${vodId}`) }
extraClasses="bg-black/50"
itemExtraClasses="w-[20vw]"
/>

View File

@@ -36,13 +36,6 @@ const UserPage: React.FC = () => {
const navigate = useNavigate();
const { streams } = useStreams(`/api/streams/${username}/data`);
const currentStream = streams[0];
console.log(vods)
const thumbnails = vods.map((vod) => ({
...vod,
thumbnail: `/vods/${vod.username}/${vod.vod_id}.png`,
}));
const fetchProfileData = useCallback(async () => {
try {
@@ -80,7 +73,7 @@ const UserPage: React.FC = () => {
if (response.ok) {
console.log("Success");
console.log(URL.createObjectURL(img))
console.log(URL.createObjectURL(img));
setProfilePicture(URL.createObjectURL(img));
}
} catch (error) {
@@ -130,7 +123,7 @@ const UserPage: React.FC = () => {
});
if (response.ok) {
setProfileData(prev => prev ? { ...prev, bio: editedBio } : undefined);
setProfileData((prev) => (prev ? { ...prev, bio: editedBio } : undefined));
setIsEditingBio(false);
}
} catch (error) {
@@ -166,7 +159,8 @@ const UserPage: React.FC = () => {
{/* Profile Picture */}
<div
className={`relative -top-[40px] sm:-top-[90px] w-[16vw] h-[16vw] sm:w-[20vw] sm:h-[20vw] max-w-[10em] max-h-[10em]
rounded-full flex-shrink-0 border-4 ${profileData.isLive ? "border-[#ff0000]" : "border-[var(--user-pfp-border)]"
rounded-full flex-shrink-0 border-4 ${
profileData.isLive ? "border-[#ff0000]" : "border-[var(--user-pfp-border)]"
} inset-0 z-20`}
style={{ boxShadow: "var(--user-pfp-border-shadow)" }}
>
@@ -189,7 +183,7 @@ const UserPage: React.FC = () => {
}}
alt={`${profileData.username}'s profile`}
className="sm:w-full h-full object-cover rounded-full group-hover:brightness-50 relative z-0 transition-all"
style={{ backgroundColor: 'white' }}
style={{ backgroundColor: "white" }}
/>
{/* If current user is the profile user then allow profile picture swap */}
@@ -283,10 +277,7 @@ const UserPage: React.FC = () => {
</div>
{/* Content Section */}
<div
id="content"
className="col-span-2 bg-[var(--user-contentBox)] rounded-lg p-6 flex flex-col items-center w-full"
>
<div id="content" className="col-span-2 bg-[var(--user-contentBox)] rounded-lg p-6 flex flex-col items-center w-full">
{/* Stream */}
{currentStream && (
<div className="mb-8 max-w-[500px] w-full">
@@ -295,7 +286,7 @@ const UserPage: React.FC = () => {
font-black mb-4 rounded-full text-center"
>
Currently Live!
</h2>
</h2>
<StreamListItem
id={profileData.id}
title={currentStream.title || ""}
@@ -312,14 +303,11 @@ const UserPage: React.FC = () => {
{/* VODs */}
{vods.length > 0 && (
<div>
<h2 className="text-2xl font-bold mb-4"></h2>
<ListRow
type="vod"
title={`Past Broadcasts (${vods.length})`}
items={thumbnails}
onItemClick={(vod) => {
console.log("VOD Clicked:", vod);
}}
items={vods}
onItemClick={(user, vodId) => handleNavigation(`/vods/${user}/${vodId}`)}
extraClasses="w-fit max-w-[40vw] py-0 mt-0"
amountForScroll={2}
itemExtraClasses="w-[15vw]"
@@ -342,14 +330,12 @@ const UserPage: React.FC = () => {
onMouseEnter={(e) => (e.currentTarget.style.boxShadow = "var(--follow-shadow)")}
onMouseLeave={(e) => (e.currentTarget.style.boxShadow = "none")}
>
<button className="text-[var(--follow-text)] whitespace-pre-wrap pointer-events-none">
Following
</button>
<button className="text-[var(--follow-text)] whitespace-pre-wrap pointer-events-none">Following</button>
</div>
<div
className="bg-[var(--user-follow-bg)] rounded-[1em] hover:scale-105 transition-all ease-in-out duration-300
flex items-center justify-center w-full p-4 content-start cursor-pointer"
onClick={() => handleNavigation(`/user/${username}/vods`)}
onClick={() => handleNavigation(`/vods/${username}`)}
onMouseEnter={(e) => (e.currentTarget.style.boxShadow = "var(--follow-shadow)")}
onMouseLeave={(e) => (e.currentTarget.style.boxShadow = "none")}
>