Skip to content
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Initial load 850-1000ms

### Metrics as of 4/14/2025

- Browser memory allocation is appropriate and doesn't increase over time with no activity after 72 hours.
- Memory rises with video play normally, falls back to baseline in under 2 min from watch page unmounting.
- Browser memory allocation is appropriate and doesn't increase over time with no activity.
- Memory rises with video play normally, falls back to above numbers in under 2 min from watch page unmounting
- ~42-72MB heap size depending on how much is cached by react query (depends on usage)
- 99% performance by Lighthouse
- 0.0 CLS
Expand Down
2 changes: 1 addition & 1 deletion dev-dist/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ define(['./workbox-f6195dc0'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "/index.html",
"revision": "0.417jg7a7vso"
"revision": "0.tj0tk14ldd"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), {
Expand Down
6 changes: 2 additions & 4 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ footer {

body {
background-color: black;

overflow-x: hidden;

}

Expand All @@ -128,9 +128,7 @@ header {

}

nav {
scrollbar-gutter: stable !important
}


.swiper {
width: 100%;
Expand Down
4 changes: 3 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import TextSkeleton from './components/loadingSkeletons/TextSkeleton.tsx';
import HistoryPageSkeleton from './components/loadingSkeletons/HistoryPageSkeleton.tsx';
import ScrollToTop from './components/helpers/ScrollToTop.tsx';

const TvUpcoming = lazy(() => import('./pages/tvPages/TvUpcoming.tsx'));
const MovieUpcoming = lazy(
() => import('./pages/moviePages/MovieUpcoming.tsx'),
);
const TvUpcoming = lazy(() => import('./pages/tvPages/TvUpcoming.tsx'));

const History = lazy(() => import('./pages/watchPages/History.tsx'));
const CastMemberDetail = lazy(
() => import('./pages/detailPages/CastMemberDetail.tsx'),
Expand Down Expand Up @@ -215,6 +216,7 @@ const router = createBrowserRouter([
</DelayedSuspense>
),
},

{
path: 'tv/:series_id',
element: (
Expand Down
5 changes: 3 additions & 2 deletions src/pages/FAQ.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ const FAQPage = () => {
const faqData = [
{
question: 'Do I have to pay anything to use your site?',
answer: 'BingeBox is 100% free. ',
answer:
'BingeBox is 100% free. We may start accepting donations in the future, strictly for your appreciation of the site, not the content.',
},
{
question: 'What about all these popups & redirects?',
answer:
"We aren't putting those on you, they come from the servers we link to that allow you to stream content. To some extent it is understandable that content providers need money coming in, but we can't always be sure that the popups are safe or appropriate. If you want to block the popups, the recommendations are as follows: 1) If you are on Safari IOS mobile, you can go into settings for Safari, and under advanced options, then feature flags, you can find a toggle to verify the window.open function. This will stop everything and some of your taps will appear to do nothing. This is the absolute most comprehensive approach. 2) On Chrome desktop, you can add poper blocker. 3) For Android, we think Firefox + uBlock is a good option. 4) Brave browser will help but on iOS it can't stop all the pop-ups and honestly isn't nearly as good as #1. 4) We are working on ad blocking options you will be able to opt into later.",
"We aren't putting those on you, they come from the servers we link to that allow you to stream content. To some extent it is understandable that content providers need money coming in, but we can't always be sure that the popups are safe or appropriate. If you want to block the popups, the recommendations are as follows: 1) If you are on Safari IOS mobile, you can go into settings for Safari, and under advanced options, then feature flags, you can find a toggle to verify the window.open function. This will stop almost everything (100% all redirects/popups on SOME servers) and some of your taps will appear to do nothing. This is the absolute most comprehensive approach. 2) On Chrome or Firefox desktop, you can add Poper Blocker. 3) For Android, we think Firefox + uBlock is a good option. 4) Brave browser is another option in \"Shields Up\" mode but on iOS it can't stop all the pop-ups & redirects and isn't nearly as good as #1. 4) We are working on ad blocking options you will be able to opt into later.",
},
{
question:
Expand Down
196 changes: 196 additions & 0 deletions src/pages/watchPages/AdFreeTestMovie.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { useParams } from 'react-router-dom';
import { useWatchDetails } from '../../hooks/useItemOrWatchDetail';
import WatchDescription from '../../components/WatchDescription';
import BackButton from '../../components/buttons/BackBtn';
import FullscreenBtn from '../../components/buttons/FullScreenBtn';
import ServerList from '../../components/lists/ServerList';
import { isIphoneSafari, isIPad } from '../../utils/helpers';
import serverData from '../../utils/data/servers.json';
import { useEffect, useState, useRef } from 'react';
import dayjs from 'dayjs';
import useDocumentTitle from '../../hooks/usePageTitles';
import { useStore } from '../../state/store';

const MovieAdFree = () => {
const { addToContinueWatchingMovie } = useStore();
const { movie_id } = useParams<{ movie_id: string }>();
const { data: movie } = useWatchDetails('movie', movie_id ?? '');
const { servers } = serverData;

const iframeRef = useRef<HTMLIFrameElement>(null);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
useDocumentTitle(
movie?.title
? `Watch ${movie?.title || 'Movie'} | BingeBox`
: 'Loading... | BingeBox',
);

const [isLoading, setIsLoading] = useState(false);
const [selectedServer, setSelectedServer] = useState(() => {
const lastSelectedServer = localStorage.getItem('lastSelectedServer');
return lastSelectedServer || servers[0].value;
});

useEffect(() => {
if (!movie) return;
// setTimeout(() => {
addToContinueWatchingMovie(
Number(movie_id),
'movie',
dayjs().unix(),
movie.title,
movie.backdrop_path,
movie.release_date,
movie.runtime,
);
// }, 180000);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [movie_id, movie]);

useEffect(() => {
let newURL = '';
switch (selectedServer) {
case 'vidsrc.xyz':
newURL = `https://bingebox-server-54dc60d03f7d.herokuapp.com/api/video/movie/${movie_id}`;
break;
case 'videasy.net':
newURL = `https://player.videasy.net/movie/${movie_id}`;
break;
case 'vidlink.pro':
newURL = `https://vidlink.pro/movie/${movie_id}`;
break;
case 'moviesapi.club':
newURL = `https://moviesapi.club/movie/${movie_id}`;
break;
case 'embed.su':
newURL = `https://embed.su/embed/movie/${movie_id}`;
break;
case 'nontongo.win':
newURL = `https://www.nontongo.win/embed/movie/${movie_id}`;
break;
case 'vidsrc.wtf':
newURL = `https://vidsrc.wtf/api/3/movie/?id=${movie_id}`;
break;
case 'vidsrc.wtf-ml':
newURL = `https://vidsrc.wtf/api/2/movie/?id=${movie_id}`;
break;
case '111movies.com':
newURL = ` https://111movies.com/movie/${movie_id}`;
break;
case 'vidfast.pro':
newURL = `https://vidfast.pro/movie/${movie_id}`;
break;
case 'superembed.stream':
newURL = ` https://multiembed.mov/directstream.php?video_id=${movie_id}&tmdb=1`;
break;
}

if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
setIsLoading(true);
if (iframeRef.current) {
iframeRef.current.contentWindow?.location.replace('about:blank');
}
setTimeout(() => {
iframeRef.current?.contentWindow?.location.replace(newURL);
timeoutRef.current = setTimeout(() => {
setIsLoading(false);
}, 750);
}, 300);

localStorage.setItem('lastSelectedServer', selectedServer);
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
}, [selectedServer, movie_id]);

return (
<div className='min-h-screen pt-[60px]'>
<div className='flex flex-col lg:flex-row lg:gap-[24px] p-[16px] lg:p-[24px] lg:max-w-[2200px] lg:mx-auto'>
<div className='relative primary flex-1 w-full lg:max-w-[calc(100%-424px)]'>
<div className='flex items-center justify-between text-xl mb-[16px] rounded-lg bg-[#1f1f1f] py-[12px] px-[16px]'>
<div>
<BackButton color='text-white' />
</div>
{movie && (
<p
className='font-bold truncate text-ellipsis mx-6'
title={movie.title}
>
{movie.title || ''}
</p>
)}
{/* iphone safari doesn't support the FS api */}
<div
className={`${isIphoneSafari() || isIPad()} ? 'invisible' : ''
}`}
>
<FullscreenBtn elementId='iframe' />
</div>
</div>
<main>
<div className='relative pt-[56.25%] w-full overflow-hidden mb-[24px] rounded-lg bg-[#1f1f1f] min-h-[300px]'>
<iframe
ref={iframeRef}
id='iframe'
className='absolute top-0 left-0 w-full h-full bg-black'
width='100%'
height='100%'
src={`/api/video/movie/${movie_id}`}
allow='encrypted-media'
sandbox='allow-scripts allow-same-origin'
referrerPolicy='no-referrer'
allowFullScreen
></iframe>
{isLoading && (
<div className='absolute inset-0 flex items-center justify-center bg-black bg-opacity-70 z-10'>
<div className='text-white text-center'>
<div className='inline-block w-8 h-8 border-4 border-t-blue-500 border-r-transparent border-b-blue-500 border-l-transparent rounded-full animate-spin mb-2'></div>
<p>
Loading{' '}
{
servers.find(
(server) => server.value === selectedServer,
)?.name
}
...{' '}
</p>
</div>
</div>
)}
</div>

{/* description */}
<div className='rounded-lg bg-[#1f1f1f] border-[#2f2f2f] p-[24px] mb-[24px]'>
{movie && (
<WatchDescription
title={movie?.title}
rt={movie?.runtime}
date={movie?.release_date}
overview={movie?.overview || 'No summary available'}
/>
)}
</div>
</main>
</div>
<div className='secondary lg:w-[400px] lg:flex-shrink-0 '>
{/* right side with server choices and episodes for tv*/}
<div className='sidebar bg-[#1f1f1f] max-h-[800px] flex flex-col rounded-lg'>
<ServerList
serverData={servers}
selectedServer={selectedServer}
setSelectedServer={setSelectedServer}
/>
</div>
</div>
</div>
</div>
);
};

export default MovieAdFree;
Loading