diff --git a/web/static/search.js b/web/static/search.js index 4e09199..247bd5a 100644 --- a/web/static/search.js +++ b/web/static/search.js @@ -1,16 +1,14 @@ "use strict"; - +Object.defineProperty(exports, "__esModule", { value: true }); let searchTimeout = null; const SEARCH_DEBOUNCE_MS = 300; const SEARCH_MIN_CHARS = 2; - function initializeSearch() { const searchInput = document.getElementById('header-search'); if (!searchInput) { console.warn('Search input not found'); return; } - searchInput.addEventListener('input', handleSearchInput); searchInput.addEventListener('keydown', handleSearchKeydown); searchInput.addEventListener('focus', () => { @@ -18,114 +16,116 @@ function initializeSearch() { performSearch(searchInput.value); } }); - document.addEventListener('click', (e) => { const searchResults = document.getElementById('search-results'); - const searchInput = document.getElementById('header-search'); - - if (searchResults && !searchResults.contains(e.target) && e.target !== searchInput) { + const searchInputEl = document.getElementById('header-search'); + if (searchResults && !searchResults.contains(e.target) && e.target !== searchInputEl) { hideSearchResults(); } }); } - function handleSearchInput(e) { - const query = e.target.value.trim(); - - clearTimeout(searchTimeout); - + const target = e.target; + const query = target.value.trim(); + if (searchTimeout) { + clearTimeout(searchTimeout); + } if (query.length < SEARCH_MIN_CHARS) { hideSearchResults(); return; } - searchTimeout = setTimeout(() => { performSearch(query); }, SEARCH_DEBOUNCE_MS); } - function handleSearchKeydown(e) { const searchResults = document.getElementById('search-results'); if (!searchResults || searchResults.classList.contains('hidden')) { return; } - const items = searchResults.querySelectorAll('.search-result-item'); const currentIndex = parseInt(searchResults.dataset.selectedIndex || '-1'); - if (e.key === 'ArrowDown') { e.preventDefault(); const nextIndex = Math.min(currentIndex + 1, items.length - 1); selectSearchResult(items, nextIndex); - } else if (e.key === 'ArrowUp') { + } + else if (e.key === 'ArrowUp') { e.preventDefault(); const prevIndex = Math.max(currentIndex - 1, -1); selectSearchResult(items, prevIndex); - } else if (e.key === 'Enter') { + } + else if (e.key === 'Enter') { e.preventDefault(); if (currentIndex >= 0 && items[currentIndex]) { - items[currentIndex].querySelector('a').click(); + const link = items[currentIndex].querySelector('a'); + if (link) + link.click(); } - } else if (e.key === 'Escape') { + } + else if (e.key === 'Escape') { hideSearchResults(); } } - function selectSearchResult(items, index) { items.forEach((item, i) => { if (i === index) { item.classList.add('bg-opacity-80'); - } else { + } + else { item.classList.remove('bg-opacity-80'); } }); - const searchResults = document.getElementById('search-results'); - searchResults.dataset.selectedIndex = index.toString(); + if (searchResults) { + searchResults.dataset.selectedIndex = index.toString(); + } } - function performSearch(query) { const token = localStorage.getItem('token'); if (!token) { console.warn('No authentication token found'); return; } - showSearchLoading(); - fetch(`/api/media-items/search?q=${encodeURIComponent(query)}`, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } }) - .then(response => { + .then(response => { if (response.status === 404) { return { error: 'no results found', results: [] }; } return response.json(); }) - .then(data => { + .then((data) => { hideSearchLoading(); - - if (data.error && data.error === 'no results found') { + if (data && 'error' in data && data.error === 'no results found') { showNoResults(query); - } else if (Array.isArray(data) && data.length > 0) { + } + else if (Array.isArray(data) && data.length > 0) { showSearchResults(data, query); - } else { + } + else if (Array.isArray(data)) { + showNoResults(query); + } + else { showNoResults(query); } }) - .catch(error => { + .catch(error => { hideSearchLoading(); console.error('Search error:', error); showSearchError(); }); } - function showSearchLoading() { createSearchResultsContainer(); const searchResults = document.getElementById('search-results'); + if (!searchResults) + return; searchResults.innerHTML = `
@@ -134,22 +134,19 @@ function showSearchLoading() { `; searchResults.classList.remove('hidden'); } - function hideSearchLoading() { - } - function showSearchResults(results, query) { createSearchResultsContainer(); const searchResults = document.getElementById('search-results'); + if (!searchResults) + return; searchResults.dataset.selectedIndex = '-1'; - const libraryIconMap = { 'ebooks': '📚', 'comics': '📖', 'manga': '🗾' }; - let html = `

@@ -158,19 +155,17 @@ function showSearchResults(results, query) {

`; - results.forEach((item, index) => { const icon = libraryIconMap[item.library_type_name] || '📁'; const titleHtml = highlightMatch(item.title, query); const authorHtml = item.author ? highlightMatch(item.author, query) : ''; - html += ` - `; }); - html += `

- Press ↑↓ to navigate, + Press ↑↓ to navigate, Enter to select

`; - searchResults.innerHTML = html; searchResults.classList.remove('hidden'); } - function showNoResults(query) { createSearchResultsContainer(); const searchResults = document.getElementById('search-results'); - + if (!searchResults) + return; searchResults.innerHTML = `
🔍
@@ -215,11 +208,11 @@ function showNoResults(query) { `; searchResults.classList.remove('hidden'); } - function showSearchError() { createSearchResultsContainer(); const searchResults = document.getElementById('search-results'); - + if (!searchResults) + return; searchResults.innerHTML = `
⚠️
@@ -229,14 +222,12 @@ function showSearchError() { `; searchResults.classList.remove('hidden'); } - function hideSearchResults() { const searchResults = document.getElementById('search-results'); if (searchResults) { searchResults.classList.add('hidden'); } } - function createSearchResultsContainer() { let searchResults = document.getElementById('search-results'); if (!searchResults) { @@ -244,32 +235,31 @@ function createSearchResultsContainer() { searchResults.id = 'search-results'; searchResults.className = 'hidden absolute z-50 w-full max-w-2xl mt-2 rounded-lg shadow-lg border'; searchResults.style.cssText = 'background-color: var(--bg-secondary); border-color: var(--border)'; - const searchInput = document.getElementById('header-search'); - const searchContainer = searchInput.closest('.relative'); - searchContainer.appendChild(searchResults); + if (searchInput) { + const searchContainer = searchInput.closest('.relative'); + if (searchContainer) { + searchContainer.appendChild(searchResults); + } + } } } - function highlightMatch(text, query) { - if (!text) return ''; + if (!text) + return ''; const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(`(${escapedQuery})`, 'gi'); return escapeHtml(text).replace(regex, '$1'); } - function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } - function selectLibraryAndBook(libraryId, bookId) { localStorage.setItem('selectedLibrary', libraryId); localStorage.setItem('selectedBook', bookId); hideSearchResults(); } - document.addEventListener('DOMContentLoaded', initializeSearch); - -window.selectLibraryAndBook = selectLibraryAndBook; \ No newline at end of file +window.selectLibraryAndBook = selectLibraryAndBook;