« get me outta code hell

client: search results behavior stub - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/static
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-04-30 21:01:36 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-31 12:11:46 -0300
commitb705b488b04522a0d21da989015c40461f120c6e (patch)
tree85c99cd7a321515857a900e7441633e9f1760a6d /src/static
parent188916742f82c937d114b886ef54e71d150cea44 (diff)
client: search results behavior stub
Diffstat (limited to 'src/static')
-rw-r--r--src/static/css/site.css39
-rw-r--r--src/static/js/client.js136
2 files changed, 174 insertions, 1 deletions
diff --git a/src/static/css/site.css b/src/static/css/site.css
index 2dc06469..d2c121e6 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -462,7 +462,7 @@ summary .group-name {
   font-weight: normal;
 }
 
-.search-sidebar-box {
+.wiki-search-sidebar-box {
   padding: 2px;
   position: sticky;
   top: 5px;
@@ -490,6 +490,43 @@ summary .group-name {
   color: inherit;
 }
 
+.wiki-search-results-container hr {
+  border-color: var(--primary-color);
+  border-style: none none dotted none;
+}
+
+.wiki-search-results-container {
+  margin-bottom: 5px;
+}
+
+.wiki-search-result {
+  display: flex;
+  padding: 0 6px;
+  margin: 3px 0 5px 0;
+}
+
+.wiki-search-result-name {
+  align-self: center;
+  flex-grow: 1;
+  padding-bottom: 2px;
+}
+
+.wiki-search-result-image,
+.wiki-search-result-image-placeholder {
+  align-self: flex-start;
+  width: 1.8em;
+  height: 1.8em;
+  margin-right: 6px;
+}
+
+.wiki-search-result-image-placeholder {
+  display: inline-block;
+}
+
+.wiki-search-results:not(:has(.wiki-search-result-image)) .wiki-search-result-image-placeholder {
+  display: none;
+}
+
 .wiki-search-input:focus {
   border: 1px solid var(--primary-color);
 }
diff --git a/src/static/js/client.js b/src/static/js/client.js
index a3d63719..0a4dc0ff 100644
--- a/src/static/js/client.js
+++ b/src/static/js/client.js
@@ -3456,6 +3456,142 @@ document.addEventListener('DOMContentLoaded', initSearch);
 
 window.searchAll = searchAll;
 
+// Sidebar search box -------------------------------------
+
+const sidebarSearchInfo = initInfo('sidebarSearchInfo', {
+  searchBox: null,
+  searchInput: null,
+
+  resultsContainer: null,
+  results: null,
+});
+
+function getSidebarSearchReferences() {
+  const info = sidebarSearchInfo;
+
+  info.searchBox =
+    document.querySelector('.wiki-search-sidebar-box');
+
+  info.searchInput =
+    document.querySelector('.wiki-search-input');
+}
+
+function mutateSidebarSearchContent() {
+  const info = sidebarSearchInfo;
+
+  if (!info.searchBox) return;
+
+  info.resultsContainer =
+    document.createElement('div');
+
+  info.resultsContainer.classList.add('wiki-search-results-container');
+
+  cssProp(info.resultsContainer, 'display', 'none');
+  info.resultsContainer.appendChild(document.createElement('hr'));
+
+  info.results =
+    document.createElement('div');
+
+  info.results.classList.add('wiki-search-results');
+
+  info.resultsContainer.appendChild(info.results);
+
+  info.searchBox.appendChild(info.resultsContainer);
+}
+
+function addSidebarSearchListeners() {
+  const info = sidebarSearchInfo;
+
+  if (!info.searchInput) return;
+
+  info.searchInput.addEventListener('change', domEvent => {
+    activateSidebarSearch(info.searchInput.value);
+  });
+}
+
+function activateSidebarSearch(query) {
+  showSidebarSearchResults(searchAll(query, {enrich: true}));
+}
+
+function showSidebarSearchResults(results) {
+  const info = sidebarSearchInfo;
+
+  const flatResults =
+    Object.entries(results)
+      .flatMap(([index, results]) => results
+        .flatMap(({field, result}) => result
+          .flatMap(({doc, id}) => ({
+            index,
+            field,
+            reference: id ?? null,
+            directory: (id ? id.split(':')[1] : null),
+            data: doc,
+          }))));
+
+  console.log(flatResults);
+
+  while (info.results.firstChild) {
+    info.results.firstChild.remove();
+  }
+
+  cssProp(info.resultsContainer, 'display', 'block');
+
+  for (const result of flatResults) {
+    if (result.index !== 'tracks') continue;
+
+    const link = document.createElement('a');
+    link.classList.add('wiki-search-result');
+
+    link.setAttribute('href', openTrack(result.directory));
+    cssProp(link, '--primary-color', result.data.color);
+
+    const span = document.createElement('span');
+    span.classList.add('wiki-search-result-name');
+
+    span.appendChild(document.createTextNode(result.data.name));
+
+    let image;
+    image = document.createElement('img');
+    image.classList.add('wiki-search-result-image');
+
+    switch (result.data.artworkKind) {
+      case 'track':
+        image.setAttribute('src', rebase(
+          (`album-art`
+         + `/${result.data.albumDirectory}`
+         + `/${result.directory}`
+         + `.small.jpg`),
+          'rebaseThumb'));
+        break;
+
+      case 'album':
+        image.setAttribute('src', rebase(
+          (`album-art`
+         + `/${result.data.albumDirectory}`
+         + `/cover.small.jpg`),
+          'rebaseThumb'));
+        break;
+
+      default:
+        image = document.createElement('span');
+        image.classList.add('wiki-search-result-image-placeholder');
+        break;
+    }
+
+    if (image) {
+      link.appendChild(image);
+    }
+
+    link.appendChild(span);
+
+    info.results.appendChild(link);
+  }
+}
+
+clientSteps.getPageReferences.push(getSidebarSearchReferences);
+clientSteps.mutatePageContent.push(mutateSidebarSearchContent);
+clientSteps.addPageListeners.push(addSidebarSearchListeners);
+
 // Sticky commentary sidebar ------------------------------
 
 const albumCommentarySidebarInfo = initInfo('albumCommentarySidebarInfo', {