333 lines
14 KiB
JavaScript
333 lines
14 KiB
JavaScript
import { state } from './state.js';
|
|
import { switchView, resetView, showMainView, showItemDetails, applyFilters, searchByActor, loadContent, toggleFavorite, addStreamToList, downloadM3U, showTrailer, closeTrailer, openSettingsModal, saveSettings, updateSectionTitle, generateStatistics, loadFavorites, loadLocalContent, phpScriptGenerator, initPhotosView, handlePhotoGridClick, handlePhotoTokenChange, showNextPhoto, showPrevPhoto, closePhotoLightbox, activateSettingsTab, deleteHistoryItem, clearAllHistory, getTrailerKey } from './ui.js';
|
|
import { debounce, showNotification, _ } from './utils.js';
|
|
import { clearContentData, loadTokensToEditor, saveTokensFromEditor, exportDatabase, importDatabase } from './db.js';
|
|
import { startPlexScan } from './plex.js';
|
|
import { Equalizer } from './equalizer.js';
|
|
|
|
async function handleDatabaseUpdate() {
|
|
showNotification(_('updatingView'), "info", 2000);
|
|
await loadLocalContent();
|
|
|
|
switch(state.currentView) {
|
|
case 'stats':
|
|
generateStatistics();
|
|
break;
|
|
case 'movies':
|
|
case 'series':
|
|
case 'search':
|
|
loadContent();
|
|
break;
|
|
case 'favorites':
|
|
loadFavorites();
|
|
break;
|
|
case 'photos':
|
|
initPhotosView();
|
|
break;
|
|
}
|
|
}
|
|
|
|
export function setupEventListeners() {
|
|
document.getElementById('sidebar-toggle').addEventListener('click', () => {
|
|
document.getElementById('sidebar-nav').classList.toggle('open');
|
|
document.getElementById('main-container').classList.toggle('sidebar-open');
|
|
});
|
|
|
|
document.getElementById('nav-movies').addEventListener('click', (e) => { e.preventDefault(); switchView('movies'); });
|
|
document.getElementById('nav-series').addEventListener('click', (e) => { e.preventDefault(); switchView('series'); });
|
|
document.getElementById('nav-photos').addEventListener('click', (e) => { e.preventDefault(); switchView('photos'); });
|
|
document.getElementById('nav-stats').addEventListener('click', (e) => { e.preventDefault(); switchView('stats'); });
|
|
document.getElementById('nav-favorites').addEventListener('click', (e) => { e.preventDefault(); switchView('favorites'); });
|
|
document.getElementById('nav-history').addEventListener('click', (e) => { e.preventDefault(); switchView('history'); });
|
|
document.getElementById('nav-recommendations').addEventListener('click', (e) => { e.preventDefault(); switchView('recommendations'); });
|
|
document.getElementById('reset-view-btn').addEventListener('click', (e) => { e.preventDefault(); resetView(); });
|
|
|
|
document.getElementById('footer-logo-btn').addEventListener('click', (e) => { e.preventDefault(); resetView(); });
|
|
document.getElementById('footer-movies').addEventListener('click', (e) => { e.preventDefault(); switchView('movies'); });
|
|
document.getElementById('footer-series').addEventListener('click', (e) => { e.preventDefault(); switchView('series'); });
|
|
document.getElementById('footer-stats').addEventListener('click', (e) => { e.preventDefault(); switchView('stats'); });
|
|
document.getElementById('footer-favorites').addEventListener('click', (e) => { e.preventDefault(); switchView('favorites'); });
|
|
|
|
document.getElementById('load-more').addEventListener('click', () => {
|
|
if (!state.isLoading) {
|
|
state.currentPage++;
|
|
loadContent(true);
|
|
}
|
|
});
|
|
|
|
document.getElementById('search-input').addEventListener('keyup', debounce(async (e) => {
|
|
const query = e.target.value.trim();
|
|
if (query === state.currentParams.query && state.currentView === 'search') return;
|
|
state.currentView = 'search';
|
|
state.currentParams.query = query;
|
|
state.currentPage = 1;
|
|
if (!query) {
|
|
switchView(state.currentParams.contentType === 'movie' ? 'movies' : 'series');
|
|
} else {
|
|
updateSectionTitle();
|
|
await loadContent();
|
|
}
|
|
}, 400));
|
|
|
|
document.getElementById('genre-filter').addEventListener('change', applyFilters);
|
|
document.getElementById('year-filter').addEventListener('change', applyFilters);
|
|
document.getElementById('sort-filter').addEventListener('change', applyFilters);
|
|
document.getElementById('stats-token-filter').addEventListener('change', generateStatistics);
|
|
document.getElementById('photos-token-select').addEventListener('change', handlePhotoTokenChange);
|
|
|
|
document.querySelector('.back-button').addEventListener('click', showMainView);
|
|
|
|
document.getElementById('main-view').addEventListener('click', handleMainViewClick);
|
|
document.getElementById('item-details-view').addEventListener('click', handleDetailsClick);
|
|
|
|
document.getElementById('settings-btn').addEventListener('click', openSettingsModal);
|
|
|
|
document.getElementById('import-db-btn').addEventListener('click', async () => {
|
|
const input = document.createElement('input');
|
|
input.type = 'file';
|
|
input.accept = '.json';
|
|
input.onchange = async (e) => {
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
await importDatabase(file);
|
|
bootstrap.Modal.getInstance(document.getElementById('settingsModal'))?.hide();
|
|
}
|
|
};
|
|
input.click();
|
|
});
|
|
|
|
document.getElementById('confirmScanBtn').addEventListener('click', () => {
|
|
const selectedTypes = Array.from(document.querySelectorAll('#plex input[type="checkbox"]:checked'))
|
|
.map(cb => cb.value)
|
|
.filter(v => v && v !== 'on');
|
|
|
|
if (selectedTypes.length > 0) {
|
|
bootstrap.Modal.getInstance(document.getElementById('settingsModal')).hide();
|
|
document.getElementById('consoleOutputContainer').style.display = 'block';
|
|
document.getElementById('consoleOutput').style.display = 'block';
|
|
startPlexScan(selectedTypes);
|
|
}
|
|
});
|
|
|
|
document.getElementById('clearDataBtn').addEventListener('click', () => {
|
|
if (confirm(_('confirmClearContent'))) {
|
|
clearContentData();
|
|
}
|
|
});
|
|
|
|
document.getElementById('saveTokensBtn').addEventListener('click', saveTokensFromEditor);
|
|
document.getElementById('exportDbBtn').addEventListener('click', exportDatabase);
|
|
document.getElementById('saveSettingsBtn').addEventListener('click', saveSettings);
|
|
|
|
document.getElementById('settingsModal').addEventListener('shown.bs.modal', () => {
|
|
loadTokensToEditor();
|
|
activateSettingsTab('general');
|
|
});
|
|
|
|
document.getElementById('updateAll').addEventListener('change', (e) => {
|
|
document.querySelectorAll('#plex input[type="checkbox"]').forEach(cb => {
|
|
if (cb.id !== 'updateAll') cb.checked = e.target.checked;
|
|
});
|
|
});
|
|
|
|
document.querySelector('.lightbox-close').addEventListener('click', closeTrailer);
|
|
document.getElementById('video-lightbox').addEventListener('click', (e) => {
|
|
if(e.target === e.currentTarget) closeTrailer();
|
|
});
|
|
|
|
document.getElementById('photo-lightbox-close').addEventListener('click', closePhotoLightbox);
|
|
document.getElementById('photo-lightbox-next').addEventListener('click', showNextPhoto);
|
|
document.getElementById('photo-lightbox-prev').addEventListener('click', showPrevPhoto);
|
|
document.getElementById('photo-lightbox').addEventListener('click', (e) => {
|
|
if (e.target.id === 'photo-lightbox') {
|
|
closePhotoLightbox();
|
|
}
|
|
});
|
|
|
|
window.addEventListener('indexedDBUpdated', handleDatabaseUpdate);
|
|
|
|
const eqBtn = document.getElementById('eqBtn');
|
|
const closeEqBtn = document.getElementById('closeEqBtn');
|
|
const equalizerPanel = document.getElementById('equalizer-panel');
|
|
|
|
function initializeEqualizer() {
|
|
if (state.isEqualizerInitialized) return;
|
|
|
|
const audioPlayer = document.getElementById('audioPlayer');
|
|
const canvas = document.getElementById('visualizer-canvas');
|
|
state.equalizer = new Equalizer(audioPlayer, canvas);
|
|
|
|
if (state.equalizer.init()) {
|
|
state.isEqualizerInitialized = true;
|
|
setupEqualizerControls();
|
|
} else {
|
|
eqBtn.disabled = true;
|
|
eqBtn.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
eqBtn.addEventListener('click', () => {
|
|
initializeEqualizer();
|
|
if (!state.isEqualizerInitialized) return;
|
|
|
|
gsap.set(equalizerPanel, { display: 'block' });
|
|
gsap.to(equalizerPanel, {
|
|
y: 0,
|
|
duration: 0.5,
|
|
ease: "power3.out"
|
|
});
|
|
});
|
|
|
|
closeEqBtn.addEventListener('click', () => {
|
|
gsap.to(equalizerPanel, {
|
|
y: '100%',
|
|
duration: 0.4,
|
|
ease: "power3.in",
|
|
onComplete: () => gsap.set(equalizerPanel, { display: 'none' })
|
|
});
|
|
});
|
|
|
|
function setupEqualizerControls() {
|
|
const preampSlider = document.getElementById('preamp-slider');
|
|
preampSlider.addEventListener('input', (e) => {
|
|
const value = parseFloat(e.target.value);
|
|
state.equalizer.changePreamp(value);
|
|
e.target.nextElementSibling.textContent = `${value.toFixed(0)} dB`;
|
|
});
|
|
|
|
const bandSliders = document.querySelectorAll('.band-slider');
|
|
bandSliders.forEach(slider => {
|
|
slider.addEventListener('input', (e) => {
|
|
const bandIndex = parseInt(e.target.dataset.band);
|
|
const value = parseFloat(e.target.value);
|
|
state.equalizer.changeGain(bandIndex, value);
|
|
e.target.nextElementSibling.textContent = `${value.toFixed(0)} dB`;
|
|
});
|
|
});
|
|
|
|
const presetsSelect = document.getElementById('eq-presets');
|
|
presetsSelect.addEventListener('change', (e) => {
|
|
state.equalizer.applyPreset(e.target.value);
|
|
});
|
|
}
|
|
|
|
const audioPlayer = document.getElementById('audioPlayer');
|
|
audioPlayer.addEventListener('play', initializeEqualizer, { once: true });
|
|
|
|
phpScriptGenerator.init();
|
|
}
|
|
|
|
function handleMainViewClick(e) {
|
|
const clearHistoryBtn = e.target.closest('#clear-history-btn');
|
|
if (clearHistoryBtn) {
|
|
clearAllHistory();
|
|
return;
|
|
}
|
|
|
|
const historyItem = e.target.closest('.history-item');
|
|
if (historyItem) {
|
|
handleHistoryClick(e, historyItem);
|
|
return;
|
|
}
|
|
|
|
const photoCard = e.target.closest('.album-card, .photo-card');
|
|
if (photoCard) {
|
|
handlePhotoGridClick(photoCard);
|
|
return;
|
|
}
|
|
|
|
const card = e.target.closest('.item-card');
|
|
if (!card) return;
|
|
|
|
state.lastClickedCardElement = card;
|
|
const actionBtn = e.target.closest('.action-btn');
|
|
|
|
if (actionBtn) {
|
|
e.stopPropagation();
|
|
const { id, type } = card.dataset;
|
|
const title = card.querySelector('.item-title')?.textContent;
|
|
if (actionBtn.classList.contains('info-btn')) showItemDetails(Number(id), type);
|
|
else if (actionBtn.classList.contains('favorites-btn')) toggleFavorite(Number(id), type);
|
|
else if (actionBtn.classList.contains('play-btn')) addStreamToList(title, type, actionBtn);
|
|
else if (actionBtn.classList.contains('download-btn')) downloadM3U(title, type, actionBtn);
|
|
return;
|
|
}
|
|
|
|
const { id, type } = card.dataset;
|
|
if (id && type) showItemDetails(Number(id), type);
|
|
}
|
|
|
|
async function handleHistoryClick(e, historyItem) {
|
|
const { id, type, title } = historyItem.dataset;
|
|
const button = e.target.closest('.action-btn');
|
|
|
|
if (button) {
|
|
e.stopPropagation();
|
|
if (button.classList.contains('delete-btn')) {
|
|
deleteHistoryItem(id, type, historyItem);
|
|
} else if (button.classList.contains('play-btn')) {
|
|
addStreamToList(title, type, button);
|
|
} else if (button.classList.contains('trailer-btn')) {
|
|
const originalIcon = button.innerHTML;
|
|
button.innerHTML = `<span class="spinner-border spinner-border-sm"></span>`;
|
|
button.disabled = true;
|
|
const trailerKey = await getTrailerKey(id, type);
|
|
if (trailerKey) {
|
|
showTrailer(trailerKey);
|
|
} else {
|
|
showNotification(_('trailerNotFound'), 'warning');
|
|
}
|
|
button.innerHTML = originalIcon;
|
|
button.disabled = false;
|
|
} else if (button.classList.contains('info-btn')) {
|
|
state.lastClickedCardElement = historyItem;
|
|
showItemDetails(Number(id), type);
|
|
}
|
|
} else if (e.target.closest('.info-btn')) {
|
|
state.lastClickedCardElement = historyItem;
|
|
showItemDetails(Number(id), type);
|
|
}
|
|
}
|
|
|
|
async function handleDetailsClick(e) {
|
|
const trailerBtn = e.target.closest('.trailer-btn');
|
|
if (trailerBtn) {
|
|
showTrailer(trailerBtn.dataset.trailerKey);
|
|
return;
|
|
}
|
|
|
|
const favoritesBtn = e.target.closest('.favorites-btn');
|
|
if (favoritesBtn) {
|
|
toggleFavorite(Number(favoritesBtn.dataset.id), favoritesBtn.dataset.type);
|
|
return;
|
|
}
|
|
|
|
const castCard = e.target.closest('.cast-card');
|
|
if (castCard) {
|
|
const { actorId } = castCard.dataset;
|
|
const actorName = castCard.querySelector('.cast-name').textContent;
|
|
if (actorId && actorName) await searchByActor(actorId, actorName);
|
|
return;
|
|
}
|
|
|
|
const similarCard = e.target.closest('.similar-item-card');
|
|
if (similarCard) {
|
|
state.lastClickedCardElement = similarCard;
|
|
const { id, type } = similarCard.dataset;
|
|
if (id && type) showItemDetails(Number(id), type);
|
|
}
|
|
|
|
const addStreamBtn = e.target.closest('.play-btn');
|
|
if (addStreamBtn) {
|
|
const { title, type } = addStreamBtn.dataset;
|
|
addStreamToList(title, type, addStreamBtn);
|
|
return;
|
|
}
|
|
|
|
const downloadM3uBtn = e.target.closest('.download-btn');
|
|
if (downloadM3uBtn) {
|
|
const { title, type } = downloadM3uBtn.dataset;
|
|
downloadM3U(title, type, downloadM3uBtn);
|
|
return;
|
|
}
|
|
} |