177 lines
6.6 KiB
JavaScript
177 lines
6.6 KiB
JavaScript
import { fetchTMDB } from './api.js';
|
|
import { state } from './state.js';
|
|
import { _, showNotification } from './utils.js';
|
|
import { renderGrid } from './ui.js';
|
|
|
|
let currentProviderId = null;
|
|
let currentPage = 1;
|
|
let totalPages = 1;
|
|
|
|
export async function getAvailableProviders(type, region) {
|
|
try {
|
|
const url = `watch/providers/${type}`;
|
|
const providers = await fetchTMDB(url, { watch_region: region });
|
|
return providers.results || [];
|
|
} catch (error) {
|
|
console.error(`Error fetching ${type} providers for region ${region}:`, error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export async function fetchAllProviders(region) {
|
|
const [movieProviders, tvProviders] = await Promise.all([
|
|
getAvailableProviders('movie', region),
|
|
getAvailableProviders('tv', region)
|
|
]);
|
|
|
|
const allProvidersMap = new Map();
|
|
[...movieProviders, ...tvProviders].forEach(provider => {
|
|
allProvidersMap.set(provider.provider_id, provider);
|
|
});
|
|
|
|
return Array.from(allProvidersMap.values()).sort((a, b) => a.provider_name.localeCompare(b.provider_name));
|
|
}
|
|
|
|
export async function getRegions() {
|
|
try {
|
|
const regions = await fetchTMDB('watch/providers/regions');
|
|
return regions.results || [];
|
|
} catch (error) {
|
|
console.error('Error fetching regions:', error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
export function resetProvidersView() {
|
|
const providersSection = document.getElementById('providers-section');
|
|
if (!providersSection) return;
|
|
|
|
const grid = document.getElementById('providers-grid');
|
|
const itemsContainer = document.getElementById('provider-items-container');
|
|
const titleElement = document.querySelector('#providers-section .section-title');
|
|
const backButton = document.getElementById('back-to-providers');
|
|
|
|
if (grid) grid.style.display = 'grid';
|
|
if (itemsContainer) itemsContainer.style.display = 'none';
|
|
if (titleElement) titleElement.textContent = _('navProviders');
|
|
if (backButton) backButton.style.display = 'none';
|
|
}
|
|
|
|
export async function backToProviders() {
|
|
resetProvidersView();
|
|
const providers = await fetchAllProviders(state.settings.watchRegion);
|
|
renderProviders(providers);
|
|
}
|
|
|
|
export function renderProviders(providers) {
|
|
const grid = document.getElementById('providers-grid');
|
|
if (!grid) return;
|
|
|
|
grid.style.display = 'grid';
|
|
if (providers.length === 0) {
|
|
grid.innerHTML = `<div class="empty-state"><i class="fas fa-tv"></i><p>${_('noProvidersFound')}</p></div>`;
|
|
return;
|
|
}
|
|
|
|
const availableProviderIds = new Set(state.localSeries.flatMap(s => s.titulos).map(t => t.provider_id));
|
|
|
|
const providersHtml = providers.map(provider => {
|
|
const isAvailable = availableProviderIds.has(provider.provider_id);
|
|
return `
|
|
<div class="provider-card ${isAvailable ? 'available' : ''}" data-provider-id="${provider.provider_id}" data-provider-name="${provider.provider_name}">
|
|
<img src="https://image.tmdb.org/t/p/w200${provider.logo_path}" alt="${provider.provider_name}" class="provider-logo">
|
|
<div class="provider-tooltip">${provider.provider_name}</div>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
|
|
grid.innerHTML = providersHtml;
|
|
|
|
gsap.fromTo(".provider-card",
|
|
{ scale: 0.5, opacity: 0 },
|
|
{
|
|
duration: 0.5,
|
|
scale: 1,
|
|
opacity: 1,
|
|
delay: 0.2,
|
|
stagger: 0.08,
|
|
ease: "back.out(1.7)",
|
|
force3D: true
|
|
}
|
|
);
|
|
}
|
|
|
|
export async function getProviderItems(providerId, page = 1) {
|
|
try {
|
|
const watchRegion = state.settings.watchRegion || 'US';
|
|
|
|
const params = {
|
|
with_watch_providers: providerId,
|
|
watch_region: watchRegion,
|
|
page: page,
|
|
};
|
|
|
|
const moviesResponse = await fetchTMDB('discover/movie', params);
|
|
const seriesResponse = await fetchTMDB('discover/tv', params);
|
|
|
|
const movies = moviesResponse.results.map(item => ({ ...item, media_type: 'movie' }));
|
|
const series = seriesResponse.results.map(item => ({ ...item, media_type: 'tv' }));
|
|
|
|
const items = [...movies, ...series].sort((a, b) => b.popularity - a.popularity);
|
|
const total_pages = Math.max(moviesResponse.total_pages, seriesResponse.total_pages);
|
|
|
|
return { success: true, items, total_pages };
|
|
} catch (error) {
|
|
showNotification(`${_('couldNotLoadContent')}: ${error.message}`, 'error');
|
|
return { success: false, items: [], total_pages: 0 };
|
|
}
|
|
}
|
|
|
|
export async function loadProviderContent(providerId, providerName, page = 1) {
|
|
currentProviderId = providerId;
|
|
currentPage = page;
|
|
|
|
const itemsContainer = document.getElementById('provider-items-container');
|
|
const providersGrid = document.getElementById('providers-grid');
|
|
const itemsGrid = document.getElementById('provider-items');
|
|
const paginationControls = document.getElementById('pagination-controls');
|
|
const pageNumberSpan = document.getElementById('page-number');
|
|
const prevButton = document.getElementById('prev-page');
|
|
const nextButton = document.getElementById('next-page');
|
|
const sectionTitle = document.querySelector('#providers-section .section-title');
|
|
const backButton = document.getElementById('back-to-providers');
|
|
|
|
providersGrid.style.display = 'none';
|
|
itemsContainer.style.display = 'block';
|
|
backButton.style.display = 'block';
|
|
if (sectionTitle) sectionTitle.textContent = providerName;
|
|
|
|
itemsGrid.innerHTML = `<div class="col-12 text-center mt-5"><div class="spinner" style="position: static; margin: auto; display: block;"></div></div>`;
|
|
paginationControls.style.display = 'none';
|
|
|
|
const { success, items, total_pages } = await getProviderItems(providerId, page);
|
|
|
|
if (success) {
|
|
totalPages = total_pages;
|
|
renderGrid(items, false, 'provider-items');
|
|
|
|
if (totalPages > 1) {
|
|
paginationControls.style.display = 'flex';
|
|
pageNumberSpan.textContent = `${_('page')} ${currentPage} / ${totalPages}`;
|
|
prevButton.disabled = currentPage === 1;
|
|
nextButton.disabled = currentPage >= totalPages;
|
|
}
|
|
} else {
|
|
itemsGrid.innerHTML = `<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>${_('couldNotLoadContent')}</p></div>`;
|
|
}
|
|
}
|
|
|
|
export function changeProviderPage(direction) {
|
|
const newPage = currentPage + direction;
|
|
if (newPage > 0 && newPage <= totalPages && currentProviderId) {
|
|
const providerName = document.querySelector('#providers-section .section-title').textContent;
|
|
loadProviderContent(currentProviderId, providerName, newPage);
|
|
}
|
|
}
|
|
|