const BASE_URL = "https://oevortex-webscout-api.hf.space";
const searchForm = document.getElementById("search-form");
const searchQueryInput = document.getElementById("search-query");
const resultsContainer = document.getElementById("results");
const suggestionsContainer = document.getElementById("suggestions");
const loadingOverlay = document.querySelector('.loading-overlay');
const noResultsMessage = document.getElementById('no-results');
const loadingMoreIndicator = document.getElementById('loading-more');
const aiResponseContainer = document.getElementById('ai-response');
const INITIAL_RESULTS = 5;
const CACHED_RESULTS = 50;
const RESULTS_PER_PAGE = 5;
let allResultsFetched = false;
const seenUrls = new Set();
let selectedSuggestionIndex = -1;
let suggestionRequestTimeout;
let cachedSearchResults = [];
const suggestionCache = {};
let prefetchTimeout;
let allResults = [];
let startTime;
function debounce(func, delay) {
return function() {
clearTimeout(suggestionRequestTimeout);
suggestionRequestTimeout = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
async function fetchSuggestions(query) {
if (suggestionCache[query]) {
return suggestionCache[query];
}
try {
const response = await fetch(`${BASE_URL}/api/suggestions?q=${encodeURIComponent(query)}`);
if (response.ok) {
const suggestions = await response.json();
suggestionCache[query] = suggestions;
return suggestions;
} else {
console.error("Error fetching suggestions:", response.status);
return [];
}
} catch (error) {
console.error("Error fetching suggestions:", error);
return [];
}
}
searchQueryInput.addEventListener("input", () => {
clearTimeout(prefetchTimeout);
const searchQuery = searchQueryInput.value.trim();
if (searchQuery === "") {
suggestionsContainer.style.display = "none";
return;
}
prefetchTimeout = setTimeout(async () => {
const suggestions = await fetchSuggestions(searchQuery);
displaySuggestions(suggestions);
}, 100);
});
function displaySuggestions(suggestions) {
suggestionsContainer.innerHTML = "";
if (suggestions.length === 0 || searchQueryInput.value.trim() === "") {
suggestionsContainer.style.display = "none";
return;
}
const suggestionList = document.createElement("ul");
suggestions.forEach((suggestion, index) => {
const listItem = document.createElement("li");
listItem.textContent = suggestion.phrase;
listItem.addEventListener("click", () => {
searchQueryInput.value = suggestion.phrase;
suggestionsContainer.style.display = "none";
performSearch(suggestion.phrase);
});
listItem.addEventListener("focus", () => {
selectedSuggestionIndex = index;
updateSuggestionSelection();
});
suggestionList.appendChild(listItem);
});
suggestionsContainer.appendChild(suggestionList);
suggestionsContainer.style.display = "block";
}
function updateSuggestionSelection() {
const suggestionItems = suggestionsContainer.querySelectorAll("li");
suggestionItems.forEach((item, index) => {
item.classList.toggle("selected", index === selectedSuggestionIndex);
});
}
function showLoading() {
loadingOverlay.style.display = 'block';
}
function hideLoading() {
loadingOverlay.style.display = 'none';
}
async function performSearch(query) {
showLoading();
aiResponseContainer.style.display = 'none';
suggestionsContainer.style.display = "none";
startTime = performance.now();
seenUrls.clear();
allResultsFetched = false;
resultsContainer.innerHTML = '';
noResultsMessage.style.display = 'none';
loadingMoreIndicator.classList.remove('active');
speechSynthesis.cancel();
const initialResults = await fetchResults(query, INITIAL_RESULTS);
displayResults(initialResults);
hideLoading();
fetchResults(query, CACHED_RESULTS).then(cachedResults => {
cachedSearchResults = removeDuplicateResults(cachedResults);
allResults = allResults.concat(cachedSearchResults);
displayResults(cachedSearchResults.slice(INITIAL_RESULTS, RESULTS_PER_PAGE), true);
if (cachedSearchResults.length > RESULTS_PER_PAGE) {
allResultsFetched = false;
loadingMoreIndicator.classList.add('active');
}
});
fetchAIResponse(query).then(aiResponse => {
displayAIResponse(aiResponse);
aiResponseContainer.style.display = 'block';
}).catch(error => {
console.error("Error fetching AI response:", error);
});
updateURLWithQuery(query);
}
async function fetchAIResponse(query) {
try {
const encodedQuery = encodeURIComponent(query);
const response = await fetch(`${BASE_URL}/api/ask_website?url=https://google.com/search?q=${encodedQuery}&question=Answer this question from google search result ${encodedQuery}&model=gpt-4o-mini`);
if (response.ok) {
const aiResponse = await response.json();
return aiResponse;
} else {
console.error("Error fetching AI response from website:", response.status);
return null;
}
} catch (error) {
console.error("Error fetching AI response from website:", error);
return null;
}
}
function displayAIResponse(response) {
aiResponseContainer.innerHTML = '';
if (response) {
const aiResultElement = document.createElement('div');
aiResultElement.classList.add('ai-result');
const aiHeading = document.createElement('h2');
aiHeading.textContent = "AI Response";
aiResultElement.appendChild(aiHeading);
const aiText = document.createElement('p');
const decodedResponse = decodeHtml(response);
const msg = new SpeechSynthesisUtterance(decodedResponse);
speechSynthesis.speak(msg);
aiText.textContent = decodedResponse;
const pauseButton = document.createElement('button');
pauseButton.id = 'pause';
pauseButton.innerHTML = '';
const stopButton = document.createElement('button');
stopButton.id = 'stop';
stopButton.innerHTML = '';
let isPaused = false;
let isStoped = false;
pauseButton.addEventListener('click', () => {
if ('speechSynthesis' in window) {
if (isPaused) {
window.speechSynthesis.resume();
isPaused = false;
stopButton.style.display = 'inline-block';
pauseButton.innerHTML = '';
} else {
window.speechSynthesis.pause();
isPaused = true;
stopButton.style.display = 'none';
pauseButton.innerHTML = '';
}
}
});
stopButton.addEventListener('click', () => {
if ('speechSynthesis' in window) {
if (isStoped) {
speechSynthesis.speak(msg);
isPaused = false;
isStoped = false;
pauseButton.innerHTML = '';
pauseButton.style.display = 'inline-block';
stopButton.innerHTML = '';
} else {
window.speechSynthesis.cancel();