JavaScript/HTML: Displaying Only 4 Videos in 'Continue Watching' Section Without Interfering with Other Cards

31 Views Asked by At

I'm facing a challenge in my JavaScript/HTML project where I want to display only four videos in the 'Continue Watching' section without affecting other video cards on the page. The current implementation interferes with non-'Continue Watching' videos when I limit the display to four. Looking for guidance on resolving this issue.

https://e4171bb3-9e7c-4e1f-bfa9-093c7adb1510-00-2yr904r2mq889.spock.replit.dev

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta
      name="description"
      content="MelliePlay - A Better Version of YouTube"
    />

    <!-- Open Graph Meta Tags -->
    <meta property="og:title" content="MelliePlay" />
    <meta
      property="og:description"
      content="Discover and enjoy amazing content on MelliePlay."
    />
    <meta property="og:image" content="url_to_thumbnail_image.jpg" />
    <meta property="og:url" content="url_to_your_site" />

    <!-- Google Font API -->
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css?family=YourChosenFont:300,400,500"
    />

    <!-- LottieFiles CDN -->
    <script src="https://cdn.lottiefiles.com/5.7.8/lottie.js"></script>

    <!-- XRegExp -->
    <script src="https://unpkg.com/[email protected]/xregexp-all.js"></script>

    <!-- Hammer.js -->
    <script src="https://unpkg.com/[email protected]/hammer.min.js"></script>

    <!-- Polymer Framework -->
    <script
      type="module"
      src="https://unpkg.com/@polymer/[email protected]/lib/polymer-element.js"
    ></script>
    <!-- Include other Polymer elements as needed -->

    <link rel="stylesheet" href="style.css" />
    <!-- Link to the external style.css file -->

    <title>MelliePlay</title>
  </head>
  <body>
    <!-- Top Bar -->
    <div id="header">
      <div id="menu-arrow" onclick="toggleSideMenu()">▶️</div>
      <a id="logo" href="https://e4171bb3-9e7c-4e1f-bfa9-093c7adb1510-00-2yr904r2mq889.spock.replit.dev/">MelliePlay</a>
      <div id="searchBox">
        <input class="searchInput" type="text" name="" placeholder="Search" />
        <button class="searchButton" href="#">
          <i class="material-icons">&#x1F50E;&#xFE0E;</i>
        </button>
      </div>
    </div>
    <div id="side-menu-overlay" onclick="closeSideMenu()">✖</div>
    <div id="side-menu">
      <div id="close-button" onclick="closeSideMenu()">✖</div>
      <ul>
          <li><a href="#">Home</a></li>
          <li><a href="yourchannrl.html"><svg class="svg-icon" viewBox="0 0 20 20">
              <path fill="none" d="M14.023,12.154c1.514-1.192,2.488-3.038,2.488-5.114c0-3.597-2.914-6.512-6.512-6.512
                c-3.597,0-6.512,2.916-6.512,6.512c0,2.076,0.975,3.922,2.489,5.114c-2.714,1.385-4.625,4.117-4.836,7.318h1.186
                c0.229-2.998,2.177-5.512,4.86-6.566c0.853,0.41,1.804,0.646,2.813,0.646c1.01,0,1.961-0.236,2.812-0.646
                c2.684,1.055,4.633,3.568,4.859,6.566h1.188C18.648,16.271,16.736,13.539,14.023,12.154z M10,12.367
                c-2.943,0-5.328-2.385-5.328-5.327c0-2.943,2.385-5.328,5.328-5.328c2.943,0,5.328,2.385,5.328,5.328
                C15.328,9.982,12.943,12.367,10,12.367z"></path>
            </svg>  Your channel</a></li>
          <li><a href="#">Item 3</a></li>
          <li><a href="#">Item 4</a></li>
          <li><a href="#">Item 5</a></li>
          <!-- Add more items as needed -->
      </ul>
    </div>
    <!-- Currently Playing Video -->
    <div id="continue-watching">
      <!-- Video Player Placeholder -->
      <div id="video-player">Continue Watching:</div>
      <!-- List of Last Four Videos -->
      <div class="video-card" onclick="playVideo('video4')">
        <img src="thumbnail0.jpg" alt="Video 4" class="video-thumbnail" />
        <div class="video-details">
          <div class="video-title">Video 4 Title</div>
          <div class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>
      <div class="video-card" onclick="playVideo('video3')">
        <img src="thumbnail0.jpg" alt="Video 3" class="video-thumbnail" />
        <div class="video-details">
          <div class="video-title">Video 3 Title</div>
          <div class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>
      <div class="video-card" onclick="playVideo('video2')">
        <img src="thumbnail0.jpg" alt="Video 2" class="video-thumbnail" />
        <div class="video-details">
          <div class="video-title">Video 2 Title</div>
          <div class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>
      <div class="video-card" onclick="playVideo('video1')">
        <img src="thumbnail1.jpg" alt="Video 1" class="video-thumbnail" />
        <div class="video-details">
          <div class="video-title">Video 1 Title</div>
          <div class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>
    </div>

    <hr
      style="
        width: 100%;
        margin: 0;
        border: none;
        height: 2px;
        background-color: #ccc;
      "
    />
    <!-- Video Container -->
    <div id="video-container">
      
      <!-- Video Card 1 -->
    <div class="video-card" onclick="playVideo('video1')" id="video-card-1">
      <a href="watch.html?videoId=video1">
     <img src="thumbnails/thumbnail1.jpg" alt="Video 1" id="video-thumbnail-video1" class="video-thumbnail"/>
  <div class="video-details">
    <div id="video-title-video1">Video Title Placeholder</div>
    <div id="video-description-video1" class="video-description">
      Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    </div>
  </div>
</div>

      <!-- Video Card 2 -->
      <div class="video-card" onclick="playVideo('video2')" id="video-card-2">
        <a href="watch.html?videoId=video2">
           <img src="thumbnails/thumbnail2.jpg" alt="Video 2" id="video-thumbnail-video2" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video2">Video Title Placeholder</div>
          <div id="video-description-video2" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>


      <!-- Video Card 3 -->
      <div class="video-card" onclick="playVideo('video3')" id="video-card-3">
        <a href="watch.html?videoId=video3">
           <img src="thumbnails/thumbnail3.jpg" alt="Video 3" id="video-thumbnail-video3" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video3">Video Title Placeholder</div>
          <div id="video-description-video3" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>


      <!-- Video Card 4 -->
      <div class="video-card" onclick="playVideo('video4')" id="video-card-4">
        <a href="watch.html?videoId=video4">
           <img src="thumbnails/thumbnail4.jpg" alt="Video 4" id="video-thumbnail-video4" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video4">Video Title Placeholder</div>
          <div id="video-description-video4" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>


      <!-- Video Card 5 -->
      <div class="video-card" onclick="playVideo('video5')" id="video-card-5">
        <a href="watch.html?videoId=video5">
           <img src="thumbnails/thumbnail5.jpg" alt="Video 5" id="video-thumbnail-video5" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video5">Video Title Placeholder</div>
          <div id="video-description-video5" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>


      <!-- Video Card 6 -->
      <div class="video-card" onclick="playVideo('video6')" id="video-card-6">
        <a href="watch.html?videoId=video6">
           <img src="thumbnails/thumbnail6.jpg" alt="Video 6" id="video-thumbnail-video6" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video6">Video Title Placeholder</div>
          <div id="video-description-video6" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>

      <!-- Video Card 7 -->
      <div class="video-card" onclick="playVideo('video7')" id="video-card-7">
        <a href="watch.html?videoId=video7">
           <img src="thumbnails/thumbnail6.jpg" alt="Video 7" id="video-thumbnail-video7" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video7">Video Title Placeholder</div>
          <div id="video-description-video7" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>

      <!-- Video Card 8 -->
      <div class="video-card" onclick="playVideo('video8')" id="video-card-8">
        <a href="watch.html?videoId=video8">
           <img src="thumbnails/thumbnail6.jpg" alt="Video 8" id="video-thumbnail-video8" class="video-thumbnail" />
        <div class="video-details">
          <div id="video-title-video8">Video Title Placeholder</div>
          <div id="video-description-video8" class="video-description">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          </div>
        </div>
      </div>

    </div>
      
    <script>
      let loaded = false;
      let currentPage = 1;
      const videosPerPage = 4; // Display only 4 videos
      let loadedVideos = [];
      let lastWatchedVideos = [];

      if (localStorage.getItem('lastWatchedVideos')) {
        lastWatchedVideos = JSON.parse(localStorage.getItem('lastWatchedVideos'));
      }

      function setDefaultInfo(videoId) {
        // Function to set default information if details are not available
        const videoTitle = document.getElementById(`video-title-${videoId}`);
        const videoDescription = document.getElementById(`video-description-${videoId}`);
        const videoThumbnail = document.getElementById(`video-thumbnail-${videoId}`);

        if (videoTitle && videoDescription && videoThumbnail) {
          videoTitle.innerText = "No Title Found";
          videoDescription.innerText = "No Description Found";

          videoThumbnail.src = `images/thumbnails/${videoId}.jpg`;
          videoThumbnail.alt = "Video Title";
          videoThumbnail.className = "video-thumbnail";

          console.log(`Default info set for video ${videoId}`);
        }
      }

      function playVideo(videoId) {
        if (!loaded) {
          const videoPlayer = document.getElementById('video-player');
          const videoTitle = document.getElementById(`video-title-${videoId}`);
          const videoDescription = document.getElementById(`video-description-${videoId}`);
          const videoThumbnail = document.getElementById(`video-thumbnail-${videoId}`);

          if (videoPlayer && videoTitle && videoDescription && videoThumbnail) {
            fetch(`details/${videoId}.json`)
              .then((response) => {
                if (!response.ok) {
                  throw new Error(`HTTP error! Status: ${response.status}`);
                }
                return response.json();
              })
              .then((data) => {
                console.log('Fetched data:', data);

                const { title, description, thumbnail, videoSrc } = data;

                if (videoSrc) {
                  videoPlayer.src = videoSrc;
                }

                videoTitle.innerText = title || 'No Title Found';
                videoDescription.innerText = description || 'No Description Found';
                videoThumbnail.src = thumbnail || `images/thumbnails/${videoId}.jpg`;

                loaded = true;
              })
              .catch((error) => {
                console.error('Error fetching video details:', error);
                setDefaultInfo(videoId);
              });
          } else {
            console.error(`One or more elements not found for video ${videoId}`);
          }
        } else {
          console.log(`Video ${videoId} clicked or loaded.`);
        }

        // Add the following lines to track the last four videos
        if (!lastWatchedVideos.includes(videoId)) {
          lastWatchedVideos.unshift(videoId); // Add to the beginning of the array
          if (lastWatchedVideos.length > 4) {
            lastWatchedVideos.pop(); // Remove the oldest video if the array size exceeds four
          }

          // Save updated lastWatchedVideos to localStorage
          localStorage.setItem('lastWatchedVideos', JSON.stringify(lastWatchedVideos));
        }

        // Update the "Continue Watching" section
        updateContinueWatching();
      }

      function updateContinueWatching() {
        const continueWatchingSection = document.getElementById('continue-watching');
        continueWatchingSection.innerHTML = '<div id="video-player">Continue Watching:</div>';

        // Display "No videos found" message if there are no last watched videos
        if (lastWatchedVideos.length === 0) {
          displayNoVideosMessage(continueWatchingSection);
          return;
        }

        // Slice the last four videos from the array
        const lastFourWatchedVideos = lastWatchedVideos.slice(0, 4);

        lastFourWatchedVideos.forEach((videoId) => {
          const videoCard = document.createElement('div');
          videoCard.classList.add('video-card');
          videoCard.onclick = () => playVideo(videoId);

          // Fetch details and populate the card as per your existing logic
          fetchVideoDetails(videoId).then((data) => {
            // Update the card content using data from the fetch
            // You can modify this part based on your existing logic
            const { title, description, thumbnail } = data;

            videoCard.innerHTML = `
              <img src="${thumbnail || `images/thumbnails/${videoId}.jpg`}" alt="Video ${videoId}" class="video-thumbnail" />
              <div class="video-details">
                <div class="video-title">${title || 'No Title Found'}</div>
                <div class="video-description">${description || 'No Description Found'}</div>
              </div>
            `;

            continueWatchingSection.appendChild(videoCard);
          });
        });
      }

      // Function to fetch video details
      function fetchVideoDetails(videoId) {
        return fetch(`details/${videoId}.json`)
          .then((response) => {
            if (!response.ok) {
              throw new Error(`HTTP error! Status: ${response.status}`);
            }
            return response.json();
          })
          .catch((error) => {
            console.error('Error fetching video details:', error);
            return {};
          });
      }

      // Ensure that the lastWatchedVideos array is updated on page load
      window.addEventListener('DOMContentLoaded', () => {
        if (loadedVideos.length === 0) {
          displayAllVideosMessage();
          updateContinueWatching();
        }
      });

      function loadVideos() {
        for (let i = 1; i <= videosPerPage; i++) {
          const videoIndex = (currentPage - 1) * videosPerPage + i;
          if (!loadedVideos.includes(videoIndex)) {
            playVideo(`video${videoIndex}`);
            loadedVideos.push(videoIndex);
          }
        }
      }

      function handleScroll() {
        const lastVideoCard = document.querySelector('.video-card:last-child');
        const lastCardOffset = lastVideoCard.offsetTop + lastVideoCard.clientHeight;
        const pageOffset = window.pageYOffset + window.innerHeight;

        if (pageOffset > lastCardOffset - 100 && !loaded) {
          loaded = true;
          loadVideos();
          currentPage++;
        }
      }

      function displayAllVideosMessage() {
        const videoContainer = document.getElementById('video-container');
        const message = document.createElement('p');
        message.innerText = 'All videos in our database are loaded! :p';
        videoContainer.appendChild(message);
      }

      // Check if all videos are loaded and display a message
      window.addEventListener('DOMContentLoaded', () => {
        if (loadedVideos.length === 0) {
          displayAllVideosMessage();
        }
      });

      function toggleSideMenu() {
        const sideMenuOverlay = document.getElementById('side-menu-overlay');
        const sideMenu = document.getElementById('side-menu');

        if (sideMenuOverlay.style.display === 'block' || sideMenu.style.display === 'block') {
          sideMenuOverlay.style.display = 'none';
          sideMenu.style.display = 'none';
        } else {
          sideMenuOverlay.style.display = 'block';
          sideMenu.style.display = 'block';
        }
      }

      function closeSideMenu() {
        const sideMenuOverlay = document.getElementById('side-menu-overlay');
        const sideMenu = document.getElementById('side-menu');

        sideMenuOverlay.style.display = 'none';
        sideMenu.style.display = 'none';
      }

      function displayNoVideosMessage(continueWatchingSection) {
        const message = document.createElement('p');
        message.innerText = 'No videos found!';
        continueWatchingSection.appendChild(message);
      }

      // Initial load of videos
      loadVideos();

      // Add scroll event listener
      window.addEventListener('scroll', handleScroll);
    </script>







   
  </body>
</html>

I attempted to modify the JavaScript code to limit the 'Continue Watching' section to display only four videos. I expected that this change would not interfere with the display of other non-'Continue Watching' video cards. However, the issue persists, and the adjustment seems to impact other video cards on the page. I just found out when i click on the 'Continue Watching' section it's then show 4 rather then 21 but the videos cards under it only show 4/8 which i dont want!

1

There are 1 best solutions below

0
Witch Of Greed On

The issue was caused by the loop that created and appended four video cards for the last four watched videos, including empty placeholders. The fix involved modifying the updateContinueWatching function to create only one video card for the last watched video and display it without any empty placeholders.

Here's a breakdown of the changes:

  1. Removed the loop that created four video cards and empty placeholders:

    const lastFourWatchedVideos = lastWatchedVideos.slice(0, 4);
    
    lastFourWatchedVideos.forEach((videoId) => {
      // existing code to create video cards
    });
    
    // existing code to add empty placeholders
    

    This loop was replaced with a single video card creation for the last watched video:

    if (lastWatchedVideos.length > 0) {
      const lastVideoId = lastWatchedVideos[0];
      const videoCard = document.createElement('div');
      videoCard.classList.add('video-card', 'continue-watching');
      videoCard.onclick = () => playVideo(lastVideoId);
    
      // existing code to fetch details and populate the card
    }
    
  2. Removed the loop that added empty placeholders separately:

    for (let i = 0; i < 4; i++) {
      const emptyPlaceholder = document.createElement('div');
      emptyPlaceholder.classList.add('video-card', 'continue-watching', 'empty-placeholder');
      continueWatchingSection.appendChild(emptyPlaceholder);
    }
    

    This loop was removed as it's not needed when we are displaying only one video card for the last watched video.

By making these changes, we ensure that only one video card is created for the last watched video, and no empty placeholders are added.