« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/content/dependencies/generateChronologyLinksScopeSwitcher.js52
-rw-r--r--src/content/dependencies/generateScopedTrackChronologyLinks.js54
-rw-r--r--src/content/dependencies/generateTrackChronologyLinks.js31
-rw-r--r--src/static/css/site.css11
-rw-r--r--src/static/js/client.js44
-rw-r--r--src/strings-default.yaml6
6 files changed, 126 insertions, 72 deletions
diff --git a/src/content/dependencies/generateChronologyLinksScopeSwitcher.js b/src/content/dependencies/generateChronologyLinksScopeSwitcher.js
new file mode 100644
index 00000000..53ec87a6
--- /dev/null
+++ b/src/content/dependencies/generateChronologyLinksScopeSwitcher.js
@@ -0,0 +1,52 @@
+import {stitchArrays} from '#sugar';
+
+export default {
+  extraDependencies: ['html', 'language'],
+
+  slots: {
+    scopes: {
+      validate: v => v.strictArrayOf(v.isStringNonEmpty),
+    },
+
+    contents: {
+      validate: v => v.strictArrayOf(v.isHTML),
+    },
+
+    open: {
+      type: 'boolean',
+      default: true,
+    },
+  },
+
+  generate: (slots, {html, language}) =>
+    html.tag('details', {class: 'scoped-chronology-switcher'},
+      slots.open &&
+        {open: true},
+
+      [
+        html.tag('summary',
+          language.$('trackPage.nav.chronology.scope.title', {
+            scope:
+              slots.scopes.map((scope, index) =>
+                html.tag('a', {class: 'switcher-link'},
+                  {href: '#'},
+
+                  (index === 0
+                    ? {style: 'display: inline'}
+                    : {style: 'display: none'}),
+
+                  language.$('trackPage.nav.chronology.scope', scope))),
+          })),
+
+        stitchArrays({
+          scope: slots.scopes,
+          content: slots.contents,
+        }).map(({scope, content}, index) =>
+            html.tag('div', {class: 'scope-' + scope},
+              (index === 0
+                ? {style: 'display: block'}
+                : {style: 'display: none'}),
+
+              content)),
+      ]),
+};
diff --git a/src/content/dependencies/generateScopedTrackChronologyLinks.js b/src/content/dependencies/generateScopedTrackChronologyLinks.js
index 7cb9ee63..87a7c0fd 100644
--- a/src/content/dependencies/generateScopedTrackChronologyLinks.js
+++ b/src/content/dependencies/generateScopedTrackChronologyLinks.js
@@ -10,8 +10,6 @@ export default {
     'linkTrack',
   ],
 
-  extraDependencies: ['html', 'language'],
-
   relations(relation, album, track) {
     const albumFilter =
       (album
@@ -73,41 +71,19 @@ export default {
     };
   },
 
-  slots: {
-    scope: {
-      validate: v => v.is('wiki', 'album'),
-    },
-
-    visible: {type: 'boolean'},
-  },
-
-  generate: (relations, slots, {html, language}) =>
-    html.tag('div', {class: 'scoped-chronology'},
-      {class: 'scope-' + slots.scope},
-      slots.visible && {style: 'display: block'},
-
-      [
-        html.tag('p',
-          language.$('trackPage.nav.chronology.scope', {
-            scope:
-              html.tag('a', {class: 'scoped-chronology-switcher'},
-                {href: '#'},
-                language.$('trackPage.nav.chronology.scope', slots.scope)),
-          })),
-
-        relations.chronologyLinks.slots({
-          showOnly: true,
-
-          chronologyInfoSets: [
-            {
-              headingString: 'misc.chronology.heading.track',
-              contributions: relations.artistChronologyContributions,
-            },
-            {
-              headingString: 'misc.chronology.heading.coverArt',
-              contributions: relations.coverArtistChronologyContributions,
-            },
-          ],
-        }),
-      ]),
+  generate: (relations) =>
+    relations.chronologyLinks.slots({
+      showOnly: true,
+
+      chronologyInfoSets: [
+        {
+          headingString: 'misc.chronology.heading.track',
+          contributions: relations.artistChronologyContributions,
+        },
+        {
+          headingString: 'misc.chronology.heading.coverArt',
+          contributions: relations.coverArtistChronologyContributions,
+        },
+      ],
+    }),
 };
diff --git a/src/content/dependencies/generateTrackChronologyLinks.js b/src/content/dependencies/generateTrackChronologyLinks.js
index 33911c79..accb9ef1 100644
--- a/src/content/dependencies/generateTrackChronologyLinks.js
+++ b/src/content/dependencies/generateTrackChronologyLinks.js
@@ -1,8 +1,13 @@
 export default {
-  contentDependencies: ['generateScopedTrackChronologyLinks'],
-  extraDependencies: ['html'],
+  contentDependencies: [
+    'generateChronologyLinksScopeSwitcher',
+    'generateScopedTrackChronologyLinks',
+  ],
 
   relations: (relation, track) => ({
+    scopeSwitcher:
+      relation('generateChronologyLinksScopeSwitcher'),
+
     wikiChronologyLinks:
       relation('generateScopedTrackChronologyLinks', null, track),
 
@@ -10,16 +15,16 @@ export default {
       relation('generateScopedTrackChronologyLinks', track.album, track),
   }),
 
-  generate: (relations, {html}) =>
-    html.tags([
-      relations.wikiChronologyLinks.slots({
-        scope: 'wiki',
-        visible: true,
-      }),
+  generate: (relations) =>
+    relations.scopeSwitcher.slots({
+      scopes: [
+        'wiki',
+        'album',
+      ],
 
-      relations.albumChronologyLinks.slots({
-        scope: 'album',
-        visible: false,
-      }),
-    ]),
+      contents: [
+        relations.wikiChronologyLinks,
+        relations.albumChronologyLinks,
+      ],
+    }),
 };
diff --git a/src/static/css/site.css b/src/static/css/site.css
index 622c3ac1..c068c07d 100644
--- a/src/static/css/site.css
+++ b/src/static/css/site.css
@@ -510,16 +510,15 @@ a:not([href]):hover {
   display: none;
 }
 
-#header .scoped-chronology p {
-  margin-top: 0;
-  margin-bottom: 0.25em;
-}
-
-#header .scoped-chronology-switcher {
+#header .scoped-chronology-switcher .switcher-link {
   text-decoration: underline;
   text-decoration-style: dotted;
 }
 
+#header .scoped-chronology-switcher > div {
+  margin-left: 20px;
+}
+
 #secondary-nav {
   text-align: center;
 }
diff --git a/src/static/js/client.js b/src/static/js/client.js
index 5611a349..fe45ba16 100644
--- a/src/static/js/client.js
+++ b/src/static/js/client.js
@@ -2954,7 +2954,7 @@ clientSteps.addPageListeners.push(addAdditionalNamesBoxListeners);
 
 const scopedChronologyLinksInfo = initInfo('scopedChronologyLinksInfo', {
   containers: null,
-  switchers: null,
+  switcherLinks: null,
   modes: null,
 
   session: {
@@ -2965,12 +2965,18 @@ const scopedChronologyLinksInfo = initInfo('scopedChronologyLinksInfo', {
 function getScopedChronologyLinksReferences() {
   const info = scopedChronologyLinksInfo;
 
+  const switcher =
+    document.querySelector('.scoped-chronology-switcher');
+
+  if (!switcher) {
+    return;
+  }
+
   info.containers =
-    Array.from(document.querySelectorAll('.scoped-chronology'));
+    Array.from(switcher.querySelectorAll(':scope > div'));
 
-  info.switchers =
-    info.containers
-      .map(container => container.querySelector('.scoped-chronology-switcher'));
+  info.switcherLinks =
+    Array.from(switcher.querySelectorAll('.switcher-link'));
 
   info.modes =
     info.containers
@@ -2984,21 +2990,29 @@ function addScopedChronologyLinksPageHandlers() {
   const info = scopedChronologyLinksInfo;
   const {session} = scopedChronologyLinksInfo;
 
-  for (const [index, switcher] of info.switchers.entries()) {
-    const currentContainer =
-      info.containers[index];
-
+  for (const [index, {
+    container: currentContainer,
+    switcherLink: currentSwitcherLink,
+  }] of stitchArrays({
+    container: info.containers,
+    switcherLink: info.switcherLinks,
+  }).entries()) {
     const nextContainer =
       atOffset(info.containers, index, +1, {wrap: true});
 
+    const nextSwitcherLink =
+      atOffset(info.switcherLinks, index, +1, {wrap: true});
+
     const nextMode =
       atOffset(info.modes, index, +1, {wrap: true});
 
-    switcher.addEventListener('click', domEvent => {
+    currentSwitcherLink.addEventListener('click', domEvent => {
       domEvent.preventDefault();
 
       cssProp(currentContainer, 'display', 'none');
+      cssProp(currentSwitcherLink, 'display', 'none');
       cssProp(nextContainer, 'display', 'block');
+      cssProp(nextSwitcherLink, 'display', 'inline');
 
       session.selectedMode = nextMode;
     });
@@ -3013,11 +3027,19 @@ function mutateScopedChronologyLinksContent() {
   if (info.modes.includes(selectedMode)) {
     const selectedIndex = info.modes.indexOf(selectedMode);
 
-    for (const [index, container] of info.containers.entries()) {
+    for (const [index, {
+      container,
+      switcherLink,
+    }] of stitchArrays({
+      container: info.containers,
+      switcherLink: info.switcherLinks,
+    }).entries()) {
       if (index === selectedIndex) {
         cssProp(container, 'display', 'block');
+        cssProp(switcherLink, 'display', 'inline');
       } else {
         cssProp(container, 'display', 'none');
+        cssProp(switcherLink, 'display', 'none');
       }
     }
   }
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index c1298555..a2814112 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -1844,9 +1844,9 @@ trackPage:
 
     chronology:
       scope:
-        _: "({SCOPE})"
-        wiki: "Across this wiki..."
-        album: "Within this album..."
+        title: "Chronology links {SCOPE}:"
+        wiki: "across this wiki"
+        album: "within this album"
 
   socialEmbed:
     heading: "{ALBUM}"