diff --git a/script.js b/script.js index bdc06f3..8efc675 100644 --- a/script.js +++ b/script.js @@ -382,6 +382,49 @@ window.changeSemester = function (sem) { renderPDFs(); }; +function prepareSearchIndex() { + const today = new Date(); + const oneWeek = 7 * 24 * 60 * 60 * 1000; + + // Category Icons Map + const categoryIcons = { + 'Organic': 'fa-flask', + 'Inorganic': 'fa-atom', + 'Physical': 'fa-calculator', + 'Physics': 'fa-infinity', + 'Math': 'fa-square-root-alt', + 'Biology': 'fa-dna', + 'History': 'fa-landmark', + 'General': 'fa-globe', + 'Syllabus': 'fa-list-alt' + }; + + pdfDatabase.forEach(pdf => { + // 1. Search String (Lowercased for case-insensitive search) + pdf._searchStr = ( + (pdf.title || '') + ' ' + + (pdf.description || '') + ' ' + + (pdf.category || '') + ' ' + + (pdf.author || '') + ).toLowerCase(); + + // 2. Date Formatting & New Badge + if (pdf.uploadDate) { + const dateObj = new Date(pdf.uploadDate); + pdf._formattedDate = dateObj.toLocaleDateString('en-US', { + year: 'numeric', month: 'short', day: 'numeric' + }); + pdf._isNew = (today - dateObj) < oneWeek && (today - dateObj) >= 0; + } else { + pdf._formattedDate = ''; + pdf._isNew = false; + } + + // 3. Category Icon + pdf._icon = categoryIcons[pdf.category] || 'fa-file-pdf'; + }); +} + async function syncClassSwitcher() { const classSelect = document.getElementById('classSelect'); if (!classSelect) return; @@ -451,6 +494,8 @@ async function loadPDFDatabase() { if (shouldUseCache) { pdfDatabase = cachedData; + // Optim: Prepare Search Index + prepareSearchIndex(); // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderSemesterTabs(); @@ -474,6 +519,9 @@ async function loadPDFDatabase() { data: pdfDatabase })); + // Optim: Prepare Search Index + prepareSearchIndex(); + // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderPDFs(); @@ -788,7 +836,17 @@ function getEmbeddableUrl(url) { return `https://docs.google.com/gview?embedded=true&url=${encodeURIComponent(url)}`; } -async function viewPDF(pdf, pushToHistory = true) { +async function viewPDF(pdfOrId, pushToHistory = true) { + let pdf = pdfOrId; + if (typeof pdfOrId === 'string') { + pdf = pdfDatabase.find(p => p.id === pdfOrId); + } + + if (!pdf) { + showToast('PDF not found.', 'error'); + return; + } + const originalPdfPath = pdf.pdfUrl; logInteraction('view_pdf', pdf.title, pdf.id); @@ -915,10 +973,7 @@ function renderPDFs() { matchesCategory = currentCategory === 'all' || pdf.category === currentCategory; } - const matchesSearch = pdf.title.toLowerCase().includes(searchTerm) || - pdf.description.toLowerCase().includes(searchTerm) || - pdf.category.toLowerCase().includes(searchTerm) || - pdf.author.toLowerCase().includes(searchTerm); + const matchesSearch = (pdf._searchStr || "").includes(searchTerm); // Update return statement to include matchesClass return matchesSemester && matchesClass && matchesCategory && matchesSearch; @@ -991,26 +1046,14 @@ function createPDFCard(pdf, favoritesList, index = 0, highlightRegex = null) { const heartIconClass = isFav ? 'fas' : 'far'; const btnActiveClass = isFav ? 'active' : ''; - const uploadDateObj = new Date(pdf.uploadDate); - const timeDiff = new Date() - uploadDateObj; - const isNew = timeDiff < (7 * 24 * 60 * 60 * 1000); // 7 days + const isNew = pdf._isNew; const newBadgeHTML = isNew ? `NEW` : ''; - const categoryIcons = { - 'Organic': 'fa-flask', - 'Inorganic': 'fa-atom', - 'Physical': 'fa-calculator', - 'Physics': 'fa-infinity' // Ensure Physics icon is mapped if used - }; - const categoryIcon = categoryIcons[pdf.category] || 'fa-file-pdf'; - - // Formatting Date - const formattedDate = new Date(pdf.uploadDate).toLocaleDateString('en-US', { - year: 'numeric', month: 'short', day: 'numeric' - }); + const categoryIcon = pdf._icon || 'fa-file-pdf'; + const formattedDate = pdf._formattedDate || ''; // Uses global escapeHtml() now @@ -1020,8 +1063,6 @@ function createPDFCard(pdf, favoritesList, index = 0, highlightRegex = null) { return safeText.replace(highlightRegex, '$1'); }; - const safePdfString = JSON.stringify(pdf).replace(/"/g, '"'); - // --- NEW: Calculate Stagger Delay --- // Cap at 1s (20 items) so the list doesn't feel unresponsive const delay = Math.min(index * 0.05, 1); @@ -1037,7 +1078,7 @@ function createPDFCard(pdf, favoritesList, index = 0, highlightRegex = null) {

${highlightText(pdf.description)}

-