From cd19de3f023e95fedf4dd08acc25cab5ab033bea Mon Sep 17 00:00:00 2001 From: Son Nguyen Date: Tue, 14 May 2024 08:42:11 +0700 Subject: [PATCH] WIP: Fixed IMDB Ratings (#190) --- .../www/MovieVerse-Frontend/README.md | 10 +-- .../www/MovieVerse-Frontend/html/search.html | 2 +- .../MovieVerse-Frontend/js/movie-details.js | 83 ++++++++++++------- MovieVerse-Mobile/www/index.html | 3 +- MovieVerse-Mobile/www/index.js | 19 +++++ index.js | 1 + 6 files changed, 80 insertions(+), 38 deletions(-) diff --git a/MovieVerse-Mobile/www/MovieVerse-Frontend/README.md b/MovieVerse-Mobile/www/MovieVerse-Frontend/README.md index 25977334..e1a37968 100644 --- a/MovieVerse-Mobile/www/MovieVerse-Frontend/README.md +++ b/MovieVerse-Mobile/www/MovieVerse-Frontend/README.md @@ -6,7 +6,7 @@ Welcome to the MovieVerse app, your ultimate guide to the world of movies! This The MovieVerse app's `MovieVerse-Frontend` directory is organized into four primary directories: `css`, `html`, `js`, and `react`. Each directory contains specific files that contribute to the functionality and appearance of the app. Here's a detailed overview: -### CSS Directory +### CSS Directory - `css` This directory contains the Cascading Style Sheets (CSS) files responsible for the styling of the web pages. @@ -15,7 +15,7 @@ This directory contains the Cascading Style Sheets (CSS) files responsible for t - `discussions.css`: Styles specific to the discussions page. - `trivia.css`: Styles for the trivia section of the app. -### HTML Directory +### HTML Directory - `html` The HTML directory includes all the markup files necessary for the structure of the web pages. @@ -46,7 +46,7 @@ The HTML directory includes all the markup files necessary for the structure of - `404.html`: A 404 error page for when a page is not found. - `index.ejs`: The entry point for the app. -### JS Directory +### JS Directory - `js` The JavaScript directory contains scripts that add interactivity and functionality to the web pages. @@ -72,7 +72,7 @@ The JavaScript directory contains scripts that add interactivity and functionali - `single-spa-config.js`: Configuration file for the single-spa framework used in the app. - `systemjs-importmap.js`: Import map for the systemJS module loader. -### React Directory +### React Directory - `react` The React directory contains a collection of React components developed for the MovieVerse application. @@ -88,7 +88,7 @@ Please note that it is currently under development, and the components may under - `UserProfile.jsx`: Component for managing user profiles - `FeaturedMoviesCarousel.jsx`: Component for featured movies carousel -### Tests Directory +### Tests Directory - `tests` The tests directory contains a collection of test scripts for the MovieVerse application. These tests are designed to ensure that the app's functionality is working as expected and to identify any potential issues or bugs. diff --git a/MovieVerse-Mobile/www/MovieVerse-Frontend/html/search.html b/MovieVerse-Mobile/www/MovieVerse-Frontend/html/search.html index f57c1045..9eadcd60 100644 --- a/MovieVerse-Mobile/www/MovieVerse-Frontend/html/search.html +++ b/MovieVerse-Mobile/www/MovieVerse-Frontend/html/search.html @@ -820,7 +820,7 @@

Search Results

- Movie Trivia + Trivia diff --git a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/movie-details.js b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/movie-details.js index 2d685af5..df8c381e 100644 --- a/MovieVerse-Mobile/www/MovieVerse-Frontend/js/movie-details.js +++ b/MovieVerse-Mobile/www/MovieVerse-Frontend/js/movie-details.js @@ -818,46 +818,64 @@ function getRatingDetails(rating) { } async function fetchMovieRatings(imdbId, tmdbMovieData) { - const omdbCode = `${getMovieCode2()}`; - const omdb = `https://${getMovieActor()}/?i=${imdbId}&${getMovieName()}${omdbCode}`; - - try { - const response = await fetch(omdb); - const data = await response.json(); + const apiKeys = [ + await getMovieCode2(), + '58efe859', + '60a09d79', + '956e468a' + ]; - let imdbRating = data.imdbRating ? data.imdbRating : 'N/A'; + const baseURL = `https://${getMovieActor()}/?i=${imdbId}&${getMovieName()}`; - if (imdbRating === 'N/A' && tmdbMovieData.vote_average) { - imdbRating = (tmdbMovieData.vote_average / 2).toFixed(1) * 2; + async function tryFetch(apiKey) { + const url = `${baseURL}${apiKey}`; + try { + const response = await fetch(url); + if (!response.ok) throw new Error('API limit reached or other error'); + return await response.json(); + } catch (error) { + return null; } + } - const rtRatingObj = data.Ratings.find(rating => rating.Source === "Rotten Tomatoes"); - let rtRating = rtRatingObj ? rtRatingObj.Value : 'N/A'; + let data; + for (const key of apiKeys) { + data = await tryFetch(key); + if (data) break; + } - let metascore = data.Metascore ? `${data.Metascore}/100` : 'N/A'; - let awards = data.Awards; - let rated = data.Rated ? data.Rated : 'Rating information unavailable'; + if (!data) { + populateMovieDetails(tmdbMovieData, tmdbMovieData.vote_average, 'N/A', 'Metascore information unavailable, click to search on Metacritics', 'Awards information unavailable'); + return; + } - if (awards === 'N/A') { - awards = 'Awards information unavailable'; - } + let imdbRating = data.imdbRating ? data.imdbRating : 'N/A'; + if (imdbRating === 'N/A' || imdbRating === '0.0') { + imdbRating = 'N/A'; + } - if (metascore === 'N/A/100') { - const metacriticsRatingValue = imdbRating !== 'N/A' ? parseFloat(imdbRating) : (tmdbMovieData.vote_average / 2); - metascore = calculateFallbackMetacriticsRating(metacriticsRatingValue, tmdbMovieData.vote_average) + '/100'; - } + const rtRatingObj = data.Ratings.find(rating => rating.Source === "Rotten Tomatoes"); + let rtRating = rtRatingObj ? rtRatingObj.Value : 'N/A'; - if (rtRating === 'N/A') { - const imdbRatingValue = imdbRating !== 'N/A' ? parseFloat(imdbRating) : (tmdbMovieData.vote_average / 2); - rtRating = calculateFallbackRTRating(imdbRatingValue, tmdbMovieData.vote_average) - } + let metascore = data.Metascore ? `${data.Metascore}/100` : 'N/A'; + let awards = data.Awards; + let rated = data.Rated ? data.Rated : 'Rating information unavailable'; - populateMovieDetails(tmdbMovieData, imdbRating, rtRating, metascore, awards, rated); + if (awards === 'N/A') { + awards = 'Awards information unavailable'; } - catch (error) { - const fallbackImdbRating = (tmdbMovieData.vote_average / 2).toFixed(1) * 2; - populateMovieDetails(tmdbMovieData, fallbackImdbRating, 'N/A', 'Metascore information unavailable, click to search on Metacritics', 'Awards information unavailable'); + + if (metascore === 'N/A/100') { + const metacriticsRatingValue = imdbRating !== 'N/A' ? parseFloat(imdbRating) : (tmdbMovieData.vote_average / 2); + metascore = calculateFallbackMetacriticsRating(metacriticsRatingValue, tmdbMovieData.vote_average) + '/100'; + } + + if (rtRating === 'N/A') { + const imdbRatingValue = imdbRating !== 'N/A' ? parseFloat(imdbRating) : (tmdbMovieData.vote_average / 2); + rtRating = calculateFallbackRTRating(imdbRatingValue, tmdbMovieData.vote_average) } + + populateMovieDetails(tmdbMovieData, imdbRating, rtRating, metascore, awards, rated); } function updateBrowserURL(title) { @@ -1378,7 +1396,7 @@ async function populateMovieDetails(movie, imdbRating, rtRating, metascore, awar function createImdbRatingCircle(imdbRating, imdbId) { if (imdbRating === 'N/A' || imdbRating === null || imdbRating === undefined) { - imdbRating = 0; + imdbRating = 'N/A'; } let circleContainer = document.getElementById('imdbRatingCircleContainer'); @@ -1397,6 +1415,11 @@ function createImdbRatingCircle(imdbRating, imdbId) { ${imdbRating} `; + + if (imdbRating === 'N/A') { + circleContainer.innerHTML += `

Rating information currently unavailable

`; + } + document.getElementById('movie-description').appendChild(circleContainer); } else { diff --git a/MovieVerse-Mobile/www/index.html b/MovieVerse-Mobile/www/index.html index f9c8798b..558c963c 100644 --- a/MovieVerse-Mobile/www/index.html +++ b/MovieVerse-Mobile/www/index.html @@ -1574,7 +1574,6 @@

Timeless Classics: Trending Classic Movie searchInput.addEventListener('blur', clearSelection); }); - - + \ No newline at end of file diff --git a/MovieVerse-Mobile/www/index.js b/MovieVerse-Mobile/www/index.js index 69ce520c..0b913f5c 100644 --- a/MovieVerse-Mobile/www/index.js +++ b/MovieVerse-Mobile/www/index.js @@ -17,6 +17,7 @@ document.addEventListener('DOMContentLoaded', function() { const pagination = document.getElementById('most-popular-pagination'); const genresContainer = document.querySelector('.genres'); const mainContainer = document.getElementById('most-popular'); + function movePagination() { if (window.innerWidth <= 767) { mainContainer.parentNode.insertBefore(pagination, mainContainer); @@ -25,6 +26,7 @@ document.addEventListener('DOMContentLoaded', function() { genresContainer.appendChild(pagination); } } + movePagination(); window.addEventListener('resize', movePagination); }); @@ -81,9 +83,11 @@ document.addEventListener('DOMContentLoaded', function() { button.innerHTML = text; button.disabled = !enabled; button.className = 'nav-button'; + if (enabled) { button.onclick = clickHandler; } + return button; }; @@ -91,6 +95,7 @@ document.addEventListener('DOMContentLoaded', function() { const button = document.createElement('button'); button.textContent = pageNum; button.className = 'page-button'; + if (pageNum === '...') { button.disabled = true; } @@ -99,12 +104,14 @@ document.addEventListener('DOMContentLoaded', function() { currentPageMostPopular = pageNum; fetchAndUpdateMostPopular(); }; + if (pageNum === currentPageMostPopular) { button.classList.add('active'); } } return button; }; + fetchAndUpdateMostPopular(); }); @@ -227,6 +234,7 @@ function setupPagination(mainElementId, paginationContainerId, genresContainerId const button = document.createElement('button'); button.textContent = pageNum; button.className = 'page-button'; + if (pageNum === '...') { button.disabled = true; } @@ -255,6 +263,7 @@ async function fetchAndDisplayMovies(url, count, mainElement) { const response = await fetch(`${url}`); const data = await response.json(); const movies = data.results.slice(0, count); + movies.sort(() => Math.random() - 0.5); showMovies(movies, mainElement); } @@ -438,6 +447,7 @@ function updateFavoriteGenre(genre_ids) { function updateUniqueMoviesViewed(movieId) { let viewedMovies = JSON.parse(localStorage.getItem('uniqueMoviesViewed')) || []; + if (!viewedMovies.includes(movieId)) { viewedMovies.push(movieId); localStorage.setItem('uniqueMoviesViewed', JSON.stringify(viewedMovies)); @@ -452,6 +462,7 @@ async function ensureGenreMapIsAvailable() { async function fetchGenreMap() { const url = `https://${getMovieVerseData()}/3/genre/movie/list?${generateMovieNames()}${getMovieCode()}`; + try { const response = await fetch(url); const data = await response.json(); @@ -637,6 +648,7 @@ function getMostVisitedActor() { function getMostVisitedDirector() { const directorVisits = JSON.parse(localStorage.getItem('directorVisits')) || {}; + let mostVisitedDirector = ''; let maxVisits = 0; @@ -662,6 +674,7 @@ function getTriviaAccuracy() { function getMostCommonGenre() { const favoriteGenresArray = JSON.parse(localStorage.getItem('favoriteGenres')) || []; + const genreCounts = favoriteGenresArray.reduce((acc, genre) => { acc[genre] = (acc[genre] || 0) + 1; return acc; @@ -798,6 +811,7 @@ function adjustNavBar() { document.addEventListener('mousemove', function(event) { const sideNav = document.getElementById('side-nav'); + if (event.clientX < 10 && !sideNav.classList.contains('manual-toggle')) { sideNav.style.left = '0'; } @@ -806,6 +820,7 @@ document.addEventListener('mousemove', function(event) { document.addEventListener('click', function(event) { const sideNav = document.getElementById('side-nav'); const navToggle = document.getElementById('nav-toggle'); + if (!sideNav.contains(event.target) && !navToggle.contains(event.target) && sideNav.classList.contains('manual-toggle')) { sideNav.classList.remove('manual-toggle'); adjustNavBar(); @@ -869,6 +884,7 @@ setInterval(changeDirector, 3600000); function updateDirectorSpotlight() { const director = directors[currentDirectorIndex]; document.getElementById('spotlight-director-name').textContent = director.name; + const url = `https://${getMovieVerseData()}/3/discover/movie?${generateMovieNames()}${getMovieCode()}&with_people=${director.id}&sort_by=popularity.desc&sort_by=vote_average.desc`; getDirectorSpotlight(url); } @@ -890,6 +906,7 @@ async function getDirectorSpotlight(url) { const resp = await fetch(url); const respData = await resp.json(); let allMovies = []; + if (respData.results.length > 0) { allMovies = respData.results.slice(0, numberOfMovies); showMoviesDirectorSpotlight(allMovies); @@ -898,6 +915,7 @@ async function getDirectorSpotlight(url) { function showMoviesDirectorSpotlight(movies) { director_main.innerHTML = ''; + movies.forEach((movie) => { const { id, poster_path, title, vote_average, genre_ids } = movie; const movieEl = document.createElement('div'); @@ -946,6 +964,7 @@ function handleSignInOut() { window.location.href = 'MovieVerse-Frontend/html/sign-in.html'; return; } + updateSignInButtonState(); } diff --git a/index.js b/index.js index e9245610..0b913f5c 100644 --- a/index.js +++ b/index.js @@ -884,6 +884,7 @@ setInterval(changeDirector, 3600000); function updateDirectorSpotlight() { const director = directors[currentDirectorIndex]; document.getElementById('spotlight-director-name').textContent = director.name; + const url = `https://${getMovieVerseData()}/3/discover/movie?${generateMovieNames()}${getMovieCode()}&with_people=${director.id}&sort_by=popularity.desc&sort_by=vote_average.desc`; getDirectorSpotlight(url); }