diff --git a/css/app.js b/css/app.js index 8780a9f8..f1005283 100644 --- a/css/app.js +++ b/css/app.js @@ -11,50 +11,52 @@ video.addEventListener('volumechange', function() { }); // Get the progress bar and container elements -const progressBar1 = document.querySelector(".progress-bar"); -const progressContainer1 = document.querySelector(".progress-container"); +const progressBar = document.querySelector(".progress-bar"); +const progressContainer = document.querySelector(".progress-container"); // Set the initial width of the progress bar to 0% -progressBar1.style.width = "0%"; -progressContainer1.style.display = 'block'; +progressBar.style.width = "0%"; +progressContainer.style.display = 'block'; // Attach an event listener to the window object to listen for the 'load' event window.addEventListener("load", () => { - progressBar1.style.width = "100%"; + progressBar.style.width = "100%"; setTimeout(() => { - progressContainer1.style.display = 'none'; + progressContainer.style.display = 'none'; }, 500); }); - + +// Lazy load background images document.addEventListener('DOMContentLoaded', function() { -let bgs = document.querySelectorAll('[data-bg]'); -let bgCount = bgs.length; - -function loadBg(index) { - let bg = bgs[index]; -let bgUrl = bg.getAttribute('data-bg'); - bg.style.backgroundImage = `url(${bgUrl})`; + const bgs = document.querySelectorAll('[data-bg]'); + let bgCount = bgs.length; + + function loadBg(index) { + const bg = bgs[index]; + const bgUrl = bg.getAttribute('data-bg'); + bg.style.backgroundImage = `url(${bgUrl})`; bg.removeAttribute('data-bg'); bg.classList.add('loaded'); } function lazyLoadBg() { for (let i = 0; i < bgCount; i++) { - let bg = bgs[i]; - let bgRect = bg.getBoundingClientRect(); + const bg = bgs[i]; + const bgRect = bg.getBoundingClientRect(); if (bgRect.top < window.innerHeight && bgRect.bottom > 0) { loadBg(i); } } } - + lazyLoadBg(); - + window.addEventListener('scroll', lazyLoadBg); window.addEventListener('resize', lazyLoadBg); }); - - const fadeInElements = () => { + +// Fade in elements on scroll or fullscreen change +function fadeInElements() { const elements = document.querySelectorAll('.fade-in'); const viewportHeight = window.innerHeight; elements.forEach(element => { @@ -65,42 +67,24 @@ let bgUrl = bg.getAttribute('data-bg'); element.classList.add('fade-in-active'); } }); -}; - -fadeInElements(); +} window.addEventListener('scroll', fadeInElements); - -document.addEventListener('fullscreenchange', () => { - fadeInElements(); -}); - +document.addEventListener('fullscreenchange', fadeInElements); setInterval(fadeInElements, 500); - -// Get all anchor links on the page except for links with "jump_to_time" onclick attribute +// Handle click events on links const links = document.querySelectorAll('a:not([data-onclick="jump_to_time"])'); - -// Add a click event listener to each link links.forEach(link => { link.addEventListener('click', e => { - // Check if the link's href includes a hash character if (!link.href.includes('#')) { - e.preventDefault(); // Prevent the default link behavior - - // Create a loading spinner element + e.preventDefault(); const spinner = document.createElement('div'); spinner.classList.add('spinner'); - - // Create a loading overlay element const loading = document.createElement('div'); loading.classList.add('loading'); loading.appendChild(spinner); - - // Add the loading overlay to the body document.body.appendChild(loading); - - // Redirect to the link after a short delay to show the loading overlay setTimeout(() => { window.location.href = link.href; }, 100); @@ -108,35 +92,13 @@ links.forEach(link => { }); }); - -const a = document.querySelectorAll('a[data-onclick="jump_to_time"]'); - -function jumpToTime(e) { - e.preventDefault(); - - const link = e.target; - const video = document.getElementById('video'); - const time = link.dataset.jumpTime; - - video.currentTime = time; - - window.location.hash = 'top'; // Add #video to the URL - - setTimeout(() => { - history.replaceState(null, null, ' '); // Remove #video after 1 second - }, 250); -} - -a.forEach(link => { +// Handle click events for time-based links +const timeLinks = document.querySelectorAll('a[data-onclick="jump_to_time"]'); +timeLinks.forEach(link => { const href = link.getAttribute('href'); - if (link.dataset.jumpTime) { - link.removeAttribute('href'); - } - - if (href && href.includes('&t=')) { + if (link.dataset.jumpTime && href && href.includes('&t=')) { const params = new URLSearchParams(href.split('?')[1]); const time = params.get('t'); - if (time) { link.dataset.jumpTime = time; link.addEventListener('click', jumpToTime); @@ -145,33 +107,26 @@ a.forEach(link => { } }); - -const urls = document.querySelectorAll('a[href*="/watch?v="]'); // get all links with "/watch?v=" in href attribute - +// Fetch URLs and handle progress saving +const urls = document.querySelectorAll('a[href*="/watch?v="]'); const spinner = document.createElement('div'); spinner.id = 'fetch-spinner'; spinner.classList.add('hide'); document.body.appendChild(spinner); - const text = document.createElement('div'); text.id = 'fetch-text'; - text.classList.add('hide'); +text.classList.add('hide'); document.body.appendChild(text); - document.body.classList.add('blur'); +document.body.classList.add('blur'); let fetchedCount = 0; urls.forEach(link => { const url = new URL(link.href); - - if (url.host !== 'www.youtube.com' && url.host !== 'youtube.com') { - if (url.host !== "redirect.poketube.fun") { - + if (url.host !== 'www.youtube.com' && url.host !== 'youtube.com' && url.host !== "redirect.poketube.fun") { console.log(`Fetching ${url.origin}`); - spinner.classList.remove('hide'); text.classList.remove('hide'); - fetch(url.href) .then(response => { if (response.status === 500) { @@ -180,31 +135,24 @@ urls.forEach(link => { console.log(`Fetched ${url.origin}`); fetchedCount++; console.clear() - if (fetchedCount === urls.length) { spinner.classList.add('hide'); text.classList.add('hide'); - document.body.classList.remove('blur'); + document.body.classList.remove('blur'); } - // Do something with the response }) .catch(error => { spinner.classList.add('hide'); text.classList.add('hide'); - console.clear() - // Ignore network errors + console.clear() if (!(error instanceof TypeError && error.message.includes('Failed to fetch'))) { console.error(`Error fetching ${url.origin}: ${error}`); } - }); } - } - }); -console.clear() - +// Save and resume video progress const videoId = new URLSearchParams(window.location.search).get('v'); const localStorageKey = `progress-${videoId}`; @@ -224,7 +172,7 @@ function resumeProgress() { } video.addEventListener('timeupdate', () => { - if (Math.floor(video.currentTime) % 1 === 0) { // save progress every 1 second + if (Math.floor(video.currentTime) % 1 === 0) { saveProgress(); } }); @@ -237,33 +185,20 @@ window.addEventListener('load', () => { resumeProgress(); }); - +// Adjust video element style on fullscreen change const videoElement = document.getElementById("video"); - -// Listen for full screen change events on the video element videoElement.addEventListener("fullscreenchange", () => { - if (document.fullscreenElement === videoElement) { - // If the video element is in full screen mode, remove the border radius - videoElement.style.borderRadius = "0em "; - } else { - // If the video element exits full screen mode, restore the border radius - videoElement.style.borderRadius = "16px"; - } - }); - - -const chnlurl = document.querySelectorAll('a[href*="/channel?id="]'); // get all links with "/watch?v=" in href attribute + videoElement.style.borderRadius = document.fullscreenElement === videoElement ? "0em" : "16px"; +}); +// Fetch channel URLs +const channelUrls = document.querySelectorAll('a[href*="/channel?id="]'); let fetchedCountChannel = 0; -chnlurl.forEach(link => { +channelUrls.forEach(link => { const url = new URL(link.href); - - if (url.host !== 'www.youtube.com' && url.host !== 'youtube.com') { - if (url.host !== "redirect.poketube.fun") { - + if (url.host !== 'www.youtube.com' && url.host !== 'youtube.com' && url.host !== "redirect.poketube.fun") { console.log(`Fetching ${url.origin}`); - fetch(url.href) .then(response => { if (response.status === 500) { @@ -272,25 +207,39 @@ chnlurl.forEach(link => { console.log(`Fetched ${url.origin}`); fetchedCountChannel++; console.clear() - - if (fetchedCountChannel === chnlurl.length) { - - document.body.classList.remove('blur'); + if (fetchedCountChannel === channelUrls.length) { + document.body.classList.remove('blur'); } - // Do something with the response }) .catch(error => { - - console.clear() - // Ignore network errors + console.clear() if (!(error instanceof TypeError && error.message.includes('Failed to fetch'))) { console.error(`Error fetching ${url.origin}: ${error}`); } - }); } - } - }); -// @license-end +// Fetch download URLs +const downloadUrls = document.querySelectorAll('a[href*="/download?v="]'); +downloadUrls.forEach(link => { + const url = new URL(link.href); + if (url.host !== 'www.youtube.com' && url.host !== 'youtube.com' && url.host !== "redirect.poketube.fun") { + console.log(`Fetching ${url.origin}`); + fetch(url.href) + .then(response => { + if (response.status === 500) { + // do nothing + } + console.log(`Fetched ${url.origin}`); + console.clear() + }) + .catch(error => { + console.clear() + if (!(error instanceof TypeError && error.message.includes('Failed to fetch'))) { + console.error(`Error fetching ${url.origin}: ${error}`); + } + }); + } +}); +// @license-end \ No newline at end of file