// Global state let currentSearchResults = []; let currentNewsSource = ''; // DOM Elements const searchForm = document.getElementById('searchForm'); const searchInput = document.getElementById('searchInput'); const resultsSection = document.getElementById('resultsSection'); const newsSection = document.getElementById('newsSection'); const searchResults = document.getElementById('searchResults'); const newsResults = document.getElementById('newsResults'); const loading = document.getElementById('loading'); const backToSearch = document.getElementById('backToSearch'); const backToResults = document.getElementById('backToResults'); const newsTitle = document.getElementById('newsTitle'); // Event Listeners document.addEventListener('DOMContentLoaded', function() { searchForm.addEventListener('submit', handleSearch); backToSearch.addEventListener('click', showSearchView); backToResults.addEventListener('click', showResultsView); // Focus search input on page load searchInput.focus(); }); // Search handler async function handleSearch(e) { e.preventDefault(); const query = searchInput.value.trim(); if (!query) return; showLoading(); hideAllSections(); try { const results = await performSearch(query); currentSearchResults = results; displaySearchResults(results); showResultsSection(); } catch (error) { console.error('Search error:', error); showError('Failed to perform search. Please try again.'); } finally { hideLoading(); } } // Perform search using DuckDuckGo Instant Answer API async function performSearch(query) { const response = await fetch(`https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_html=1&skip_disambig=1`); const data = await response.json(); let results = []; // Use RelatedTopics if available if (data.RelatedTopics && data.RelatedTopics.length > 0) { results = data.RelatedTopics .filter(topic => topic.FirstURL && topic.Text) .map(topic => ({ title: topic.Text, url: topic.FirstURL, description: topic.Text })) .slice(0, 10); } // Fallback to Abstract results if (results.length === 0 && data.Abstract) { results.push({ title: data.Heading || query, url: data.AbstractURL || `https://duckduckgo.com/?q=${encodeURIComponent(query)}`, description: data.Abstract }); } return results; } // Display search results function displaySearchResults(results) { searchResults.innerHTML = ''; if (results.length === 0) { searchResults.innerHTML = `

No results found. Try a different search term.

`; return; } results.forEach((result, index) => { const resultElement = document.createElement('div'); resultElement.className = 'result-card bg-white rounded-xl p-6 fade-in'; resultElement.style.animationDelay = `${index * 0.1}s`; resultElement.innerHTML = `

${result.title}

${result.description}

${result.url}
`; searchResults.appendChild(resultElement); }); // Add event listeners to news buttons document.querySelectorAll('.view-news-btn').forEach(button => { button.addEventListener('click', function() { const url = this.getAttribute('data-url'); loadNewsForSource(url); }); }); feather.replace(); } // Load news for a specific source async function loadNewsForSource(url) { showLoading(); hideAllSections(); try { // Extract domain from URL const domain = new URL(url).hostname.replace('www.', ''); currentNewsSource = domain; // Use NewsAPI free tier (requires registration but has free tier) // For demo purposes, we'll use a mock news API that doesn't require keys const news = await fetchNewsForDomain(domain); displayNewsResults(news, domain); showNewsSection(); } catch (error) { console.error('News loading error:', error); showError('Failed to load news. The source might not be supported.'); } finally { hideLoading(); } } // Fetch news for domain (mock implementation) async function fetchNewsForDomain(domain) { // In a real implementation, you would use NewsAPI or similar service // For demo, we'll return mock data await new Promise(resolve => setTimeout(resolve, 1000)); const mockNews = Array.from({ length: 20 }, (_, i) => ({ title: `Breaking News ${i + 1} from ${domain}`, description: `This is a sample news article from ${domain}. In a real implementation, this would fetch actual news from the domain.`, url: `https://${domain}/news/${i + 1}`, publishedAt: new Date(Date.now() - i * 3600000).toISOString(), author: `Staff Writer ${i + 1}`, source: domain })); return mockNews; } // Display news results function displayNewsResults(news, domain) { newsTitle.textContent = `Latest News from ${domain}`; newsResults.innerHTML = ''; news.forEach((article, index) => { const articleElement = document.createElement('div'); articleElement.className = 'news-card bg-white rounded-xl p-6 fade-in'; articleElement.style.animationDelay = `${index * 0.05}s`; const date = new Date(article.publishedAt).toLocaleDateString(); articleElement.innerHTML = `

${article.title}

${article.description}

${article.author} ${date}
Read Full Article
`; newsResults.appendChild(articleElement); }); feather.replace(); } // UI State Management function showLoading() { loading.classList.remove('hidden'); } function hideLoading() { loading.classList.add('hidden'); } function showResultsSection() { resultsSection.classList.remove('hidden'); } function showNewsSection() { newsSection.classList.remove('hidden'); } function hideAllSections() { resultsSection.classList.add('hidden'); newsSection.classList.add('hidden'); } function showSearchView() { hideAllSections(); searchInput.focus(); } function showResultsView() { hideAllSections(); showResultsSection(); } function showError(message) { hideAllSections(); searchResults.innerHTML = `

${message}

`; showResultsSection(); feather.replace(); } // Utility function to extract domain from URL function extractDomain(url) { try { return new URL(url).hostname.replace('www.', ''); } catch { return url; } }