From 841fa33cad1b74d1d6eb1bf9a173fd0ce64750f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20V=C3=B6lkel?= <mail@konradvoelkel.com> Date: Thu, 13 Mar 2025 10:59:48 +0100 Subject: [PATCH] loading animation --- index.js | 42 ++++++++++++++++++++++++++++++++++++++++-- semSearch.html | 2 +- worker.js | 7 ++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 2a8ebed..337cd5d 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 dae0e18..62f4617 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 3dfe4d0..087e678 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': -- GitLab