diff --git a/_locales/de/messages.json b/_locales/de/messages.json index cce5ec8..42e7de1 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "Verlauf" }, "navRecommendations": { "message": "Empfehlungen" }, "navMusic": { "message": "Musik" }, - "heroWelcome": { "message": "Willkommen bei CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Entdecke Tausende von Filmen und Serien." }, "addStream": { "message": "Stream hinzufügen" }, "moreInfo": { "message": "Mehr Infos" }, diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5d52025..edc8dfb 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "History" }, "navRecommendations": { "message": "Recommendations" }, "navMusic": { "message": "Music" }, - "heroWelcome": { "message": "Welcome to CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Explore thousands of movies and series." }, "addStream": { "message": "Add Stream" }, "moreInfo": { "message": "More Info" }, diff --git a/_locales/es/messages.json b/_locales/es/messages.json index b75e60b..8f77212 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "Historial" }, "navRecommendations": { "message": "Recomendaciones" }, "navMusic": { "message": "Música" }, - "heroWelcome": { "message": "Bienvenido a CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Explora miles de películas y series." }, "addStream": { "message": "Añadir Stream" }, "moreInfo": { "message": "Más información" }, diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index fd40009..82c2c56 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "Historique" }, "navRecommendations": { "message": "Recommandations" }, "navMusic": { "message": "Musique" }, - "heroWelcome": { "message": "Bienvenue sur CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Explorez des milliers de films et de séries." }, "addStream": { "message": "Ajouter le flux" }, "moreInfo": { "message": "Plus d'infos" }, diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 3c10de0..d959053 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "Cronologia" }, "navRecommendations": { "message": "Consigliati" }, "navMusic": { "message": "Musica" }, - "heroWelcome": { "message": "Benvenuto su CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Esplora migliaia di film e serie TV." }, "addStream": { "message": "Aggiungi Stream" }, "moreInfo": { "message": "Più informazioni" }, diff --git a/_locales/pt/messages.json b/_locales/pt/messages.json index 41d163b..7cbcbc4 100644 --- a/_locales/pt/messages.json +++ b/_locales/pt/messages.json @@ -15,7 +15,7 @@ "navHistory": { "message": "Histórico" }, "navRecommendations": { "message": "Recomendações" }, "navMusic": { "message": "Música" }, - "heroWelcome": { "message": "Bem-vindo ao CinePlex" }, + "heroWelcome": { "message": "" }, "heroSubtitle": { "message": "Explore milhares de filmes e séries." }, "addStream": { "message": "Adicionar Stream" }, "moreInfo": { "message": "Mais Informações" }, diff --git a/css/hero.css b/css/hero.css index ce370d1..1d43bc2 100644 --- a/css/hero.css +++ b/css/hero.css @@ -22,6 +22,10 @@ z-index: 1; } +.hero.no-overlay::before { + display: none; +} + .hero-background-container { position: absolute; top: 0; diff --git a/css/navbar.css b/css/navbar.css index e87050a..90e1b4f 100644 --- a/css/navbar.css +++ b/css/navbar.css @@ -217,6 +217,10 @@ body.light-theme .sidebar-nav { } } +body.sidebar-open .sidebar-nav { + transform: translateX(0); +} + body.sidebar-collapsed .sidebar-nav { transform: translateX(-100%); } diff --git a/img/hero-def.png b/img/hero-def.png new file mode 100644 index 0000000..250c849 Binary files /dev/null and b/img/hero-def.png differ diff --git a/js/eventListeners.js b/js/eventListeners.js index 0b3eaa4..842b37d 100644 --- a/js/eventListeners.js +++ b/js/eventListeners.js @@ -36,9 +36,12 @@ export function setupEventListeners() { document.body.classList.remove('sidebar-collapsed'); } document.getElementById('sidebar-toggle').addEventListener('click', () => { - document.body.classList.toggle('sidebar-collapsed'); - const isCollapsed = document.body.classList.contains('sidebar-collapsed'); - localStorage.setItem('sidebarCollapsed', isCollapsed); + if (window.innerWidth < 992) { + document.body.classList.toggle('sidebar-open'); + } else { + document.body.classList.toggle('sidebar-collapsed'); + localStorage.setItem('sidebarCollapsed', document.body.classList.contains('sidebar-collapsed')); + } }); document.getElementById('nav-movies').addEventListener('click', (e) => { e.preventDefault(); switchView('movies'); }); diff --git a/js/ui.js b/js/ui.js index c7cb622..feae219 100644 --- a/js/ui.js +++ b/js/ui.js @@ -1200,92 +1200,78 @@ export async function initializeHeroSection() { const heroSection = document.getElementById('hero-section'); if (heroSection.style.display === 'none') return; - try { - const type = Math.random() > 0.5 ? 'movie' : 'tv'; - const data = await fetchTMDB(`${type}/popular?page=1`); - const popularItems = data.results.filter(i => i.backdrop_path && i.overview).slice(0, 8); + const bg1 = document.querySelector('.hero-background-1'); + const bg2 = document.querySelector('.hero-background-2'); + const content = document.querySelector('.hero-content'); - if (popularItems.length === 0) { - heroSection.style.display = 'none'; - return; - } + // Set static background and show default content + heroSection.classList.add('no-overlay'); + gsap.set(bg1, { backgroundImage: `url(img/hero-def.png)`, autoAlpha: 1, scale: 1 }); + gsap.set(bg2, { autoAlpha: 0 }); + gsap.set(content, { autoAlpha: 1 }); // Show welcome message + heroSection.classList.remove('loading'); - const bg1 = document.querySelector('.hero-background-1'); - const bg2 = document.querySelector('.hero-background-2'); - const content = document.querySelector('.hero-content'); - let currentBg = bg1; - let nextBg = bg2; - let currentIndex = -1; + // After 5 seconds, load the dynamic content + setTimeout(loadTmdbHeroContent, 5000); - function changeHeroSlide(isFirst = false) { - currentIndex = (currentIndex + 1) % popularItems.length; - const item = popularItems[currentIndex]; - const nextImage = new Image(); - nextImage.src = `https://image.tmdb.org/t/p/original${item.backdrop_path}`; + async function loadTmdbHeroContent() { + heroSection.classList.remove('no-overlay'); + try { + const type = Math.random() > 0.5 ? 'movie' : 'tv'; + const data = await fetchTMDB(`${type}/popular?page=1`); + const popularItems = data.results.filter(i => i.backdrop_path && i.overview).slice(0, 8); - nextImage.onload = () => { - updateHeroContent(item); + if (popularItems.length === 0) { + return; // Keep static image if no items + } - const heroElements = [ - content.querySelector('.hero-title'), - content.querySelector('.hero-subtitle'), - ...content.querySelectorAll('.hero-meta-item'), - content.querySelector('.hero-buttons') - ]; + let currentBg = bg1; + let nextBg = bg2; + let currentIndex = -1; + + function changeHeroSlide() { + currentIndex = (currentIndex + 1) % popularItems.length; + const item = popularItems[currentIndex]; + const nextImage = new Image(); + nextImage.src = `https://image.tmdb.org/t/p/original${item.backdrop_path}`; + + nextImage.onload = () => { + updateHeroContent(item); + + const heroElements = [ + content.querySelector('.hero-title'), + content.querySelector('.hero-subtitle'), + ...content.querySelectorAll('.hero-meta-item'), + content.querySelector('.hero-buttons') + ]; - if (isFirst) { - gsap.set(currentBg, { backgroundImage: `url(${nextImage.src})` }); - gsap.to(currentBg, { autoAlpha: 1, duration: 2.5, ease: 'power2.out' }); - gsap.to(content, { autoAlpha: 1, duration: 1.2, delay: 0.8, ease: 'power3.out' }); - gsap.fromTo(currentBg, { scale: 1.15, transformOrigin: 'center center' }, { scale: 1, duration: 12, ease: 'none' }); - heroSection.classList.remove('loading'); // Remove loading class after first slide is ready - } else { const tl = gsap.timeline({ onComplete: () => { const temp = currentBg; currentBg = nextBg; nextBg = temp; - gsap.set(nextBg, { autoAlpha: 0 }); // Reset nextBg opacity for next transition + gsap.set(nextBg, { autoAlpha: 0 }); } }); - tl.to(heroElements, { - autoAlpha: 0, - y: 30, - stagger: 0.08, - duration: 0.6, - ease: 'power3.in' - }, 0); // Start content fade out at the beginning of the timeline - - gsap.set(nextBg, { backgroundImage: `url(${nextImage.src})`, autoAlpha: 0 }); // Set new image and hide it - tl.to(currentBg, { autoAlpha: 0, duration: 2.5, ease: 'power2.inOut' }, 0); // Fade out current background - tl.to(nextBg, { autoAlpha: 1, duration: 2.5, ease: 'power2.inOut' }, 0); // Fade in new background simultaneously - + tl.to(heroElements, { autoAlpha: 0, y: 30, stagger: 0.08, duration: 0.6, ease: 'power3.in' }, 0); + gsap.set(nextBg, { backgroundImage: `url(${nextImage.src})`, autoAlpha: 0 }); + tl.to(currentBg, { autoAlpha: 0, duration: 2.5, ease: 'power2.inOut' }, 0); + tl.to(nextBg, { autoAlpha: 1, duration: 2.5, ease: 'power2.inOut' }, 0); gsap.fromTo(nextBg, { scale: 1.15, transformOrigin: 'center center' }, { scale: 1, duration: 12, ease: 'none' }); + tl.fromTo(heroElements, { y: -30, autoAlpha: 0 }, { y: 0, autoAlpha: 1, stagger: 0.1, duration: 1.2, ease: 'power3.out' }, '>-0.8'); + }; + } - tl.fromTo(heroElements, { - y: -30, - autoAlpha: 0 - }, { - y: 0, - autoAlpha: 1, - stagger: 0.1, - duration: 1.2, - ease: 'power3.out' - }, '>-0.8'); // Start content fade in slightly before background transition ends - } - }; + if (state.heroIntervalId) { + clearInterval(state.heroIntervalId); + } + changeHeroSlide(); + state.heroIntervalId = setInterval(changeHeroSlide, 12000); + + } catch (error) { + console.error("Error initializing hero section from TMDB:", error); } - - gsap.set(content, { autoAlpha: 0 }); - gsap.set([bg1, bg2], { autoAlpha: 0 }); - - changeHeroSlide(true); - state.heroIntervalId = setInterval(() => changeHeroSlide(false), 12000); - - } catch (error) { - console.error("Error initializing hero section:", error); - heroSection.style.display = 'none'; } }