diff options
-rw-r--r-- | src/content/dependencies/generateAlbumCommentaryPage.js | 1 | ||||
-rw-r--r-- | src/content/dependencies/generateAlbumNavAccent.js | 2 | ||||
-rw-r--r-- | src/content/dependencies/generateAlbumSidebar.js | 8 | ||||
-rw-r--r-- | src/content/dependencies/generateFlashActSidebar.js | 24 | ||||
-rw-r--r-- | src/content/dependencies/generateGroupSidebar.js | 1 | ||||
-rw-r--r-- | src/content/dependencies/generateListingSidebar.js | 1 | ||||
-rw-r--r-- | src/content/dependencies/generatePageLayout.js | 31 | ||||
-rw-r--r-- | src/content/dependencies/generateWikiHomeNewsBox.js | 1 | ||||
-rw-r--r-- | src/content/dependencies/generateWikiHomePage.js | 1 | ||||
-rw-r--r-- | src/content/dependencies/listRandomPageLinks.js | 9 | ||||
-rw-r--r-- | src/static/client3.js (renamed from src/static/client2.js) | 275 | ||||
-rw-r--r-- | src/static/site5.css | 10 | ||||
-rw-r--r-- | src/strings-default.yaml | 5 | ||||
-rw-r--r-- | src/write/build-modes/live-dev-server.js | 11 | ||||
-rw-r--r-- | src/write/build-modes/static-build.js | 18 | ||||
-rw-r--r-- | src/write/common-templates.js | 40 |
16 files changed, 246 insertions, 192 deletions
diff --git a/src/content/dependencies/generateAlbumCommentaryPage.js b/src/content/dependencies/generateAlbumCommentaryPage.js index 3ad1549e..e2415516 100644 --- a/src/content/dependencies/generateAlbumCommentaryPage.js +++ b/src/content/dependencies/generateAlbumCommentaryPage.js @@ -201,6 +201,7 @@ export default { ], leftSidebarStickyMode: 'column', + leftSidebarClass: 'commentary-track-list-sidebar-box', leftSidebarContent: [ html.tag('h1', relations.sidebarAlbumLink), relations.sidebarTrackSections.map(section => diff --git a/src/content/dependencies/generateAlbumNavAccent.js b/src/content/dependencies/generateAlbumNavAccent.js index 7eb1dac0..01c88bf7 100644 --- a/src/content/dependencies/generateAlbumNavAccent.js +++ b/src/content/dependencies/generateAlbumNavAccent.js @@ -92,7 +92,7 @@ export default { html.tag('a', { href: '#', - 'data-random': 'track-in-album', + 'data-random': 'track-in-sidebar', id: 'random-button', }, (data.isTrackPage diff --git a/src/content/dependencies/generateAlbumSidebar.js b/src/content/dependencies/generateAlbumSidebar.js index a84f4357..5ef4501b 100644 --- a/src/content/dependencies/generateAlbumSidebar.js +++ b/src/content/dependencies/generateAlbumSidebar.js @@ -30,6 +30,7 @@ export default { generate(data, relations, {html}) { const trackListBox = { + class: 'track-list-sidebar-box', content: html.tags([ html.tag('h1', relations.albumLink), @@ -40,8 +41,10 @@ export default { if (data.isAlbumPage) { const groupBoxes = relations.groupBoxes - .map(content => content.slot('mode', 'album')) - .map(content => ({content})); + .map(content => ({ + class: 'individual-group-sidebar-box', + content: content.slot('mode', 'album'), + })); return { leftSidebarMultiple: [ @@ -52,6 +55,7 @@ export default { } const conjoinedGroupBox = { + class: 'conjoined-group-sidebar-box', content: relations.groupBoxes .flatMap((content, i, {length}) => [ diff --git a/src/content/dependencies/generateFlashActSidebar.js b/src/content/dependencies/generateFlashActSidebar.js index 80072483..29379644 100644 --- a/src/content/dependencies/generateFlashActSidebar.js +++ b/src/content/dependencies/generateFlashActSidebar.js @@ -137,7 +137,7 @@ export default { }), generate(data, relations, {getColors, html, language}) { - const currentActBox = html.tags([ + const currentActBoxContent = html.tags([ html.tag('h1', relations.currentActLink), html.tag('details', @@ -160,7 +160,7 @@ export default { ]), ]); - const sideMapBox = html.tags([ + const sideMapBoxContent = html.tags([ html.tag('h1', relations.flashIndexLink), stitchArrays({ @@ -188,17 +188,21 @@ export default { ])), ]); + const sideMapBox = { + class: 'flash-act-map-sidebar-box', + content: sideMapBoxContent, + }; + + const currentActBox = { + class: 'flash-current-act-sidebar-box', + content: currentActBoxContent, + }; + return { leftSidebarMultiple: (data.isFlashActPage - ? [ - {content: sideMapBox}, - {content: currentActBox}, - ] - : [ - {content: currentActBox}, - {content: sideMapBox}, - ]), + ? [sideMapBox, currentActBox] + : [currentActBox, sideMapBox]), }; }, }; diff --git a/src/content/dependencies/generateGroupSidebar.js b/src/content/dependencies/generateGroupSidebar.js index 6baf37f4..98b288fa 100644 --- a/src/content/dependencies/generateGroupSidebar.js +++ b/src/content/dependencies/generateGroupSidebar.js @@ -22,6 +22,7 @@ export default { generate(relations, slots, {html, language}) { return { + leftSidebarClass: 'category-map-sidebar-box', leftSidebarContent: [ html.tag('h1', language.$('groupSidebar.title')), diff --git a/src/content/dependencies/generateListingSidebar.js b/src/content/dependencies/generateListingSidebar.js index fe2a08fa..1cdd236b 100644 --- a/src/content/dependencies/generateListingSidebar.js +++ b/src/content/dependencies/generateListingSidebar.js @@ -11,6 +11,7 @@ export default { generate(relations, {html}) { return { + leftSidebarClass: 'listing-map-sidebar-box', leftSidebarContent: [ html.tag('h1', relations.listingIndexLink), relations.listingIndexList.slot('mode', 'sidebar'), diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 5fa6e751..95551f3e 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -6,12 +6,19 @@ function sidebarSlots(side) { // if specified. [side + 'Content']: {type: 'html'}, - // Multiple is an array of {content: (HTML)} objects. Each of these - // will generate one sidebar section. + // A single class to apply to the whole sidebar. If specifying multiple + // sections, this be added to the containing sidebar-column - specify a + // class on each section if that's more suitable. + [side + 'Class']: {type: 'string'}, + + // Multiple is an array of objects, each specifying content (HTML) and + // optionally class (a string). Each of these will generate one sidebar + // section. [side + 'Multiple']: { validate: v => v.sparseArrayOf( v.validateProperties({ + class: v.optional(v.isString), content: v.isHTML, })), }, @@ -27,6 +34,7 @@ function sidebarSlots(side) { // the whole section's containing box (or the sidebar column as a whole). [side + 'StickyMode']: { validate: v => v.is('last', 'column', 'static'), + default: 'static', }, // Collapsing sidebars disappear when the viewport is sufficiently @@ -354,6 +362,7 @@ export default { const generateSidebarHTML = (side, id) => { const content = slots[side + 'Content']; + const topClass = slots[side + 'Class']; const multiple = slots[side + 'Multiple']; const stickyMode = slots[side + 'StickyMode']; const wide = slots[side + 'Wide']; @@ -363,20 +372,18 @@ export default { let sidebarContent = html.blank(); if (!html.isBlank(content)) { - sidebarClasses = ['sidebar']; + sidebarClasses = ['sidebar', topClass]; sidebarContent = content; } else if (multiple) { - sidebarClasses = ['sidebar-multiple']; + sidebarClasses = ['sidebar-multiple', topClass]; sidebarContent = multiple .filter(Boolean) - .map(({content}) => - html.tag('div', - { - [html.onlyIfContent]: true, - class: 'sidebar', - }, - content)); + .map(box => + html.tag('div', { + [html.onlyIfContent]: true, + class: ['sidebar', box.class], + }, box.content)); } if (html.isBlank(sidebarContent)) { @@ -648,7 +655,7 @@ export default { html.tag('script', { type: 'module', - src: to('shared.staticFile', 'client2.js', cachebust), + src: to('shared.staticFile', 'client3.js', cachebust), }), ]), ]) diff --git a/src/content/dependencies/generateWikiHomeNewsBox.js b/src/content/dependencies/generateWikiHomeNewsBox.js index 8acd426c..0d8303f1 100644 --- a/src/content/dependencies/generateWikiHomeNewsBox.js +++ b/src/content/dependencies/generateWikiHomeNewsBox.js @@ -42,6 +42,7 @@ export default { } return { + class: 'latest-news-sidebar-box', content: [ html.tag('h1', language.$('homepage.news.title')), diff --git a/src/content/dependencies/generateWikiHomePage.js b/src/content/dependencies/generateWikiHomePage.js index 40a6b1c5..36fcc6f2 100644 --- a/src/content/dependencies/generateWikiHomePage.js +++ b/src/content/dependencies/generateWikiHomePage.js @@ -75,6 +75,7 @@ export default { leftSidebarMultiple: [ (relations.customSidebarContent ? { + class: 'custom-content-sidebar-box', content: relations.customSidebarContent .slot('mode', 'multiline'), diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 0b904019..18585696 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -114,13 +114,14 @@ export default { language.$('listingPage.other.randomPages.chooseLinkLine.browserSupportPart'), })), - html.tag('p', - {class: 'js-hide-once-data'}, + html.tag('p', {id: 'data-loading-line'}, language.$('listingPage.other.randomPages.dataLoadingLine')), - html.tag('p', - {class: 'js-show-once-data'}, + html.tag('p', {id: 'data-loaded-line'}, language.$('listingPage.other.randomPages.dataLoadedLine')), + + html.tag('p', {id: 'data-error-line'}, + language.$('listingPage.other.randomPages.dataErrorLine')), ], showSkipToSection: true, diff --git a/src/static/client2.js b/src/static/client3.js index 0ec052bd..8372a268 100644 --- a/src/static/client2.js +++ b/src/static/client3.js @@ -7,16 +7,7 @@ import {getColors} from '../util/colors.js'; import {empty, stitchArrays} from '../util/sugar.js'; - -import { - filterMultipleArrays, - getArtistNumContributions, -} from '../util/wiki-data.js'; - -let albumData, artistData; -let officialAlbumData, fandomAlbumData, beyondAlbumData; - -let ready = false; +import {filterMultipleArrays} from '../util/wiki-data.js'; const clientInfo = window.hsmusicClientInfo = Object.create(null); @@ -76,15 +67,6 @@ function cssProp(el, key) { return getComputedStyle(el).getPropertyValue(key).trim(); } -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}`); @@ -108,6 +90,13 @@ const scriptedLinkInfo = clientInfo.scriptedLinkInfo = { nextLink: null, previousLink: null, randomLink: null, + + state: { + albumDirectories: null, + albumTrackDirectories: null, + artistDirectories: null, + artistNumContributions: null, + }, }; function getScriptedLinkReferences() { @@ -129,109 +118,130 @@ 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); + }); + } +} - const tracks = albumData => - albumData - .map(album => album.tracks) - .reduce((acc, tracks) => acc.concat(tracks), []); +function handleRandomLinkClicked(a, domEvent) { + const href = determineRandomLinkHref(a); - setTimeout(() => { - a.href = rebase('js-disabled'); - }); + if (!href) { + domEvent.preventDefault(); + return; + } - switch (a.dataset.random) { - case 'album': - a.href = openAlbum(pick(albumData).directory); - break; + setTimeout(() => { + a.href = '#' + }); - case 'track': - a.href = openTrack(getRefDirectory(pick(tracks(albumData)))); - break; + a.href = href; +} - case 'album-in-group-dl': { - const albumLinks = - Array.from(a - .closest('dt') - .nextElementSibling - .querySelectorAll('li a')) +function determineRandomLinkHref(a) { + const {state} = scriptedLinkInfo; - const albumDirectories = - albumLinks.map(a => - getComputedStyle(a).getPropertyValue('--album-directory')); + const trackDirectoriesFromAlbumDirectories = albumDirectories => + albumDirectories + .map(directory => state.albumDirectories.indexOf(directory)) + .map(index => state.albumTrackDirectories[index]) + .reduce((acc, trackDirectories) => acc.concat(trackDirectories, [])); - a.href = openAlbum(pick(albumDirectories)); - break; - } + switch (a.dataset.random) { + case 'album': { + const {albumDirectories} = state; + if (!albumDirectories) return null; + + return openAlbum(pick(albumDirectories)); + } - case 'track-in-group-dl': { - const albumLinks = - Array.from(a - .closest('dt') - .nextElementSibling - .querySelectorAll('li a')) + case 'track': { + const {albumDirectories} = state; + if (!albumDirectories) return null; - const albumDirectories = - albumLinks.map(a => - getComputedStyle(a).getPropertyValue('--album-directory')); + const trackDirectories = + trackDirectoriesFromAlbumDirectories( + albumDirectories); - const filteredAlbumData = - albumData.filter(album => - albumDirectories.includes(album.directory)); + return openTrack(pick(trackDirectories)); + } - a.href = openTrack(getRefDirectory(pick(tracks(filteredAlbumData)))); - break; - } + case 'album-in-group-dl': { + const albumLinks = + Array.from(a + .closest('dt') + .nextElementSibling + .querySelectorAll('li a')) - /* Legacy links, for old versions * - * of generateListRandomPageLinksGroupSection */ + const listAlbumDirectories = + albumLinks + .map(a => cssProp(a, '--album-directory')); - case 'album-in-official': - a.href = openAlbum(pick(officialAlbumData).directory); - break; + return openAlbum(pick(listAlbumDirectories)); + } - case 'album-in-fandom': - a.href = openAlbum(pick(fandomAlbumData).directory); - break; + case 'track-in-group-dl': { + const {albumDirectories} = state; + if (!albumDirectories) return null; - case 'album-in-beyond': - a.href = openAlbum(pick(beyondAlbumData).directory); - break; + const albumLinks = + Array.from(a + .closest('dt') + .nextElementSibling + .querySelectorAll('li a')) - /* End legacy links */ + const listAlbumDirectories = + albumLinks + .map(a => cssProp(a, '--album-directory')); - case 'track-in-album': - a.href = openTrack(getRefDirectory(pick(getAlbum(a).tracks))); - break; + const trackDirectories = + trackDirectoriesFromAlbumDirectories( + listAlbumDirectories); - case 'track-in-official': - a.href = openTrack(getRefDirectory(pick(tracks(officialAlbumData)))); - break; + return openTrack(pick(trackDirectories)); + } - case 'track-in-fandom': - a.href = openTrack(getRefDirectory(pick(tracks(fandomAlbumData)))); - break; + 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')); - case 'track-in-beyond': - a.href = openTrack(getRefDirectory(pick(tracks(beyondAlbumData)))); - break; + return pick(trackLinks).href; + } - case 'artist': - a.href = openArtist(pick(artistData).directory); - break; + case 'track-in-album': { + const {albumDirectories, albumTrackDirectories} = state; + if (!albumDirectories || !albumTrackDirectories) return null; - case 'artist-more-than-one-contrib': - a.href = - openArtist( - pick(artistData.filter((artist) => getArtistNumContributions(artist) > 1)) - .directory); - break; - } - }); + const albumDirectory = cssProp(a, '--album-directory'); + const albumIndex = albumDirectories.indexOf(albumDirectory); + const trackDirectories = albumTrackDirectories[albumIndex]; + + return openTrack(pick(trackDirectories)); + } + + case 'artist': { + const {artistDirectories} = state; + if (!artistDirectories) return null; + + return openArtist(pick(artistDirectories)); + } + + case 'artist-more-than-one-contrib': { + const {artistDirectories, artistNumContributions} = state; + if (!artistDirectories || !artistNumContributions) return null; + + const filteredArtistDirectories = + artistDirectories + .filter((_artist, index) => artistNumContributions[index] > 1); + + return openArtist(pick(filteredArtistDirectories)); + } } } @@ -255,9 +265,7 @@ function addNavigationKeyPressListeners() { } else if (event.charCode === 'P'.charCodeAt(0)) { scriptedLinkInfo.previousNavLink?.click(); } else if (event.charCode === 'R'.charCodeAt(0)) { - if (ready) { - scriptedLinkInfo.randomNavLink?.click(); - } + scriptedLinkInfo.randomNavLink?.click(); } } }); @@ -282,31 +290,44 @@ 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'); - -for (const element of elements1) element.style.display = 'block'; - -fetch(rebase('data.json', 'rebaseShared')) - .then((data) => data.json()) - .then((data) => { - albumData = data.albumData; - artistData = data.artistData; - - const albumsInGroup = directory => - albumData - .filter(album => - album.groups.includes(`group:${directory}`)); - - officialAlbumData = albumsInGroup('official'); - fandomAlbumData = albumsInGroup('fandom'); - beyondAlbumData = albumsInGroup('beyond'); - - for (const element of elements1) element.style.display = 'none'; - for (const element of elements2) element.style.display = 'block'; +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'); + const dataErrorLine = document.getElementById('data-error-line'); + + dataLoadingLine.style.display = 'block'; + + fetch(rebase('random-link-data.json', 'rebaseShared')) + .then(data => data.json()) + .then(data => { + const {state} = scriptedLinkInfo; + + Object.assign(state, { + albumDirectories: data.albumDirectories, + albumTrackDirectories: data.albumTrackDirectories, + artistDirectories: data.artistDirectories, + artistNumContributions: data.artistNumContributions, + }); - ready = true; - }); + dataLoadingLine.style.display = 'none'; + dataLoadedLine.style.display = 'block'; + }, () => { + dataLoadingLine.style.display = 'none'; + dataErrorLine.style.display = 'block'; + }) + .then(() => { + const {randomLinks} = scriptedLinkInfo; + for (const a of randomLinks) { + const href = determineRandomLinkHref(a); + if (!href) { + a.removeAttribute('href'); + } + } + }); +} // Data & info card --------------------------------------- diff --git a/src/static/site5.css b/src/static/site5.css index 1ffe5044..ba44ec37 100644 --- a/src/static/site5.css +++ b/src/static/site5.css @@ -803,6 +803,16 @@ 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, +html[data-url-key="localized.listing"][data-url-value0="random"] #data-error-line { + display: none; +} + +html[data-url-key="localized.listing"][data-url-value0="random"] #content a:not([href]) { + opacity: 0.7; +} + /* Images */ .image-container { diff --git a/src/strings-default.yaml b/src/strings-default.yaml index eccfc80c..f83412e9 100644 --- a/src/strings-default.yaml +++ b/src/strings-default.yaml @@ -1568,7 +1568,7 @@ listingPage: If your browser doesn't support relatively modern JavaScript or you've disabled it, these links won't work - sorry. - # dataLoadingLine, dataLoadedLine: + # dataLoadingLine, dataLoadedLine, dataErrorLine: # Since the links on this page depend on access to a fairly # large data file that is downloaded separately and in the # background, these messages indicate the status of that @@ -1580,6 +1580,9 @@ listingPage: dataLoadedLine: >- (Data files have finished being downloaded. The links should work!) + dataErrorLine: >- + (Data files failed to download. Sorry, some of these links won't work right now!) + chunk: title: diff --git a/src/write/build-modes/live-dev-server.js b/src/write/build-modes/live-dev-server.js index ab6ceecb..8828a5bd 100644 --- a/src/write/build-modes/live-dev-server.js +++ b/src/write/build-modes/live-dev-server.js @@ -16,7 +16,7 @@ import { } from '#urls'; import {bindUtilities} from '../bind-utilities.js'; -import {generateGlobalWikiDataJSON, generateRedirectHTML} from '../common-templates.js'; +import {generateRandomLinkDataJSON, generateRedirectHTML} from '../common-templates.js'; const defaultHost = '0.0.0.0'; const defaultPort = 8002; @@ -157,19 +157,20 @@ export async function go({ // Specialized routes - if (pathname === '/data.json') { + if (pathname === '/random-link-data.json') { try { - const json = generateGlobalWikiDataJSON({ + const json = generateRandomLinkDataJSON({ serializeThings, wikiData, }); + response.writeHead(200, contentTypeJSON); response.end(json); - if (loudResponses) console.log(`${requestHead} [200] /data.json`); + if (loudResponses) console.log(`${requestHead} [200] ${pathname}`); } catch (error) { response.writeHead(500, contentTypeJSON); response.end(`Internal error serializing wiki JSON`); - console.error(`${requestHead} [500] /data.json`); + console.error(`${requestHead} [500] ${pathname}`); showError(error); } return; diff --git a/src/write/build-modes/static-build.js b/src/write/build-modes/static-build.js index b6dc9643..a8e0eb23 100644 --- a/src/write/build-modes/static-build.js +++ b/src/write/build-modes/static-build.js @@ -31,7 +31,7 @@ import { } from '#urls'; import {bindUtilities} from '../bind-utilities.js'; -import {generateRedirectHTML, generateGlobalWikiDataJSON} from '../common-templates.js'; +import {generateRedirectHTML, generateRandomLinkDataJSON} from '../common-templates.js'; const pageFlags = Object.keys(pageSpecs); @@ -145,14 +145,8 @@ export async function go({ }); await writeSharedFilesAndPages({ - language: defaultLanguage, outputPath, - urls, - wikiData, - wikiDataJSON: generateGlobalWikiDataJSON({ - serializeThings, - wikiData, - }), + randomLinkDataJSON: generateRandomLinkDataJSON({wikiData}), }); const buildSteps = writeAll @@ -477,12 +471,12 @@ async function writeFavicon({ async function writeSharedFilesAndPages({ outputPath, - wikiDataJSON, + randomLinkDataJSON, }) { return progressPromiseAll(`Writing files & pages shared across languages.`, [ - wikiDataJSON && + randomLinkDataJSON && writeFile( - path.join(outputPath, 'data.json'), - wikiDataJSON), + path.join(outputPath, 'random-link-data.json'), + randomLinkDataJSON), ].filter(Boolean)); } diff --git a/src/write/common-templates.js b/src/write/common-templates.js index 2dd4c924..d897a73b 100644 --- a/src/write/common-templates.js +++ b/src/write/common-templates.js @@ -1,4 +1,5 @@ import * as html from '#html'; +import {getArtistNumContributions} from '#wiki-data'; export function generateRedirectHTML(title, target, {language}) { return `<!DOCTYPE html>\n` + html.tag('html', [ @@ -30,22 +31,25 @@ export function generateRedirectHTML(title, target, {language}) { ]); } -export function generateGlobalWikiDataJSON({ - serializeThings, - wikiData, -}) { - const stringifyThings = thingData => - JSON.stringify(serializeThings(thingData)); - - return '{\n' + - ([ - `"albumData": ${stringifyThings(wikiData.albumData)},`, - wikiData.wikiInfo.enableFlashesAndGames && - `"flashData": ${stringifyThings(wikiData.flashData)},`, - `"artistData": ${stringifyThings(wikiData.artistData)}`, - ] - .filter(Boolean) - .map(line => ' ' + line) - .join('\n')) + - '\n}'; +export function generateRandomLinkDataJSON({wikiData}) { + const {albumData, artistData} = wikiData; + + return JSON.stringify({ + albumDirectories: + albumData + .map(album => album.directory), + + albumTrackDirectories: + albumData + .map(album => album.tracks + .map(track => track.directory)), + + artistDirectories: + artistData + .map(artist => artist.directory), + + artistNumContributions: + artistData + .map(artist => getArtistNumContributions(artist)), + }); } |