Spaces:
Running
Running
| // Global State | |
| let appState = { | |
| theme: 'dark', | |
| isLocked: false, | |
| currentPage: 'home', | |
| userSettings: { | |
| animations: true, | |
| sounds: true, | |
| notifications: true | |
| } | |
| }; | |
| // Initialize App | |
| document.addEventListener('DOMContentLoaded', () => { | |
| initTheme(); | |
| initNavigation(); | |
| loadFeatures(); | |
| initChat(); | |
| createParticles(); | |
| }); | |
| // Theme Management | |
| function initTheme() { | |
| const savedTheme = localStorage.getItem('theme') || 'dark'; | |
| appState.theme = savedTheme; | |
| document.documentElement.classList.add(savedTheme); | |
| // Set theme colors based on user preference | |
| if (appState.theme === 'dark') { | |
| document.documentElement.style.setProperty('--primary', '#4F46E5'); | |
| document.documentElement.style.setProperty('--secondary', '#EC4899'); | |
| document.documentElement.style.setProperty('--accent', '#06B6D4'); | |
| document.documentElement.style.setProperty('--background', '#0F172A'); | |
| document.documentElement.style.setProperty('--surface', '#1E293B'); | |
| document.documentElement.style.setProperty('--text', '#F8FAFC'); | |
| document.documentElement.style.setProperty('--subtle', '#94A3B8'); | |
| } | |
| } | |
| // Navigation System | |
| function initNavigation() { | |
| const navButtons = document.querySelectorAll('.nav-btn'); | |
| const mainContent = document.getElementById('main-content'); | |
| navButtons.forEach(btn => { | |
| btn.addEventListener('click', () => { | |
| const targetPage = btn.dataset.nav; | |
| // Update active state | |
| navButtons.forEach(b => b.classList.remove('active')); | |
| btn.classList.add('active'); | |
| // Update app state | |
| appState.currentPage = targetPage; | |
| // Load page content | |
| loadPageContent(targetPage); | |
| // Update URL without reload | |
| history.pushState({ page: targetPage }, '', `/${targetPage}`); | |
| }); | |
| }); | |
| // Handle browser back/forward | |
| window.addEventListener('popstate', (event) => { | |
| if (event.state && event.state.page) { | |
| loadPageContent(event.state.page); | |
| } | |
| }); | |
| } | |
| async function loadPageContent(page) { | |
| const mainContent = document.getElementById('main-content'); | |
| // Show loading state | |
| mainContent.innerHTML = ` | |
| <div class="flex items-center justify-center min-h-[60vh]"> | |
| <div class="text-center"> | |
| <div class="loading-dots inline-block mb-4"> | |
| <span></span><span></span><span></span> | |
| </div> | |
| <p class="text-subtle">Loading ${page}...</p> | |
| </div> | |
| `; | |
| try { | |
| const response = await fetch(`pages/${page}.html`); | |
| const content = await response.text(); | |
| // Add fade-in animation | |
| mainContent.innerHTML = content; | |
| mainContent.classList.add('opacity-0'); | |
| setTimeout(() => { | |
| mainContent.classList.remove('opacity-0'); | |
| mainContent.classList.add('opacity-100'); | |
| }, 50); | |
| // Re-initialize page-specific functionality | |
| switch(page) { | |
| case 'home': | |
| loadFeatures(); | |
| break; | |
| case 'chat': | |
| initChat(); | |
| break; | |
| case 'settings': | |
| initSettings(); | |
| break; | |
| } | |
| } catch (error) { | |
| mainContent.innerHTML = ` | |
| <div class="text-center py-12"> | |
| <i data-feather="alert-triangle" class="w-16 h-16 mx-auto text-secondary mb-4"></i> | |
| <h3 class="text-xl font-bold mb-2">Page Not Found</h3> | |
| <p class="text-subtle mb-6">The requested page could not be loaded.</p> | |
| <button onclick="loadPageContent('home')" class="bg-primary text-white px-6 py-3 rounded-lg hover:bg-primary/80 transition"> | |
| Return Home | |
| </button> | |
| </div> | |
| `; | |
| feather.replace(); | |
| } | |
| } | |
| // Load Features from Public API | |
| async function loadFeatures() { | |
| const featuresContainer = document.querySelector('.features-section .grid'); | |
| if (!featuresContainer) return; | |
| try { | |
| // Using NASA APOD API for demonstration | |
| const response = await fetch('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&count=6'); | |
| const features = await response.json(); | |
| featuresContainer.innerHTML = features.map((feature, index) => ` | |
| <div class="hover-card glass rounded-2xl p-6 transform transition-all duration-300 hover:scale-[1.02] animate-float" style="animation-delay: ${index * 0.1}s"> | |
| <div class="flex items-center gap-4 mb-4"> | |
| <div class="w-12 h-12 rounded-xl bg-gradient-to-br from-primary to-secondary flex items-center justify-center"> | |
| <i data-feather="${getRandomIcon()}" class="text-white"></i> | |
| </div> | |
| <h3 class="text-lg font-bold mb-2">${feature.title}</h3> | |
| <p class="text-subtle text-sm mb-4">${feature.explanation.substring(0, 100)}...</p> | |
| <div class="flex items-center justify-between"> | |
| <span class="text-xs bg-surface px-3 py-1 rounded-full"> | |
| ${new Date(feature.date).toLocaleDateString()} | |
| </span> | |
| <button onclick="openFeatureModal(${index})" class="text-accent hover:text-accent/80 transition"> | |
| <i data-feather="arrow-right"></i> | |
| </button> | |
| </div> | |
| </div> | |
| `).join(''); | |
| feather.replace(); | |
| } catch (error) { | |
| featuresContainer.innerHTML = ` | |
| <div class="col-span-3 text-center py-8"> | |
| <p class="text-subtle">Unable to load features at this time.</p> | |
| </div> | |
| `; | |
| } | |
| } | |
| // Chat System | |
| function initChat() { | |
| const chatInterface = document.querySelector('.chat-interface'); | |
| if (!chatInterface) return; | |
| chatInterface.innerHTML = ` | |
| <div class="flex flex-col space-y-4 mb-6"> | |
| <div class="chat-message user"> | |
| <p>Hello AI Mirror!</p> | |
| </div> | |
| <div class="chat-message ai"> | |
| <p>Greetings! I am your neural companion. How can I assist you today?</p> | |
| </div> | |
| </div> | |
| <div class="flex gap-2"> | |
| <input type="text" placeholder="Ask me anything..." class="flex-1 bg-surface border border-white/10 rounded-lg px-4 py-3 focus:outline-none focus:ring-2 focus:ring-primary"> | |
| <button onclick="sendMessage()" class="bg-primary text-white px-6 py-3 rounded-lg hover:bg-primary/80 transition"> | |
| <i data-feather="send"></i> | |
| </button> | |
| </div> | |
| `; | |
| feather.replace(); | |
| } | |
| function sendMessage() { | |
| const input = document.querySelector('.chat-interface input'); | |
| const message = input.value.trim(); | |
| if (!message) return; | |
| const chatInterface = document.querySelector('.chat-interface'); | |
| // Add user message | |
| chatInterface.insertAdjacentHTML('beforeend', ` | |
| <div class="chat-message user"> | |
| <p>${message}</p> | |
| </div> | |
| `); | |
| // Clear input | |
| input.value = ''; | |
| // Show typing indicator | |
| chatInterface.insertAdjacentHTML('beforeend', ` | |
| <div class="typing-indicator"> | |
| <span></span><span></span><span></span> | |
| </div> | |
| `); | |
| // Simulate AI response after delay | |
| setTimeout(() => { | |
| document.querySelector('.typing-indicator')?.remove(); | |
| // Using public AI API (example with DeepAI) | |
| fetchAIResponse(message).then(response => { | |
| chatInterface.insertAdjacentHTML('beforeend', ` | |
| <div class="chat-message ai"> | |
| <p>${response}</p> | |
| </div> | |
| `); | |
| // Scroll to bottom | |
| chatInterface.scrollTop = chatInterface.scrollHeight; | |
| }); | |
| }, 1500); | |
| } | |
| async function fetchAIResponse(message) { | |
| try { | |
| // Using OpenAI-like API (example) | |
| const response = await fetch('https://api.deepai.org/api/text-generator', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'api-key': 'quickstart-QUdJIGlzIGNvbWluZy4uLi4K', | |
| }, | |
| body: JSON.stringify({ | |
| text: message, | |
| model: 'gpt-3' | |
| }) | |
| }); | |
| const data = await response.json(); | |
| return data.output || "I'm processing your request. Please try again."; | |
| } catch (error) { | |
| return "I apologize, but I'm having trouble processing your request right now."; | |
| } | |
| } | |
| // Utility Functions | |
| function getRandomIcon() { | |
| const icons = ['star', 'moon', 'sun', 'cloud', 'compass', 'zap', 'heart', 'cpu', 'globe', 'eye']; | |
| return icons[Math.floor(Math.random() * icons.length)]; | |
| } | |
| function openFeatureModal(index) { | |
| const modal = document.createElement('div'); | |
| modal.className = 'fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm'; | |
| modal.innerHTML = ` | |
| <div class="bg-surface rounded-2xl p-6 max-w-md w-full"> | |
| <h3 class="text-xl font-bold mb-4">Feature Details</h3> | |
| <p>Detailed information about feature ${index + 1}.</p> | |
| <div class="flex justify-end gap-2 mt-6"> | |
| <button onclick="this.closest('.fixed').remove()" class="px-4 py-2 rounded-lg bg-surface hover:bg-surface/80 transition"> | |
| Close | |
| </button> | |
| </div> | |
| </div> | |
| `; | |
| document.body.appendChild(modal); | |
| feather.replace(); | |
| } | |
| // Particle Background | |
| function createParticles() { | |
| const particleCount = 50; | |
| for (let i = 0; i < particleCount; i++) { | |
| const particle = document.createElement('div'); | |
| particle.className = 'particle'; | |
| // Random position and size | |
| const size = Math.random() * 3 + 1; | |
| particle.style.width = `${size}px`; | |
| particle.style.height = `${size}px`; | |
| particle.style.left = `${Math.random() * 100}vw`; | |
| particle.style.top = `${Math.random() * 100}vh`; | |
| // Random animation | |
| particle.style.animation = `float ${Math.random() * 10 + 10}s ease-in-out infinite`; | |
| particle.style.animationDelay = `${Math.random() * 5}s`; | |
| document.body.appendChild(particle); | |
| } | |
| } | |
| // Settings Management | |
| function initSettings() { | |
| const settingsElements = document.querySelectorAll('.setting-toggle'); | |
| settingsElements.forEach(element => { | |
| element.addEventListener('change', (e) => { | |
| const setting = e.target.dataset.setting; | |
| const value = e.target.checked; | |
| appState.userSettings[setting] = value; | |
| localStorage.setItem('settings', JSON.stringify(appState.userSettings)); | |
| // Apply setting changes | |
| if (setting === 'animations') { | |
| document.body.classList.toggle('no-animations', !value); | |
| } | |
| }); | |
| } | |
| // Lock Screen Management | |
| function toggleLockScreen() { | |
| const lockScreen = document.querySelector('custom-lockscreen'); | |
| if (lockScreen) { | |
| lockScreen.toggleLock(); | |
| } | |
| } | |
| // Export functions for components | |
| window.appFunctions = { | |
| loadPageContent, | |
| toggleLockScreen, | |
| sendMessage | |
| }; |