« get me outta code hell

client, search: disambiguate harder - 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>2026-02-12 17:55:47 -0400
committer(quasar) nebula <qznebula@protonmail.com>2026-02-12 17:55:47 -0400
commite82707fadb8a441c9ef8dc2de85a34d53d7c5abe (patch)
tree5143745c9f9332f26f0142fc90177431d2af4341 /src/static
parentf227fe62e80f4671ed1e260680ae1adf6f80ba75 (diff)
client, search: disambiguate harder
Diffstat (limited to 'src/static')
-rw-r--r--src/static/js/client/sidebar-search.js90
1 files changed, 79 insertions, 11 deletions
diff --git a/src/static/js/client/sidebar-search.js b/src/static/js/client/sidebar-search.js
index a06c95fd..5b3c0ee1 100644
--- a/src/static/js/client/sidebar-search.js
+++ b/src/static/js/client/sidebar-search.js
@@ -1,5 +1,11 @@
 import {getColors} from '../../shared-util/colors.js';
-import {accumulateSum, empty, unique} from '../../shared-util/sugar.js';
+
+import {
+  accumulateSum,
+  compareArrays,
+  empty,
+  unique,
+} from '../../shared-util/sugar.js';
 
 import {
   cssProp,
@@ -80,7 +86,8 @@ export const info = {
 
   groupResultDisambiguatorString: null,
   flashResultDisambiguatorString: null,
-  trackResultDisambiguatorString: null,
+  trackResultDisambiguatorString1: null,
+  trackResultDisambiguatorString2: null,
 
   albumResultFilterString: null,
   artistResultFilterString: null,
@@ -224,8 +231,11 @@ export function getPageReferences() {
   info.flashResultDisambiguatorString =
     findString('flash-result-disambiguator');
 
-  info.trackResultDisambiguatorString =
-    findString('track-result-disambiguator');
+  info.trackResultDisambiguatorString1 =
+    findString('track-result-album-disambiguator');
+
+  info.trackResultDisambiguatorString2 =
+    findString('track-result-artist-disambiguator');
 
   info.albumResultFilterString =
     findString('album-result-filter');
@@ -1087,18 +1097,76 @@ function generateSidebarSearchResult(result, results) {
   const compareName = otherResult =>
     getSearchResultName(otherResult) === getSearchResultName(result);
 
-  const ambiguous =
-    results.some(otherResult =>
+  const ambiguousWith =
+    results.filter(otherResult =>
       otherResult !== result &&
       compareReferenceType(otherResult) &&
       compareName(otherResult));
 
-  if (ambiguous) {
-    preparedSlots.disambiguate =
-      result.data.disambiguator;
+  if (!empty(ambiguousWith)) disambiguate: {
+    const allAmbiguous = [result, ...ambiguousWith];
+
+    // First search for an ideal disambiguation, which disambiguates
+    // all ambiguous results in the same way.
+    let disambiguation = null, i;
+    for (i = 0; i < result.data.disambiguators.length; i++) {
+      const disambiguations =
+        allAmbiguous.map(r => r.data.disambiguators[i]);
+
+      if (unique(disambiguations).length === allAmbiguous.length) {
+        disambiguation = result.data.disambiguators[i];
+        break;
+      }
+    }
+
+    // Otherwise, search for a disambiguation which disambiguates
+    // *this result* with at least one other result which it is
+    // *otherwise* ambiguous with.
+    if (!disambiguation) {
+      for (i = 1; i < result.data.disambiguators.length; i++) {
+        const otherwiseAmbiguousWith =
+          ambiguousWith.filter(otherResult =>
+            compareArrays(
+              otherResult.data.disambiguators.slice(0, i),
+              result.data.disambiguators.slice(0, i)));
+
+        if (
+          otherwiseAmbiguousWith.find(otherResult =>
+            otherResult.data.disambiguators[i] !==
+            result.data.disambiguators[i])
+        ) {
+          disambiguation = result.data.disambiguators[i];
+          break;
+        }
+      }
+    }
+
+    // Otherwise, search for a disambiguation which disambiguates
+    // this result at all.
+    if (!disambiguation) {
+      for (i = 0; i < result.data.disambiguators.length; i++) {
+        if (
+          ambiguousWith.find(otherResult =>
+            otherResult.data.disambiguators[i] !==
+            result.data.disambiguators[i])
+        ) {
+          disambiguation = result.data.disambiguators[i];
+          break;
+        }
+      }
+    }
+
+    if (!disambiguation) {
+      break disambiguate;
+    }
+
+    const string =
+      info[result.referenceType + 'ResultDisambiguatorString' + (i + 1)];
+
+    if (!string) break disambiguate;
 
-    preparedSlots.disambiguatorString =
-      info[result.referenceType + 'ResultDisambiguatorString'];
+    preparedSlots.disambiguate = disambiguation;
+    preparedSlots.disambiguatorString = string;
   }
 
   return generateSidebarSearchResultTemplate(preparedSlots);