From a735545f1442d9aab870ce34c76d43487f7ed547 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 4 Jun 2021 15:26:03 -0300 Subject: module-ify homepage --- src/util/wiki-data.js | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'src/util') diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index e4142c85..2527a4b3 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -159,3 +159,119 @@ export function getTrackCover(track, {to}) { return to('media.trackCover', track.album.directory, track.directory); } } + +// Big-ass homepage row functions + +export function getNewAdditions(numAlbums, {wikiData}) { + const { albumData } = wikiData; + + // Sort al8ums, in descending order of priority, 8y... + // + // * D8te of addition to the wiki (descending). + // * Major releases first. + // * D8te of release (descending). + // + // Major releases go first to 8etter ensure they show up in the list (and + // are usually at the start of the final output for a given d8 of release + // too). + const sortedAlbums = albumData.filter(album => album.isListedOnHomepage).sort((a, b) => { + if (a.dateAdded > b.dateAdded) return -1; + if (a.dateAdded < b.dateAdded) return 1; + if (a.isMajorRelease && !b.isMajorRelease) return -1; + if (!a.isMajorRelease && b.isMajorRelease) return 1; + if (a.date > b.date) return -1; + if (a.date < b.date) return 1; + }); + + // When multiple al8ums are added to the wiki at a time, we want to show + // all of them 8efore pulling al8ums from the next (earlier) date. We also + // want to show a diverse selection of al8ums - with limited space, we'd + // rather not show only the latest al8ums, if those happen to all 8e + // closely rel8ted! + // + // Specifically, we're concerned with avoiding too much overlap amongst + // the primary (first/top-most) group. We do this 8y collecting every + // primary group present amongst the al8ums for a given d8 into one + // (ordered) array, initially sorted (inherently) 8y latest al8um from + // the group. Then we cycle over the array, adding one al8um from each + // group until all the al8ums from that release d8 have 8een added (or + // we've met the total target num8er of al8ums). Once we've added all the + // al8ums for a given group, it's struck from the array (so the groups + // with the most additions on one d8 will have their oldest releases + // collected more towards the end of the list). + + const albums = []; + + let i = 0; + outerLoop: while (i < sortedAlbums.length) { + // 8uild up a list of groups and their al8ums 8y order of decending + // release, iter8ting until we're on a different d8. (We use a map for + // indexing so we don't have to iter8te through the entire array each + // time we access one of its entries. This is 8asically unnecessary + // since this will never 8e an expensive enough task for that to + // matter.... 8ut it's nicer code. BBBB) ) + const currentDate = sortedAlbums[i].dateAdded; + const groupMap = new Map(); + const groupArray = []; + for (let album; (album = sortedAlbums[i]) && +album.dateAdded === +currentDate; i++) { + const primaryGroup = album.groups[0]; + if (groupMap.has(primaryGroup)) { + groupMap.get(primaryGroup).push(album); + } else { + const entry = [album] + groupMap.set(primaryGroup, entry); + groupArray.push(entry); + } + } + + // Then cycle over that sorted array, adding one al8um from each to + // the main array until we've run out or have met the target num8er + // of al8ums. + while (groupArray.length) { + let j = 0; + while (j < groupArray.length) { + const entry = groupArray[j]; + const album = entry.shift(); + albums.push(album); + + + // This is the only time we ever add anything to the main al8um + // list, so it's also the only place we need to check if we've + // met the target length. + if (albums.length === numAlbums) { + // If we've met it, 8r8k out of the outer loop - we're done + // here! + break outerLoop; + } + + if (entry.length) { + j++; + } else { + groupArray.splice(j, 1); + } + } + } + } + + // Finally, do some quick mapping shenanigans to 8etter display the result + // in a grid. (This should pro8a8ly 8e a separ8te, shared function, 8ut + // whatevs.) + return albums.map(album => ({large: album.isMajorRelease, item: album})); +} + +export function getNewReleases(numReleases, {wikiData}) { + const { albumData } = wikiData; + + const latestFirst = albumData.filter(album => album.isListedOnHomepage).reverse(); + const majorReleases = latestFirst.filter(album => album.isMajorRelease); + majorReleases.splice(1); + + const otherReleases = latestFirst + .filter(album => !majorReleases.includes(album)) + .slice(0, numReleases - majorReleases.length); + + return [ + ...majorReleases.map(album => ({large: true, item: album})), + ...otherReleases.map(album => ({large: false, item: album})) + ]; +} -- cgit 1.3.0-6-gf8a5