From ed422988035ce2e67464c544267adce4df4f5f35 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 15 Apr 2023 19:50:02 -0300 Subject: content: generateChronologyLinks, generatePreviousNextLinks --- src/content/dependencies/generateAlbumNavLinks.js | 59 +++++++-------- .../dependencies/generateChronologyLinks.js | 88 ++++++++++++++++++++++ .../dependencies/generatePreviousNextLinks.js | 36 +++++++++ src/content/dependencies/generateTrackInfoPage.js | 51 ++++++++++++- src/content/util/getChronologyRelations.js | 19 +++++ 5 files changed, 221 insertions(+), 32 deletions(-) create mode 100644 src/content/dependencies/generateChronologyLinks.js create mode 100644 src/content/dependencies/generatePreviousNextLinks.js create mode 100644 src/content/util/getChronologyRelations.js diff --git a/src/content/dependencies/generateAlbumNavLinks.js b/src/content/dependencies/generateAlbumNavLinks.js index d9645319..4ce94e1c 100644 --- a/src/content/dependencies/generateAlbumNavLinks.js +++ b/src/content/dependencies/generateAlbumNavLinks.js @@ -2,6 +2,7 @@ import {empty} from '../../util/sugar.js'; export default { contentDependencies: [ + 'generatePreviousNextLinks', 'linkTrack', 'linkAlbumCommentary', 'linkAlbumGallery', @@ -12,6 +13,12 @@ export default { relations(relation, album, track) { const relations = {}; + relations.previousNextLinks = + relation('generatePreviousNextLinks'); + + relations.previousTrackLink = null; + relations.nextTrackLink = null; + if (track) { const index = album.tracks.indexOf(track); @@ -60,36 +67,28 @@ export default { }, content(slots) { - const extraLinks = - (slots.showExtraLinks - ? [ - relations.albumGalleryLink.slots({ - attributes: {class: slots.currentExtra === 'gallery' && 'current'}, - content: language.$('albumPage.nav.gallery'), - }), - - relations.albumCommentaryLink.slots({ - attributes: {class: slots.currentExtra === 'commentary' && 'current'}, - content: language.$('albumPage.nav.commentary'), - }), - ] - : []); - - const previousNextLinks = - (slots.showTrackNavigation - ? [ - relations.previousTrackLink?.slots({ - tooltip: true, - attributes: {id: 'previous-button'}, - content: language.$('misc.nav.previous'), - }), - relations.nextTrackLink?.slots({ - tooltip: true, - attributes: {id: 'next-button'}, - content: language.$('misc.nav.next'), - }), - ] - : []); + const {content: extraLinks = []} = + slots.showExtraLinks && + {content: [ + relations.albumGalleryLink.slots({ + attributes: {class: slots.currentExtra === 'gallery' && 'current'}, + content: language.$('albumPage.nav.gallery'), + }), + + relations.albumCommentaryLink.slots({ + attributes: {class: slots.currentExtra === 'commentary' && 'current'}, + content: language.$('albumPage.nav.commentary'), + }), + ]}; + + const {content: previousNextLinks = []} = + slots.showTrackNavigation && + data.isTrackPage && + data.hasMultipleTracks && + relations.previousNextLinks.slots({ + previousLink: relations.previousTrackLink, + nextLink: relations.nextTrackLink, + }); const randomLink = slots.showTrackNavigation && diff --git a/src/content/dependencies/generateChronologyLinks.js b/src/content/dependencies/generateChronologyLinks.js new file mode 100644 index 00000000..a61b5e6f --- /dev/null +++ b/src/content/dependencies/generateChronologyLinks.js @@ -0,0 +1,88 @@ +import {accumulateSum, empty} from '../../util/sugar.js'; + +export default { + extraDependencies: ['html', 'language'], + + generate({html, language}) { + return html.template({ + annotation: `generateChronologyLinks`, + + slots: { + chronologyInfoSets: { + validate: v => + v.arrayOf( + v.validateProperties({ + headingString: v.isString, + contributions: v.arrayOf(v.validateProperties({ + index: v.isCountingNumber, + artistLink: v.isHTML, + previousLink: v.isHTML, + nextLink: v.isHTML, + })), + })), + } + }, + + content(slots) { + if (empty(slots.chronologyInfoSets)) { + return html.blank(); + } + + const totalContributionCount = + accumulateSum( + slots.chronologyInfoSets, + ({contributions}) => contributions.length); + + if (totalContributionCount === 0) { + return html.blank(); + } + + if (totalContributionCount > 8) { + return html.tag('div', {class: 'chronology'}, + language.$('misc.chronology.seeArtistPages')); + } + + return html.tags( + slots.chronologyInfoSets.map(({ + headingString, + contributions, + }) => + contributions.map(({ + index, + artistLink, + previousLink, + nextLink, + }) => { + const heading = + html.tag('span', {class: 'heading'}, + language.$(headingString, { + index: language.formatIndex(index), + artist: artistLink, + })); + + const navigation = + (previousLink || nextLink) && + html.tag('span', {class: 'buttons'}, + language.formatUnitList([ + previousLink?.slots({ + tooltip: true, + color: false, + content: language.$('misc.nav.previous'), + }), + + nextLink?.slots({ + tooltip: true, + color: false, + content: language.$('misc.nav.next'), + }), + ].filter(Boolean))); + + return html.tag('div', {class: 'chronology'}, + (navigation + ? language.$('misc.chronology.withNavigation', {heading, navigation}) + : heading)); + }))); + }, + }); + }, +}; diff --git a/src/content/dependencies/generatePreviousNextLinks.js b/src/content/dependencies/generatePreviousNextLinks.js new file mode 100644 index 00000000..42b2c42b --- /dev/null +++ b/src/content/dependencies/generatePreviousNextLinks.js @@ -0,0 +1,36 @@ +export default { + // Returns an array with the slotted previous and next links, prepared + // for inclusion in a page's navigation bar. Include with other links + // in the nav bar and then join them all as a unit list, for example. + + extraDependencies: ['html', 'language'], + + generate({html, language}) { + return html.template({ + annotation: `generatePreviousNextLinks`, + + slots: { + previousLink: {type: 'html'}, + nextLink: {type: 'html'}, + }, + + content(slots) { + return [ + !html.isBlank(slots.previousLink) && + slots.previousLink.slots({ + tooltip: true, + attributes: {id: 'previous-button'}, + content: language.$('misc.nav.previous'), + }), + + !html.isBlank(slots.nextLink) && + slots.nextLink?.slots({ + tooltip: true, + attributes: {id: 'next-button'}, + content: language.$('misc.nav.next'), + }), + ].filter(Boolean); + }, + }); + }, +}; diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index acf8461b..570aac9d 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -1,3 +1,6 @@ +import getChronologyRelations from '../util/getChronologyRelations.js'; +import {sortAlbumsTracksChronologically} from '../../util/wiki-data.js'; + export default { contentDependencies: [ 'generateTrackInfoPageContent', @@ -8,6 +11,7 @@ export default { 'generatePageLayout', 'linkAlbum', 'linkTrack', + 'generateChronologyLinks', ], extraDependencies: ['language'], @@ -15,6 +19,37 @@ export default { relations(relation, track) { return { layout: relation('generatePageLayout'), + chronologyLinks: relation('generateChronologyLinks'), + + artistChronologyContributions: getChronologyRelations(track, { + contributions: [...track.artistContribs, ...track.contributorContribs], + + linkArtist: artist => relation('linkArtist', artist), + linkThing: track => relation('linkTrack', track), + + getThings: artist => + sortAlbumsTracksChronologically([ + ...artist.tracksAsArtist, + ...artist.tracksAsContributor, + ]), + }), + + coverArtistChronologyContributions: getChronologyRelations(track, { + contributions: track.coverArtistContribs, + + linkArtist: artist => relation('linkArtist', artist), + + linkThing: trackOrAlbum => + (trackOrAlbum.album + ? relation('linkTrack', trackOrAlbum) + : relation('linkAlbum', trackOrAlbum)), + + getThings: artist => + sortAlbumsTracksChronologically([ + ...artist.albumsAsCoverArtist, + ...artist.tracksAsCoverArtist, + ]), + }), albumLink: relation('linkAlbum', track.album), trackLink: relation('linkTrack', track), @@ -67,14 +102,26 @@ export default { }, ], - navContent: '(Chronology links here)', - navBottomRowContent: relations.albumNavLinks.slots({ showTrackNavigation: true, showExtraLinks: false, }), + navContent: + relations.chronologyLinks.slots({ + chronologyInfoSets: [ + { + headingString: 'misc.chronology.heading.track', + contributions: relations.artistChronologyContributions, + }, + { + headingString: 'misc.chronology.heading.coverArt', + contributions: relations.coverArtistChronologyContributions, + }, + ], + }), + ...relations.sidebar, }); }, diff --git a/src/content/util/getChronologyRelations.js b/src/content/util/getChronologyRelations.js new file mode 100644 index 00000000..cdfdef39 --- /dev/null +++ b/src/content/util/getChronologyRelations.js @@ -0,0 +1,19 @@ +export default function getChronologyRelations(thing, { + contributions, + linkArtist, + linkThing, + getThings, +}) { + return contributions.map(({who}) => { + const things = getThings(who); + const index = things.indexOf(thing); + const previous = things[index - 1]; + const next = things[index + 1]; + return { + index: index + 1, + artistLink: linkArtist(who), + previousLink: previous ? linkThing(previous) : null, + nextLink: next ? linkThing(next) : null, + }; + }); +} -- cgit 1.3.0-6-gf8a5