« get me outta code hell

client: search failed state - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-05-17 21:37:02 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-31 12:11:55 -0300
commit3d7d540611f7fb4870f6886392d2694f0c6003e6 (patch)
tree048f3cd0f1773775faeb33419fd4c4ac6cd2a9b5
parent46297d244e3e0d83bf2dabf2582482c278287f6f (diff)
client: search failed state
-rw-r--r--src/content/dependencies/generateSearchSidebarBox.js3
-rw-r--r--src/static/css/site.css13
-rw-r--r--src/static/js/client.js83
-rw-r--r--src/strings-default.yaml6
4 files changed, 95 insertions, 10 deletions
diff --git a/src/content/dependencies/generateSearchSidebarBox.js b/src/content/dependencies/generateSearchSidebarBox.js
index cc215783..df11c5d9 100644
--- a/src/content/dependencies/generateSearchSidebarBox.js
+++ b/src/content/dependencies/generateSearchSidebarBox.js
@@ -29,6 +29,9 @@ export default {
         html.tag('template', {class: 'wiki-search-searching-string'},
           language.$('misc.search.searching')),
 
+        html.tag('template', {class: 'wiki-search-failed-string'},
+          language.$('misc.search.failed')),
+
         html.tag('template', {class: 'wiki-search-no-results-string'},
           language.$('misc.search.noResults')),
 
diff --git a/src/static/css/site.css b/src/static/css/site.css
index e94484e5..c6411ead 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -507,6 +507,11 @@ summary .group-name {
   color: inherit;
 }
 
+.wiki-search-input[disabled] {
+  opacity: 0.6;
+  cursor: not-allowed;
+}
+
 .wiki-search-sidebar-box hr {
   border-color: var(--primary-color);
   border-style: none none dotted none;
@@ -531,6 +536,14 @@ summary .group-name {
   flex-grow: 1;
 }
 
+.wiki-search-failed-container {
+  padding: 2px 3px 4px 6px;
+}
+
+.wiki-search-failed-container p {
+  margin: 0;
+}
+
 .wiki-search-results-container {
   margin-bottom: 0;
   padding: 2px;
diff --git a/src/static/js/client.js b/src/static/js/client.js
index 5f9143e9..58f1acb9 100644
--- a/src/static/js/client.js
+++ b/src/static/js/client.js
@@ -3529,7 +3529,7 @@ function handleSearchWorkerStatusMessage(message) {
 
     case 'setup-error':
       console.debug(`Search worker failed to initialize.`);
-      state.workerReadyPromiseResolvers.reject('setup-error');
+      state.workerReadyPromiseResolvers.reject(new Error('Received "setup-error" status from worker'));
       dispatchInternalEvent(event, 'whenWorkerFailsToInitialize');
       break;
 
@@ -3675,6 +3675,9 @@ const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
   progressLabel: null,
   progressBar: null,
 
+  failedRule: null,
+  failedContainer: null,
+
   resultsRule: null,
   resultsContainer: null,
   results: null,
@@ -3686,6 +3689,7 @@ const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
   preparingString: null,
   loadingDataString: null,
   searchingString: null,
+  failedString: null,
 
   noResultsString: null,
   currentResultString: null,
@@ -3739,6 +3743,9 @@ function getSidebarSearchReferences() {
   info.searchingString =
     findString('searching');
 
+  info.failedString =
+    findString('failed');
+
   info.noResultsString =
     findString('no-results');
 
@@ -3823,6 +3830,28 @@ function mutateSidebarSearchContent() {
   info.searchBox.appendChild(info.progressRule);
   info.searchBox.appendChild(info.progressContainer);
 
+  // Search failed section
+
+  info.failedRule =
+    document.createElement('hr');
+
+  info.failedContainer =
+    document.createElement('div');
+
+  info.failedContainer.classList.add('wiki-search-failed-container');
+
+  {
+    const p = document.createElement('p');
+    p.appendChild(templateContent(info.failedString));
+    info.failedContainer.appendChild(p);
+  }
+
+  cssProp(info.failedRule, 'display', 'none');
+  cssProp(info.failedContainer, 'display', 'none');
+
+  info.searchBox.appendChild(info.failedRule);
+  info.searchBox.appendChild(info.failedContainer);
+
   // Results section
 
   info.resultsRule =
@@ -3941,6 +3970,7 @@ function trackSidebarSearchWorkerFailsToInitialize() {
   const {state} = sidebarSearchInfo;
 
   state.workerStatus = 'failed';
+  state.searchStage = 'failed';
 }
 
 function trackSidebarSearchDownloadsBegin(event) {
@@ -3982,7 +4012,15 @@ async function activateSidebarSearch(query) {
       : 'preparing');
   updateSidebarSearchStatus();
 
-  const results = await searchAll(query, {enrich: true});
+  let results;
+  try {
+    results = await searchAll(query, {enrich: true});
+  } catch (error) {
+    console.error(`There was an error performing a sidebar search:`);
+    console.error(error);
+    showSidebarSearchFailed();
+    return;
+  }
 
   state.searchStage = 'complete';
   updateSidebarSearchStatus();
@@ -4022,6 +4060,21 @@ function updateSidebarSearchStatus() {
   const info = sidebarSearchInfo;
   const {state} = info;
 
+  if (state.searchStage === 'failed') {
+    hideSidebarSearchResults();
+    showSidebarSearchFailed();
+
+    return;
+  }
+
+  if (state.searchStage === 'preparing') {
+    showSidebarSearchProgress(
+      null,
+      templateContent(info.preparingString));
+
+    return;
+  }
+
   const searchIndexDownloads =
     getSearchWorkerDownloadContext('search-indexes');
 
@@ -4038,14 +4091,6 @@ function updateSidebarSearchStatus() {
     return;
   }
 
-  if (state.searchStage === 'preparing') {
-    showSidebarSearchProgress(
-      null,
-      templateContent(info.preparingString));
-
-    return;
-  }
-
   if (state.searchStage === 'searching') {
     showSidebarSearchProgress(
       null,
@@ -4083,6 +4128,24 @@ function hideSidebarSearchProgress() {
   cssProp(info.progressContainer, 'display', 'none');
 }
 
+function showSidebarSearchFailed() {
+  const info = sidebarSearchInfo;
+  const {state} = info;
+
+  hideSidebarSearchProgress();
+  hideSidebarSearchResults();
+
+  cssProp(info.failedRule, 'display', null);
+  cssProp(info.failedContainer, 'display', null);
+
+  info.searchInput.disabled = true;
+
+  if (state.stoppedTypingTimeout) {
+    clearTimeout(state.stoppedTypingTimeout);
+    state.stoppedTypingTimeout = null;
+  }
+}
+
 function showSidebarSearchResults(results) {
   const info = sidebarSearchInfo;
 
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index aaa74dca..3ed73b2b 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -626,6 +626,12 @@ misc:
     loadingData: "Loading data..."
     searching: "Searching..."
 
+    failed: >-
+      There was an internal error,
+      and your search couldn't be processed.
+      Reloading this page and trying again may help.
+      Sorry for the trouble!
+
     noResults: >-
       No results for this query, sorry!
       Check spelling and use complete words.