Spaces:
Running
Running
| // 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; |