« 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/generateAlbumSecondaryNav.js166
-rw-r--r--src/content/dependencies/generateAlbumSecondaryNavGroupPart.js98
-rw-r--r--src/strings-default.yaml13
3 files changed, 129 insertions, 148 deletions
diff --git a/src/content/dependencies/generateAlbumSecondaryNav.js b/src/content/dependencies/generateAlbumSecondaryNav.js
index d6ff8a0a..4a3d18be 100644
--- a/src/content/dependencies/generateAlbumSecondaryNav.js
+++ b/src/content/dependencies/generateAlbumSecondaryNav.js
@@ -1,96 +1,22 @@
-import {sortChronologically} from '#sort';
-import {atOffset, stitchArrays} from '#sugar';
-
 export default {
   contentDependencies: [
-    'generateColorStyleAttribute',
-    'generatePreviousNextLinks',
+    'generateAlbumSecondaryNavGroupPart',
     'generateSecondaryNav',
-    'linkAlbumDynamically',
-    'linkGroup',
-    'linkTrack',
   ],
 
-  extraDependencies: ['html', 'language'],
-
-  query(album) {
-    const query = {};
-
-    query.groups =
-      album.groups;
-
-    if (album.date) {
-      // Sort by latest first. This matches the sorting order used on group
-      // gallery pages, ensuring that previous/next matches moving up/down
-      // the gallery. Note that this makes the index offsets "backwards"
-      // compared to how latest-last chronological lists are accessed.
-      const groupAlbums =
-        query.groups.map(group =>
-          sortChronologically(
-            group.albums.filter(album => album.date),
-            {latestFirst: true}));
-
-      const groupCurrentIndex =
-        groupAlbums.map(albums =>
-          albums.indexOf(album));
-
-      query.groupPreviousAlbum =
-        stitchArrays({
-          albums: groupAlbums,
-          index: groupCurrentIndex,
-        }).map(({albums, index}) =>
-            atOffset(albums, index, +1));
-
-      query.groupNextAlbum =
-        stitchArrays({
-          albums: groupAlbums,
-          index: groupCurrentIndex,
-        }).map(({albums, index}) =>
-            atOffset(albums, index, -1));
-    }
-
-    return query;
-  },
-
-  relations(relation, query, album) {
-    const relations = {};
-
-    relations.secondaryNav =
-      relation('generateSecondaryNav');
-
-    relations.groupLinks =
-      query.groups
-        .map(group => relation('linkGroup', group));
+  extraDependencies: ['html'],
 
-    relations.colorStyles =
-      query.groups
-        .map(group => relation('generateColorStyleAttribute', group.color));
+  relations: (relation, album) => ({
+    secondaryNav:
+      relation('generateSecondaryNav'),
 
-    if (album.date) {
-      relations.previousNextLinks =
-        stitchArrays({
-          previousAlbum: query.groupPreviousAlbum,
-          nextAlbum: query.groupNextAlbum
-        }).map(({previousAlbum, nextAlbum}) =>
-            (previousAlbum || nextAlbum
-              ? relation('generatePreviousNextLinks')
-              : null));
-
-      relations.previousAlbumLinks =
-        query.groupPreviousAlbum.map(previousAlbum =>
-          (previousAlbum
-            ? relation('linkAlbumDynamically', previousAlbum)
-            : null));
-
-      relations.nextAlbumLinks =
-        query.groupNextAlbum.map(nextAlbum =>
-          (nextAlbum
-            ? relation('linkAlbumDynamically', nextAlbum)
-            : null));
-    }
-
-    return relations;
-  },
+    groupParts:
+      album.groups
+        .map(group =>
+          relation('generateAlbumSecondaryNavGroupPart',
+            group,
+            album)),
+  }),
 
   slots: {
     mode: {
@@ -99,67 +25,11 @@ export default {
     },
   },
 
-  generate(relations, slots, {html, language}) {
-    const navLinksShouldShowPreviousNext =
-      (slots.mode === 'track'
-        ? Array.from(relations.previousNextLinks ?? [], () => false)
-        : stitchArrays({
-            previousAlbumLink: relations.previousAlbumLinks ?? null,
-            nextAlbumLink: relations.nextAlbumLinks ?? null,
-          }).map(({previousAlbumLink, nextAlbumLink}) =>
-              previousAlbumLink ||
-              nextAlbumLink));
-
-    const navLinkPreviousNextLinks =
-      stitchArrays({
-        showPreviousNext: navLinksShouldShowPreviousNext,
-        previousNextLinks: relations.previousNextLinks ?? null,
-        previousAlbumLink: relations.previousAlbumLinks ?? null,
-        nextAlbumLink: relations.nextAlbumLinks ?? null,
-      }).map(({
-          showPreviousNext,
-          previousNextLinks,
-          previousAlbumLink,
-          nextAlbumLink,
-        }) =>
-          (showPreviousNext
-            ? previousNextLinks.slots({
-                previousLink: previousAlbumLink,
-                nextLink: nextAlbumLink,
-                id: false,
-              })
-            : null));
-
-    for (const groupLink of relations.groupLinks) {
-      groupLink.setSlot('color', false);
-    }
-
-    const navLinkContents =
-      stitchArrays({
-        groupLink: relations.groupLinks,
-        previousNextLinks: navLinkPreviousNextLinks,
-      }).map(({groupLink, previousNextLinks}) => [
-          language.$('albumSidebar.groupBox.title', {
-            group: groupLink,
-          }),
-
-          previousNextLinks &&
-            `(${language.formatUnitList(previousNextLinks.content)})`,
-        ]);
-
-    const navLinks =
-      stitchArrays({
-        content: navLinkContents,
-        colorStyle: relations.colorStyles,
-      }).map(({content, colorStyle}) =>
-          html.tag('span', {class: 'nav-link'},
-            colorStyle.slot('context', 'primary-only'),
-
-            content));
-
-    return relations.secondaryNav.slots({
+  generate: (relations, slots) =>
+    relations.secondaryNav.slots({
       class: 'nav-links-groups',
-      content: navLinks,
-    });
-  },
+      content:
+        relations.groupParts
+          .map(part => part.slot('mode', slots.mode)),
+    }),
 };
diff --git a/src/content/dependencies/generateAlbumSecondaryNavGroupPart.js b/src/content/dependencies/generateAlbumSecondaryNavGroupPart.js
new file mode 100644
index 00000000..81b0c75a
--- /dev/null
+++ b/src/content/dependencies/generateAlbumSecondaryNavGroupPart.js
@@ -0,0 +1,98 @@
+import {sortChronologically} from '#sort';
+import {atOffset} from '#sugar';
+
+export default {
+  contentDependencies: [
+    'generateColorStyleAttribute',
+    'generatePreviousNextLinks',
+    'linkAlbumDynamically',
+    'linkGroup',
+  ],
+
+  extraDependencies: ['html', 'language'],
+
+  query(group, album) {
+    const query = {};
+
+    if (album.date) {
+      // Sort by latest first. This matches the sorting order used on group
+      // gallery pages, ensuring that previous/next matches moving up/down
+      // the gallery. Note that this makes the index offsets "backwards"
+      // compared to how latest-last chronological lists are accessed.
+      const albums =
+        sortChronologically(
+          group.albums.filter(album => album.date),
+          {latestFirst: true});
+
+      const currentIndex =
+        albums.indexOf(album);
+
+      query.previousAlbum =
+        atOffset(albums, currentIndex, +1);
+
+      query.nextAlbum =
+        atOffset(albums, currentIndex, -1);
+    }
+
+    return query;
+  },
+
+  relations: (relation, query, group, _album) => ({
+    groupLink:
+      relation('linkGroup', group),
+
+    colorStyle:
+      relation('generateColorStyleAttribute', group.color),
+
+    previousNextLinks:
+      relation('generatePreviousNextLinks'),
+
+    previousAlbumLink:
+      (query.previousAlbum
+        ? relation('linkAlbumDynamically', query.previousAlbum)
+        : null),
+
+    nextAlbumLink:
+      (query.nextAlbum
+        ? relation('linkAlbumDynamically', query.nextAlbum)
+        : null),
+  }),
+
+  slots: {
+    mode: {
+      validate: v => v.is('album', 'track'),
+      default: 'album',
+    },
+  },
+
+  generate: (relations, slots, {html, language}) =>
+    html.tag('span', {class: 'nav-link'},
+      relations.colorStyle
+        .slot('context', 'primary-only'),
+
+      language.encapsulate('albumSecondaryNav.group', workingCapsule => {
+        const workingOptions = {};
+
+        workingOptions.group =
+          relations.groupLink
+            .slot('color', false);
+
+        if (slots.mode === 'album') {
+          const {previousNextLinks} = relations;
+
+          previousNextLinks.setSlots({
+            previousLink: relations.previousAlbumLink,
+            nextLink: relations.nextAlbumLink,
+            id: false,
+          });
+
+          if (!html.isBlank(previousNextLinks)) {
+            workingCapsule += '.withPreviousNext';
+            workingOptions.previousNext =
+              language.formatUnitList(previousNextLinks.content);
+          }
+        }
+
+        return language.$(workingCapsule, workingOptions);
+      })),
+};
diff --git a/src/strings-default.yaml b/src/strings-default.yaml
index aaa38c59..731943a0 100644
--- a/src/strings-default.yaml
+++ b/src/strings-default.yaml
@@ -931,6 +931,19 @@ albumSidebar:
     previous: "Previous: {ALBUM}"
 
 #
+# albumSecondaryNav:
+#   The secondary nav bar is shown in medium and thin layouts,
+#   and provides access to the same navigational features present
+#   in the sidebar (with a more compact view).
+#
+albumSecondaryNav:
+  group: >-
+    {GROUP}
+
+  group.withPreviousNext: >-
+    {GROUP} ({PREVIOUS_NEXT})
+
+#
 # albumPage:
 #
 #   Albums group together tracks and provide quick access to each of