diff options
Diffstat (limited to 'src/content/dependencies/generateTrackInfoPage.js')
-rw-r--r-- | src/content/dependencies/generateTrackInfoPage.js | 790 |
1 files changed, 298 insertions, 492 deletions
diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index a3ff07bd..e994aacf 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -1,613 +1,419 @@ -import {sortAlbumsTracksChronologically, sortFlashesChronologically} - from '#sort'; -import {empty, stitchArrays} from '#sugar'; - -import getChronologyRelations from '../util/getChronologyRelations.js'; - export default { contentDependencies: [ - 'generateAbsoluteDatetimestamp', - 'generateAdditionalFilesShortcut', - 'generateAlbumAdditionalFilesList', + 'generateAdditionalFilesList', + 'generateAdditionalNamesBox', 'generateAlbumNavAccent', 'generateAlbumSecondaryNav', 'generateAlbumSidebar', - 'generateAlbumStyleRules', - 'generateChronologyLinks', - 'generateColorStyleAttribute', - 'generateCommentarySection', + 'generateAlbumStyleTags', + 'generateCommentaryEntry', + 'generateContentContentHeading', 'generateContentHeading', 'generateContributionList', + 'generateLyricsSection', 'generatePageLayout', - 'generateRelativeDatetimestamp', - 'generateTrackAdditionalNamesBox', - 'generateTrackCoverArtwork', + 'generateTrackArtistCommentarySection', + 'generateTrackArtworkColumn', + 'generateTrackInfoPageFeaturedByFlashesList', + 'generateTrackInfoPageOtherReleasesList', 'generateTrackList', 'generateTrackListDividedByGroups', + 'generateTrackNavLinks', 'generateTrackReleaseInfo', 'generateTrackSocialEmbed', 'linkAlbum', - 'linkArtist', - 'linkFlash', 'linkTrack', 'transformContent', ], - extraDependencies: ['html', 'language', 'wikiData'], - - sprawl({wikiInfo}) { - return { - divideTrackListsByGroups: wikiInfo.divideTrackListsByGroups, - enableFlashesAndGames: wikiInfo.enableFlashesAndGames, - }; - }, - - relations(relation, sprawl, track) { - const relations = {}; - const sections = relations.sections = {}; - const {album} = track; - - relations.layout = - relation('generatePageLayout'); - - relations.albumStyleRules = - relation('generateAlbumStyleRules', track.album, track); - - relations.socialEmbed = - relation('generateTrackSocialEmbed', track); - - relations.artistChronologyContributions = - getChronologyRelations(track, { - contributions: [ - ...track.artistContribs ?? [], - ...track.contributorContribs ?? [], - ], - - linkArtist: artist => relation('linkArtist', artist), - linkThing: track => relation('linkTrack', track), - - getThings(artist) { - const getDate = thing => thing.date; - - const things = [ - ...artist.tracksAsArtist, - ...artist.tracksAsContributor, - ].filter(getDate); - - return sortAlbumsTracksChronologically(things, {getDate}); - }, - }); - - relations.coverArtistChronologyContributions = - getChronologyRelations(track, { - contributions: track.coverArtistContribs ?? [], - - linkArtist: artist => relation('linkArtist', artist), - - linkThing: trackOrAlbum => - (trackOrAlbum.album - ? relation('linkTrack', trackOrAlbum) - : relation('linkAlbum', trackOrAlbum)), - - getThings(artist) { - const getDate = thing => thing.coverArtDate ?? thing.date; - - const things = [ - ...artist.albumsAsCoverArtist, - ...artist.tracksAsCoverArtist, - ].filter(getDate); - - return sortAlbumsTracksChronologically(things, {getDate}); - }, - }), - - relations.albumLink = - relation('linkAlbum', track.album); - - relations.trackLink = - relation('linkTrack', track); - - relations.albumNavAccent = - relation('generateAlbumNavAccent', track.album, track); - - relations.chronologyLinks = - relation('generateChronologyLinks'); - - relations.secondaryNav = - relation('generateAlbumSecondaryNav', track.album); + extraDependencies: ['html', 'language'], - relations.sidebar = - relation('generateAlbumSidebar', track.album, track); + query: (track) => ({ + mainReleaseTrack: + (track.isMainRelease + ? track + : track.mainReleaseTrack), + }), - const additionalFilesSection = additionalFiles => ({ - heading: relation('generateContentHeading'), - list: relation('generateAlbumAdditionalFilesList', album, additionalFiles), - }); + relations: (relation, query, track) => ({ + layout: + relation('generatePageLayout'), - // This'll take care of itself being blank if there's nothing to show here. - relations.additionalNamesBox = - relation('generateTrackAdditionalNamesBox', track); + albumStyleTags: + relation('generateAlbumStyleTags', track.album, track), - if (track.hasUniqueCoverArt || album.hasCoverArt) { - relations.cover = - relation('generateTrackCoverArtwork', track); - } + socialEmbed: + relation('generateTrackSocialEmbed', track), - // Section: Release info + navLinks: + relation('generateTrackNavLinks', track), - relations.releaseInfo = - relation('generateTrackReleaseInfo', track); + albumNavLink: + relation('linkAlbum', track.album), - // Section: Extra links + albumNavAccent: + relation('generateAlbumNavAccent', track.album, track), - const extra = sections.extra = {}; + secondaryNav: + relation('generateAlbumSecondaryNav', track.album), - if (!empty(track.additionalFiles)) { - extra.additionalFilesShortcut = - relation('generateAdditionalFilesShortcut', track.additionalFiles); - } + sidebar: + relation('generateAlbumSidebar', track.album, track), - // Section: Other releases + additionalNamesBox: + relation('generateAdditionalNamesBox', track.additionalNames), - if (!empty(track.otherReleases)) { - const otherReleases = sections.otherReleases = {}; + artworkColumn: + relation('generateTrackArtworkColumn', track), - otherReleases.heading = - relation('generateContentHeading'); + contentHeading: + relation('generateContentHeading'), - otherReleases.colorStyles = - track.otherReleases - .map(track => relation('generateColorStyleAttribute', track.color)); + contentContentHeading: + relation('generateContentContentHeading', track), - otherReleases.trackLinks = - track.otherReleases - .map(track => relation('linkTrack', track)); + releaseInfo: + relation('generateTrackReleaseInfo', track), - otherReleases.albumLinks = - track.otherReleases - .map(track => relation('linkAlbum', track.album)); + otherReleasesList: + relation('generateTrackInfoPageOtherReleasesList', track), - otherReleases.datetimestamps = - track.otherReleases.map(track2 => - (track2.date - ? (track.date - ? relation('generateRelativeDatetimestamp', - track2.date, - track.date) - : relation('generateAbsoluteDatetimestamp', - track2.date)) - : null)); + contributorContributionList: + relation('generateContributionList', track.contributorContribs), - otherReleases.items = - track.otherReleases.map(track => ({ - trackLink: relation('linkTrack', track), - albumLink: relation('linkAlbum', track.album), - })); - } + referencedTracksList: + relation('generateTrackList', track.referencedTracks), - // Section: Contributors + sampledTracksList: + relation('generateTrackList', track.sampledTracks), - if (!empty(track.contributorContribs)) { - const contributors = sections.contributors = {}; + referencedByTracksList: + relation('generateTrackListDividedByGroups', + query.mainReleaseTrack.referencedByTracks), - contributors.heading = - relation('generateContentHeading'); + sampledByTracksList: + relation('generateTrackListDividedByGroups', + query.mainReleaseTrack.sampledByTracks), - contributors.list = - relation('generateContributionList', track.contributorContribs); - } + flashesThatFeatureList: + relation('generateTrackInfoPageFeaturedByFlashesList', track), - // Section: Referenced tracks + lyricsSection: + relation('generateLyricsSection', track.lyrics), - if (!empty(track.referencedTracks)) { - const references = sections.references = {}; + sheetMusicFilesList: + relation('generateAdditionalFilesList', track.sheetMusicFiles), - references.heading = - relation('generateContentHeading'); + midiProjectFilesList: + relation('generateAdditionalFilesList', track.midiProjectFiles), - references.list = - relation('generateTrackList', track.referencedTracks); - } + additionalFilesList: + relation('generateAdditionalFilesList', track.additionalFiles), - // Section: Sampled tracks + artistCommentarySection: + relation('generateTrackArtistCommentarySection', track), - if (!empty(track.sampledTracks)) { - const samples = sections.samples = {}; + creditingSourceEntries: + track.creditingSources + .map(entry => relation('generateCommentaryEntry', entry)), - samples.heading = - relation('generateContentHeading'); + referencingSourceEntries: + track.referencingSources + .map(entry => relation('generateCommentaryEntry', entry)), + }), - samples.list = - relation('generateTrackList', track.sampledTracks); - } + data: (_query, track) => ({ + name: + track.name, - // Section: Tracks that reference + color: + track.color, - if (!empty(track.referencedByTracks)) { - const referencedBy = sections.referencedBy = {}; + singleTrackSingle: + track.album.style === 'single' && + track.album.tracks.length === 1, + }), - referencedBy.heading = - relation('generateContentHeading'); - - referencedBy.list = - relation('generateTrackListDividedByGroups', - track.referencedByTracks, - sprawl.divideTrackListsByGroups); - } - - // Section: Tracks that sample - - if (!empty(track.sampledByTracks)) { - const sampledBy = sections.sampledBy = {}; - - sampledBy.heading = - relation('generateContentHeading'); - - sampledBy.list = - relation('generateTrackListDividedByGroups', - track.sampledByTracks, - sprawl.divideTrackListsByGroups); - } - - // Section: Flashes that feature + generate: (data, relations, {html, language}) => + language.encapsulate('trackPage', pageCapsule => + relations.layout.slots({ + title: + language.$(pageCapsule, 'title', { + track: data.name, + }), - if (sprawl.enableFlashesAndGames) { - const sortedFeatures = - sortFlashesChronologically( - [track, ...track.otherReleases].flatMap(track => - track.featuredInFlashes.map(flash => ({ - // These aren't going to be exposed directly, they're processed - // into the appropriate relations after this sort. - flash, track, + headingMode: 'sticky', - // These properties are only used for the sort. - act: flash.act, - date: flash.date, - })))); + additionalNames: relations.additionalNamesBox, - if (!empty(sortedFeatures)) { - const flashesThatFeature = sections.flashesThatFeature = {}; + color: data.color, + styleTags: relations.albumStyleTags, - flashesThatFeature.heading = - relation('generateContentHeading'); + artworkColumnContent: + relations.artworkColumn, - flashesThatFeature.entries = - sortedFeatures.map(({flash, track: directlyFeaturedTrack}) => - (directlyFeaturedTrack === track - ? { - flashLink: relation('linkFlash', flash), - } - : { - flashLink: relation('linkFlash', flash), - trackLink: relation('linkTrack', directlyFeaturedTrack), - })); - } - } + mainContent: [ + relations.releaseInfo, - // Section: Lyrics + html.tag('p', + {[html.onlyIfContent]: true}, + {[html.joinChildren]: html.tag('br')}, - if (track.lyrics) { - const lyrics = sections.lyrics = {}; + language.encapsulate('releaseInfo', capsule => [ + !html.isBlank(relations.sheetMusicFilesList) && + language.encapsulate(capsule, 'sheetMusicFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#sheet-music-files'}, + language.$(capsule, 'link')), + })), - lyrics.heading = - relation('generateContentHeading'); + !html.isBlank(relations.midiProjectFilesList) && + language.encapsulate(capsule, 'midiProjectFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#midi-project-files'}, + language.$(capsule, 'link')), + })), - lyrics.content = - relation('transformContent', track.lyrics); - } + !html.isBlank(relations.additionalFilesList) && + language.encapsulate(capsule, 'additionalFiles.shortcut', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#midi-project-files'}, + language.$(capsule, 'link')), + })), - // Sections: Sheet music files, MIDI/proejct files, additional files + !html.isBlank(relations.artistCommentarySection) && + language.encapsulate(capsule, 'readCommentary', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#artist-commentary'}, + language.$(capsule, 'link')), + })), - if (!empty(track.sheetMusicFiles)) { - sections.sheetMusicFiles = additionalFilesSection(track.sheetMusicFiles); - } + !html.isBlank(relations.creditingSourceEntries) && + language.encapsulate(capsule, 'readCreditingSources', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#crediting-sources'}, + language.$(capsule, 'link')), + })), - if (!empty(track.midiProjectFiles)) { - sections.midiProjectFiles = additionalFilesSection(track.midiProjectFiles); - } + !html.isBlank(relations.referencingSourceEntries) && + language.encapsulate(capsule, 'readReferencingSources', capsule => + language.$(capsule, { + link: + html.tag('a', + {href: '#referencing-sources'}, + language.$(capsule, 'link')), + })), + ])), - if (!empty(track.additionalFiles)) { - sections.additionalFiles = additionalFilesSection(track.additionalFiles); - } + relations.otherReleasesList, - // Section: Artist commentary + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'contributors'}, + title: language.$('releaseInfo.contributors'), + }), - if (track.commentary) { - sections.artistCommentary = - relation('generateCommentarySection', track.commentary); - } + relations.contributorContributionList.slots({ + chronologyKind: 'trackContribution', + }), + ]), + + html.tags([ + language.encapsulate('releaseInfo.tracksReferenced', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'references'}, + + title: + language.$(capsule, { + track: + html.tag('i', data.name), + }), + + stickyTitle: + language.$(capsule, 'sticky'), + })), - return relations; - }, + relations.referencedTracksList, + ]), - data(sprawl, track) { - return { - name: track.name, - color: track.color, + html.tags([ + language.encapsulate('releaseInfo.tracksSampled', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'samples'}, - hasTrackNumbers: track.album.hasTrackNumbers, - trackNumber: track.album.tracks.indexOf(track) + 1, + title: + language.$(capsule, { + track: + html.tag('i', data.name), + }), - numAdditionalFiles: track.additionalFiles.length, - }; - }, + stickyTitle: + language.$(capsule, 'sticky'), + })), - generate(data, relations, {html, language}) { - const {sections: sec} = relations; + relations.sampledTracksList, + ]), - return relations.layout - .slots({ - title: language.$('trackPage.title', {track: data.name}), - headingMode: 'sticky', + language.encapsulate('releaseInfo.tracksThatReference', capsule => + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'referenced-by'}, - additionalNames: relations.additionalNamesBox, + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - color: data.color, - styleRules: [relations.albumStyleRules], + stickyTitle: + language.$(capsule, 'sticky'), + }), - cover: - (relations.cover - ? relations.cover.slots({ - alt: language.$('misc.alt.trackCover'), - }) - : null), + relations.referencedByTracksList + .slots({ + headingString: capsule, + }), + ])), - mainContent: [ - relations.releaseInfo, + language.encapsulate('releaseInfo.tracksThatSample', capsule => + html.tags([ + relations.contentHeading.clone() + .slots({ + attributes: {id: 'sampled-by'}, - html.tag('p', - {[html.onlyIfContent]: true}, - {[html.joinChildren]: html.tag('br')}, + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - [ - sec.sheetMusicFiles && - language.$('releaseInfo.sheetMusicFiles.shortcut', { - link: html.tag('a', - {href: '#sheet-music-files'}, - language.$('releaseInfo.sheetMusicFiles.shortcut.link')), + stickyTitle: + language.$(capsule, 'sticky'), }), - sec.midiProjectFiles && - language.$('releaseInfo.midiProjectFiles.shortcut', { - link: html.tag('a', - {href: '#midi-project-files'}, - language.$('releaseInfo.midiProjectFiles.shortcut.link')), + relations.sampledByTracksList + .slots({ + headingString: capsule, }), + ])), - sec.additionalFiles && - sec.extra.additionalFilesShortcut, + html.tags([ + language.encapsulate('releaseInfo.flashesThatFeature', capsule => + relations.contentHeading.clone() + .slots({ + attributes: {id: 'featured-in'}, - sec.artistCommentary && - language.$('releaseInfo.readCommentary', { - link: html.tag('a', - {href: '#artist-commentary'}, - language.$('releaseInfo.readCommentary.link')), - }), - ]), - - sec.otherReleases && [ - sec.otherReleases.heading - .slots({ - id: 'also-released-as', - title: language.$('releaseInfo.alsoReleasedAs'), - }), + title: + language.$(capsule, { + track: html.tag('i', data.name), + }), - html.tag('ul', - stitchArrays({ - trackLink: sec.otherReleases.trackLinks, - albumLink: sec.otherReleases.albumLinks, - datetimestamp: sec.otherReleases.datetimestamps, - colorStyle: sec.otherReleases.colorStyles, - }).map(({ - trackLink, - albumLink, - datetimestamp, - colorStyle, - }) => { - const parts = ['releaseInfo.alsoReleasedAs.item']; - const options = {}; - - options.track = trackLink.slot('color', false); - options.album = albumLink; - - if (datetimestamp) { - parts.push('withYear'); - options.year = - datetimestamp.slots({ - style: 'year', - tooltip: true, - }); - } - - return ( - html.tag('li', - colorStyle, - language.$(...parts, options))); + stickyTitle: + language.$(capsule, 'sticky'), })), - ], - sec.contributors && [ - sec.contributors.heading - .slots({ - id: 'contributors', - title: language.$('releaseInfo.contributors'), - }), + relations.flashesThatFeatureList, + ]), - sec.contributors.list, - ], + relations.lyricsSection, - sec.references && [ - sec.references.heading + html.tags([ + relations.contentHeading.clone() .slots({ - id: 'references', - title: - language.$('releaseInfo.tracksReferenced', { - track: html.tag('i', data.name), - }), - }), - - sec.references.list, - ], - - sec.samples && [ - sec.samples.heading - .slots({ - id: 'samples', - title: - language.$('releaseInfo.tracksSampled', { - track: html.tag('i', data.name), - }), - }), - - sec.samples.list, - ], - - sec.referencedBy && [ - sec.referencedBy.heading - .slots({ - id: 'referenced-by', - title: - language.$('releaseInfo.tracksThatReference', { - track: html.tag('i', data.name), - }), + attributes: {id: 'sheet-music-files'}, + title: language.$('releaseInfo.sheetMusicFiles.heading'), }), - sec.referencedBy.list, - ], + relations.sheetMusicFilesList, + ]), - sec.sampledBy && [ - sec.sampledBy.heading + html.tags([ + relations.contentHeading.clone() .slots({ - id: 'referenced-by', - title: - language.$('releaseInfo.tracksThatSample', { - track: html.tag('i', data.name), - }), + attributes: {id: 'midi-project-files'}, + title: language.$('releaseInfo.midiProjectFiles.heading'), }), - sec.sampledBy.list, - ], + relations.midiProjectFilesList, + ]), - sec.flashesThatFeature && [ - sec.flashesThatFeature.heading + html.tags([ + relations.contentHeading.clone() .slots({ - id: 'featured-in', - title: - language.$('releaseInfo.flashesThatFeature', { - track: html.tag('i', data.name), - }), + attributes: {id: 'additional-files'}, + title: language.$('releaseInfo.additionalFiles.heading'), }), - html.tag('ul', sec.flashesThatFeature.entries.map(({flashLink, trackLink}) => - (trackLink - ? html.tag('li', {class: 'rerelease'}, - language.$('releaseInfo.flashesThatFeature.item.asDifferentRelease', { - flash: flashLink, - track: trackLink, - })) - : html.tag('li', - language.$('releaseInfo.flashesThatFeature.item', { - flash: flashLink, - }))))), - ], - - sec.lyrics && [ - sec.lyrics.heading - .slots({ - id: 'lyrics', - title: language.$('releaseInfo.lyrics'), - }), + relations.additionalFilesList, + ]), - html.tag('blockquote', - sec.lyrics.content - .slot('mode', 'lyrics')), - ], + relations.artistCommentarySection, - sec.sheetMusicFiles && [ - sec.sheetMusicFiles.heading + html.tags([ + relations.contentContentHeading.clone() .slots({ - id: 'sheet-music-files', - title: language.$('releaseInfo.sheetMusicFiles.heading'), + attributes: {id: 'crediting-sources'}, + string: 'misc.creditingSources', }), - sec.sheetMusicFiles.list, - ], + relations.creditingSourceEntries, + ]), - sec.midiProjectFiles && [ - sec.midiProjectFiles.heading + html.tags([ + relations.contentContentHeading.clone() .slots({ - id: 'midi-project-files', - title: language.$('releaseInfo.midiProjectFiles.heading'), + attributes: {id: 'referencing-sources'}, + string: 'misc.referencingSources', }), - sec.midiProjectFiles.list, - ], - - sec.additionalFiles && [ - sec.additionalFiles.heading - .slots({ - id: 'additional-files', - title: - language.$('releaseInfo.additionalFiles.heading', { - additionalFiles: - language.countAdditionalFiles(data.numAdditionalFiles, {unit: true}), - }), - }), - - sec.additionalFiles.list, - ], - - sec.artistCommentary, + relations.referencingSourceEntries, + ]), ], navLinkStyle: 'hierarchical', - navLinks: [ - {auto: 'home'}, - {html: relations.albumLink.slot('color', false)}, - { - html: - (data.hasTrackNumbers - ? language.$('trackPage.nav.track.withNumber', { - number: data.trackNumber, - track: relations.trackLink - .slot('attributes', {class: 'current'}), - }) - : language.$('trackPage.nav.track', { - track: relations.trackLink - .slot('attributes', {class: 'current'}), - })), - }, - ], + navLinks: + (data.singleTrackSingle + ? [ + {auto: 'home'}, + { + html: relations.albumNavLink, + accent: + relations.albumNavAccent.slots({ + showTrackNavigation: false, + showExtraLinks: true, + }), + }, + ] + : html.resolve(relations.navLinks)), navBottomRowContent: - relations.albumNavAccent.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, - }, - ], - }), + (data.singleTrackSingle + ? null + : relations.albumNavAccent.slots({ + showTrackNavigation: true, + showExtraLinks: false, + })), secondaryNav: relations.secondaryNav - .slot('mode', 'track'), + .slot('mode', data.singleTrackSingle ? 'album' : 'track'), leftSidebar: relations.sidebar, socialEmbed: relations.socialEmbed, - }); - }, + })), }; /* |