From 6be3c4a25d05d424fce3e116ba69dfd83aa6fac9 Mon Sep 17 00:00:00 2001 From: Pierre Demailly Date: Sat, 7 Dec 2024 13:32:49 +0100 Subject: [PATCH] feat(search): add spinner while searching package versions --- public/components/views/search/search.css | 5 +++ public/components/views/search/search.js | 40 ++++++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/public/components/views/search/search.css b/public/components/views/search/search.css index 1bca4cb0..daa23f52 100644 --- a/public/components/views/search/search.css +++ b/public/components/views/search/search.css @@ -236,3 +236,8 @@ input:-webkit-autofill { background: #5468842a; cursor: pointer; } + +.spinner-option { + font-size: smaller; + text-align: center; +} diff --git a/public/components/views/search/search.js b/public/components/views/search/search.js index aa89b022..5a61a627 100644 --- a/public/components/views/search/search.js +++ b/public/components/views/search/search.js @@ -102,15 +102,39 @@ export class SearchView { optionElement.textContent = version; selectElement.appendChild(optionElement); selectElement.addEventListener("click", async() => { - const versions = await this.fetchPackageVersions(name); - for (const pkgVersion of versions) { - if (pkgVersion === version) { - continue; + const spinnerOption = ""; + selectElement.insertAdjacentHTML("beforeend", spinnerOption); + + function spinnerOptionSpin() { + const spinnerOptionElement = selectElement.querySelector(".spinner-option"); + spinnerOptionElement.textContent += "."; + if (spinnerOptionElement.textContent.length > 3) { + spinnerOptionElement.textContent = "."; } - const optionElement = document.createElement("option"); - optionElement.value = pkgVersion; - optionElement.textContent = pkgVersion; - selectElement.appendChild(optionElement); + } + + const spinIntervalId = setInterval(spinnerOptionSpin, 180); + + try { + const versions = await this.fetchPackageVersions(name); + + clearInterval(spinIntervalId); + + selectElement.querySelector(".spinner-option").remove(); + + for (const pkgVersion of versions) { + if (pkgVersion === version) { + continue; + } + const optionElement = document.createElement("option"); + optionElement.value = pkgVersion; + optionElement.textContent = pkgVersion; + selectElement.appendChild(optionElement); + } + } + catch { + clearInterval(spinIntervalId); + selectElement.querySelector(".spinner-option").remove(); } }, { once: true }); divResultElement.appendChild(selectElement);