Spaces:
Running
Running
Ctrl+K
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Empathy Horizon | Experience Our Global Emotional Connection</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> <style> /* Previous styles remain unchanged */ /* New Chat System Styles */ .chat-container { display: flex; flex-direction: column; height: 300px; background: rgba(20, 30, 60, 0.5); border-radius: 10px; overflow: hidden; margin-top: 1rem; } .chat-header { background: rgba(30, 45, 90, 0.7); padding: 0.8rem; font-weight: 600; color: #6eb6ff; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(100, 150, 255, 0.2); } .online-count { background: #1dd1a1; color: #0c0f1d; padding: 0.2rem 0.5rem; border-radius: 20px; font-size: 0.8rem; font-weight: bold; } .chat-messages { flex: 1; overflow-y: auto; padding: 0.8rem; display: flex; flex-direction: column; } .message { max-width: 80%; padding: 0.8rem; margin-bottom: 0.8rem; border-radius: 12px; position: relative; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .received { align-self: flex-start; background: rgba(30, 45, 90, 0.7); border-top-left-radius: 4px; } .sent { align-self: flex-end; background: linear-gradient(135deg, #4facfe, #00f2fe); color: white; border-top-right-radius: 4px; } .message-header { display: flex; justify-content: space-between; font-size: 0.8rem; margin-bottom: 0.3rem; } .message-sender { font-weight: bold; } .message-time { color: rgba(255, 255, 255, 0.6); } .chat-input-container { display: flex; padding: 0.8rem; background: rgba(30, 45, 90, 0.7); border-top: 1px solid rgba(100, 150, 255, 0.2); } .chat-input { flex: 1; padding: 0.8rem; border-radius: 20px; border: none; background: rgba(20, 30, 60, 0.8); color: white; outline: none; } .chat-send-btn { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(135deg, #4facfe, #00f2fe); border: none; color: white; display: flex; align-items: center; justify-content: center; margin-left: 0.5rem; cursor: pointer; transition: all 0.3s ease; } .chat-send-btn:hover { transform: scale(1.1); } .emotion-tag { display: inline-block; padding: 0.2rem 0.5rem; border-radius: 20px; font-size: 0.8rem; margin-top: 0.5rem; background: rgba(255, 255, 255, 0.1); } .joy-tag { background: rgba(255, 209, 102, 0.2); } .sadness-tag { background: rgba(110, 182, 255, 0.2); } .anger-tag { background: rgba(255, 107, 107, 0.2); } .fear-tag { background: rgba(161, 130, 255, 0.2); } .trust-tag { background: rgba(29, 209, 161, 0.2); } .surprise-tag { background: rgba(255, 159, 243, 0.2); } /* Typing indicator */ .typing-indicator { display: none; align-self: flex-start; padding: 0.8rem; background: rgba(30, 45, 90, 0.7); border-radius: 12px; margin-bottom: 0.8rem; font-size: 0.8rem; color: #a0c8ff; } .typing-indicator span { display: inline-block; width: 8px; height: 8px; background: #6eb6ff; border-radius: 50%; margin: 0 2px; animation: bounce 1.3s infinite; } .typing-indicator span:nth-child(2) { animation-delay: 0.15s; } .typing-indicator span:nth-child(3) { animation-delay: 0.3s; } @keyframes bounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } } /* New chat notification */ .new-message-notification { position: absolute; top: 10px; right: 10px; background: #ff6b6b; color: white; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; font-weight: bold; display: none; } </style> </head> <body> <header> <div class="logo"> <div class="logo-icon">EH</div> <div class="logo-text">EMPATHY HORIZON</div> </div> <div class="premium-badge" id="premiumBadge"> <i class="fas fa-crown"></i> GO PREMIUM </div> <div class="premium-modal" id="premiumModal"> <h3>Unlock Premium Features</h3> <div class="premium-feature"> <i class="fas fa-globe-americas"></i> <div>Real-time global emotion heatmaps</div> </div> <div class="premium-feature"> <i class="fas fa-comments"></i> <div>Advanced chat with emotion filters</div> </div> <div class="premium-feature"> <i class="fas fa-history"></i> <div>Historical emotion trend analysis</div> </div> <div class="premium-feature"> <i class="fas fa-user-astronaut"></i> <div>Personal emotion journal & insights</div> </div> <div class="premium-feature"> <i class="fas fa-ad"></i> <div>Ad-free experience</div> </div> <div class="premium-plans"> <div class="plan" id="monthlyPlan"> <h4>Monthly</h4> <div class="plan-price">$4.99</div> <div class="plan-features">Billed monthly</div> </div> <div class="plan" id="annualPlan"> <h4>Annual</h4> <div class="plan-price">$49.99</div> <div class="plan-features">Save 15%</div> </div> </div> </div> </header> <div class="main-container"> <div id="visualization-container"> <div class="intro-overlay" id="introOverlay"> <h1 class="intro-title">EMPATHY HORIZON</h1> <p class="intro-text">Experience the emotional pulse of our planet in real-time. This visualization transforms global sentiment data into a breathtaking cosmic symphony, revealing the invisible bonds that connect us all.</p> <button class="start-button" id="startButton">ACTIVATE RESONANCE FIELD</button> </div> </div> <div class="control-panel"> <!-- Global Emotional State Panel (unchanged) --> <div class="panel-section"> <h2 class="section-title"><i class="fas fa-user-astronaut"></i> YOUR IMPACT</h2> <!-- User stats and challenges (unchanged) --> </div> <!-- Global Leaderboard Panel (unchanged) --> <div class="panel-section"> <h2 class="section-title"><i class="fas fa-newspaper"></i> EMOTIONAL EVENTS</h2> <!-- Event log (unchanged) --> </div> <!-- NEW CHAT SECTION --> <div class="panel-section"> <h2 class="section-title"><i class="fas fa-comments"></i> GLOBAL CHAT <span class="new-message-notification" id="newMessageNotification">3</span></h2> <p>Connect with people worldwide sharing emotions in real-time</p> <div class="chat-container"> <div class="chat-header"> <span>Global Emotion Chat</span> <span class="online-count"><i class="fas fa-user"></i> <span id="onlineCount">128</span> online</span> </div> <div class="chat-messages" id="chatMessages"> <div class="message received"> <div class="message-header"> <span class="message-sender">Maria K. <span class="emotion-tag joy-tag">Joy</span></span> <span class="message-time">12:04</span> </div> <div>Seeing all this hope in the visualization gives me so much energy!</div> </div> <div class="message received"> <div class="message-header"> <span class="message-sender">Alex J. <span class="emotion-tag trust-tag">Trust</span></span> <span class="message-time">12:05</span> </div> <div>Anyone else feeling that wave of solidarity right now? The blue patterns are incredible</div> </div> <div class="message received"> <div class="message-header"> <span class="message-sender">GlobalMind <span class="emotion-tag surprise-tag">AI</span></span> <span class="message-time">12:06</span> </div> <div>Current emotion patterns show 68% positive sentiment in this chat. Keep sharing your feelings!</div> </div> <div class="message sent"> <div class="message-header"> <span class="message-sender">You <span class="emotion-tag joy-tag">Joy</span></span> <span class="message-time">12:07</span> </div> <div>This is amazing! I just shared my happiness and saw it ripple through the visualization</div> </div> <div class="typing-indicator" id="typingIndicator"> <span>GlobalMind</span> is typing <span></span><span></span><span></span> </div> </div> <div class="chat-input-container"> <input type="text" class="chat-input" id="chatInput" placeholder="Share your feelings..."> <button class="chat-send-btn" id="chatSendBtn"> <i class="fas fa-paper-plane"></i> </button> </div> </div> <div class="legend" style="margin-top: 1rem;"> <div class="legend-item"> <div class="legend-color joy-color"></div> <span>Joy</span> </div> <div class="legend-item"> <div class="legend-color sadness-color"></div> <span>Sadness</span> </div> <div class="legend-item"> <div class="legend-color anger-color"></div> <span>Anger</span> </div> <div class="legend-item"> <div class="legend-color fear-color"></div> <span>Fear</span> </div> <div class="legend-item"> <div class="legend-color trust-color"></div> <span>Trust</span> </div> <div class="legend-item"> <div class="legend-color surprise-color"></div> <span>Surprise</span> </div> </div> </div> <div class="ad-container"> Advertisement Space (Premium removes ads) </div> </div> </div> <div class="status-bar"> <div class="status-item">Resonance Field: <span id="fieldStatus">STANDBY</span></div> <div class="status-item">Connected Users: <span id="nodeCount">0</span></div> <div class="status-item">Emotional Data: <span id="dataCount">0</span></div> <div class="status-item">Your Rank: <span id="userRank">#4</span></div> </div> <div class="notification" id="notification"> <div class="notification-header"> <div class="notification-title">New Achievement!</div> <div class="notification-close" id="closeNotification">×</div> </div> <div class="notification-content"> You've earned the "Empathy Explorer" badge for 5 contributions! </div> </div> <script> // Initialize Three.js and core functionality (unchanged) // New Chat Functionality const chatMessages = document.getElementById('chatMessages'); const chatInput = document.getElementById('chatInput'); const chatSendBtn = document.getElementById('chatSendBtn'); const typingIndicator = document.getElementById('typingIndicator'); const onlineCount = document.getElementById('onlineCount'); const newMessageNotification = document.getElementById('newMessageNotification'); // User data const users = ['Alex J.', 'Maria K.', 'Sam T.', 'Jordan L.', 'Taylor R.', 'Casey M.', 'Riley W.', 'Morgan B.', 'GlobalMind']; const emotions = ['joy', 'sadness', 'anger', 'fear', 'trust', 'surprise']; const emotionClasses = { joy: 'joy-tag', sadness: 'sadness-tag', anger: 'anger-tag', fear: 'fear-tag', trust: 'trust-tag', surprise: 'surprise-tag' }; // Chat messages history let unreadMessages = 0; // Initialize chat function initChat() { // Set random online count onlineCount.textContent = Math.floor(Math.random() * 100) + 50; // Add initial messages simulateIncomingMessages(); // Start periodic chat updates setInterval(simulateIncomingMessages, 10000); } // Send message function sendMessage() { const message = chatInput.value.trim(); if (message) { const now = new Date(); const emotion = emotions[Math.floor(Math.random() * emotions.length)]; const messageElement = document.createElement('div'); messageElement.className = 'message sent'; messageElement.innerHTML = ` <div class="message-header"> <span class="message-sender">You <span class="emotion-tag ${emotionClasses[emotion]}">${emotion.charAt(0).toUpperCase() + emotion.slice(1)}</span></span> <span class="message-time">${formatTime(now)}</span> </div> <div>${message}</div> `; chatMessages.appendChild(messageElement); chatInput.value = ''; // Scroll to bottom chatMessages.scrollTop = chatMessages.scrollTop + 100; // Simulate typing indicator simulateTyping(); // Add to user contributions userContributions++; document.getElementById('contributionCount').textContent = userContributions; updateChallengeProgress(); } } // Format time for messages function formatTime(date) { return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; } // Simulate incoming messages function simulateIncomingMessages() { // Only add messages if not at the bottom (simulating unread messages) const isAtBottom = chatMessages.scrollTop + chatMessages.clientHeight >= chatMessages.scrollHeight - 20; const shouldAdd = Math.random() > 0.3; if (shouldAdd) { const user = users[Math.floor(Math.random() * users.length)]; const emotion = emotions[Math.floor(Math.random() * emotions.length)]; const now = new Date(); const messages = [ `The ${emotion} patterns in the visualization are so strong right now!`, `I'm feeling so much ${emotion} today. Anyone else?`, `Just shared my ${emotion} and saw it ripple through the cosmos!`, `This ${emotion} wave is incredible! Look at the visualization!`, `How is everyone feeling about the current ${emotion} resonance?`, `I can see my ${emotion} contribution affecting the global pattern!`, `The ${emotion} clusters forming near the center are beautiful`, `Sending ${emotion} to everyone in the chat right now!` ]; const message = messages[Math.floor(Math.random() * messages.length)]; const messageElement = document.createElement('div'); messageElement.className = 'message received'; messageElement.innerHTML = ` <div class="message-header"> <span class="message-sender">${user} <span class="emotion-tag ${emotionClasses[emotion]}">${emotion.charAt(0).toUpperCase() + emotion.slice(1)}</span></span> <span class="message-time">${formatTime(now)}</span> </div> <div>${message}</div> `; chatMessages.appendChild(messageElement); // Update unread messages count if (!isAtBottom) { unreadMessages++; newMessageNotification.textContent = unreadMessages; newMessageNotification.style.display = 'flex'; } // Scroll to bottom if user was already there if (isAtBottom) { chatMessages.scrollTop = chatMessages.scrollHeight; } } } // Simulate AI typing function simulateTyping() { typingIndicator.style.display = 'flex'; setTimeout(() => { typingIndicator.style.display = 'none'; // Add AI response const now = new Date(); const responses = [ "Your emotion has been added to the global resonance field!", "I can see your emotional signature in the visualization!", "Your contribution is affecting the global emotional patterns.", "Thank you for sharing your emotional state with the world!", "I've detected increased resonance from your emotional input.", "Your emotion is creating beautiful patterns in the cosmos!", "The collective consciousness is responding to your emotion!" ]; const response = responses[Math.floor(Math.random() * responses.length)]; const messageElement = document.createElement('div'); messageElement.className = 'message received'; messageElement.innerHTML = ` <div class="message-header"> <span class="message-sender">GlobalMind <span class="emotion-tag surprise-tag">AI</span></span> <span class="message-time">${formatTime(now)}</span> </div> <div>${response}</div> `; chatMessages.appendChild(messageElement); chatMessages.scrollTop = chatMessages.scrollHeight; // Update unread messages unreadMessages++; newMessageNotification.textContent = unreadMessages; newMessageNotification.style.display = 'flex'; }, 2000 + Math.random() * 2000); } // Update challenge progress function updateChallengeProgress() { const progress = (userContributions % 3) * 33.33; challengeProgress.style.width = `${progress}%`; document.querySelector('.daily-challenge div').textContent = `${userContributions % 3}/3 completed`; if (userContributions % 3 === 0) { showNotification("Daily challenge completed! +10 Influence Points"); userInfluence += 10; document.getElementById('influenceScore').textContent = userInfluence; } } // Initialize chat when the app starts startButton.addEventListener('click', () => { // ... existing initialization code ... initChat(); }); // Send message events chatSendBtn.addEventListener('click', sendMessage); chatInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { sendMessage(); } }); // Clear notification when chat is viewed chatMessages.addEventListener('scroll', () => { const isAtBottom = chatMessages.scrollTop + chatMessages.clientHeight >= chatMessages.scrollHeight - 20; if (isAtBottom && unreadMessages > 0) { unreadMessages = 0; newMessageNotification.style.display = 'none'; } }); // ... rest of the JavaScript code remains unchanged ... </script> </body> </html> - Initial Deployment
4595ef8 verified