Skip to content

Commit

Permalink
Merge pull request #291 from NymexData/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
felipealfonsog authored Aug 25, 2023
2 parents da6cad1 + 3007c0b commit fae57e0
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 63 deletions.
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Theaterflix Extension",
"version": "1.1.2",
"version": "1.1.3",
"description": "Extension to display personalized worldwide recommendations for movies and series.",
"action": {
"default_popup": "popup/index.html"
Expand Down
8 changes: 7 additions & 1 deletion popup/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ <h1>Theaterflix Extension</h1>
<p>Explore a world of personalized movie and TV show recommendations! Our extension harnesses TMDb's vast database
to deliver tailored content, enhancing your entertainment journey with seamless suggestions!</p>
</div>
Search: <input type="text" id="search-input" placeholder="Search for movies and shows...">

<br>
<br>


<div id="recommendations-list">
<!-- Recommendations will be displayed here -->
<!-- Recommendations and search results will be displayed here -->
</div>


<!-- Load More button -->
<button id="load-more-button" class="button" style="display: none;">Load More</button>
Expand Down
219 changes: 158 additions & 61 deletions popup/popup.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,142 @@
document.addEventListener('DOMContentLoaded', () => {
const saveButton = document.getElementById('save-button');
const apiKeyInput = document.getElementById('api-key');
const statusMessage = document.getElementById('status-message');
const loadMoreButton = document.getElementById('load-more-button');
const recommendationsList = document.getElementById('recommendations-list');
const configSection = document.getElementById('config-section');
const refreshButton = document.getElementById('refresh-button');

let apiKey = '';
document.addEventListener("DOMContentLoaded", () => {
const saveButton = document.getElementById("save-button");
const apiKeyInput = document.getElementById("api-key");
const statusMessage = document.getElementById("status-message");
const loadMoreButton = document.getElementById("load-more-button");
const recommendationsList = document.getElementById("recommendations-list");
const configSection = document.getElementById("config-section");
const refreshButton = document.getElementById("refresh-button");

const searchInput = document.getElementById("search-input");
let searchTimeout;

configSection.classList.add("inactive");

let apiKey = "";
let page = 1;
const moviesPerPage = 20;
let movieRecommendations = [];

let searchResults = [];

const defaultMoviesPerPage = 20;
let currentMoviesPerPage = defaultMoviesPerPage;

searchInput.addEventListener("input", () => {
clearTimeout(searchTimeout);
const searchTerm = searchInput.value.toLowerCase();

searchTimeout = setTimeout(async () => {
if (searchTerm === "") {
currentMoviesPerPage = defaultMoviesPerPage;
renderMovieRecommendations();
searchResults = [];
loadMoreButton.style.display = "block";
} else {
try {
searchResults = await fetchSearchResults(searchTerm);
renderMovieRecommendations(searchResults);
loadMoreButton.style.display = "block";
} catch (error) {
console.error("Error fetching search results:", error);
}
}
}, 500);
});

const accordionHeader = document.querySelector('.accordion-header');
accordionHeader.addEventListener('click', () => {
configSection.classList.toggle('active');
const accordionHeader = document.querySelector(".accordion-header");
accordionHeader.addEventListener("click", () => {
configSection.classList.toggle("active");
configSection.classList.toggle("inactive");
});

apiKeyInput.addEventListener('input', (event) => {
apiKeyInput.addEventListener("input", (event) => {
apiKey = event.target.value.trim();
validateApiKey(apiKey);
});

saveButton.addEventListener('click', () => {
saveButton.addEventListener("click", () => {
if (!apiKey) {
statusMessage.textContent = 'Please enter a valid API Key.';
statusMessage.textContent = "Please enter a valid API Key.";
return;
}

if (!isValidApiKey(apiKey)) {
statusMessage.textContent = 'Please enter a valid API Key (letters and numbers only, no spaces).';
statusMessage.textContent =
"Please enter a valid API Key (letters and numbers only, no spaces).";
return;
}

localStorage.setItem('tmdb_api_key', apiKey);
statusMessage.textContent = 'API Key saved successfully!';
localStorage.setItem("tmdb_api_key", apiKey);
statusMessage.textContent = "API Key saved successfully!";
refreshRecommendations();
});

loadMoreButton.addEventListener('click', () => {
loadMoreRecommendations();
loadMoreButton.addEventListener("click", () => {
if (searchResults.length > 0) {
loadMoreSearchResults();
} else {
loadMoreRecommendations();
}
});

refreshButton.addEventListener('click', () => {
refreshButton.addEventListener("click", () => {
refreshRecommendations();
});

async function fetchSearchResults(searchTerm) {
if (!apiKey) {
throw new Error("API Key is required to fetch search results.");
}

try {
const response = await axios.get(
`https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&query=${searchTerm}`
);
return response.data.results;
} catch (error) {
console.error("Error fetching search results:", error);
throw error;
}
}

function renderSearchResults(searchResults) {
recommendationsList.innerHTML = "";

searchResults.forEach((movie) => {
const movieBox = document.createElement("div");
movieBox.className = "movie-box";

recommendationsList.appendChild(movieBox);
});
}

async function refreshRecommendations() {
if (!apiKey) {
statusMessage.textContent = 'Please enter a valid API Key before refreshing recommendations.';
statusMessage.textContent =
"Please enter a valid API Key before refreshing recommendations.";
return;
}

page = 1; // Reset page number on refresh
page = 1;

try {
const recommendations = await fetchMovieRecommendations();
movieRecommendations = recommendations;
renderMovieRecommendations();
loadMoreButton.style.display = 'block';
loadMoreButton.style.display = "block"; // Muestra el botón Load More
} catch (error) {
console.error('Error fetching movie recommendations:', error);
statusMessage.textContent = 'Error fetching movie recommendations. Please try again later.';
console.error("Error fetching movie recommendations:", error);
statusMessage.textContent =
"Error fetching movie recommendations. Please try again later.";
}
}

async function loadMoreRecommendations() {
configSection.classList.add("inactive");
if (!apiKey) {
statusMessage.textContent = 'Please enter a valid API Key before loading more recommendations.';
statusMessage.textContent =
"Please enter a valid API Key before loading more recommendations.";
return;
}

Expand All @@ -77,16 +145,37 @@ document.addEventListener('DOMContentLoaded', () => {
const recommendations = await fetchMovieRecommendations();
movieRecommendations.push(...recommendations);
renderMovieRecommendations();
loadMoreButton.style.display = 'block';
loadMoreButton.style.display = "block";
} catch (error) {
console.error('Error fetching movie recommendations:', error);
statusMessage.textContent = 'Error fetching movie recommendations. Please try again later.';
console.error("Error fetching movie recommendations:", error);
statusMessage.textContent =
"Error fetching movie recommendations. Please try again later.";
}
}

async function loadMoreSearchResults() {
page++;
loadMoreButton.style.display = "block";
try {
const additionalResults = await fetchSearchResults(
searchInput.value.toLowerCase(),
page
);

if (additionalResults.length > 0) {
searchResults.push(...additionalResults);
renderMovieRecommendations(searchResults);
}
} catch (error) {
console.error("Error fetching search results:", error);
}
}

async function fetchMovieRecommendations() {
try {
const response = await axios.get(`https://api.themoviedb.org/3/movie/popular?api_key=${apiKey}&page=${page}`);
const response = await axios.get(
`https://api.themoviedb.org/3/movie/popular?api_key=${apiKey}&page=${page}`
);
const movies = response.data.results;
const moviePromises = movies.map(async (movie) => {
const streamingInfo = await fetchStreamingInfo(apiKey, movie.id);
Expand All @@ -97,89 +186,96 @@ document.addEventListener('DOMContentLoaded', () => {
const moviesWithStreamingInfo = await Promise.all(moviePromises);
return moviesWithStreamingInfo;
} catch (error) {
console.error('Error fetching movie recommendations:', error);
console.error("Error fetching movie recommendations:", error);
throw error;
}
}

async function fetchStreamingInfo(apiKey, movieId) {
try {
const response = await axios.get(`https://api.themoviedb.org/3/movie/${movieId}/watch/providers?api_key=${apiKey}`);
const response = await axios.get(
`https://api.themoviedb.org/3/movie/${movieId}/watch/providers?api_key=${apiKey}`
);
const results = response.data.results;
const streamingServices = new Set();

// Collect streaming information from all countries without duplicates
for (const country in results) {
if (results[country].flatrate) {
const countryStreamingServices = results[country].flatrate.map(service => service.provider_name);
countryStreamingServices.forEach(service => streamingServices.add(service));
const countryStreamingServices = results[country].flatrate.map(
(service) => service.provider_name
);
countryStreamingServices.forEach((service) =>
streamingServices.add(service)
);
}
}

return Array.from(streamingServices);
} catch (error) {
console.error('Error fetching streaming information:', error);
console.error("Error fetching streaming information:", error);
return [];
}
}

function renderMovieRecommendations() {
function renderMovieRecommendations(results = movieRecommendations) {
const startIndex = (page - 1) * moviesPerPage;
const endIndex = startIndex + moviesPerPage;
const visibleRecommendations = movieRecommendations.slice(0, endIndex);

recommendationsList.innerHTML = '';
recommendationsList.innerHTML = "";

visibleRecommendations.forEach((movie) => {
const movieBox = document.createElement('div');
movieBox.className = 'movie-box';
results.forEach((movie) => {
const movieBox = document.createElement("div");
movieBox.className = "movie-box";

const moviePoster = document.createElement('img');
moviePoster.className = 'movie-poster';
const moviePoster = document.createElement("img");
moviePoster.className = "movie-poster";
moviePoster.src = `https://image.tmdb.org/t/p/w185${movie.poster_path}`;
movieBox.appendChild(moviePoster);

const movieInfo = document.createElement('div');
movieInfo.className = 'movie-info';
const movieInfo = document.createElement("div");
movieInfo.className = "movie-info";

const movieTitle = document.createElement('h2');
const movieTitle = document.createElement("h2");
movieTitle.textContent = movie.title;
movieInfo.appendChild(movieTitle);

const movieOverview = document.createElement('p');
const movieOverview = document.createElement("p");
movieOverview.textContent = movie.overview;
movieInfo.appendChild(movieOverview);

if (movie.streamingInfo && movie.streamingInfo.length > 0) {
const streamingInfo = document.createElement('p');
const services = movie.streamingInfo.join(', ');
const streamingInfo = document.createElement("p");
const services = movie.streamingInfo.join(", ");
streamingInfo.innerHTML = `<b>Available on:</b> ${services}`;
movieInfo.appendChild(streamingInfo);
} else {
const noStreamingInfo = document.createElement('p');
noStreamingInfo.textContent = 'Not available on any streaming service at the moment. Check local cinemas for availability.';
noStreamingInfo.style.fontWeight = 'bold'; // Make the message bold
const noStreamingInfo = document.createElement("p");
noStreamingInfo.textContent =
"Not available on any streaming service at the moment. Check local cinemas for availability.";
noStreamingInfo.style.fontWeight = "bold";
movieInfo.appendChild(noStreamingInfo);
}

movieBox.appendChild(movieInfo);
recommendationsList.appendChild(movieBox);
});

if (endIndex >= movieRecommendations.length) {
loadMoreButton.style.display = 'none';
if (endIndex >= results.length) {
loadMoreButton.style.display = "block";
} else {
loadMoreButton.style.display = 'block';
loadMoreButton.style.display = "block";
}
}

function validateApiKey(apiKey) {
const apiKeyRegex = /^[A-Za-z0-9]+$/;
if (apiKeyRegex.test(apiKey)) {
statusMessage.textContent = '';
statusMessage.textContent = "";
saveButton.disabled = false;
} else {
statusMessage.textContent = 'Please enter a valid API Key (letters and numbers only, no spaces).';
statusMessage.textContent =
"Please enter a valid API Key (letters and numbers only, no spaces).";
saveButton.disabled = true;
}
}
Expand All @@ -189,12 +285,13 @@ document.addEventListener('DOMContentLoaded', () => {
return apiKeyRegex.test(apiKey);
}

// Cargar API Key si existe en el almacenamiento local
const savedApiKey = localStorage.getItem('tmdb_api_key');
const savedApiKey = localStorage.getItem("tmdb_api_key");
if (savedApiKey) {
apiKeyInput.value = savedApiKey;
apiKey = savedApiKey;
validateApiKey(apiKey);
refreshRecommendations();
}

renderMovieRecommendations();
});
Loading

0 comments on commit fae57e0

Please sign in to comment.