|
|
| let currentPlatformURL = '';
|
| let currentPlatformName = '';
|
| let currentPlatform = '';
|
| let currentNoteEditPlatform = '';
|
| let timeTrackingInterval = null;
|
| let startTime = null;
|
| let currentImageData = null;
|
| let currentDescription = '';
|
| let currentCaptions = '';
|
| let currentHashtags = '';
|
|
|
|
|
| const StorageManager = {
|
|
|
| getFavorites: () => {
|
| const favorites = localStorage.getItem('socialHub_favorites');
|
| return favorites ? JSON.parse(favorites) : [];
|
| },
|
|
|
|
|
| setFavorites: (favorites) => {
|
| localStorage.setItem('socialHub_favorites', JSON.stringify(favorites));
|
| },
|
|
|
|
|
| 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;
|
| },
|
|
|
|
|
| getNotes: () => {
|
| const notes = localStorage.getItem('socialHub_notes');
|
| return notes ? JSON.parse(notes) : {};
|
| },
|
|
|
|
|
| setNote: (platform, note) => {
|
| const notes = StorageManager.getNotes();
|
| if (note.trim()) {
|
| notes[platform] = note;
|
| } else {
|
| delete notes[platform];
|
| }
|
| localStorage.setItem('socialHub_notes', JSON.stringify(notes));
|
| },
|
|
|
|
|
| getAnalytics: () => {
|
| const analytics = localStorage.getItem('socialHub_analytics');
|
| return analytics ? JSON.parse(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));
|
| },
|
|
|
|
|
| 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));
|
| },
|
|
|
|
|
| getRecentActivity: () => {
|
| const recent = localStorage.getItem('socialHub_recent');
|
| return recent ? JSON.parse(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));
|
| },
|
|
|
|
|
| getTheme: () => {
|
| return localStorage.getItem('socialHub_theme') || 'dark';
|
| },
|
|
|
|
|
| setTheme: (theme) => {
|
| localStorage.setItem('socialHub_theme', theme);
|
| },
|
|
|
|
|
| getCustomPlatforms: () => {
|
| const custom = localStorage.getItem('socialHub_custom');
|
| return custom ? JSON.parse(custom) : [];
|
| },
|
|
|
|
|
| addCustomPlatform: (platform) => {
|
| const custom = StorageManager.getCustomPlatforms();
|
| custom.push(platform);
|
| localStorage.setItem('socialHub_custom', JSON.stringify(custom));
|
| },
|
|
|
|
|
| removeCustomPlatform: (id) => {
|
| let custom = StorageManager.getCustomPlatforms();
|
| custom = custom.filter(p => p.id !== id);
|
| localStorage.setItem('socialHub_custom', JSON.stringify(custom));
|
| }
|
| };
|
|
|
|
|
| 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();
|
|
|
|
|
| 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.addEventListener('resize', () => {
|
| canvas.width = window.innerWidth;
|
| canvas.height = window.innerHeight;
|
| initParticles();
|
| });
|
|
|
|
|
| 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);
|
| }
|
|
|
|
|
| const filterTabs = document.querySelectorAll('.filter-tab');
|
| const recentTimeline = document.getElementById('recentTimeline');
|
|
|
| filterTabs.forEach(tab => {
|
| tab.addEventListener('click', () => {
|
|
|
| filterTabs.forEach(t => t.classList.remove('active'));
|
| tab.classList.add('active');
|
|
|
| const filter = tab.getAttribute('data-filter');
|
|
|
|
|
| if (filter === 'recent') {
|
| updateRecentTimeline();
|
| recentTimeline.style.display = 'block';
|
| } else {
|
| recentTimeline.style.display = 'none';
|
| }
|
|
|
|
|
| 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');
|
| }
|
| });
|
| }
|
|
|
|
|
| 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();
|
| }
|
|
|
|
|
| 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);
|
|
|
|
|
| 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();
|
| });
|
|
|
|
|
|
|
| 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'
|
| };
|
|
|
|
|
| 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'
|
| };
|
|
|
|
|
| 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');
|
|
|
|
|
| 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`);
|
|
|
|
|
| StorageManager.updateAnalytics(platform);
|
| StorageManager.addToRecent(platform, platformName, icon);
|
| updateVisitBadge(card, platform);
|
| updateAnalyticsDisplay();
|
|
|
|
|
| openPlatformModal(url, platformName, platform);
|
|
|
|
|
| card.style.transform = 'scale(0.95)';
|
| setTimeout(() => {
|
| card.style.transform = '';
|
| }, 200);
|
| });
|
| });
|
|
|
|
|
| function openPlatformModal(url, name, platform) {
|
| currentPlatformURL = url;
|
| currentPlatformName = name;
|
| currentPlatform = platform;
|
|
|
|
|
| platformTitle.textContent = name;
|
| platformIcon.className = 'platform-icon ' + platformIcons[platform];
|
|
|
|
|
| platformNameText.textContent = name;
|
| platformIconLarge.className = 'platform-icon-large ' + platformIcons[platform];
|
| platformIconSmall.className = 'platform-icon-small ' + platformIcons[platform];
|
| platformLoginText.textContent = `Login with ${name} Account`;
|
|
|
|
|
| modal.classList.add('active');
|
| document.body.style.overflow = 'hidden';
|
|
|
|
|
| authSection.style.display = 'flex';
|
| platformSection.style.display = 'none';
|
| }
|
|
|
|
|
| function closePlatformModal() {
|
| modal.classList.remove('active');
|
| document.body.style.overflow = '';
|
| modalContent.classList.remove('fullscreen');
|
|
|
|
|
| stopTimeTracking();
|
|
|
|
|
| setTimeout(() => {
|
| modalFrame.src = '';
|
| authSection.style.display = 'flex';
|
| platformSection.style.display = 'none';
|
| loadingSpinner.classList.remove('hidden');
|
| }, 300);
|
| }
|
|
|
|
|
| function loadPlatform(authMethod) {
|
| console.log(`Loading ${currentPlatformName} with ${authMethod} authentication`);
|
|
|
|
|
| authSection.style.display = 'none';
|
| platformSection.style.display = 'block';
|
|
|
|
|
| loadingSpinner.classList.remove('hidden');
|
|
|
|
|
| modalFrame.src = currentPlatformURL;
|
|
|
|
|
| modalFrame.onload = () => {
|
| setTimeout(() => {
|
| loadingSpinner.classList.add('hidden');
|
| }, 500);
|
| };
|
|
|
|
|
| setTimeout(() => {
|
| loadingSpinner.classList.add('hidden');
|
| }, 3000);
|
| }
|
|
|
|
|
| googleSignInBtn.addEventListener('click', () => {
|
| console.log('Google Sign-In clicked');
|
| showNotification('Google Sign-In feature coming soon! Opening platform directly...', 'info');
|
|
|
|
|
| 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);
|
| });
|
|
|
|
|
| platformSignInBtn.addEventListener('click', () => {
|
| console.log('Platform Sign-In clicked');
|
| showNotification(`Opening ${currentPlatformName} in new window...`, 'success');
|
|
|
|
|
| startTimeTracking(currentPlatform);
|
|
|
|
|
| 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`
|
| );
|
|
|
|
|
| setTimeout(() => {
|
| closePlatformModal();
|
| }, 500);
|
| });
|
|
|
|
|
| guestAccessBtn.addEventListener('click', () => {
|
| console.log('Guest access clicked');
|
| showNotification(`Opening ${currentPlatformName} web version...`, 'info');
|
|
|
|
|
| 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`
|
| );
|
|
|
|
|
| setTimeout(() => {
|
| closePlatformModal();
|
| }, 500);
|
| });
|
|
|
|
|
| function showNotification(message, type = 'info') {
|
| const notification = document.createElement('div');
|
| notification.className = `notification notification-${type}`;
|
| notification.innerHTML = `
|
| <i class="fas fa-${type === 'success' ? 'check-circle' : type === 'warning' ? 'exclamation-triangle' : 'info-circle'}"></i>
|
| <span>${message}</span>
|
| `;
|
|
|
| document.body.appendChild(notification);
|
|
|
|
|
| setTimeout(() => notification.classList.add('show'), 10);
|
|
|
|
|
| setTimeout(() => {
|
| notification.classList.remove('show');
|
| setTimeout(() => notification.remove(), 300);
|
| }, 3000);
|
| }
|
|
|
|
|
| closeBtn.addEventListener('click', closePlatformModal);
|
|
|
|
|
| modal.addEventListener('click', (e) => {
|
| if (e.target === modal) {
|
| closePlatformModal();
|
| }
|
| });
|
|
|
|
|
| refreshBtn.addEventListener('click', () => {
|
| loadingSpinner.classList.remove('hidden');
|
| modalFrame.src = modalFrame.src;
|
|
|
| setTimeout(() => {
|
| loadingSpinner.classList.add('hidden');
|
| }, 2000);
|
| });
|
|
|
|
|
| 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';
|
| }
|
| });
|
|
|
|
|
| logoutBtn.addEventListener('click', () => {
|
| showNotification('Logged out successfully', 'success');
|
| authSection.style.display = 'flex';
|
| platformSection.style.display = 'none';
|
| modalFrame.src = '';
|
| });
|
|
|
|
|
| document.addEventListener('keydown', (e) => {
|
| if (e.key === 'Escape' && modal.classList.contains('active')) {
|
| closePlatformModal();
|
| }
|
| });
|
|
|
|
|
| socialCards.forEach(card => {
|
| card.addEventListener('mouseenter', () => {
|
| card.style.transition = 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)';
|
| });
|
| });
|
|
|
|
|
| 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'
|
| });
|
| }
|
| });
|
| });
|
|
|
|
|
| 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';
|
| }
|
| }
|
|
|
|
|
| window.addEventListener('load', () => {
|
| document.body.style.opacity = '0';
|
| setTimeout(() => {
|
| document.body.style.transition = 'opacity 0.5s ease';
|
| document.body.style.opacity = '1';
|
| }, 100);
|
| });
|
|
|
|
|
| initParticles();
|
| animateParticles();
|
| updateGreeting();
|
| initializeFavorites();
|
| initializeNotes();
|
| initializeAnalytics();
|
| initializeTheme();
|
| initializeCustomPlatforms();
|
| initializeStatusIndicators();
|
| initializeKeyboardShortcuts();
|
| initializeHeaderControls();
|
|
|
|
|
| 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 = '<p style="color: var(--text-secondary); text-align: center;">No usage data yet</p>';
|
| 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 = `
|
| <div class="chart-bar">
|
| <div class="chart-label">${name}</div>
|
| <div class="chart-bar-container">
|
| <div class="chart-bar-fill" style="width: ${percentage}%">
|
| ${data.visits}
|
| </div>
|
| </div>
|
| </div>
|
| `;
|
| chartContainer.innerHTML += barHTML;
|
| });
|
| }
|
|
|
|
|
| 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');
|
| }
|
| }
|
|
|
|
|
| function updateRecentTimeline() {
|
| const recent = StorageManager.getRecentActivity();
|
| const timelineItems = document.getElementById('timelineItems');
|
|
|
| if (recent.length === 0) {
|
| timelineItems.innerHTML = '<p style="color: var(--text-secondary); text-align: center;">No recent activity</p>';
|
| return;
|
| }
|
|
|
| timelineItems.innerHTML = '';
|
|
|
| recent.forEach(item => {
|
| const timeAgo = getTimeAgo(new Date(item.timestamp));
|
| const itemHTML = `
|
| <div class="timeline-item" data-platform="${item.platform}">
|
| <i class="${item.icon}"></i>
|
| <div class="timeline-info">
|
| <h4>${item.name}</h4>
|
| <span>${timeAgo}</span>
|
| </div>
|
| </div>
|
| `;
|
| timelineItems.innerHTML += itemHTML;
|
| });
|
|
|
|
|
| timelineItems.querySelectorAll('.timeline-item').forEach(item => {
|
| item.addEventListener('click', () => {
|
| const platform = item.getAttribute('data-platform');
|
| const card = document.querySelector(`[data-platform="${platform}"]`);
|
| if (card) {
|
| card.querySelector('.launch-btn').click();
|
| }
|
| });
|
| });
|
| }
|
|
|
| function getTimeAgo(date) {
|
| const seconds = Math.floor((new Date() - date) / 1000);
|
|
|
| if (seconds < 60) return 'Just now';
|
| if (seconds < 3600) return `${Math.floor(seconds / 60)} minutes ago`;
|
| if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours ago`;
|
| return `${Math.floor(seconds / 86400)} days ago`;
|
| }
|
|
|
|
|
| function initializeCustomPlatforms() {
|
| const customPlatforms = StorageManager.getCustomPlatforms();
|
| const socialGrid = document.getElementById('socialGrid');
|
|
|
| customPlatforms.forEach(platform => {
|
| addCustomPlatformCard(platform, socialGrid);
|
| });
|
| }
|
|
|
| function addCustomPlatformCard(platform, container) {
|
| const cardHTML = `
|
| <div class="social-card" data-platform="${platform.id}" data-category="${platform.category}" data-custom="true">
|
| <div class="card-inner">
|
| <div class="card-front" style="background: ${platform.color};">
|
| <div class="card-top-controls">
|
| <button class="favorite-btn" title="Add to Favorites">
|
| <i class="far fa-star"></i>
|
| </button>
|
| <button class="note-btn" title="Add Note">
|
| <i class="far fa-sticky-note"></i>
|
| </button>
|
| <button class="delete-custom-btn" title="Delete Platform" style="background: rgba(255, 71, 87, 0.8);">
|
| <i class="fas fa-trash"></i>
|
| </button>
|
| <div class="status-indicator" title="Status: Online"></div>
|
| </div>
|
| <div class="platform-logo">
|
| <i class="${platform.icon}"></i>
|
| </div>
|
| <h3 class="platform-name">${platform.name}</h3>
|
| <div class="platform-badges">
|
| <span class="visit-badge" style="display: none;">0 visits</span>
|
| <span class="note-indicator" style="display: none;"><i class="fas fa-sticky-note"></i></span>
|
| </div>
|
| <p class="platform-desc">Custom platform</p>
|
| <div class="card-stats">
|
| <span><i class="fas fa-globe"></i> Custom</span>
|
| </div>
|
| </div>
|
| </div>
|
| <a href="${platform.url}" target="_blank" class="launch-btn" data-url="${platform.url}">
|
| <i class="fas fa-external-link-alt"></i> Launch
|
| </a>
|
| </div>
|
| `;
|
|
|
| container.innerHTML += cardHTML;
|
|
|
|
|
| const newCard = container.lastElementChild;
|
| initializeCardFeatures(newCard, platform.id);
|
| }
|
|
|
| function initializeCardFeatures(card, platform) {
|
|
|
| const favBtn = card.querySelector('.favorite-btn');
|
| const favorites = StorageManager.getFavorites();
|
| 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);
|
| });
|
|
|
|
|
| const noteBtn = card.querySelector('.note-btn');
|
| const notes = StorageManager.getNotes();
|
| if (notes[platform]) {
|
| noteBtn.classList.add('has-note');
|
| card.querySelector('.note-indicator').style.display = 'inline-flex';
|
| }
|
| noteBtn.addEventListener('click', (e) => {
|
| e.stopPropagation();
|
| e.preventDefault();
|
| openNoteModal(platform, card.querySelector('.platform-name').textContent);
|
| });
|
|
|
|
|
| const deleteBtn = card.querySelector('.delete-custom-btn');
|
| if (deleteBtn) {
|
| deleteBtn.addEventListener('click', (e) => {
|
| e.stopPropagation();
|
| e.preventDefault();
|
| if (confirm('Delete this custom platform?')) {
|
| StorageManager.removeCustomPlatform(platform);
|
| card.remove();
|
| showNotification('Platform deleted', 'success');
|
| }
|
| });
|
| }
|
|
|
|
|
| const launchBtn = card.querySelector('.launch-btn');
|
| launchBtn.addEventListener('click', (e) => {
|
| e.preventDefault();
|
| const platformName = card.querySelector('.platform-name').textContent;
|
| const url = launchBtn.getAttribute('data-url');
|
| const icon = card.querySelector('.platform-logo i').className;
|
|
|
| StorageManager.updateAnalytics(platform);
|
| StorageManager.addToRecent(platform, platformName, icon);
|
| updateVisitBadge(card, platform);
|
| updateAnalyticsDisplay();
|
|
|
| openPlatformModal(url, platformName, platform);
|
|
|
| card.style.transform = 'scale(0.95)';
|
| setTimeout(() => {
|
| card.style.transform = '';
|
| }, 200);
|
| });
|
| }
|
|
|
|
|
| function initializeStatusIndicators() {
|
|
|
|
|
| document.querySelectorAll('.status-indicator').forEach(indicator => {
|
| indicator.classList.remove('offline');
|
| });
|
| }
|
|
|
|
|
| function initializeKeyboardShortcuts() {
|
| document.addEventListener('keydown', (e) => {
|
|
|
| if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
|
| return;
|
| }
|
|
|
|
|
| if (e.key === '?') {
|
| e.preventDefault();
|
| document.getElementById('shortcutsModal').classList.add('active');
|
| }
|
|
|
|
|
| if (e.ctrlKey && e.key === 'k') {
|
| e.preventDefault();
|
| document.getElementById('analyticsModal').classList.add('active');
|
| updateAnalyticsDisplay();
|
| }
|
|
|
|
|
| if (e.ctrlKey && e.key === 'd') {
|
| e.preventDefault();
|
| document.getElementById('themeToggle').click();
|
| }
|
|
|
|
|
| if (e.ctrlKey && e.key === 'i') {
|
| e.preventDefault();
|
| document.getElementById('aiCaptionBtn').click();
|
| }
|
|
|
|
|
| if (e.key >= '1' && e.key <= '9') {
|
| const index = parseInt(e.key) - 1;
|
| const visibleCards = Array.from(socialCards).filter(card => !card.classList.contains('hidden'));
|
| if (visibleCards[index]) {
|
| visibleCards[index].querySelector('.launch-btn').click();
|
| }
|
| }
|
| });
|
| }
|
|
|
|
|
| function initializeHeaderControls() {
|
|
|
| document.getElementById('themeToggle').addEventListener('click', () => {
|
| const currentTheme = StorageManager.getTheme();
|
| const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
| StorageManager.setTheme(newTheme);
|
| applyTheme(newTheme);
|
| showNotification(`Switched to ${newTheme} mode`, 'success');
|
| });
|
|
|
|
|
|
|
|
|
|
|
| document.getElementById('shortcutsBtn').addEventListener('click', () => {
|
| document.getElementById('shortcutsModal').classList.add('active');
|
| });
|
|
|
|
|
| document.getElementById('analyticsBtn').addEventListener('click', () => {
|
| document.getElementById('analyticsModal').classList.add('active');
|
| updateAnalyticsDisplay();
|
| });
|
|
|
|
|
| document.getElementById('addPlatformBtn').addEventListener('click', () => {
|
| document.getElementById('addPlatformModal').classList.add('active');
|
| });
|
| }
|
|
|
|
|
| document.getElementById('addPlatformForm').addEventListener('submit', (e) => {
|
| e.preventDefault();
|
|
|
| const platform = {
|
| id: 'custom_' + Date.now(),
|
| name: document.getElementById('customPlatformName').value,
|
| url: document.getElementById('customPlatformURL').value,
|
| icon: document.getElementById('customPlatformIcon').value,
|
| color: document.getElementById('customPlatformColor').value,
|
| category: document.getElementById('customPlatformCategory').value
|
| };
|
|
|
| StorageManager.addCustomPlatform(platform);
|
| addCustomPlatformCard(platform, document.getElementById('socialGrid'));
|
|
|
| document.getElementById('addPlatformModal').classList.remove('active');
|
| document.getElementById('addPlatformForm').reset();
|
| showNotification('Custom platform added!', 'success');
|
| });
|
|
|
|
|
| function startTimeTracking(platform) {
|
| startTime = Date.now();
|
| const tracker = document.getElementById('timeTracker');
|
| tracker.style.display = 'flex';
|
|
|
| timeTrackingInterval = setInterval(() => {
|
| const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
| const minutes = Math.floor(elapsed / 60);
|
| const seconds = elapsed % 60;
|
| document.getElementById('trackerTime').textContent =
|
| `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
| }, 1000);
|
| }
|
|
|
| function stopTimeTracking() {
|
| if (timeTrackingInterval) {
|
| clearInterval(timeTrackingInterval);
|
| const elapsed = Math.floor((Date.now() - startTime) / 1000);
|
| StorageManager.updateTimeSpent(currentPlatform, elapsed);
|
| document.getElementById('timeTracker').style.display = 'none';
|
| updateAnalyticsDisplay();
|
| }
|
| }
|
|
|
| document.getElementById('stopTracking').addEventListener('click', stopTimeTracking);
|
|
|
|
|
|
|
| const GROQ_API_KEY = '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';
|
| const GROQ_API_URL = 'https://api.groq.com/openai/v1/chat/completions';
|
| const HF_IMAGE_API = 'https://api-inference.huggingface.co/models/Salesforce/blip-image-captioning-base';
|
| const HF_API_TOKEN = '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';
|
|
|
|
|
| document.getElementById('aiCaptionBtn').addEventListener('click', () => {
|
| document.getElementById('aiCaptionModal').classList.add('active');
|
| document.body.style.overflow = 'hidden';
|
| });
|
|
|
|
|
| const imageInput = document.getElementById('imageInput');
|
| const uploadArea = document.getElementById('uploadArea');
|
| const uploadSection = document.getElementById('uploadSection');
|
| const resultsSection = document.getElementById('resultsSection');
|
| const imagePreview = document.getElementById('imagePreview');
|
|
|
| imageInput.addEventListener('change', handleImageUpload);
|
|
|
|
|
| uploadArea.addEventListener('dragover', (e) => {
|
| e.preventDefault();
|
| uploadArea.style.borderColor = 'var(--accent-color)';
|
| uploadArea.style.background = 'rgba(0, 212, 255, 0.15)';
|
| });
|
|
|
| uploadArea.addEventListener('dragleave', () => {
|
| uploadArea.style.borderColor = 'rgba(0, 212, 255, 0.3)';
|
| uploadArea.style.background = 'rgba(0, 212, 255, 0.05)';
|
| });
|
|
|
| uploadArea.addEventListener('drop', (e) => {
|
| e.preventDefault();
|
| uploadArea.style.borderColor = 'rgba(0, 212, 255, 0.3)';
|
| uploadArea.style.background = 'rgba(0, 212, 255, 0.05)';
|
|
|
| const files = e.dataTransfer.files;
|
| if (files.length > 0 && files[0].type.startsWith('image/')) {
|
| imageInput.files = files;
|
| handleImageUpload();
|
| }
|
| });
|
|
|
| async function handleImageUpload() {
|
| const file = imageInput.files[0];
|
| if (!file) return;
|
|
|
|
|
| const reader = new FileReader();
|
| reader.onload = (e) => {
|
| imagePreview.src = e.target.result;
|
| currentImageData = e.target.result;
|
| };
|
| reader.readAsDataURL(file);
|
|
|
|
|
| uploadSection.style.display = 'none';
|
| resultsSection.style.display = 'grid';
|
|
|
|
|
| showLoadingState();
|
|
|
|
|
| await generateAIContent(file);
|
| }
|
|
|
| function showLoadingState() {
|
| document.getElementById('aiDescription').innerHTML = '<div class="loading-dots"><span></span><span></span><span></span></div>';
|
| document.getElementById('aiCaptions').innerHTML = '<div class="loading-dots"><span></span><span></span><span></span></div>';
|
| document.getElementById('aiHashtags').innerHTML = '<div class="loading-dots"><span></span><span></span><span></span></div>';
|
| }
|
|
|
| async function generateAIContent(imageFile) {
|
| try {
|
| console.log('=== Starting AI Generation ===');
|
| console.log('Image file:', imageFile.name, imageFile.type, imageFile.size, 'bytes');
|
|
|
|
|
| showNotification('Analyzing image with AI...', 'info');
|
| const description = await getImageDescription(imageFile);
|
| currentDescription = description;
|
|
|
| console.log('✓ Image description:', description);
|
| document.getElementById('aiDescription').innerHTML = `<p>${description}</p>`;
|
|
|
|
|
| showNotification('Generating creative captions...', 'info');
|
| const captions = await generateCaptions(description);
|
| currentCaptions = captions;
|
|
|
| console.log('✓ Captions generated:', captions);
|
| document.getElementById('aiCaptions').innerHTML = formatCaptions(captions);
|
|
|
|
|
| showNotification('Creating hashtags...', 'info');
|
| const hashtags = await generateHashtags(description);
|
| currentHashtags = hashtags;
|
|
|
| console.log('✓ Hashtags created:', hashtags);
|
| document.getElementById('aiHashtags').innerHTML = `<p>${hashtags}</p>`;
|
|
|
| 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 {
|
|
|
| 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 (response.status === 503) {
|
| showNotification('AI model is loading, retrying in 3 seconds...', 'info');
|
| await new Promise(resolve => setTimeout(resolve, 3000));
|
| return getImageDescription(imageFile);
|
| }
|
|
|
| throw new Error('Image API request failed');
|
| }
|
|
|
| const result = await response.json();
|
| console.log('Image description result:', result);
|
|
|
|
|
| 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 || '';
|
|
|
|
|
| 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) {
|
|
|
| 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) {
|
|
|
| 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) {
|
|
|
| const captionArray = captions.split(/\d+\./).filter(c => c.trim());
|
|
|
| let html = '';
|
| captionArray.forEach((caption, index) => {
|
| if (caption.trim()) {
|
| html += `<p><strong>Caption ${index + 1}:</strong> ${caption.trim()}</p>`;
|
| }
|
| });
|
|
|
| return html || `<p>${captions}</p>`;
|
| }
|
|
|
| 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 = `<p>${currentDescription}</p>`;
|
| document.getElementById('aiCaptions').innerHTML = formatCaptions(currentCaptions);
|
| document.getElementById('aiHashtags').innerHTML = `<p>${currentHashtags}</p>`;
|
| }
|
|
|
|
|
| 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');
|
| });
|
| }
|
|
|
|
|
| document.querySelectorAll('.platform-post-btn').forEach(btn => {
|
| btn.addEventListener('click', () => {
|
| const platform = btn.getAttribute('data-platform');
|
| postToPlatform(platform);
|
| });
|
| });
|
|
|
| function postToPlatform(platform) {
|
|
|
| const fullContent = `${currentCaptions.split('\n')[0]}\n\n${currentHashtags}`;
|
| copyToClipboard(fullContent, `Content copied! Opening ${platform}...`);
|
|
|
|
|
| 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);
|
| }
|
| }
|
|
|
|
|
|
|
| let ticking = false;
|
| window.addEventListener('scroll', () => {
|
| if (!ticking) {
|
| window.requestAnimationFrame(() => {
|
|
|
| ticking = false;
|
| });
|
| ticking = true;
|
| }
|
| });
|
|
|
|
|
| document.addEventListener('keydown', (e) => {
|
|
|
| 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'));
|
| }
|
| }
|
| });
|
|
|
|
|
| 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 = '<kbd style="background: rgba(0,212,255,0.1); padding: 2px 6px; border-radius: 3px; font-size: 0.7rem;">/ to search</kbd>';
|
| searchContainer.appendChild(hintElement);
|
|
|
| searchInput.addEventListener('focus', () => {
|
| hintElement.style.opacity = '0';
|
| });
|
|
|
| searchInput.addEventListener('blur', () => {
|
| if (!searchInput.value) {
|
| hintElement.style.opacity = '0.6';
|
| }
|
| });
|
|
|
|
|
| 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);
|
| });
|
| });
|
|
|
|
|
| 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;');
|
|
|