// Theme Management class ThemeManager { constructor() { this.theme = localStorage.getItem('theme') || 'light'; this.init(); } init() { document.documentElement.setAttribute('data-theme', this.theme); this.updateThemeIcon(); } toggle() { this.theme = this.theme === 'light' ? 'dark' : 'light'; document.documentElement.setAttribute('data-theme', this.theme); localStorage.setItem('theme', this.theme); this.updateThemeIcon(); } updateThemeIcon() { const lightIcon = document.querySelector('.light-icon'); const darkIcon = document.querySelector('.dark-icon'); if (this.theme === 'light') { lightIcon.style.display = 'block'; darkIcon.style.display = 'none'; } else { lightIcon.style.display = 'none'; darkIcon.style.display = 'block'; } } } // Date Management class DateManager { constructor() { // Start with today's date, but it will be updated when we get the actual available date this.currentDate = new Date(); this.init(); } init() { this.updateDateDisplay(); this.bindEvents(); } formatDate(date) { const options = { year: 'numeric', month: 'short', day: 'numeric' }; return date.toLocaleDateString('en-US', options); } updateDateDisplay() { const dateDisplay = document.getElementById('dateDisplay'); dateDisplay.textContent = this.formatDate(this.currentDate); } navigateDate(direction) { const newDate = new Date(this.currentDate); newDate.setDate(newDate.getDate() + direction); this.currentDate = newDate; this.updateDateDisplay(); this.loadDaily(); } bindEvents() { document.getElementById('prevDate').addEventListener('click', () => { this.navigateDate(-1); }); document.getElementById('nextDate').addEventListener('click', () => { this.navigateDate(1); }); } getDateString() { const pad = (n) => String(n).padStart(2, '0'); return `${this.currentDate.getFullYear()}-${pad(this.currentDate.getMonth()+1)}-${pad(this.currentDate.getDate())}`; } } // Search Management class SearchManager { constructor() { this.init(); } init() { this.bindEvents(); } bindEvents() { const searchInput = document.querySelector('.search-input'); const aiSearchInput = document.querySelector('.ai-search-input'); searchInput.addEventListener('input', (e) => { this.handleSearch(e.target.value); }); aiSearchInput.addEventListener('input', (e) => { this.handleAISearch(e.target.value); }); } handleSearch(query) { // Implement search functionality console.log('Search query:', query); } handleAISearch(query) { // Implement AI search functionality console.log('AI search query:', query); } } // Paper Card Renderer class PaperCardRenderer { constructor() { this.cardsContainer = document.getElementById('cards'); } generateThumbnail(title) { // Generate a simple thumbnail based on title const canvas = document.createElement('canvas'); canvas.width = 400; canvas.height = 120; const ctx = canvas.getContext('2d'); // Create gradient background const gradient = ctx.createLinearGradient(0, 0, 400, 120); gradient.addColorStop(0, '#3b82f6'); gradient.addColorStop(1, '#06b6d4'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 400, 120); // Add text ctx.fillStyle = 'rgba(255, 255, 255, 0.9)'; ctx.font = 'bold 16px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const words = title.split(' '); const lines = []; let currentLine = ''; for (const word of words) { const testLine = currentLine + word + ' '; const metrics = ctx.measureText(testLine); if (metrics.width > 350 && currentLine !== '') { lines.push(currentLine); currentLine = word + ' '; } else { currentLine = testLine; } } lines.push(currentLine); const yStart = 60 - (lines.length * 20) / 2; lines.forEach((line, index) => { ctx.fillText(line.trim(), 200, yStart + index * 20); }); return canvas.toDataURL(); } generateAuthorAvatars(authorCount) { const avatars = []; const count = Math.min(authorCount, 5); for (let i = 0; i < count; i++) { avatars.push(`
`); } return avatars.join(''); } renderCard(paper) { const title = paper.title || 'Untitled Paper'; const abstract = paper.abstract || 'No abstract available'; const authors = paper.authors || []; const authorCount = paper.author_count || authors.length || 0; const upvotes = paper.upvotes || 0; const githubStars = paper.github_stars || 0; const comments = paper.comments || 0; const submitter = paper.submitter || 'Anonymous'; // Generate thumbnail URL - try to use HF thumbnail if available const arxivId = paper.arxiv_id; const thumbnailUrl = arxivId ? `https://cdn-thumbnails.huggingface.co/social-thumbnails/papers/${arxivId}.png` : this.generateThumbnail(title); const authorAvatars = this.generateAuthorAvatars(authorCount); const card = document.createElement('article'); card.className = 'hf-paper-card'; card.innerHTML = `Try selecting a different date or check back later.
Backend unavailable on static hosting. Try opening the daily page on Hugging Face:
Open on Hugging FacePapers for ${requestedDate} not available. Showing latest available: ${actualDate}
`; document.body.appendChild(notification); // Remove notification after 5 seconds setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 5000); } showCacheNotification(cachedAt) { // Create a temporary notification const notification = document.createElement('div'); notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: var(--bg-primary); border: 1px solid var(--border-medium); border-radius: 8px; padding: 16px; box-shadow: var(--shadow-lg); z-index: 1000; max-width: 300px; color: var(--text-primary); `; const cacheTime = new Date(cachedAt).toLocaleString(); notification.innerHTML = `Showing cached data from ${cacheTime}
`; document.body.appendChild(notification); // Remove notification after 3 seconds setTimeout(() => { if (notification.parentNode) { notification.parentNode.removeChild(notification); } }, 3000); } } // Initialize the application when DOM is loaded document.addEventListener('DOMContentLoaded', () => { new PaperIndexApp(); });