// ===== GLOBAL VARIABLES AND INITIALIZATION ===== let currentPlatformURL = ''; let currentPlatformName = ''; let currentPlatform = ''; let currentNoteEditPlatform = ''; let timeTrackingInterval = null; let startTime = null; let currentImageData = null; let currentDescription = ''; let currentCaptions = ''; let currentHashtags = ''; // ===== STORAGE MANAGER ===== const StorageManager = { // Get favorites getFavorites: () => { const favorites = localStorage.getItem('socialHub_favorites'); return favorites ? JSON.parse(favorites) : []; }, // Set favorites setFavorites: (favorites) => { localStorage.setItem('socialHub_favorites', JSON.stringify(favorites)); }, // Toggle favorite toggleFavorite: (platform) => { const favorites = StorageManager.getFavorites(); const index = favorites.indexOf(platform); if (index > -1) { favorites.splice(index, 1); } else { favorites.push(platform); } StorageManager.setFavorites(favorites); return favorites; }, // Get notes getNotes: () => { const notes = localStorage.getItem('socialHub_notes'); return notes ? JSON.parse(notes) : {}; }, // Set note setNote: (platform, note) => { const notes = StorageManager.getNotes(); if (note.trim()) { notes[platform] = note; } else { delete notes[platform]; } localStorage.setItem('socialHub_notes', JSON.stringify(notes)); }, // Get analytics getAnalytics: () => { const analytics = localStorage.getItem('socialHub_analytics'); return analytics ? JSON.parse(analytics) : {}; }, // Update analytics updateAnalytics: (platform) => { const analytics = StorageManager.getAnalytics(); if (!analytics[platform]) { analytics[platform] = { visits: 0, time: 0, lastVisit: null }; } analytics[platform].visits++; analytics[platform].lastVisit = new Date().toISOString(); localStorage.setItem('socialHub_analytics', JSON.stringify(analytics)); }, // Update time spent updateTimeSpent: (platform, seconds) => { const analytics = StorageManager.getAnalytics(); if (!analytics[platform]) { analytics[platform] = { visits: 0, time: 0, lastVisit: null }; } analytics[platform].time = (analytics[platform].time || 0) + seconds; localStorage.setItem('socialHub_analytics', JSON.stringify(analytics)); }, // Get recent activity getRecentActivity: () => { const recent = localStorage.getItem('socialHub_recent'); return recent ? JSON.parse(recent) : []; }, // Add to recent addToRecent: (platform, name, icon) => { let recent = StorageManager.getRecentActivity(); recent = recent.filter(item => item.platform !== platform); recent.unshift({ platform, name, icon, timestamp: new Date().toISOString() }); recent = recent.slice(0, 10); localStorage.setItem('socialHub_recent', JSON.stringify(recent)); }, // Get theme getTheme: () => { return localStorage.getItem('socialHub_theme') || 'dark'; }, // Set theme setTheme: (theme) => { localStorage.setItem('socialHub_theme', theme); }, // Get custom platforms getCustomPlatforms: () => { const custom = localStorage.getItem('socialHub_custom'); return custom ? JSON.parse(custom) : []; }, // Add custom platform addCustomPlatform: (platform) => { const custom = StorageManager.getCustomPlatforms(); custom.push(platform); localStorage.setItem('socialHub_custom', JSON.stringify(custom)); }, // Remove custom platform removeCustomPlatform: (id) => { let custom = StorageManager.getCustomPlatforms(); custom = custom.filter(p => p.id !== id); localStorage.setItem('socialHub_custom', JSON.stringify(custom)); } }; // ===== Particles Background Animation ===== const canvas = document.getElementById('particles'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; let particlesArray = []; const numberOfParticles = 100; class Particle { constructor() { this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.size = Math.random() * 2 + 1; this.speedX = Math.random() * 1 - 0.5; this.speedY = Math.random() * 1 - 0.5; this.opacity = Math.random() * 0.5 + 0.2; } update() { this.x += this.speedX; this.y += this.speedY; if (this.x > canvas.width || this.x < 0) { this.speedX = -this.speedX; } if (this.y > canvas.height || this.y < 0) { this.speedY = -this.speedY; } } draw() { ctx.fillStyle = `rgba(0, 212, 255, ${this.opacity})`; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); } } function initParticles() { particlesArray = []; for (let i = 0; i < numberOfParticles; i++) { particlesArray.push(new Particle()); } } function animateParticles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i = 0; i < particlesArray.length; i++) { particlesArray[i].update(); particlesArray[i].draw(); // Connect particles with lines for (let j = i; j < particlesArray.length; j++) { const dx = particlesArray[i].x - particlesArray[j].x; const dy = particlesArray[i].y - particlesArray[j].y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 100) { ctx.strokeStyle = `rgba(0, 212, 255, ${0.2 * (1 - distance / 100)})`; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(particlesArray[i].x, particlesArray[i].y); ctx.lineTo(particlesArray[j].x, particlesArray[j].y); ctx.stroke(); } } } requestAnimationFrame(animateParticles); } // ===== Window Resize Handler ===== window.addEventListener('resize', () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; initParticles(); }); // ===== Search Functionality ===== const searchInput = document.getElementById('searchInput'); const socialCards = document.querySelectorAll('.social-card'); searchInput.addEventListener('input', (e) => { const searchTerm = e.target.value.toLowerCase(); const activeFilter = document.querySelector('.filter-tab.active')?.getAttribute('data-filter') || 'all'; socialCards.forEach(card => { const platform = card.getAttribute('data-platform'); const platformName = card.querySelector('.platform-name').textContent.toLowerCase(); const platformDesc = card.querySelector('.platform-desc').textContent.toLowerCase(); const category = card.getAttribute('data-category'); const isFavorite = StorageManager.getFavorites().includes(platform); const matchesSearch = platform.includes(searchTerm) || platformName.includes(searchTerm) || platformDesc.includes(searchTerm); const matchesFilter = activeFilter === 'all' || (activeFilter === 'favorites' && isFavorite) || (activeFilter === 'recent' && isInRecentActivity(platform)) || (activeFilter !== 'favorites' && activeFilter !== 'recent' && category === activeFilter); if (matchesSearch && matchesFilter) { card.classList.remove('hidden'); } else { card.classList.add('hidden'); } }); }); function isInRecentActivity(platform) { const recent = StorageManager.getRecentActivity(); return recent.some(item => item.platform === platform); } // ===== FILTER FUNCTIONALITY ===== const filterTabs = document.querySelectorAll('.filter-tab'); const recentTimeline = document.getElementById('recentTimeline'); filterTabs.forEach(tab => { tab.addEventListener('click', () => { // Update active tab filterTabs.forEach(t => t.classList.remove('active')); tab.classList.add('active'); const filter = tab.getAttribute('data-filter'); // Show/hide recent timeline if (filter === 'recent') { updateRecentTimeline(); recentTimeline.style.display = 'block'; } else { recentTimeline.style.display = 'none'; } // Filter cards filterCards(filter); }); }); function filterCards(filter) { const favorites = StorageManager.getFavorites(); socialCards.forEach(card => { const platform = card.getAttribute('data-platform'); const category = card.getAttribute('data-category'); const searchTerm = searchInput.value.toLowerCase(); const platformName = card.querySelector('.platform-name').textContent.toLowerCase(); const platformDesc = card.querySelector('.platform-desc').textContent.toLowerCase(); const matchesSearch = !searchTerm || platform.includes(searchTerm) || platformName.includes(searchTerm) || platformDesc.includes(searchTerm); let show = false; if (filter === 'all') { show = true; } else if (filter === 'favorites') { show = favorites.includes(platform); } else if (filter === 'recent') { show = isInRecentActivity(platform); } else { show = category === filter; } if (show && matchesSearch) { card.classList.remove('hidden'); } else { card.classList.add('hidden'); } }); } // ===== FAVORITES FUNCTIONALITY ===== function initializeFavorites() { const favorites = StorageManager.getFavorites(); socialCards.forEach(card => { const platform = card.getAttribute('data-platform'); const favBtn = card.querySelector('.favorite-btn'); if (favorites.includes(platform)) { favBtn.classList.add('active'); favBtn.querySelector('i').classList.remove('far'); favBtn.querySelector('i').classList.add('fas'); } favBtn.addEventListener('click', (e) => { e.stopPropagation(); e.preventDefault(); toggleFavorite(platform, favBtn); }); }); } function toggleFavorite(platform, btn) { const favorites = StorageManager.toggleFavorite(platform); const isFavorite = favorites.includes(platform); if (isFavorite) { btn.classList.add('active'); btn.querySelector('i').classList.remove('far'); btn.querySelector('i').classList.add('fas'); showNotification(`Added to favorites!`, 'success'); } else { btn.classList.remove('active'); btn.querySelector('i').classList.remove('fas'); btn.querySelector('i').classList.add('far'); showNotification(`Removed from favorites`, 'info'); } updateAnalyticsDisplay(); } // ===== NOTES FUNCTIONALITY ===== const noteModal = document.getElementById('noteModal'); const noteTextarea = document.getElementById('noteTextarea'); const notePlatformName = document.getElementById('notePlatformName'); const saveNoteBtn = document.getElementById('saveNoteBtn'); const deleteNoteBtn = document.getElementById('deleteNoteBtn'); function initializeNotes() { const notes = StorageManager.getNotes(); socialCards.forEach(card => { const platform = card.getAttribute('data-platform'); const noteBtn = card.querySelector('.note-btn'); const noteIndicator = card.querySelector('.note-indicator'); if (notes[platform]) { noteBtn.classList.add('has-note'); noteIndicator.style.display = 'inline-flex'; } noteBtn.addEventListener('click', (e) => { e.stopPropagation(); e.preventDefault(); openNoteModal(platform, card.querySelector('.platform-name').textContent); }); }); } function openNoteModal(platform, name) { currentNoteEditPlatform = platform; notePlatformName.textContent = name; const notes = StorageManager.getNotes(); noteTextarea.value = notes[platform] || ''; noteModal.classList.add('active'); document.body.style.overflow = 'hidden'; noteTextarea.focus(); } saveNoteBtn.addEventListener('click', () => { const note = noteTextarea.value; StorageManager.setNote(currentNoteEditPlatform, note); // Update UI const card = document.querySelector(`[data-platform="${currentNoteEditPlatform}"]`); const noteBtn = card.querySelector('.note-btn'); const noteIndicator = card.querySelector('.note-indicator'); if (note.trim()) { noteBtn.classList.add('has-note'); noteIndicator.style.display = 'inline-flex'; showNotification('Note saved!', 'success'); } else { noteBtn.classList.remove('has-note'); noteIndicator.style.display = 'none'; showNotification('Note deleted', 'info'); } noteModal.classList.remove('active'); document.body.style.overflow = ''; }); deleteNoteBtn.addEventListener('click', () => { noteTextarea.value = ''; saveNoteBtn.click(); }); // ===== Card Click Analytics (Optional) ===== // Platform URLs mapping const platformURLs = { facebook: 'https://www.facebook.com', instagram: 'https://www.instagram.com', twitter: 'https://www.twitter.com', linkedin: 'https://www.linkedin.com', youtube: 'https://www.youtube.com', tiktok: 'https://www.tiktok.com', reddit: 'https://www.reddit.com', whatsapp: 'https://web.whatsapp.com', telegram: 'https://web.telegram.org', discord: 'https://discord.com/app', snapchat: 'https://www.snapchat.com', pinterest: 'https://www.pinterest.com' }; // Platform icons mapping const platformIcons = { facebook: 'fab fa-facebook-f', instagram: 'fab fa-instagram', twitter: 'fab fa-twitter', linkedin: 'fab fa-linkedin-in', youtube: 'fab fa-youtube', tiktok: 'fab fa-tiktok', reddit: 'fab fa-reddit-alien', whatsapp: 'fab fa-whatsapp', telegram: 'fab fa-telegram-plane', discord: 'fab fa-discord', snapchat: 'fab fa-snapchat-ghost', pinterest: 'fab fa-pinterest-p' }; // Modal elements const modal = document.getElementById('platformModal'); const modalFrame = document.getElementById('platformFrame'); const loadingSpinner = document.querySelector('.loading-spinner'); const closeBtn = document.querySelector('.close-btn'); const platformIcon = document.querySelector('.platform-icon'); const platformTitle = document.querySelector('.platform-title'); const modalContent = document.querySelector('.modal-content'); // Auth section elements const authSection = document.getElementById('authSection'); const platformSection = document.getElementById('platformSection'); const googleSignInBtn = document.getElementById('googleSignIn'); const platformSignInBtn = document.getElementById('platformSignIn'); const guestAccessBtn = document.getElementById('guestAccess'); const refreshBtn = document.querySelector('.refresh-btn'); const fullscreenBtn = document.querySelector('.fullscreen-btn'); const logoutBtn = document.querySelector('.logout-btn'); const platformIconLarge = document.querySelector('.platform-icon-large'); const platformIconSmall = document.querySelector('.platform-icon-small'); const platformNameText = document.querySelector('.platform-name-text'); const platformLoginText = document.querySelector('.platform-login-text'); socialCards.forEach(card => { const launchBtn = card.querySelector('.launch-btn'); launchBtn.addEventListener('click', (e) => { e.preventDefault(); const platform = card.getAttribute('data-platform'); const platformName = card.querySelector('.platform-name').textContent; const url = platformURLs[platform]; const icon = platformIcons[platform]; console.log(`Opening ${platform} in modal`); // Update analytics StorageManager.updateAnalytics(platform); StorageManager.addToRecent(platform, platformName, icon); updateVisitBadge(card, platform); updateAnalyticsDisplay(); // Open platform in modal openPlatformModal(url, platformName, platform); // Add a visual feedback card.style.transform = 'scale(0.95)'; setTimeout(() => { card.style.transform = ''; }, 200); }); }); // Open platform in modal function openPlatformModal(url, name, platform) { currentPlatformURL = url; currentPlatformName = name; currentPlatform = platform; // Set platform info in header platformTitle.textContent = name; platformIcon.className = 'platform-icon ' + platformIcons[platform]; // Set platform info in auth section platformNameText.textContent = name; platformIconLarge.className = 'platform-icon-large ' + platformIcons[platform]; platformIconSmall.className = 'platform-icon-small ' + platformIcons[platform]; platformLoginText.textContent = `Login with ${name} Account`; // Show modal with auth section modal.classList.add('active'); document.body.style.overflow = 'hidden'; // Show auth section, hide platform section authSection.style.display = 'flex'; platformSection.style.display = 'none'; } // Close modal function closePlatformModal() { modal.classList.remove('active'); document.body.style.overflow = ''; modalContent.classList.remove('fullscreen'); // Stop time tracking stopTimeTracking(); // Clear iframe and reset to auth section setTimeout(() => { modalFrame.src = ''; authSection.style.display = 'flex'; platformSection.style.display = 'none'; loadingSpinner.classList.remove('hidden'); }, 300); } // Load platform with authentication function loadPlatform(authMethod) { console.log(`Loading ${currentPlatformName} with ${authMethod} authentication`); // Hide auth section, show platform section authSection.style.display = 'none'; platformSection.style.display = 'block'; // Show loading loadingSpinner.classList.remove('hidden'); // Load iframe modalFrame.src = currentPlatformURL; // Hide loading when iframe loads (or after timeout) modalFrame.onload = () => { setTimeout(() => { loadingSpinner.classList.add('hidden'); }, 500); }; // Fallback timeout for platforms that block iframes setTimeout(() => { loadingSpinner.classList.add('hidden'); }, 3000); } // Google Sign-In googleSignInBtn.addEventListener('click', () => { console.log('Google Sign-In clicked'); showNotification('Google Sign-In feature coming soon! Opening platform directly...', 'info'); // Open platform in a large popup window const width = 1200; const height = 800; const left = (screen.width - width) / 2; const top = (screen.height - height) / 2; setTimeout(() => { window.open( currentPlatformURL, currentPlatformName, `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no,scrollbars=yes,resizable=yes` ); closePlatformModal(); }, 1000); }); // Platform Sign-In platformSignInBtn.addEventListener('click', () => { console.log('Platform Sign-In clicked'); showNotification(`Opening ${currentPlatformName} in new window...`, 'success'); // Start time tracking startTimeTracking(currentPlatform); // Open platform in a large popup window const width = 1200; const height = 800; const left = (screen.width - width) / 2; const top = (screen.height - height) / 2; window.open( currentPlatformURL, currentPlatformName, `width=${width},height=${height},left=${left},top=${top},toolbar=no,menubar=no,scrollbars=yes,resizable=yes` ); // Close the modal since platform opened in new window setTimeout(() => { closePlatformModal(); }, 500); }); // Guest Access / Web Version guestAccessBtn.addEventListener('click', () => { console.log('Guest access clicked'); showNotification(`Opening ${currentPlatformName} web version...`, 'info'); // Open platform in a large popup window const width = 1200; const height = 800; const left = (screen.width - width) / 2; const top = (screen.height - height) / 2; window.open( currentPlatformURL, currentPlatformName + '_Web', `width=${width},height=${height},left=${left},top=${top},toolbar=yes,menubar=no,scrollbars=yes,resizable=yes,location=yes` ); // Close the modal setTimeout(() => { closePlatformModal(); }, 500); }); // Notification system function showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.innerHTML = ` ${message} `; document.body.appendChild(notification); // Animate in setTimeout(() => notification.classList.add('show'), 10); // Remove after 3 seconds setTimeout(() => { notification.classList.remove('show'); setTimeout(() => notification.remove(), 300); }, 3000); } // Close button closeBtn.addEventListener('click', closePlatformModal); // Close on background click modal.addEventListener('click', (e) => { if (e.target === modal) { closePlatformModal(); } }); // Refresh button refreshBtn.addEventListener('click', () => { loadingSpinner.classList.remove('hidden'); modalFrame.src = modalFrame.src; setTimeout(() => { loadingSpinner.classList.add('hidden'); }, 2000); }); // Fullscreen button fullscreenBtn.addEventListener('click', () => { modalContent.classList.toggle('fullscreen'); const icon = fullscreenBtn.querySelector('i'); if (modalContent.classList.contains('fullscreen')) { icon.classList.remove('fa-expand'); icon.classList.add('fa-compress'); fullscreenBtn.title = 'Exit Fullscreen'; } else { icon.classList.remove('fa-compress'); icon.classList.add('fa-expand'); fullscreenBtn.title = 'Fullscreen'; } }); // Logout button - returns to auth screen logoutBtn.addEventListener('click', () => { showNotification('Logged out successfully', 'success'); authSection.style.display = 'flex'; platformSection.style.display = 'none'; modalFrame.src = ''; }); // Escape key to close modal document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && modal.classList.contains('active')) { closePlatformModal(); } }); // ===== Card Hover Sound Effect (Optional) ===== socialCards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)'; }); }); // ===== Smooth Scroll ===== document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // ===== Dynamic Time-based Greeting (Optional Enhancement) ===== function updateGreeting() { const hour = new Date().getHours(); const subtitle = document.querySelector('.subtitle'); if (hour >= 5 && hour < 12) { subtitle.textContent = 'Good morning! Connect to your favorite platforms'; } else if (hour >= 12 && hour < 17) { subtitle.textContent = 'Good afternoon! Connect to your favorite platforms'; } else if (hour >= 17 && hour < 21) { subtitle.textContent = 'Good evening! Connect to your favorite platforms'; } else { subtitle.textContent = 'Connect to your favorite platforms instantly'; } } // ===== Loading Animation ===== window.addEventListener('load', () => { document.body.style.opacity = '0'; setTimeout(() => { document.body.style.transition = 'opacity 0.5s ease'; document.body.style.opacity = '1'; }, 100); }); // ===== Initialize Everything ===== initParticles(); animateParticles(); updateGreeting(); initializeFavorites(); initializeNotes(); initializeAnalytics(); initializeTheme(); initializeCustomPlatforms(); initializeStatusIndicators(); initializeKeyboardShortcuts(); initializeHeaderControls(); // ===== ANALYTICS FUNCTIONS ===== function initializeAnalytics() { const analytics = StorageManager.getAnalytics(); socialCards.forEach(card => { const platform = card.getAttribute('data-platform'); updateVisitBadge(card, platform); }); } function updateVisitBadge(card, platform) { const analytics = StorageManager.getAnalytics(); const visitBadge = card.querySelector('.visit-badge'); if (analytics[platform] && analytics[platform].visits > 0) { visitBadge.textContent = `${analytics[platform].visits} visits`; visitBadge.style.display = 'inline-flex'; } } function updateAnalyticsDisplay() { const analytics = StorageManager.getAnalytics(); const favorites = StorageManager.getFavorites(); let totalVisits = 0; let totalTime = 0; let mostUsedPlatform = '-'; let maxVisits = 0; Object.keys(analytics).forEach(platform => { totalVisits += analytics[platform].visits || 0; totalTime += analytics[platform].time || 0; if (analytics[platform].visits > maxVisits) { maxVisits = analytics[platform].visits; mostUsedPlatform = platform; } }); document.getElementById('totalVisits').textContent = totalVisits; document.getElementById('totalFavorites').textContent = favorites.length; const hours = Math.floor(totalTime / 3600); const minutes = Math.floor((totalTime % 3600) / 60); document.getElementById('totalTime').textContent = `${hours}h ${minutes}m`; if (mostUsedPlatform !== '-') { const card = document.querySelector(`[data-platform="${mostUsedPlatform}"]`); if (card) { mostUsedPlatform = card.querySelector('.platform-name').textContent; } } document.getElementById('mostUsed').textContent = mostUsedPlatform; updateUsageChart(analytics); } function updateUsageChart(analytics) { const chartContainer = document.getElementById('usageChart'); chartContainer.innerHTML = ''; const sorted = Object.entries(analytics) .sort((a, b) => b[1].visits - a[1].visits) .slice(0, 10); if (sorted.length === 0) { chartContainer.innerHTML = '
No usage data yet
'; return; } const maxVisits = sorted[0][1].visits; sorted.forEach(([platform, data]) => { const card = document.querySelector(`[data-platform="${platform}"]`); const name = card ? card.querySelector('.platform-name').textContent : platform; const percentage = (data.visits / maxVisits) * 100; const barHTML = ` `; chartContainer.innerHTML += barHTML; }); } // ===== THEME TOGGLE ===== function initializeTheme() { const theme = StorageManager.getTheme(); applyTheme(theme); } function applyTheme(theme) { const themeToggle = document.getElementById('themeToggle'); const icon = themeToggle.querySelector('i'); if (theme === 'light') { document.body.classList.add('light-mode'); icon.classList.remove('fa-moon'); icon.classList.add('fa-sun'); } else { document.body.classList.remove('light-mode'); icon.classList.remove('fa-sun'); icon.classList.add('fa-moon'); } } // ===== RECENT ACTIVITY TIMELINE ===== function updateRecentTimeline() { const recent = StorageManager.getRecentActivity(); const timelineItems = document.getElementById('timelineItems'); if (recent.length === 0) { timelineItems.innerHTML = 'No recent activity
'; return; } timelineItems.innerHTML = ''; recent.forEach(item => { const timeAgo = getTimeAgo(new Date(item.timestamp)); const itemHTML = `${description}
`; // Step 2: Generate captions showNotification('Generating creative captions...', 'info'); const captions = await generateCaptions(description); currentCaptions = captions; console.log('β Captions generated:', captions); document.getElementById('aiCaptions').innerHTML = formatCaptions(captions); // Step 3: Generate hashtags showNotification('Creating hashtags...', 'info'); const hashtags = await generateHashtags(description); currentHashtags = hashtags; console.log('β Hashtags created:', hashtags); document.getElementById('aiHashtags').innerHTML = `${hashtags}
`; console.log('=== AI Generation Complete ==='); showNotification('AI generation complete! β¨', 'success'); } catch (error) { console.error('=== AI Generation Error ==='); console.error('Error:', error); showNotification('AI generation failed. Using fallback content...', 'warning'); useFallbackGeneration(); } } async function getImageDescription(imageFile) { try { // Convert image to base64 for API const imageData = await imageFile.arrayBuffer(); const blob = new Blob([imageData]); const response = await fetch(HF_IMAGE_API, { method: 'POST', headers: { 'Authorization': `Bearer ${HF_API_TOKEN}`, }, body: blob }); if (!response.ok) { const errorText = await response.text(); console.error('HF API Error:', errorText); // If model is loading, wait and retry if (response.status === 503) { showNotification('AI model is loading, retrying in 3 seconds...', 'info'); await new Promise(resolve => setTimeout(resolve, 3000)); return getImageDescription(imageFile); // Retry } throw new Error('Image API request failed'); } const result = await response.json(); console.log('Image description result:', result); // Extract description from response const description = result[0]?.generated_text || result?.generated_text || 'an interesting image'; return description.trim(); } catch (error) { console.error('Image description error:', error); showNotification('Using basic image analysis...', 'warning'); return 'a photo with interesting elements'; } } async function generateCaptions(description) { const prompt = `Generate exactly 3 unique, creative, and engaging social media captions for a photo that shows: "${description}". Make them catchy and suitable for Instagram, Facebook, or Twitter. Format as: 1. [first caption] 2. [second caption] 3. [third caption] Only provide the numbered captions, nothing else.`; try { console.log('Generating captions for:', description); const response = await fetch(GROQ_API_URL, { method: 'POST', headers: { 'Authorization': `Bearer ${GROQ_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'llama-3.1-8b-instant', messages: [ { role: 'system', content: 'You are a creative social media caption writer. Generate engaging, concise captions.' }, { role: 'user', content: prompt } ], max_tokens: 200, temperature: 0.8 }) }); if (!response.ok) { const errorText = await response.text(); console.error('Groq API Error:', errorText); throw new Error('Caption API request failed'); } const result = await response.json(); console.log('Caption result:', result); const generatedText = result.choices[0]?.message?.content || ''; return generatedText.trim() || getFallbackCaptions(description); } catch (error) { console.error('Caption generation error:', error); showNotification('Using fallback captions...', 'warning'); return getFallbackCaptions(description); } } async function generateHashtags(description) { const prompt = `Generate exactly 10 relevant and trending hashtags for a photo that shows: "${description}". Only provide the hashtags with # symbol, separated by spaces. No explanations.`; try { console.log('Generating hashtags for:', description); const response = await fetch(GROQ_API_URL, { method: 'POST', headers: { 'Authorization': `Bearer ${GROQ_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: 'llama-3.1-8b-instant', messages: [ { role: 'system', content: 'You are a social media expert. Generate relevant hashtags based on image descriptions.' }, { role: 'user', content: prompt } ], max_tokens: 100, temperature: 0.7 }) }); if (!response.ok) { const errorText = await response.text(); console.error('Hashtag API Error:', errorText); throw new Error('Hashtag API request failed'); } const result = await response.json(); console.log('Hashtag result:', result); let hashtags = result.choices[0]?.message?.content || ''; // Clean up hashtags - ensure they have # and are properly formatted hashtags = hashtags.split(/\s+/) .map(tag => tag.trim()) .filter(tag => tag.length > 0) .map(tag => tag.startsWith('#') ? tag : '#' + tag) .slice(0, 10) .join(' '); return hashtags || getFallbackHashtags(description); } catch (error) { console.error('Hashtag generation error:', error); return getFallbackHashtags(description); } } function getFallbackHashtags(description) { // Extract keywords from description and create hashtags const words = description.split(' ') .filter(w => w.length > 3) .map(w => w.replace(/[^a-zA-Z]/g, '')) .filter(w => w.length > 0); const baseHashtags = words.slice(0, 5).map(w => '#' + w.toLowerCase()); const genericHashtags = [ '#photography', '#photooftheday', '#instagood', '#beautiful', '#instadaily', '#picoftheday', '#instagram', '#love', '#amazing', '#art' ]; const allHashtags = [...new Set([...baseHashtags, ...genericHashtags])].slice(0, 10); return allHashtags.join(' '); } function getFallbackCaptions(description) { // Create captions based on the actual description const mainSubject = description.split(' ').slice(0, 3).join(' '); return `1. Capturing the beauty of ${description} πΈβ¨ 2. ${description.charAt(0).toUpperCase() + description.slice(1)} - moments like these make life special π 3. Just ${mainSubject}... living my best life! π« #blessed`; } function formatCaptions(captions) { // Split captions by numbers or newlines const captionArray = captions.split(/\d+\./).filter(c => c.trim()); let html = ''; captionArray.forEach((caption, index) => { if (caption.trim()) { html += `Caption ${index + 1}: ${caption.trim()}
`; } }); return html || `${captions}
`; } function useFallbackGeneration() { currentDescription = 'a wonderful moment captured in time'; currentCaptions = getFallbackCaptions(currentDescription); currentHashtags = '#photography #photooftheday #instagood #beautiful #instadaily #picoftheday #instagram #love #amazing #art'; document.getElementById('aiDescription').innerHTML = `${currentDescription}
`; document.getElementById('aiCaptions').innerHTML = formatCaptions(currentCaptions); document.getElementById('aiHashtags').innerHTML = `${currentHashtags}
`; } // Copy functionality document.getElementById('copyCaptionBtn').addEventListener('click', () => { copyToClipboard(currentCaptions, 'Caption copied!'); }); document.getElementById('copyHashtagsBtn').addEventListener('click', () => { copyToClipboard(currentHashtags, 'Hashtags copied!'); }); document.getElementById('copyAllBtn').addEventListener('click', () => { const allText = `${currentCaptions}\n\n${currentHashtags}`; copyToClipboard(allText, 'All content copied!'); }); function copyToClipboard(text, message) { navigator.clipboard.writeText(text).then(() => { showNotification(message, 'success'); }).catch(() => { showNotification('Copy failed', 'warning'); }); } // Post to platform document.querySelectorAll('.platform-post-btn').forEach(btn => { btn.addEventListener('click', () => { const platform = btn.getAttribute('data-platform'); postToPlatform(platform); }); }); function postToPlatform(platform) { // Copy caption and hashtags to clipboard first const fullContent = `${currentCaptions.split('\n')[0]}\n\n${currentHashtags}`; copyToClipboard(fullContent, `Content copied! Opening ${platform}...`); // Open platform in popup const platformURL = platformURLs[platform]; if (platformURL) { setTimeout(() => { const width = 1200; const height = 800; const left = (screen.width - width) / 2; const top = (screen.height - height) / 2; window.open( platformURL, platform, `width=${width},height=${height},left=${left},top=${top},toolbar=yes,menubar=no,scrollbars=yes,resizable=yes` ); showNotification(`Paste your caption and upload the image on ${platform}!`, 'info'); }, 500); } } // ===== Performance Optimization ===== // Throttle scroll events let ticking = false; window.addEventListener('scroll', () => { if (!ticking) { window.requestAnimationFrame(() => { // Add scroll-based animations here if needed ticking = false; }); ticking = true; } }); // ===== Keyboard Navigation ===== document.addEventListener('keydown', (e) => { // Don't trigger shortcuts if modal is open (except Escape) if (modal.classList.contains('active') && e.key !== 'Escape') { return; } if (e.key === '/') { e.preventDefault(); searchInput.focus(); } if (e.key === 'Escape') { if (modal.classList.contains('active')) { closePlatformModal(); } else { searchInput.blur(); searchInput.value = ''; searchInput.dispatchEvent(new Event('input')); } } }); // ===== Show keyboard shortcut hint ===== const searchContainer = document.querySelector('.search-container'); const hintElement = document.createElement('div'); hintElement.style.cssText = ` position: absolute; right: 4rem; top: 50%; transform: translateY(-50%); font-size: 0.8rem; color: var(--text-secondary); opacity: 0.6; pointer-events: none; `; hintElement.innerHTML = '/ to search'; searchContainer.appendChild(hintElement); searchInput.addEventListener('focus', () => { hintElement.style.opacity = '0'; }); searchInput.addEventListener('blur', () => { if (!searchInput.value) { hintElement.style.opacity = '0.6'; } }); // ===== Add ripple effect on card click ===== socialCards.forEach(card => { card.addEventListener('click', function(e) { const ripple = document.createElement('div'); const rect = this.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = e.clientX - rect.left - size / 2; const y = e.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; width: ${size}px; height: ${size}px; border-radius: 50%; background: rgba(255, 255, 255, 0.3); left: ${x}px; top: ${y}px; pointer-events: none; animation: rippleEffect 0.6s ease-out; `; this.style.position = 'relative'; this.style.overflow = 'hidden'; this.appendChild(ripple); setTimeout(() => ripple.remove(), 600); }); }); // Add ripple animation to stylesheet dynamically const style = document.createElement('style'); style.textContent = ` @keyframes rippleEffect { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } kbd { font-family: 'Courier New', monospace; } `; document.head.appendChild(style); console.log('%cπ Social Hub Loaded Successfully!', 'color: #00d4ff; font-size: 20px; font-weight: bold;'); console.log('%cPress "/" to search platforms', 'color: #00ff88; font-size: 14px;'); console.log('%cPress "Ctrl+I" to open AI Caption Generator', 'color: #00ff88; font-size: 14px;'); console.log('%cπ€ AI Features: Real-time image analysis with Groq + Hugging Face', 'color: #ffa502; font-size: 12px;');