AKY - Red Social
??
[ CARGANDO RECUERDOS AKY... ]

Comentarios

[ Selecciona un recuerdo para ver comentarios ]

Elige un color de fondo

Arrastra para seleccionar un color
`; htmlPost += `
`; htmlPost += `
${desc}
`; // Formatear fecha de publicación let fechaPublicacion = "Fecha no disponible"; if (data.timestamp) { const fecha = new Date(data.timestamp.seconds * 1000); fechaPublicacion = fecha.toLocaleDateString('es-ES', { day: 'numeric', month: 'long', year: 'numeric' }); } htmlPost += `
❤️ ${likeCount}
`; postElement.innerHTML = htmlPost; imageFeed.appendChild(postElement); // No cargar comentarios en el centro, solo mostrar fecha } // Configurar IntersectionObserver para reproducción automática de videos // ANDROID: VideoAdapter.kt (líneas 186-230) - ViewPager2 con PageChangeCallback const videoObserver = new IntersectionObserver((entradas) => { entradas.forEach(ent => { const video = ent.target.querySelector('video'); if (video) { if (ent.isIntersecting) { video.play().catch(e => console.log('Error reproduciendo video:', e)); } else { video.pause(); } } }); }, { threshold: 0.6 }); // Observar todos los videos document.querySelectorAll('.image-post').forEach(post => { videoObserver.observe(post); }); return Promise.resolve(); } catch (error) { console.error("Error cargando recuerdos:", error); loadingMessage.innerText = "[ ERROR DE CONEXIÓN CON FIREBASE ]"; return Promise.reject(error); } } // --- CARGA DE COMENTARIOS --- // ANDROID: CommentsAdapter.kt (líneas 42-441) - Adaptador para mostrar comentarios // Cache para evitar múltiples intentos fallidos const comentariosErrorCache = new Map(); async function cargarComentariosPost(postId, contenedorHtml) { // Verificar si ya hubo un error reciente para este post const errorCacheKey = `${postId}-error`; const cachedError = comentariosErrorCache.get(errorCacheKey); if (cachedError && Date.now() - cachedError < 30000) { // 30 segundos de espera contenedorHtml.innerHTML = `
Los comentarios no están disponibles temporalmente.
`; return; } try { const q = query(collection(db, "videos", postId, "comments"), orderBy("timestamp", "asc"), limit(50)); const snap = await getDocs(q); // Limpiar cache de errores si fue exitoso comentariosErrorCache.delete(errorCacheKey); if(snap.empty) { contenedorHtml.innerHTML = `
Sin comentarios aún.
`; return; } const listaComentarios = []; for(const docSnap of snap.docs) { const cData = docSnap.data(); console.log("Datos del comentario:", cData); let nombreMostrar = cData.userName || cData.authorName || "Usuario"; let fotoComentarista = ''; // Intentar obtener datos del usuario del comentario si tiene userId if(cData.userId) { try { const userSnap = await getDoc(doc(db, "users", cData.userId)); if(userSnap.exists()){ const userData = userSnap.data(); if(userData.userName) nombreMostrar = userData.userName; if(userData.profileImageUrl) fotoComentarista = userData.profileImageUrl; console.log("Datos del usuario comentarista:", userData); } } catch(e){ console.error("Error obteniendo datos del comentarista:", e); } } // Fallback a datos del comentario if(cData.authorName) nombreMostrar = cData.authorName; if(cData.photoUrl) fotoComentarista = cData.photoUrl; console.log("Foto del comentarista:", fotoComentarista); listaComentarios.push({ nombre: nombreMostrar, texto: cData.text || cData.comentario || cData.message || "", foto: fotoComentarista }); } let mostrados = 3; const total = listaComentarios.length; const renderizarComentarios = () => { let html = ''; const aMostrar = listaComentarios.slice(0, mostrados); aMostrar.forEach(c => { const fotoStyle = c.foto ? `background-image: url('${c.foto}');` : ''; html += `
${c.nombre}
${c.texto}
`; }); let controles = `
`; if(mostrados < total) controles += ``; if(mostrados > 3) controles += ``; controles += `
`; contenedorHtml.innerHTML = html + controles; const btnMas = document.getElementById(`btn-mas-${postId}`); if(btnMas) btnMas.onclick = () => { mostrados += 10; renderizarComentarios(); }; const btnMenos = document.getElementById(`btn-menos-${postId}`); if(btnMenos) btnMenos.onclick = () => { mostrados = 3; renderizarComentarios(); }; }; renderizarComentarios(); } catch(error) { // Guardar error en cache para evitar reintento inmediato comentariosErrorCache.set(errorCacheKey, Date.now()); // Log solo una vez por cada tipo de error if (error.code === 'permission-denied') { console.warn("Permisos denegados para comentarios. Configura las reglas de Firestore."); } else { console.error("Error inesperado cargando comentarios:", error); } contenedorHtml.innerHTML = `
Los comentarios no están disponibles temporalmente.
`; } } // --- AGREGAR COMENTARIO --- // ANDROID: CommentsBottomSheetFragment.kt - Agregar comentario window.addComment = async function() { const input = document.getElementById('commentInput'); const commentText = input.value.trim(); if (!commentText || !selectedPostId) { return; } try { let commentData = { text: commentText, timestamp: serverTimestamp() }; // Si el usuario está logueado, agregar su información if (usuarioLogueado) { commentData.userId = auth.currentUser.uid; commentData.userName = usuarioActual.displayName || "Usuario"; } else { // Si es invitado, agregar información genérica commentData.userName = "Invitado AKY"; } await addDoc(collection(db, "videos", selectedPostId, "comments"), commentData); input.value = ''; // Recargar comentarios en ambos lugares: en el post y en la columna derecha const contenedorPost = document.getElementById(`seccion-coment-${selectedPostId}`); if (contenedorPost) { cargarComentariosPost(selectedPostId, contenedorPost); } // Actualizar comentarios en columna derecha mostrarComentariosEnColumnaDerecha(selectedPostId); } catch (error) { console.error("Error agregando comentario:", error); // Mostrar mensaje de error pero no bloquear la funcionalidad const errorMsg = document.createElement('div'); errorMsg.style.color = '#ff4d4d'; errorMsg.style.fontSize = '12px'; errorMsg.style.marginTop = '5px'; errorMsg.textContent = 'No se pudo enviar el comentario. Intenta de nuevo.'; const addCommentSection = document.querySelector('.add-comment'); addCommentSection.appendChild(errorMsg); // Eliminar el mensaje de error después de 3 segundos setTimeout(() => { if (errorMsg.parentNode) { errorMsg.parentNode.removeChild(errorMsg); } }, 3000); } }; // Permitir enviar comentarios con Enter document.getElementById('commentInput').addEventListener('keypress', function(e) { if (e.key === 'Enter') { addComment(); } }); // --- FUNCIONES PARA TOGGLE DE COLUMNAS --- window.toggleColumn = function(side) { const columnId = side + 'Column'; const column = document.getElementById(columnId); const button = column.querySelector('.toggle-column'); column.classList.toggle('collapsed'); // Ajustar tamaño de columna central adjustCenterColumnWidth(); }; function adjustCenterColumnWidth() { const leftColumn = document.getElementById('leftColumn'); const rightColumn = document.getElementById('rightColumn'); const centerColumn = document.querySelector('.center-column'); const leftCollapsed = leftColumn.classList.contains('collapsed'); const rightCollapsed = rightColumn.classList.contains('collapsed'); // Calcular espacio disponible para columna central let centerFlex = '1'; if (!leftCollapsed && !rightCollapsed) { // Ambas columnas abiertas: comportamiento normal centerFlex = '1'; } else if (leftCollapsed && !rightCollapsed) { // Solo izquierda cerrada: más espacio para centro centerFlex = '1.5'; } else if (!leftCollapsed && rightCollapsed) { // Solo derecha cerrada: más espacio para centro centerFlex = '1.5'; } else { // Ambas cerradas: máximo espacio para centro centerFlex = '2'; } centerColumn.style.flex = centerFlex; } // --- FUNCIONES PARA EL CAMBIO DE COLOR --- window.openColorModal = function() { document.getElementById('colorModal').style.display = 'flex'; initializeRainbowSlider(); }; window.closeColorModal = function() { document.getElementById('colorModal').style.display = 'none'; }; function initializeRainbowSlider() { const slider = document.getElementById('rainbowSlider'); const preview = document.getElementById('colorPreview'); // Actualizar preview al mover el slider slider.addEventListener('input', function() { const hue = this.value; let color; // Si está en los primeros 5% (0-18 grados), mostrar negro en preview if (hue <= 18) { color = '#000000'; } else { color = `hsl(${hue}, 100%, 50%)`; } preview.style.backgroundColor = color; }); // Aplicar color al soltar el slider slider.addEventListener('change', function() { const hue = this.value; let color; // Si está en los primeros 5% (0-18 grados), aplicar negro if (hue <= 18) { color = '#000000'; } else { color = `hsl(${hue}, 100%, 50%)`; } console.log('Slider cambiado - hue:', hue, 'color:', color, 'easterEggActive:', easterEggActive); document.body.style.backgroundColor = color; // Desactivar Easter Egg automáticamente si está activo if (easterEggActive) { console.log('Desactivando Easter Egg...'); deactivateEasterEgg(); showEasterEggDeactivatedMessage(); } }); // Inicializar con el color actual const currentBg = window.getComputedStyle(document.body).backgroundColor; preview.style.backgroundColor = currentBg; // Inicializar detector de Easter Egg initializeEasterEgg(); } // --- EASTER EGG KONAMI CODE --- let konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'b', 'a', ' ']; let konamiIndex = 0; let colorInterval = null; let easterEggActive = false; function initializeEasterEgg() { // Resetear el índice cuando se abre el modal konamiIndex = 0; // Añadir listener para teclas document.addEventListener('keydown', function(event) { // Solo activar cuando el modal de color está abierto if (document.getElementById('colorModal').style.display === 'flex') { checkKonamiCode(event.key); } }); } function checkKonamiCode(key) { if (key === konamiCode[konamiIndex]) { konamiIndex++; // Si completa la secuencia if (konamiIndex === konamiCode.length) { activateEasterEgg(); konamiIndex = 0; // Resetear para poder usarlo de nuevo } } else { // Resetear si la tecla no es correcta konamiIndex = 0; } } function activateEasterEgg() { console.log('activateEasterEgg() llamada - easterEggActive actual:', easterEggActive); // Si ya está activo, no hacer nada (ya se desactiva automáticamente al elegir color) if (easterEggActive) { console.log('Easter Egg ya está activo, no se vuelve a activar'); return; } easterEggActive = true; console.log('Easter Egg activado - easterEggActive ahora:', easterEggActive); // Mostrar mensaje de activación showEasterEggMessage(); // Iniciar alternación de colores const colors = [ 'hsl(0, 100%, 50%)', // Rojo 'hsl(30, 100%, 50%)', // Naranja 'hsl(60, 100%, 50%)', // Amarillo 'hsl(120, 100%, 50%)', // Verde 'hsl(180, 100%, 50%)', // Cyan 'hsl(240, 100%, 50%)', // Azul 'hsl(270, 100%, 50%)', // Púrpura 'hsl(300, 100%, 50%)', // Magenta 'hsl(330, 100%, 50%)', // Rosa 'hsl(90, 100%, 50%)', // Verde lima ]; let colorIndex = 0; // Cambiar color cada 3 segundos (permanente) colorInterval = setInterval(function() { if (easterEggActive) { // Solo cambiar si sigue activo document.body.style.backgroundColor = colors[colorIndex]; colorIndex = (colorIndex + 1) % colors.length; } }, 3000); console.log('Interval iniciado - colorInterval:', colorInterval); } function showEasterEggMessage() { const message = document.createElement('div'); message.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: linear-gradient(45deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff); color: #ffffff; padding: 20px 40px; border-radius: 10px; font-size: 24px; font-weight: bold; z-index: 10000; text-align: center; box-shadow: 0 0 30px rgba(255,255,255,0.8); animation: pulse 1s infinite; `; message.innerHTML = '¡EASTER EGG ACTIVADO!
Colores mágicos permanentes

Elige un color para detener'; document.body.appendChild(message); // Eliminar mensaje después de 4 segundos setTimeout(function() { if (message.parentNode) { message.parentNode.removeChild(message); } }, 4000); } function showEasterEggDeactivatedMessage() { const message = document.createElement('div'); message.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: linear-gradient(45deg, #333333, #666666, #999999); color: #ffffff; padding: 20px 40px; border-radius: 10px; font-size: 20px; font-weight: bold; z-index: 10000; text-align: center; box-shadow: 0 0 30px rgba(255,255,255,0.5); animation: pulse 1s infinite; `; message.innerHTML = 'EASTER EGG DETENIDO
Color seleccionado aplicado'; document.body.appendChild(message); // Eliminar mensaje después de 3 segundos setTimeout(function() { if (message.parentNode) { message.parentNode.removeChild(message); } }, 3000); } function deactivateEasterEgg() { console.log('deactivateEasterEgg() llamada - colorInterval:', colorInterval, 'easterEggActive:', easterEggActive); if (colorInterval) { clearInterval(colorInterval); colorInterval = null; console.log('Interval limpiado'); } easterEggActive = false; console.log('Easter Egg desactivado - easterEggActive ahora:', easterEggActive); // No volver automáticamente al negro - mantener el último color // El usuario puede elegir un color con el slider si quiere } window.changeBackgroundColor = function(color) { document.body.style.backgroundColor = color; const colorOptions = document.querySelectorAll('.color-option'); colorOptions.forEach(option => { option.classList.remove('selected'); if (option.dataset.color === color) { option.classList.add('selected'); } }); }; // --- DETECCIÓN DE POST VISIBLE --- // ANDROID: VideoAdapter.kt (líneas 186-230) - ViewPager2 con PageChangeCallback function getVisiblePost() { const posts = document.querySelectorAll('.image-post'); const centerColumn = document.querySelector('.center-column'); const columnRect = centerColumn.getBoundingClientRect(); const columnCenter = columnRect.top + columnRect.height / 2; let visiblePost = null; let minDistance = Infinity; posts.forEach(post => { const postRect = post.getBoundingClientRect(); const postCenter = postRect.top + postRect.height / 2; const distance = Math.abs(postCenter - columnCenter); // Verificar si el post está visible en la columna if (postRect.bottom > columnRect.top && postRect.top < columnRect.bottom) { if (distance < minDistance) { minDistance = distance; visiblePost = post; } } }); return visiblePost; } function updateVisiblePostComments() { const visiblePost = getVisiblePost(); if (visiblePost && visiblePost.dataset.postId !== selectedPostId) { selectedPostId = visiblePost.dataset.postId; // Mostrar los comentarios de este post en la columna derecha mostrarComentariosEnColumnaDerecha(selectedPostId); } } function mostrarComentariosEnColumnaDerecha(postId) { const commentsSection = document.getElementById('commentsSection'); commentsSection.innerHTML = '
[ Cargando comentarios... ]
'; // Cargar comentarios del post seleccionado cargarComentariosPost(postId, commentsSection); } // --- INICIALIZACIÓN --- document.addEventListener('DOMContentLoaded', function() { // Configurar opciones de color const colorOptions = document.querySelectorAll('.color-option'); colorOptions.forEach(option => { option.addEventListener('click', function() { changeBackgroundColor(this.dataset.color); closeColorModal(); }); }); // Cerrar modal al hacer clic fuera del contenido document.getElementById('colorModal').addEventListener('click', function(e) { if (e.target === this) { closeColorModal(); } }); // Cerrar modal de login al hacer clic fuera loginModal.addEventListener('click', function(e) { if (e.target === this) { loginModal.style.display = 'none'; } }); // Configurar scroll para detectar post visible const centerColumn = document.querySelector('.center-column'); centerColumn.addEventListener('scroll', updateVisiblePostComments); // Detectar cuando cambia el tamaño de la ventana window.addEventListener('resize', updateVisiblePostComments); // Marcar el color negro como seleccionado por defecto changeBackgroundColor('#000000'); // Cargar recuerdos cargarRecuerdos().then(() => { // Después de cargar los recuerdos, detectar el post visible inicial setTimeout(updateVisiblePostComments, 100); }); });