diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/content/dependencies/generateListingPage.js | 66 | ||||
-rw-r--r-- | src/listing-spec.js | 54 |
2 files changed, 87 insertions, 33 deletions
diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 74c90baa..1974f822 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -1,4 +1,4 @@ -import {empty} from '../../util/sugar.js'; +import {empty, stitchArrays} from '../../util/sugar.js'; export default { contentDependencies: [ @@ -9,22 +9,7 @@ export default { extraDependencies: ['html', 'language', 'wikiData'], - sprawl({listingSpec}) { - return {listingSpec}; - }, - - query(sprawl, listing) { - return { - seeAlso: - (listing.seeAlso - ? listing.seeAlso.map(directory => - sprawl.listingSpec - .find(listing => listing.directory === directory)) - : null), - }; - }, - - relations(relation, query) { + relations(relation, listing) { const relations = {}; relations.layout = @@ -33,23 +18,34 @@ export default { relations.listingsIndexLink = relation('linkListingIndex'); - if (!empty(query.seeAlso)) { - // TODO: Invalid listing directories filtered here aren't warned about anywhere. - // Honestly we shouldn't be searching listingSpec here at all - listings should - // be implemented as proper things which search listingSpec themselves, and - // expose seeAlso as a list of listing objects rather than by reference. + if (listing.target.listings.length > 1) { + relations.sameTargetListingLinks = + listing.target.listings + .map(listing => relation('linkListing', listing)); + } + + if (!empty(listing.seeAlso)) { relations.seeAlsoLinks = - query.seeAlso - .map(listing => relation('linkListing', listing)) - .filter(Boolean); + listing.seeAlso + .map(listing => relation('linkListing', listing)); } return relations; }, - data(query, sprawl, listing) { + data(listing) { return { stringsKey: listing.stringsKey, + + targetStringsKey: listing.target.stringsKey, + + sameTargetListingStringsKeys: + listing.target.listings + .map(listing => listing.stringsKey), + + sameTargetListingsCurrentIndex: + listing.target.listings + .indexOf(listing), }; }, @@ -69,6 +65,24 @@ export default { headingMode: 'sticky', mainContent: [ + relations.sameTargetListingLinks && + html.tag('p', + language.$('listingPage.listingsFor', { + target: language.$(`listingPage.target.${data.targetStringsKey}`), + listings: + language.formatUnitList( + stitchArrays({ + link: relations.sameTargetListingLinks, + stringsKey: data.sameTargetListingStringsKeys, + }).map(({link, stringsKey}, index) => + html.tag('span', + {class: index === data.sameTargetListingsCurrentIndex && 'current'}, + link.slots({ + attributes: {class: 'nowrap'}, + content: language.$(`listingPage.${stringsKey}.title.short`), + })))), + })), + relations.seeAlsoLinks && html.tag('p', language.$('listingPage.seeAlso', { diff --git a/src/listing-spec.js b/src/listing-spec.js index c81c0866..9c1134f4 100644 --- a/src/listing-spec.js +++ b/src/listing-spec.js @@ -1,8 +1,9 @@ import {OFFICIAL_GROUP_DIRECTORY} from './util/magic-constants.js'; import { - empty, accumulateSum, + empty, + showAggregate, } from './util/sugar.js'; import { @@ -1078,34 +1079,73 @@ listingSpec.push({ ]), }); +{ + const errors = []; + + for (const listing of listingSpec) { + if (listing.seeAlso) { + const suberrors = []; + + for (let i = 0; i < listing.seeAlso.length; i++) { + const directory = listing.seeAlso[i]; + const match = listingSpec.find(listing => listing.directory === directory); + + if (match) { + listing.seeAlso[i] = match; + } else { + listing.seeAlso[i] = null; + suberrors.push(new Error(`(index: ${i}) Didn't find a listing matching ${directory}`)) + } + } + + listing.seeAlso = listing.seeAlso.filter(Boolean); + + if (!empty(suberrors)) { + errors.push(new AggregateError(suberrors, `Errors matching "see also" listings for ${listing.directory}`)); + } + } + } + + if (!empty(errors)) { + const aggregate = new AggregateError(errors, `Errors validating listings`); + showAggregate(aggregate, {showTraces: false}); + } +} + const filterListings = (directoryPrefix) => listingSpec.filter(l => l.directory.startsWith(directoryPrefix)); const listingTargetSpec = [ { - title: ({language}) => language.$('listingPage.target.album'), + stringsKey: 'album', listings: filterListings('album'), }, { - title: ({language}) => language.$('listingPage.target.artist'), + stringsKey: 'artist', listings: filterListings('artist'), }, { - title: ({language}) => language.$('listingPage.target.group'), + stringsKey: 'group', listings: filterListings('group'), }, { - title: ({language}) => language.$('listingPage.target.track'), + stringsKey: 'track', listings: filterListings('track'), }, { - title: ({language}) => language.$('listingPage.target.tag'), + stringsKey: 'tag', listings: filterListings('tag'), }, { - title: ({language}) => language.$('listingPage.target.other'), + stringsKey: 'other', listings: listingSpec.filter(l => l.groupUnderOther), }, ]; +for (const target of listingTargetSpec) { + for (const listing of target.listings) { + listing.target = target; + } +} + export {listingSpec, listingTargetSpec}; |