« get me outta code hell

data: new sortByPositionInFlash act function - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-04-27 16:55:06 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-04-27 16:56:00 -0300
commit6128ba16c1b5c4c6095e0ddba0977817cce4bc6e (patch)
tree2f22c42534fdfb4e8dfdd3bb1108dd7eaeaeca23
parent3a322d96666b8da2b615ffd1c245f3a2f3d0cd90 (diff)
data: new sortByPositionInFlash act function
Fixes #168.

This refactors the duplicated logic with sortByPositionInAlbum
into a new template, sortByPositionInParent.
-rw-r--r--src/data/yaml.js2
-rw-r--r--src/listing-spec.js3
-rw-r--r--src/misc-templates.js3
-rw-r--r--src/page/artist.js4
-rw-r--r--src/page/track.js4
-rw-r--r--src/util/wiki-data.js83
6 files changed, 77 insertions, 22 deletions
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 1b1195ea..de0b506b 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -24,6 +24,7 @@ import {
   sortAlbumsTracksChronologically,
   sortAlphabetically,
   sortChronologically,
+  sortFlashesChronologically,
 } from '../util/wiki-data.js';
 
 import find, {bindFind} from '../util/find.js';
@@ -1155,6 +1156,7 @@ export function sortWikiDataArrays(wikiData) {
   Object.assign(wikiData, {
     albumData: sortChronologically(wikiData.albumData.slice()),
     trackData: sortAlbumsTracksChronologically(wikiData.trackData.slice()),
+    flashData: sortFlashesChronologically(wikiData.flashData.slice()),
   });
 
   // Re-link data arrays, so that every object has the new, sorted versions.
diff --git a/src/listing-spec.js b/src/listing-spec.js
index 08799f2f..36637ee0 100644
--- a/src/listing-spec.js
+++ b/src/listing-spec.js
@@ -12,6 +12,7 @@ import {
   sortAlphabetically,
   sortByDate,
   sortChronologically,
+  sortFlashesChronologically,
 } from './util/wiki-data.js';
 
 const listingSpec = [];
@@ -775,7 +776,7 @@ listingSpec.push({
     wikiInfo.enableFlashesAndGames,
 
   data: ({wikiData: {flashData}}) =>
-    sortChronologically(flashData.slice())
+    sortFlashesChronologically(flashData.slice())
       .map(flash => ({
         flash,
         tracks: flash.featuredTracks,
diff --git a/src/misc-templates.js b/src/misc-templates.js
index 39f597eb..8f3f0166 100644
--- a/src/misc-templates.js
+++ b/src/misc-templates.js
@@ -16,6 +16,7 @@ import {
   getTotalDuration,
   sortAlbumsTracksChronologically,
   sortChronologically,
+  sortFlashesChronologically,
 } from './util/wiki-data.js';
 
 const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com'];
@@ -165,6 +166,8 @@ function unbound_generateChronologyLinks(currentThing, {
       const things = (
         thingsUnsorted.every(t => t instanceof T.Album || t instanceof T.Track)
           ? sortAlbumsTracksChronologically(...args)
+      : thingsUnsorted.every(t => t instanceof T.Flash)
+          ? sortFlashesChronologically(...args)
           : sortChronologically(...args));
 
       if (things.length === 0) return '';
diff --git a/src/page/artist.js b/src/page/artist.js
index 29e4aba6..4ef44d32 100644
--- a/src/page/artist.js
+++ b/src/page/artist.js
@@ -12,7 +12,7 @@ import {
   chunkByProperties,
   getTotalDuration,
   sortAlbumsTracksChronologically,
-  sortChronologically,
+  sortFlashesChronologically,
 } from '../util/wiki-data.js';
 
 export const description = `per-artist info & artwork gallery pages`;
@@ -129,7 +129,7 @@ export function write(artist, {wikiData}) {
 
   let flashes, flashListChunks;
   if (wikiInfo.enableFlashesAndGames) {
-    flashes = sortChronologically(artist.flashesAsContributor.slice());
+    flashes = sortFlashesChronologically(artist.flashesAsContributor.slice());
     flashListChunks = chunkByProperties(
       flashes.map((flash) => ({
         act: flash.act,
diff --git a/src/page/track.js b/src/page/track.js
index 7f0d1cf2..b6b03f35 100644
--- a/src/page/track.js
+++ b/src/page/track.js
@@ -16,7 +16,7 @@ import {
 import {
   getTrackCover,
   getAlbumListTag,
-  sortChronologically,
+  sortFlashesChronologically,
 } from '../util/wiki-data.js';
 
 export const description = `per-track info pages`;
@@ -42,7 +42,7 @@ export function write(track, {wikiData}) {
 
   let flashesThatFeature;
   if (wikiInfo.enableFlashesAndGames) {
-    flashesThatFeature = sortChronologically(
+    flashesThatFeature = sortFlashesChronologically(
       [track, ...otherReleases].flatMap((track) =>
         track.featuredInFlashes.map((flash) => ({
           flash,
diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js
index 7a3f4144..2a8f12ca 100644
--- a/src/util/wiki-data.js
+++ b/src/util/wiki-data.js
@@ -207,35 +207,52 @@ export function sortByDate(data, {
   });
 }
 
-export function sortByPositionInAlbum(data) {
+export function sortByPositionInParent(data, {
+  getParent,
+  getChildren,
+}) {
   return data.sort((a, b) => {
-    const aa = a.album;
-    const ba = b.album;
+    const parentA = getParent(a);
+    const parentB = getParent(b);
 
-    // Don't change the sort when the two tracks are from separate albums.
-    // This function doesn't change the order of albums or try to "merge"
-    // two separated chunks of tracks from the same album together.
-    if (aa !== ba) {
+    // Don't change the sort when the two items are from separate parents.
+    // This function doesn't change the order of parents or try to "merge"
+    // two separated chunks of items from the same parent together.
+    if (parentA !== parentB) {
       return 0;
     }
 
-    // Don't change the sort when only one (or neither) item is actually
-    // a track (i.e. has an album).
-    if (!aa || !ba) {
+    // Don't change the sort when either (or both) of the items doesn't
+    // even have a parent (e.g. it's the passed data is a mixed array of
+    // children and parents).
+    if (!parentA || !parentB) {
       return 0;
     }
 
-    const ai = aa.tracks.indexOf(a);
-    const bi = ba.tracks.indexOf(b);
+    const indexA = getChildren(parentA).indexOf(a);
+    const indexB = getChildren(parentB).indexOf(b);
 
-    // There's no reason this two-way reference (a track's album and the
-    // album's track list) should be broken, but if for any reason it is,
-    // don't change the sort.
-    if (ai === -1 || bi === -1) {
+    // If the getParent/getChildren relationship doesn't go both ways for
+    // some reason, don't change the sort.
+    if (indexA === -1 || indexB === -1) {
       return 0;
     }
 
-    return ai - bi;
+    return indexA - indexB;
+  });
+}
+
+export function sortByPositionInAlbum(data) {
+  return sortByPositionInParent(data, {
+    getParent: track => track.album,
+    getChildren: album => album.tracks,
+  });
+}
+
+export function sortByPositionInFlashAct(data) {
+  return sortByPositionInParent(data, {
+    getParent: flash => flash.act,
+    getChildren: act => act.flashes,
   });
 }
 
@@ -330,6 +347,38 @@ export function sortAlbumsTracksChronologically(data, {
   return data;
 }
 
+export function sortFlashesChronologically(data, {
+  latestFirst = false,
+  getDate,
+} = {}) {
+  // Flash acts don't actually have any identifying properties because they
+  // don't have dedicated pages (yet), so don't have a directory. Make up a
+  // fake key identifying them so flashes can be grouped together.
+  const flashActs = new Set(data.map(flash => flash.act));
+  const flashActIdentifiers = new Map();
+
+  let counter = 0;
+  for (const act of flashActs) {
+    flashActIdentifiers.set(act, ++counter);
+  }
+
+  // Group flashes by act...
+  data.sort((a, b) => {
+    return flashActIdentifiers.get(a.act) - flashActIdentifiers.get(b.act);
+  });
+
+  // Sort flashes by position in act...
+  sortByPositionInFlashAct(data);
+
+  // ...and finally sort by date. If flashes from more than one act were
+  // released on the same date, they'll still be grouped together by act,
+  // and flashes within an act will retain their relative positioning (i.e.
+  // stay in the same order as the act's flash listing).
+  sortByDate(data, {latestFirst, getDate});
+
+  return data;
+}
+
 // Specific data utilities
 
 export function filterAlbumsByCommentary(albums) {