/** * Sibilla — Frontend search interface * Mobile-friendly, smooth UX */ document.addEventListener('DOMContentLoaded', () => { const form = document.getElementById('search-form'); const queryInput = document.getElementById('query'); const submitBtn = document.getElementById('submit-btn'); const responseArea = document.getElementById('response-area'); const loading = document.getElementById('loading'); const answerDiv = document.getElementById('answer'); const sourcesDiv = document.getElementById('sources'); const metaBar = document.getElementById('meta-bar'); const newSearchBtn = document.getElementById('new-search-btn'); const btnText = submitBtn.querySelector('span').textContent; let isSearching = false; form.addEventListener('submit', async (e) => { e.preventDefault(); if (isSearching) return; const query = queryInput.value.trim(); if (!query) return; // Reset and show UI isSearching = true; responseArea.style.display = 'block'; loading.style.display = 'flex'; answerDiv.innerHTML = ''; sourcesDiv.innerHTML = ''; metaBar.innerHTML = ''; metaBar.style.display = 'none'; newSearchBtn.classList.remove('visible'); submitBtn.disabled = true; submitBtn.querySelector('span').textContent = 'Consultando...'; // Scroll to loading indicator on mobile loading.scrollIntoView({ behavior: 'smooth', block: 'start' }); try { const res = await fetch('/api/ask', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query }), }); if (!res.ok) { const err = await res.json(); throw new Error(err.error || 'Errore sconosciuto'); } const data = await res.json(); // Render answer — prefer server-rendered HTML, fall back to client-side markdown if (data.html_answer) { answerDiv.innerHTML = data.html_answer; } else { answerDiv.innerHTML = renderMarkdown(data.answer); } // Render metadata bar if (data.search_engine || data.tokens_used) { let metaHtml = ''; if (data.search_engine && data.search_engine !== 'none') { metaHtml += ``; } if (data.model) { metaHtml += ``; } if (data.tokens_used) { metaHtml += ``; } metaBar.innerHTML = metaHtml; metaBar.style.display = 'flex'; } // Render sources if (data.sources && data.sources.length > 0) { sourcesDiv.innerHTML = '
$1');
// Links
html = html.replace(/\[(.+?)\]\((.+?)\)/g, '$1');
// Paragraphs (double newlines)
html = html.replace(/\n\n/g, ''); html = '
' + html + '
'; html = html.replace(/\s*<\/p>/g, '');
// Line breaks
html = html.replace(/\n/g, '
');
return html;
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}