diff --git a/index.js b/index.js index 2a8ebed592d205a65a8502da95d5d4cc5849c8b6..337cd5d35fbcd5f0adaa6fcc3707f8dd40be8dbd 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ import { sendMessage } from './modules/ui.js'; -import { tokenizeText } from './modules/semanticSearch.js'; +import { tokenizeText, initializeModel } from './modules/semanticSearch.js'; import { extractFAQfromHTML } from './modules/faqData.js'; import { loadEmbedding, removeOutdatedEntries } from './modules/embeddings.js' import { handleWorker, processQuery } from './modules/workerInterface.js' @@ -35,6 +35,20 @@ localStorage.setItem('smallEmbedding', JSON.stringify(tokenEmbeddingStack)); const inputElement = document.getElementById('user-input'); const resultsContainer = document.getElementById('results'); + +/** letting users know the site is not broken by showing them a loading animation until model is loaded */ +let dotCount = 0; +let loadingAnimation = null; + +function animateDots() { + dotCount = (dotCount + 1) % 4; + let dots = '.'.repeat(dotCount); + inputElement.placeholder = `Loading ${dots}`; + loadingAnimation = setTimeout(animateDots, 300); +} + +animateDots(); + let topResult = null; inputElement.addEventListener('input', function (event) { const query = event.target.value.trim(); @@ -112,7 +126,14 @@ export function linkAndClick(output) { }, 250); } -worker.onmessage = (events) => handleWorker(events); +/** once model is initialized loading message is removed and user can start typing */ +worker.addEventListener( 'message',function(events) { + if (events.data.type === 'ready') { + readyForInput(); + console.log("Ready"); + } +}); + /** show results in chat window if "ask" is clicked */ function saveMessage(){ @@ -125,7 +146,24 @@ function sendAsk(){ } } +function readyForInput(){ + clearTimeout(loadingAnimation); + inputElement.disabled = false; + inputElement.placeholder = "Try asking: 'minimum admission grade' or 'I'm from outside the EU'"; + inputElement.focus(); +} + + +worker.onmessage = (events) => handleWorker(events); window.sendAsk = sendAsk; /** give worker work */ worker.postMessage({ act: 'initialize', textData, embeddingStack, tokenEmbeddingStack }); + + + + + + + + diff --git a/semSearch.html b/semSearch.html index dae0e181d875d01b16c276bf9d04e8e1a6a9a2ed..62f46174c79b6d61a1dc3c40da223b7824f0153b 100644 --- a/semSearch.html +++ b/semSearch.html @@ -18,7 +18,7 @@ <div id="messages"></div> <div id="messageInfo"></div> <div id="input-container"> - <input type="text" id="user-input" placeholder="Try asking: 'minimum admission grade' or 'I'm from outside the EU'"> + <input type="text" id="user-input" placeholder="Loading" disabled> <button onclick="sendAsk()">Ask</button> diff --git a/worker.js b/worker.js index 3dfe4d0ca55aeaa3ce55602db2c4f40e3b4ae02d..087e678565ad1a30d4b6b32f60d3d8350d3f0f22 100644 --- a/worker.js +++ b/worker.js @@ -12,6 +12,8 @@ import { + + let textData = []; let faqEmbeddings = []; @@ -36,7 +38,10 @@ self.onmessage = async function (event) { console.timeEnd("calcEmbeddings"); postMessage({ act: 'initialized', embeddingCache: getEmbeddingCache() }); postMessage({ act: 'tokeninit', tokenEmbeddingCache: getTokenEmbeddingCache() }); - console.log("Ready"); + + self.postMessage({ + type: 'ready' + }); break; case 'semanticSearch':