"use strict"; 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', () => { if (searchInput.value.length >= SEARCH_MIN_CHARS) { 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) { hideSearchResults(); } }); } function handleSearchInput(e) { const query = e.target.value.trim(); 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') { e.preventDefault(); const prevIndex = Math.max(currentIndex - 1, -1); selectSearchResult(items, prevIndex); } else if (e.key === 'Enter') { e.preventDefault(); if (currentIndex >= 0 && items[currentIndex]) { items[currentIndex].querySelector('a').click(); } } else if (e.key === 'Escape') { hideSearchResults(); } } function selectSearchResult(items, index) { items.forEach((item, i) => { if (i === index) { item.classList.add('bg-opacity-80'); } else { item.classList.remove('bg-opacity-80'); } }); const searchResults = document.getElementById('search-results'); 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 => { if (response.status === 404) { return { error: 'no results found', results: [] }; } return response.json(); }) .then(data => { hideSearchLoading(); if (data.error && data.error === 'no results found') { showNoResults(query); } else if (Array.isArray(data) && data.length > 0) { showSearchResults(data, query); } else { showNoResults(query); } }) .catch(error => { hideSearchLoading(); console.error('Search error:', error); showSearchError(); }); } function showSearchLoading() { createSearchResultsContainer(); const searchResults = document.getElementById('search-results'); searchResults.innerHTML = `
Searching...
${results.length} result${results.length !== 1 ? 's' : ''} for "${escapeHtml(query)}"
Press ↑↓ to navigate, Enter to select
No results found for "${escapeHtml(query)}"
Try different keywords
Search error
Please try again