// NeuroMorph Gallery - Shared JavaScript class NeuroMorphGallery { constructor() { this.artworks = []; this.currentPage = 1; this.artworksPerPage = 9; this.init(); } async init() { await this.registerServiceWorker(); this.setupEventListeners(); await this.loadArtworks(); this.updateStats(); this.setupOfflineDetection(); } // PWA Service Worker Registration async registerServiceWorker() { if ('serviceWorker' in navigator) { try { await navigator.serviceWorker.register('/sw.js'); console.log('Service Worker registered successfully'); } catch (error) { console.error('Service Worker registration failed:', error); } } } // GraphQL API Integration async fetchArtworks(page = 1) { const query = ` query GetArtworks($page: Int!, $limit: Int!) { artworks(page: $page, limit: $limit) { id title description imageUrl artist { name avatar } likes views createdAt tags } } `; try { const response = await fetch('/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ query, variables: { page, limit: this.artworksPerPage } }) }); const result = await response.json(); return result.data?.artworks || []; } catch (error) { console.error('Error fetching artworks:', error); // Fallback to mock data if API is unavailable return this.getMockArtworks(page); } } // Mock data for demonstration getMockArtworks(page) { const mockArtworks = []; const startIndex = (page - 1) * this.artworksPerPage; for (let i = 0; i < this.artworksPerPage; i++) { mockArtworks.push({ id: `artwork-${startIndex + i + 1}`, title: `AI Dreamscape ${startIndex + i + 1}`, description: 'A stunning AI-generated artwork showcasing the intersection of technology and creativity.', imageUrl: `http://static.photos/abstract/640x360/${startIndex + i + 1}`, artist: { name: `NeuralArtist${startIndex + i + 1}`, avatar: `http://static.photos/people/200x200/${startIndex + i + 1}` }, likes: Math.floor(Math.random() * 1000), views: Math.floor(Math.random() * 5000), createdAt: new Date().toISOString(), tags: ['AI', 'Digital Art', 'Abstract', 'Modern'] }); } return mockArtworks; } // Load and display artworks async loadArtworks() { const artworks = await this.fetchArtworks(this.currentPage); this.artworks = [...this.artworks, ...artworks]; this.renderArtworks(artworks); } renderArtworks(artworks) { const grid = document.getElementById('artworks-grid'); artworks.forEach(artwork => { const artworkCard = document.createElement('artwork-card'); artworkCard.setAttribute('data-artwork', JSON.stringify(artwork)); grid.appendChild(artworkCard); }); } // Update statistics updateStats() { // Simulate real-time stats updates setInterval(() => { document.getElementById('total-artworks').textContent = (1247 + Math.floor(Math.random() * 10)).toLocaleString(); document.getElementById('active-artists').textContent = (356 + Math.floor(Math.random() * 5)).toLocaleString(); document.getElementById('monthly-views').textContent = (89200 + Math.floor(Math.random() * 1000)).toLocaleString(); }, 5000); } // Event listeners setup setupEventListeners() { // Load more artworks const loadMoreBtn = document.getElementById('load-more'); if (loadMoreBtn) { loadMoreBtn.addEventListener('click', () => { this.currentPage++; this.loadArtworks(); }); } // Search functionality const searchInput = document.querySelector('input[type="search"]'); if (searchInput) { searchInput.addEventListener('input', (e) => { this.searchArtworks(e.target.value); }); } } // Search artworks searchArtworks(query) { const filtered = this.artworks.filter(artwork => artwork.title.toLowerCase().includes(query.toLowerCase()) || artwork.description.toLowerCase().includes(query.toLowerCase()) || artwork.tags.some(tag => tag.toLowerCase().includes(query.toLowerCase())) ); this.renderSearchResults(filtered); } renderSearchResults(artworks) { const grid = document.getElementById('artworks-grid'); grid.innerHTML = ''; artworks.forEach(artwork => { const artworkCard = document.createElement('artwork-card'); artworkCard.setAttribute('data-artwork', JSON.stringify(artwork)); grid.appendChild(artworkCard); }); } // Offline detection setupOfflineDetection() { window.addEventListener('online', () => { this.hideOfflineIndicator(); console.log('App is online'); }); window.addEventListener('offline', () => { this.showOfflineIndicator(); console.log('App is offline'); }); } showOfflineIndicator() { const indicator = document.createElement('div'); indicator.className = 'offline-indicator'; indicator.textContent = 'You are currently offline. Some features may be limited.'; indicator.style.display = 'block'; document.body.appendChild(indicator); } hideOfflineIndicator() { const indicator = document.querySelector('.offline-indicator'); if (indicator) { indicator.style.display = 'none'; } } // Image optimization and lazy loading optimizeImages() { const images = document.querySelectorAll('img[data-src]'); const imageObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; img.removeAttribute('data-src'); observer.unobserve(img); } }); }); images.forEach(img => imageObserver.observe(img)); } } // Initialize the gallery when DOM is loaded document.addEventListener('DOMContentLoaded', () => { new NeuroMorphGallery(); }); // Export for use in other modules window.NeuroMorphGallery = NeuroMorphGallery;