« get me outta code hell

client: tidy & better isolate random links code in client info - 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>2023-11-15 18:55:22 -0400
committer(quasar) nebula <qznebula@protonmail.com>2023-11-15 18:56:58 -0400
commit91f00a36b33d13630ea7a9ac6fcd03110b0f1a73 (patch)
tree67282bebb4546dd26b8181aee1463295a89accce /src/static
parent43141f1fc41768679b63e154ac21203e928b17c7 (diff)
client: tidy & better isolate random links code in client info
Diffstat (limited to 'src/static')
-rw-r--r--src/static/client3.js218
-rw-r--r--src/static/site5.css5
2 files changed, 126 insertions, 97 deletions
diff --git a/src/static/client3.js b/src/static/client3.js
index 94d4c4e2..31eddfe9 100644
--- a/src/static/client3.js
+++ b/src/static/client3.js
@@ -13,10 +13,6 @@ import {
   getArtistNumContributions,
 } from '../util/wiki-data.js';
 
-let albumData, artistData;
-
-let ready = false;
-
 const clientInfo = window.hsmusicClientInfo = Object.create(null);
 
 const clientSteps = {
@@ -79,11 +75,6 @@ function getRefDirectory(ref) {
   return ref.split(':')[1];
 }
 
-function getAlbum(el) {
-  const directory = cssProp(el, '--album-directory');
-  return albumData.find((album) => album.directory === directory);
-}
-
 // TODO: These should pro8a8ly access some shared urlSpec path. We'd need to
 // separ8te the tooling around that into common-shared code too.
 const getLinkHref = (type, directory) => rebase(`${type}/${directory}`);
@@ -107,6 +98,11 @@ const scriptedLinkInfo = clientInfo.scriptedLinkInfo = {
   nextLink: null,
   previousLink: null,
   randomLink: null,
+
+  state: {
+    albumData: null,
+    artistData: null,
+  },
 };
 
 function getScriptedLinkReferences() {
@@ -128,93 +124,115 @@ function getScriptedLinkReferences() {
 
 function addRandomLinkListeners() {
   for (const a of scriptedLinkInfo.randomLinks ?? []) {
-    a.addEventListener('click', evt => {
-      if (!ready) {
-        evt.preventDefault();
-        return;
-      }
+    a.addEventListener('click', domEvent => {
+      handleRandomLinkClicked(a, domEvent);
+    });
+  }
+}
+
+function handleRandomLinkClicked(a, domEvent) {
+  const href = determineRandomLinkHref(a);
+
+  if (!href) {
+    domEvent.preventDefault();
+    return;
+  }
+
+  setTimeout(() => {
+    a.href = '#'
+  });
+
+  a.href = href;
+}
+
+function determineRandomLinkHref(a) {
+  const {state} = scriptedLinkInfo;
+  const {albumData, artistData} = state;
+
+  const tracksFromAlbums = albums =>
+    albums
+      .map(album => album.tracks)
+      .reduce((acc, tracks) => acc.concat(tracks), []);
+
+  switch (a.dataset.random) {
+    case 'album':
+      if (!albumData) return null;
+      return openAlbum(pick(albumData).directory);
+
+    case 'track':
+      if (!albumData) return null;
+      return openTrack(getRefDirectory(pick(tracksFromAlbums(albumData))));
 
-      const tracks = albumData =>
+    case 'album-in-group-dl': {
+      const albumLinks =
+        Array.from(a
+          .closest('dt')
+          .nextElementSibling
+          .querySelectorAll('li a'))
+
+      const albumDirectories =
+        albumLinks
+          .map(a => cssProp(a, '--album-directory'));
+
+      return openAlbum(pick(albumDirectories));
+    }
+
+    case 'track-in-group-dl': {
+      if (!albumData) return null;
+
+      const albumLinks =
+        Array.from(a
+          .closest('dt')
+          .nextElementSibling
+          .querySelectorAll('li a'))
+
+      const albumDirectories =
+        albumLinks
+          .map(a => cssProp(a, '--album-directory'));
+
+      const filteredAlbumData =
         albumData
-          .map(album => album.tracks)
-          .reduce((acc, tracks) => acc.concat(tracks), []);
+          .filter(album =>
+            albumDirectories.includes(album.directory));
 
-      setTimeout(() => {
-        a.href = rebase('js-disabled');
-      });
-
-      switch (a.dataset.random) {
-        case 'album':
-          a.href = openAlbum(pick(albumData).directory);
-          break;
-
-        case 'track':
-          a.href = openTrack(getRefDirectory(pick(tracks(albumData))));
-          break;
-
-        case 'album-in-group-dl': {
-          const albumLinks =
-            Array.from(a
-              .closest('dt')
-              .nextElementSibling
-              .querySelectorAll('li a'))
-
-          const albumDirectories =
-            albumLinks.map(a =>
-              getComputedStyle(a).getPropertyValue('--album-directory'));
-
-          a.href = openAlbum(pick(albumDirectories));
-          break;
-        }
+      return openTrack(getRefDirectory(pick(tracksFromAlbums(filteredAlbumData))));
+    }
 
-        case 'track-in-group-dl': {
-          const albumLinks =
-            Array.from(a
-              .closest('dt')
-              .nextElementSibling
-              .querySelectorAll('li a'))
+    case 'track-in-sidebar': {
+      // Note that the container for track links may be <ol> or <ul>, and
+      // they can't be identified by href, since links from one track to
+      // another don't include "track" in the href.
+      const trackLinks =
+        Array.from(document
+          .querySelector('.track-list-sidebar-box')
+          .querySelectorAll('li a'));
 
-          const albumDirectories =
-            albumLinks.map(a =>
-              getComputedStyle(a).getPropertyValue('--album-directory'));
+      return pick(trackLinks).href;
+    }
 
-          const filteredAlbumData =
-            albumData.filter(album =>
-              albumDirectories.includes(album.directory));
+    case 'track-in-album': {
+      if (!albumData) return null;
 
-          a.href = openTrack(getRefDirectory(pick(tracks(filteredAlbumData))));
-          break;
-        }
+      const directory = cssProp(a, '--album-directory');
+      const {tracks} = albumData.find(album => album.directory === directory);
 
-        case 'track-in-sidebar': {
-          // Note that the container for track links may be <ol> or <ul>, and
-          // they can't be identified by href, since links from one track to
-          // another don't include "track" in the href.
-          const trackLinks =
-            Array.from(document
-              .querySelector('.track-list-sidebar-box')
-              .querySelectorAll('li a'));
-
-          a.href = pick(trackLinks).href;
-          break;
-        }
+      return openTrack(getRefDirectory(pick(tracks)));
+    }
+
+    case 'artist': {
+      if (!artistData) return null;
+      return openArtist(pick(artistData).directory);
+    }
 
-        case 'track-in-album':
-          a.href = openTrack(getRefDirectory(pick(getAlbum(a).tracks)));
-          break;
+    case 'artist-more-than-one-contrib': {
+      if (!artistData) return null;
 
-        case 'artist':
-          a.href = openArtist(pick(artistData).directory);
-          break;
+      const artists =
+        artistData
+          .filter(artist => getArtistNumContributions(artist) > 1);
 
-        case 'artist-more-than-one-contrib':
-          a.href =
-            openArtist(
-              pick(artistData.filter((artist) => getArtistNumContributions(artist) > 1))
-                .directory);
-          break;
-      }
-    });
+      return openArtist(pick(artists).directory);
+    }
   }
 }
 
@@ -263,22 +281,28 @@ clientSteps.addPageListeners.push(addNavigationKeyPressListeners);
 clientSteps.addPageListeners.push(addRevealLinkClickListeners);
 clientSteps.mutatePageContent.push(mutateNavigationLinkContent);
 
-const elements1 = document.getElementsByClassName('js-hide-once-data');
-const elements2 = document.getElementsByClassName('js-show-once-data');
+if (
+  document.documentElement.dataset.urlKey === 'localized.listing' &&
+  document.documentElement.dataset.urlValue0 === 'random'
+) {
+  const dataLoadingLine = document.getElementById('data-loading-line');
+  const dataLoadedLine = document.getElementById('data-loaded-line');
 
-for (const element of elements1) element.style.display = 'block';
+  dataLoadingLine.style.display = 'block';
 
-fetch(rebase('data.json', 'rebaseShared'))
-  .then((data) => data.json())
-  .then((data) => {
-    albumData = data.albumData;
-    artistData = data.artistData;
+  fetch(rebase('data.json', 'rebaseShared'))
+    .then((data) => data.json())
+    .then((data) => {
+      const {state} = scriptedLinkInfo;
 
-    for (const element of elements1) element.style.display = 'none';
-    for (const element of elements2) element.style.display = 'block';
+      state.albumData = data.albumData;
+      state.artistData = data.artistData;
 
-    ready = true;
-  });
+      dataLoadingLine.style.display = 'none';
+      dataLoadedLine.style.display = 'block';
+    });
+
+}
 
 // Data & info card ---------------------------------------
 
diff --git a/src/static/site5.css b/src/static/site5.css
index 014e6d25..9111f3a6 100644
--- a/src/static/site5.css
+++ b/src/static/site5.css
@@ -792,6 +792,11 @@ html[data-url-key="localized.albumCommentary"] li.no-commentary {
   opacity: 0.7;
 }
 
+html[data-url-key="localized.listing"][data-url-value0="random"] #data-loading-line,
+html[data-url-key="localized.listing"][data-url-value0="random"] #data-loaded-line {
+  display: none;
+}
+
 /* Images */
 
 .image-container {