diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2023-06-12 15:54:24 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2023-06-12 15:54:24 -0300 |
commit | 630af0a345f3be6c3e4aa3300ce138e48ed5ae91 (patch) | |
tree | 91cc3c76cebf93bf1042e89c05bc8f8d8442aff9 /src/content | |
parent | 0e150bbdf4c384bd2eee6fe3e06ab7b4eb3563da (diff) | |
parent | 05df0a1199dca320e0c8b92d210e6ab6e9676dfb (diff) |
Merge branch 'data-steps' of github.com:hsmusic/hsmusic-wiki into data-steps
Diffstat (limited to 'src/content')
-rw-r--r-- | src/content/dependencies/generateAlbumInfoPage.js | 303 | ||||
-rw-r--r-- | src/content/dependencies/generateAlbumInfoPageContent.js | 306 | ||||
-rw-r--r-- | src/content/dependencies/generatePageLayout.js | 2 | ||||
-rw-r--r-- | src/content/dependencies/generateReleaseInfoContributionsLine.js | 49 | ||||
-rw-r--r-- | src/content/dependencies/generateStickyHeadingContainer.js | 10 | ||||
-rw-r--r-- | src/content/dependencies/generateTrackCoverArtwork.js | 2 | ||||
-rw-r--r-- | src/content/dependencies/generateTrackInfoPage.js | 660 | ||||
-rw-r--r-- | src/content/dependencies/generateTrackInfoPageContent.js | 654 | ||||
-rw-r--r-- | src/content/dependencies/linkThing.js | 124 |
9 files changed, 1028 insertions, 1082 deletions
diff --git a/src/content/dependencies/generateAlbumInfoPage.js b/src/content/dependencies/generateAlbumInfoPage.js index 749dd2af..e317adb1 100644 --- a/src/content/dependencies/generateAlbumInfoPage.js +++ b/src/content/dependencies/generateAlbumInfoPage.js @@ -1,28 +1,51 @@ import getChronologyRelations from '../util/getChronologyRelations.js'; import {sortAlbumsTracksChronologically} from '../../util/wiki-data.js'; +import {accumulateSum, empty} from '../../util/sugar.js'; export default { contentDependencies: [ - 'generateAlbumInfoPageContent', + 'generateAdditionalFilesShortcut', + 'generateAlbumAdditionalFilesList', + 'generateAlbumCoverArtwork', 'generateAlbumNavAccent', 'generateAlbumSidebar', 'generateAlbumSocialEmbed', 'generateAlbumStyleRules', + 'generateAlbumTrackList', 'generateChronologyLinks', 'generateColorStyleRules', + 'generateContentHeading', 'generatePageLayout', + 'generateReleaseInfoContributionsLine', 'linkAlbum', + 'linkAlbumCommentary', + 'linkAlbumGallery', 'linkArtist', + 'linkExternal', 'linkTrack', + 'transformContent', ], - extraDependencies: ['language'], + extraDependencies: ['html', 'language'], relations(relation, album) { - return { - layout: relation('generatePageLayout'), + const relations = {}; + const sections = relations.sections = {}; - coverArtistChronologyContributions: getChronologyRelations(album, { + relations.layout = + relation('generatePageLayout'); + + relations.albumStyleRules = + relation('generateAlbumStyleRules', album); + + relations.colorStyleRules = + relation('generateColorStyleRules', album.color); + + relations.socialEmbed = + relation('generateAlbumSocialEmbed', album); + + relations.coverArtistChronologyContributions = + getChronologyRelations(album, { contributions: album.coverArtistContribs, linkArtist: artist => relation('linkArtist', artist), @@ -37,26 +60,124 @@ export default { ...artist.albumsAsCoverArtist, ...artist.tracksAsCoverArtist, ]), - }), + }); + + relations.albumNavAccent = + relation('generateAlbumNavAccent', album, null); + + relations.chronologyLinks = + relation('generateChronologyLinks'); + + relations.sidebar = + relation('generateAlbumSidebar', album, null); + + if (album.hasCoverArt) { + relations.cover = + relation('generateAlbumCoverArtwork', album); + } + + // Section: Release info + + const releaseInfo = sections.releaseInfo = {}; + + releaseInfo.artistContributionsLine = + relation('generateReleaseInfoContributionsLine', album.artistContribs); + + releaseInfo.coverArtistContributionsLine = + relation('generateReleaseInfoContributionsLine', album.coverArtistContribs); + + releaseInfo.wallpaperArtistContributionsLine = + relation('generateReleaseInfoContributionsLine', album.wallpaperArtistContribs); + + releaseInfo.bannerArtistContributionsLine = + relation('generateReleaseInfoContributionsLine', album.bannerArtistContribs); + + // Section: Listen on + + if (!empty(album.urls)) { + const listen = sections.listen = {}; + + listen.externalLinks = + album.urls.map(url => + relation('linkExternal', url, {type: 'album'})); + } + + // Section: Extra links + + const extra = sections.extra = {}; + + if (album.tracks.some(t => t.hasUniqueCoverArt)) { + extra.galleryLink = + relation('linkAlbumGallery', album); + } + + if (album.commentary || album.tracks.some(t => t.commentary)) { + extra.commentaryLink = + relation('linkAlbumCommentary', album); + } + + if (!empty(album.additionalFiles)) { + extra.additionalFilesShortcut = + relation('generateAdditionalFilesShortcut', album.additionalFiles); + } + + // Section: Track list + + relations.trackList = + relation('generateAlbumTrackList', album); + + // Section: Additional files + + if (!empty(album.additionalFiles)) { + const additionalFiles = sections.additionalFiles = {}; + + additionalFiles.heading = + relation('generateContentHeading'); + + additionalFiles.additionalFilesList = + relation('generateAlbumAdditionalFilesList', album, album.additionalFiles); + } + + // Section: Artist commentary + + if (album.commentary) { + const artistCommentary = sections.artistCommentary = {}; + + artistCommentary.heading = + relation('generateContentHeading'); - albumNavAccent: relation('generateAlbumNavAccent', album, null), - chronologyLinks: relation('generateChronologyLinks'), + artistCommentary.content = + relation('transformContent', album.commentary); + } - content: relation('generateAlbumInfoPageContent', album), - sidebar: relation('generateAlbumSidebar', album, null), - socialEmbed: relation('generateAlbumSocialEmbed', album), - albumStyleRules: relation('generateAlbumStyleRules', album), - colorStyleRules: relation('generateColorStyleRules', album.color), - }; + return relations; }, data(album) { - return { - name: album.name, - }; + const data = {}; + + data.name = album.name; + data.date = album.date; + + data.duration = accumulateSum(album.tracks, track => track.duration); + data.durationApproximate = album.tracks.length > 1; + + if (album.coverArtDate && +album.coverArtDate !== +album.date) { + data.coverArtDate = album.coverArtDate; + } + + if (!empty(album.additionalFiles)) { + data.numAdditionalFiles = album.additionalFiles.length; + } + + data.dateAddedToWiki = album.dateAddedToWiki; + + return data; }, - generate(data, relations, {language}) { + generate(data, relations, {html, language}) { + const {sections: sec} = relations; + return relations.layout .slots({ title: language.$('albumPage.title', {album: data.name}), @@ -65,8 +186,130 @@ export default { colorStyleRules: [relations.colorStyleRules], additionalStyleRules: [relations.albumStyleRules], - cover: relations.content.cover, - mainContent: relations.content.main.content, + cover: + (relations.cover + ? relations.cover.slots({ + alt: language.$('misc.alt.albumCover'), + }) + : null), + + mainContent: [ + html.tag('p', + { + [html.onlyIfContent]: true, + [html.joinChildren]: html.tag('br'), + }, + [ + sec.releaseInfo.artistContributionsLine + .slots({stringKey: 'releaseInfo.by'}), + + sec.releaseInfo.coverArtistContributionsLine + .slots({stringKey: 'releaseInfo.coverArtBy'}), + + sec.releaseInfo.wallpaperArtistContributionsLine + .slots({stringKey: 'releaseInfo.wallpaperArtBy'}), + + sec.releaseInfo.bannerArtistContributionsLine + .slots({stringKey: 'releasInfo.bannerArtBy'}), + + data.date && + language.$('releaseInfo.released', { + date: language.formatDate(data.date), + }), + + data.coverArtDate && + language.$('releaseInfo.artReleased', { + date: language.formatDate(data.coverArtDate), + }), + + data.duration && + language.$('releaseInfo.duration', { + duration: + language.formatDuration(data.duration, { + approximate: data.durationApproximate, + }), + }), + ]), + + sec.listen && + html.tag('p', + language.$('releaseInfo.listenOn', { + links: language.formatDisjunctionList(sec.listen.externalLinks), + })), + + html.tag('p', + { + [html.onlyIfContent]: true, + [html.joinChildren]: html.tag('br'), + }, + [ + sec.extra.additionalFilesShortcut, + + sec.extra.galleryLink && sec.extra.commentaryLink && + language.$('releaseInfo.viewGalleryOrCommentary', { + gallery: + sec.extra.galleryLink + .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.gallery')), + commentary: + sec.extra.commentaryLink + .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.commentary')), + }), + + sec.extra.galleryLink && !sec.extra.commentaryLink && + language.$('releaseInfo.viewGallery', { + link: + sec.extra.galleryLink + .slot('content', language.$('releaseInfo.viewGallery.link')), + }), + + !sec.extra.galleryLink && sec.extra.commentaryLink && + language.$('releaseInfo.viewCommentary', { + link: + sec.extra.commentaryLink + .slot('content', language.$('releaseInfo.viewCommentary.link')), + }), + ]), + + relations.trackList, + + html.tag('p', + { + [html.onlyIfContent]: true, + [html.joinChildren]: '<br>', + }, + [ + data.dateAddedToWiki && + language.$('releaseInfo.addedToWiki', { + date: language.formatDate(data.dateAddedToWiki), + }), + ]), + + sec.additionalFiles && [ + sec.additionalFiles.heading + .slots({ + id: 'additional-files', + title: + language.$('releaseInfo.additionalFiles.heading', { + additionalFiles: + language.countAdditionalFiles(data.numAdditionalFiles, {unit: true}), + }), + }), + + sec.additionalFiles.additionalFilesList, + ], + + sec.artistCommentary && [ + sec.artistCommentary.heading + .slots({ + id: 'artist-commentary', + title: language.$('releaseInfo.artistCommentary') + }), + + html.tag('blockquote', + sec.artistCommentary.content + .slot('mode', 'multiline')), + ], + ], navLinkStyle: 'hierarchical', navLinks: [ @@ -97,3 +340,23 @@ export default { }); }, }; + +/* + banner: !empty(album.bannerArtistContribs) && { + dimensions: album.bannerDimensions, + path: [ + 'media.albumBanner', + album.directory, + album.bannerFileExtension, + ], + alt: language.$('misc.alt.albumBanner'), + position: 'top', + }, + + secondaryNav: generateAlbumSecondaryNav(album, null, { + getLinkThemeString, + html, + language, + link, + }), +*/ diff --git a/src/content/dependencies/generateAlbumInfoPageContent.js b/src/content/dependencies/generateAlbumInfoPageContent.js deleted file mode 100644 index 230d7351..00000000 --- a/src/content/dependencies/generateAlbumInfoPageContent.js +++ /dev/null @@ -1,306 +0,0 @@ -import {accumulateSum, empty} from '../../util/sugar.js'; - -export default { - contentDependencies: [ - 'generateAdditionalFilesShortcut', - 'generateAlbumAdditionalFilesList', - 'generateAlbumCoverArtwork', - 'generateAlbumTrackList', - 'generateContentHeading', - 'linkAlbumCommentary', - 'linkAlbumGallery', - 'linkContribution', - 'linkExternal', - 'transformContent', - ], - - extraDependencies: ['html', 'language'], - - relations(relation, album) { - const relations = {}; - const sections = relations.sections = {}; - - const contributionLinksRelation = contribs => - contribs.map(contrib => - relation('linkContribution', contrib.who, contrib.what)); - - // Section: Release info - - const releaseInfo = sections.releaseInfo = {}; - - if (!empty(album.artistContribs)) { - releaseInfo.artistContributionLinks = - contributionLinksRelation(album.artistContribs); - } - - if (album.hasCoverArt) { - relations.cover = - relation('generateAlbumCoverArtwork', album); - releaseInfo.coverArtistContributionLinks = - contributionLinksRelation(album.coverArtistContribs); - } else { - relations.cover = null; - } - - if (album.hasWallpaperArt) { - releaseInfo.wallpaperArtistContributionLinks = - contributionLinksRelation(album.wallpaperArtistContribs); - } - - if (album.hasBannerArt) { - releaseInfo.bannerArtistContributionLinks = - contributionLinksRelation(album.bannerArtistContribs); - } - - // Section: Listen on - - if (!empty(album.urls)) { - const listen = sections.listen = {}; - - listen.externalLinks = - album.urls.map(url => - relation('linkExternal', url, {type: 'album'})); - } - - // Section: Extra links - - const extra = sections.extra = {}; - - if (album.tracks.some(t => t.hasUniqueCoverArt)) { - extra.galleryLink = - relation('linkAlbumGallery', album); - } - - if (album.commentary || album.tracks.some(t => t.commentary)) { - extra.commentaryLink = - relation('linkAlbumCommentary', album); - } - - if (!empty(album.additionalFiles)) { - extra.additionalFilesShortcut = - relation('generateAdditionalFilesShortcut', album.additionalFiles); - } - - // Section: Track list - - relations.trackList = - relation('generateAlbumTrackList', album); - - // Section: Additional files - - if (!empty(album.additionalFiles)) { - const additionalFiles = sections.additionalFiles = {}; - - additionalFiles.heading = - relation('generateContentHeading'); - - additionalFiles.additionalFilesList = - relation('generateAlbumAdditionalFilesList', album, album.additionalFiles); - } - - // Section: Artist commentary - - if (album.commentary) { - const artistCommentary = sections.artistCommentary = {}; - - artistCommentary.heading = - relation('generateContentHeading'); - - artistCommentary.content = - relation('transformContent', album.commentary); - } - - return relations; - }, - - data(album) { - const data = {}; - - data.date = album.date; - data.duration = accumulateSum(album.tracks, track => track.duration); - data.durationApproximate = album.tracks.length > 1; - - data.hasCoverArt = album.hasCoverArt; - - if (album.hasCoverArt) { - data.coverArtDirectory = album.directory; - data.coverArtFileExtension = album.coverArtFileExtension; - - if (album.coverArtDate && +album.coverArtDate !== +album.date) { - data.coverArtDate = album.coverArtDate; - } - } - - if (!empty(album.additionalFiles)) { - data.numAdditionalFiles = album.additionalFiles.length; - } - - data.dateAddedToWiki = album.dateAddedToWiki; - - return data; - }, - - generate(data, relations, { - html, - language, - }) { - const content = {}; - - const {sections: sec} = relations; - - const formatContributions = - (stringKey, contributionLinks, {showContribution = true, showIcons = true} = {}) => - contributionLinks && - language.$(stringKey, { - artists: - language.formatConjunctionList( - contributionLinks.map(link => - link.slots({showContribution, showIcons}))), - }); - - if (data.hasCoverArt) { - content.cover = relations.cover - .slots({ - alt: language.$('misc.alt.albumCover'), - }); - } else { - content.cover = null; - } - - content.main = { - headingMode: 'sticky', - content: html.tags([ - html.tag('p', - { - [html.onlyIfContent]: true, - [html.joinChildren]: html.tag('br'), - }, - [ - formatContributions('releaseInfo.by', sec.releaseInfo.artistContributionLinks), - formatContributions('releaseInfo.coverArtBy', sec.releaseInfo.coverArtistContributionLinks), - formatContributions('releaseInfo.wallpaperArtBy', sec.releaseInfo.wallpaperArtistContributionLinks), - formatContributions('releaseInfo.bannerArtBy', sec.releaseInfo.bannerArtistContributionLinks), - - data.date && - language.$('releaseInfo.released', { - date: language.formatDate(data.date), - }), - - data.coverArtDate && - language.$('releaseInfo.artReleased', { - date: language.formatDate(data.coverArtDate), - }), - - data.duration && - language.$('releaseInfo.duration', { - duration: - language.formatDuration(data.duration, { - approximate: data.durationApproximate, - }), - }), - ]), - - sec.listen && - html.tag('p', - language.$('releaseInfo.listenOn', { - links: language.formatDisjunctionList(sec.listen.externalLinks), - })), - - html.tag('p', - { - [html.onlyIfContent]: true, - [html.joinChildren]: html.tag('br'), - }, - [ - sec.extra.additionalFilesShortcut, - - sec.extra.galleryLink && sec.extra.commentaryLink && - language.$('releaseInfo.viewGalleryOrCommentary', { - gallery: - sec.extra.galleryLink - .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.gallery')), - commentary: - sec.extra.commentaryLink - .slot('content', language.$('releaseInfo.viewGalleryOrCommentary.commentary')), - }), - - sec.extra.galleryLink && !sec.extra.commentaryLink && - language.$('releaseInfo.viewGallery', { - link: - sec.extra.galleryLink - .slot('content', language.$('releaseInfo.viewGallery.link')), - }), - - !sec.extra.galleryLink && sec.extra.commentaryLink && - language.$('releaseInfo.viewCommentary', { - link: - sec.extra.commentaryLink - .slot('content', language.$('releaseInfo.viewCommentary.link')), - }), - ]), - - relations.trackList, - - html.tag('p', - { - [html.onlyIfContent]: true, - [html.joinChildren]: '<br>', - }, - [ - data.dateAddedToWiki && - language.$('releaseInfo.addedToWiki', { - date: language.formatDate(data.dateAddedToWiki), - }), - ]), - - sec.additionalFiles && [ - sec.additionalFiles.heading - .slots({ - id: 'additional-files', - title: - language.$('releaseInfo.additionalFiles.heading', { - additionalFiles: - language.countAdditionalFiles(data.numAdditionalFiles, {unit: true}), - }), - }), - - sec.additionalFiles.additionalFilesList, - ], - - sec.artistCommentary && [ - sec.artistCommentary.heading - .slots({ - id: 'artist-commentary', - title: language.$('releaseInfo.artistCommentary') - }), - - html.tag('blockquote', - sec.artistCommentary.content - .slot('mode', 'multiline')), - ], - ]), - }; - - return content; - }, -}; - -/* - banner: !empty(album.bannerArtistContribs) && { - dimensions: album.bannerDimensions, - path: [ - 'media.albumBanner', - album.directory, - album.bannerFileExtension, - ], - alt: language.$('misc.alt.albumBanner'), - position: 'top', - }, - - secondaryNav: generateAlbumSecondaryNav(album, null, { - getLinkThemeString, - html, - language, - link, - }), -*/ diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 796dc1e5..84acca0b 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -104,7 +104,6 @@ export default { showWikiNameInTitle: {type: 'boolean', default: true}, cover: {type: 'html'}, - coverNeedsReveal: {type: 'boolean'}, socialEmbed: {type: 'html'}, @@ -204,7 +203,6 @@ export default { relations.stickyHeadingContainer.slots({ title: slots.title, cover: slots.cover, - needsReveal: slots.coverNeedsReveal, }); break; case 'static': diff --git a/src/content/dependencies/generateReleaseInfoContributionsLine.js b/src/content/dependencies/generateReleaseInfoContributionsLine.js new file mode 100644 index 00000000..2b342d09 --- /dev/null +++ b/src/content/dependencies/generateReleaseInfoContributionsLine.js @@ -0,0 +1,49 @@ +import {empty} from '../../util/sugar.js'; + +export default { + contentDependencies: ['linkContribution'], + extraDependencies: ['html', 'language'], + + relations(relation, contributions) { + if (empty(contributions)) { + return {}; + } + + return { + contributionLinks: + contributions + .slice(0, 4) + .map(({who, what}) => + relation('linkContribution', who, what)), + }; + }, + + generate(relations, {html, language}) { + return html.template({ + annotation: `generateReleaseInfoContributionsLine`, + + slots: { + stringKey: {type: 'string'}, + + showContribution: {type: 'boolean', default: true}, + showIcons: {type: 'boolean', default: true}, + }, + + content(slots) { + if (!relations.contributionLinks) { + return html.blank(); + } + + return language.$(slots.stringKey, { + artists: + language.formatConjunctionList( + relations.contributionLinks.map(link => + link.slots({ + showContribution: slots.showContribution, + showIcons: slots.showIcons, + }))), + }); + }, + }); + }, +}; diff --git a/src/content/dependencies/generateStickyHeadingContainer.js b/src/content/dependencies/generateStickyHeadingContainer.js index fb6d8307..6602a2a3 100644 --- a/src/content/dependencies/generateStickyHeadingContainer.js +++ b/src/content/dependencies/generateStickyHeadingContainer.js @@ -8,7 +8,6 @@ export default { slots: { title: {type: 'html'}, cover: {type: 'html'}, - needsReveal: {type: 'boolean', default: false}, }, content(slots) { @@ -27,13 +26,8 @@ export default { hasCover && html.tag('div', {class: 'content-sticky-heading-cover-container'}, - html.tag('div', - {class: [ - 'content-sticky-heading-cover', - slots.needsReveal && - 'content-sticky-heading-cover-needs-reveal', - ]}, - slots.cover.slot('displayMode', 'thumbnail'))) + html.tag('div', {class: 'content-sticky-heading-cover'}, + slots.cover.slot('displayMode', 'thumbnail'))), ]), html.tag('div', {class: 'content-sticky-subheading-row'}, diff --git a/src/content/dependencies/generateTrackCoverArtwork.js b/src/content/dependencies/generateTrackCoverArtwork.js index f6084f36..757ad2d6 100644 --- a/src/content/dependencies/generateTrackCoverArtwork.js +++ b/src/content/dependencies/generateTrackCoverArtwork.js @@ -7,7 +7,7 @@ export default { relation('generateCoverArtwork', (track.hasUniqueCoverArt ? track.artTags - : album.artTags)), + : track.album.artTags)), }; }, diff --git a/src/content/dependencies/generateTrackInfoPage.js b/src/content/dependencies/generateTrackInfoPage.js index ee68f534..ed28edec 100644 --- a/src/content/dependencies/generateTrackInfoPage.js +++ b/src/content/dependencies/generateTrackInfoPage.js @@ -1,27 +1,61 @@ import getChronologyRelations from '../util/getChronologyRelations.js'; -import {sortAlbumsTracksChronologically} from '../../util/wiki-data.js'; + +import { + sortAlbumsTracksChronologically, + sortFlashesChronologically, +} from '../../util/wiki-data.js'; + +import {empty} from '../../util/sugar.js'; export default { contentDependencies: [ - 'generateTrackInfoPageContent', + 'generateAdditionalFilesShortcut', + 'generateAlbumAdditionalFilesList', 'generateAlbumNavAccent', 'generateAlbumSidebar', 'generateAlbumStyleRules', 'generateChronologyLinks', 'generateColorStyleRules', + 'generateContentHeading', 'generatePageLayout', + 'generateReleaseInfoContributionsLine', + 'generateTrackCoverArtwork', + 'generateTrackList', + 'generateTrackListDividedByGroups', 'linkAlbum', 'linkArtist', + 'linkContribution', + 'linkExternal', + 'linkFlash', 'linkTrack', + 'transformContent', ], - extraDependencies: ['language'], + extraDependencies: ['html', 'language', 'wikiData'], - relations(relation, track) { + sprawl({wikiInfo}) { return { - layout: relation('generatePageLayout'), + 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); + + relations.colorStyleRules = + relation('generateColorStyleRules', track.color); - artistChronologyContributions: getChronologyRelations(track, { + relations.artistChronologyContributions = + getChronologyRelations(track, { contributions: [...track.artistContribs, ...track.contributorContribs], linkArtist: artist => relation('linkArtist', artist), @@ -32,9 +66,10 @@ export default { ...artist.tracksAsArtist, ...artist.tracksAsContributor, ]), - }), + }); - coverArtistChronologyContributions: getChronologyRelations(track, { + relations.coverArtistChronologyContributions = + getChronologyRelations(track, { contributions: track.coverArtistContribs, linkArtist: artist => relation('linkArtist', artist), @@ -53,28 +88,255 @@ export default { }), }), - albumLink: relation('linkAlbum', track.album), - trackLink: relation('linkTrack', track), - albumNavAccent: relation('generateAlbumNavAccent', track.album, track), - chronologyLinks: relation('generateChronologyLinks'), + relations.albumLink = + relation('linkAlbum', track.album); - content: relation('generateTrackInfoPageContent', track), - sidebar: relation('generateAlbumSidebar', track.album, track), - albumStyleRules: relation('generateAlbumStyleRules', track.album), - colorStyleRules: relation('generateColorStyleRules', track.color), - }; + relations.trackLink = + relation('linkTrack', track); + + relations.albumNavAccent = + relation('generateAlbumNavAccent', track.album, track); + + relations.chronologyLinks = + relation('generateChronologyLinks'); + + relations.sidebar = + relation('generateAlbumSidebar', track.album, track); + + const additionalFilesSection = additionalFiles => ({ + heading: relation('generateContentHeading'), + list: relation('generateAlbumAdditionalFilesList', album, additionalFiles), + }); + + if (track.hasUniqueCoverArt || album.hasCoverArt) { + relations.cover = + relation('generateTrackCoverArtwork', track); + } + + // Section: Release info + + const releaseInfo = sections.releaseInfo = {}; + + releaseInfo.artistContributionLinks = + relation('generateReleaseInfoContributionsLine', track.artistContribs); + + if (track.hasUniqueCoverArt) { + releaseInfo.coverArtistContributionsLine = + relation('generateReleaseInfoContributionsLine', track.coverArtistContribs); + } + + // Section: Listen on + + const listen = sections.listen = {}; + + if (!empty(track.urls)) { + listen.externalLinks = + track.urls.map(url => + relation('linkExternal', url)); + } + + // Section: Extra links + + const extra = sections.extra = {}; + + if (!empty(track.additionalFiles)) { + extra.additionalFilesShortcut = + relation('generateAdditionalFilesShortcut', track.additionalFiles); + } + + // Section: Other releases + + if (!empty(track.otherReleases)) { + const otherReleases = sections.otherReleases = {}; + + otherReleases.heading = + relation('generateContentHeading'); + + otherReleases.items = + track.otherReleases.map(track => ({ + trackLink: relation('linkTrack', track), + albumLink: relation('linkAlbum', track.album), + })); + } + + // Section: Contributors + + if (!empty(track.contributorContribs)) { + const contributors = sections.contributors = {}; + + contributors.heading = + relation('generateContentHeading'); + + contributors.contributionLinks = + track.contributorContribs.map(({who, what}) => + relation('linkContribution', who, what)); + } + + // Section: Referenced tracks + + if (!empty(track.referencedTracks)) { + const references = sections.references = {}; + + references.heading = + relation('generateContentHeading'); + + references.list = + relation('generateTrackList', track.referencedTracks); + } + + // Section: Tracks that reference + + if (!empty(track.referencedByTracks)) { + const referencedBy = sections.referencedBy = {}; + + referencedBy.heading = + relation('generateContentHeading'); + + referencedBy.list = + relation('generateTrackListDividedByGroups', + track.referencedByTracks, + sprawl.divideTrackListsByGroups); + } + + // Section: Sampled tracks + + if (!empty(track.sampledTracks)) { + const samples = sections.samples = {}; + + samples.heading = + relation('generateContentHeading'); + + samples.list = + relation('generateTrackList', track.sampledTracks); + } + + // 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 + + 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, + + // These properties are only used for the sort. + act: flash.act, + date: flash.date, + })))); + + if (!empty(sortedFeatures)) { + const flashesThatFeature = sections.flashesThatFeature = {}; + + flashesThatFeature.heading = + relation('generateContentHeading'); + + flashesThatFeature.entries = + sortedFeatures.map(({flash, track: directlyFeaturedTrack}) => + (directlyFeaturedTrack === track + ? { + flashLink: relation('linkFlash', flash), + } + : { + flashLink: relation('linkFlash', flash), + trackLink: relation('linkTrack', directlyFeaturedTrack), + })); + } + } + + // Section: Lyrics + + if (track.lyrics) { + const lyrics = sections.lyrics = {}; + + lyrics.heading = + relation('generateContentHeading'); + + lyrics.content = + relation('transformContent', track.lyrics); + } + + // Sections: Sheet music files, MIDI/proejct files, additional files + + if (!empty(track.sheetMusicFiles)) { + sections.sheetMusicFiles = additionalFilesSection(track.sheetMusicFiles); + } + + if (!empty(track.midiProjectFiles)) { + sections.midiProjectFiles = additionalFilesSection(track.midiProjectFiles); + } + + if (!empty(track.additionalFiles)) { + sections.additionalFiles = additionalFilesSection(track.additionalFiles); + } + + // Section: Artist commentary + + if (track.commentary) { + const artistCommentary = sections.artistCommentary = {}; + + artistCommentary.heading = + relation('generateContentHeading'); + + artistCommentary.content = + relation('transformContent', track.commentary); + } + + return relations; }, - data(track) { - return { - name: track.name, + data(sprawl, track) { + const data = {}; + const {album} = track; - hasTrackNumbers: track.album.hasTrackNumbers, - trackNumber: track.album.tracks.indexOf(track) + 1, - }; + data.name = track.name; + data.date = track.date; + data.duration = track.duration; + + data.hasUniqueCoverArt = track.hasUniqueCoverArt; + data.hasAlbumCoverArt = album.hasCoverArt; + + if (track.hasUniqueCoverArt) { + data.albumCoverArtDirectory = album.directory; + data.trackCoverArtDirectory = track.directory; + data.coverArtFileExtension = track.coverArtFileExtension; + + if (track.coverArtDate && +track.coverArtDate !== +track.date) { + data.coverArtDate = track.coverArtDate; + } + } else if (track.album.hasCoverArt) { + data.albumCoverArtDirectory = album.directory; + data.coverArtFileExtension = album.coverArtFileExtension; + } + + data.hasTrackNumbers = album.hasTrackNumbers; + data.trackNumber = album.tracks.indexOf(track) + 1; + + if (!empty(track.additionalFiles)) { + data.numAdditionalFiles = track.additionalFiles.length; + } + + return data; }, - generate(data, relations, {language}) { + generate(data, relations, {html, language}) { + const {sections: sec} = relations; + return relations.layout .slots({ title: language.$('trackPage.title', {track: data.name}), @@ -83,9 +345,246 @@ export default { colorStyleRules: [relations.colorStyleRules], additionalStyleRules: [relations.albumStyleRules], - cover: relations.content.cover, - coverNeedsReveal: relations.content.coverNeedsReveal, - mainContent: relations.content.main.content, + cover: + (relations.cover + ? relations.cover.slots({ + alt: language.$('misc.alt.trackCover'), + }) + : null), + + mainContent: [ + html.tag('p', { + [html.onlyIfContent]: true, + [html.joinChildren]: html.tag('br'), + }, [ + sec.releaseInfo.artistContributionLinks + .slots({stringKey: 'releaseInfo.by'}), + + sec.releaseInfo.coverArtistContributionsLine + ?.slots({stringKey: 'releaseInfo.coverArtBy'}), + + data.date && + language.$('releaseInfo.released', { + date: language.formatDate(data.date), + }), + + data.coverArtDate && + language.$('releaseInfo.artReleased', { + date: language.formatDate(data.coverArtDate), + }), + + data.duration && + language.$('releaseInfo.duration', { + duration: language.formatDuration(data.duration), + }), + ]), + + html.tag('p', + (sec.listen.externalLinks + ? language.$('releaseInfo.listenOn', { + links: language.formatDisjunctionList(sec.listen.externalLinks), + }) + : language.$('releaseInfo.listenOn.noLinks', { + name: html.tag('i', data.name), + }))), + + html.tag('p', + { + [html.onlyIfContent]: true, + [html.joinChildren]: '<br>', + }, + [ + sec.sheetMusicFiles && + language.$('releaseInfo.sheetMusicFiles.shortcut', { + link: html.tag('a', + {href: '#sheet-music-files'}, + language.$('releaseInfo.sheetMusicFiles.shortcut.link')), + }), + + sec.midiProjectFiles && + language.$('releaseInfo.midiProjectFiles.shortcut', { + link: html.tag('a', + {href: '#midi-project-files'}, + language.$('releaseInfo.midiProjectFiles.shortcut.link')), + }), + + sec.additionalFiles && + sec.extra.additionalFilesShortcut, + + 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'), + }), + + html.tag('ul', + sec.otherReleases.items.map(({trackLink, albumLink}) => + html.tag('li', + language.$('releaseInfo.alsoReleasedAs.item', { + track: trackLink, + album: albumLink, + })))), + ], + + sec.contributors && [ + sec.contributors.heading + .slots({ + id: 'contributors', + title: language.$('releaseInfo.contributors'), + }), + + html.tag('ul', + sec.contributors.contributionLinks.map(contributionLink => + html.tag('li', + contributionLink + .slots({ + showIcons: true, + showContribution: true, + })))), + ], + + sec.references && [ + sec.references.heading + .slots({ + id: 'references', + title: + language.$('releaseInfo.tracksReferenced', { + track: html.tag('i', data.name), + }), + }), + + sec.references.list, + ], + + sec.referencedBy && [ + sec.referencedBy.heading + .slots({ + id: 'referenced-by', + title: + language.$('releaseInfo.tracksThatReference', { + track: html.tag('i', data.name), + }), + }), + + sec.referencedBy.list, + ], + + sec.samples && [ + sec.samples.heading + .slots({ + id: 'samples', + title: + language.$('releaseInfo.tracksSampled', { + track: html.tag('i', data.name), + }), + }), + + sec.samples.list, + ], + + sec.sampledBy && [ + sec.sampledBy.heading + .slots({ + id: 'referenced-by', + title: + language.$('releaseInfo.tracksThatSample', { + track: html.tag('i', data.name), + }), + }), + + sec.sampledBy.list, + ], + + sec.flashesThatFeature && [ + sec.flashesThatFeature.heading + .slots({ + id: 'featured-in', + title: + language.$('releaseInfo.flashesThatFeature', { + track: html.tag('i', data.name), + }), + }), + + 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'), + }), + + html.tag('blockquote', + sec.lyrics.content + .slot('mode', 'lyrics')), + ], + + sec.sheetMusicFiles && [ + sec.sheetMusicFiles.heading + .slots({ + id: 'sheet-music-files', + title: language.$('releaseInfo.sheetMusicFiles.heading'), + }), + + sec.sheetMusicFiles.list, + ], + + sec.midiProjectFiles && [ + sec.midiProjectFiles.heading + .slots({ + id: 'midi-project-files', + title: language.$('releaseInfo.midiProjectFiles.heading'), + }), + + 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 && [ + sec.artistCommentary.heading + .slots({ + id: 'artist-commentary', + title: language.$('releaseInfo.artistCommentary') + }), + + html.tag('blockquote', + sec.artistCommentary.content + .slot('mode', 'multiline')), + ], + ], navLinkStyle: 'hierarchical', navLinks: [ @@ -129,4 +628,109 @@ export default { ...relations.sidebar, }); }, -} +}; + +/* + const data = { + type: 'data', + path: ['track', track.directory], + data: ({ + serializeContribs, + serializeCover, + serializeGroupsForTrack, + serializeLink, + }) => ({ + name: track.name, + directory: track.directory, + dates: { + released: track.date, + originallyReleased: track.originalDate, + coverArtAdded: track.coverArtDate, + }, + duration: track.duration, + color: track.color, + cover: serializeCover(track, getTrackCover), + artistsContribs: serializeContribs(track.artistContribs), + contributorContribs: serializeContribs(track.contributorContribs), + coverArtistContribs: serializeContribs(track.coverArtistContribs || []), + album: serializeLink(track.album), + groups: serializeGroupsForTrack(track), + references: track.references.map(serializeLink), + referencedBy: track.referencedBy.map(serializeLink), + alsoReleasedAs: otherReleases.map((track) => ({ + track: serializeLink(track), + album: serializeLink(track.album), + })), + }), + }; + + const getSocialEmbedDescription = ({ + getArtistString: _getArtistString, + language, + }) => { + const hasArtists = !empty(track.artistContribs); + const hasCoverArtists = !empty(track.coverArtistContribs); + const getArtistString = (contribs) => + _getArtistString(contribs, { + // We don't want to put actual HTML tags in social embeds (sadly + // they don't get parsed and displayed, generally speaking), so + // override the link argument so that artist "links" just show + // their names. + link: {artist: (artist) => artist.name}, + }); + if (!hasArtists && !hasCoverArtists) return ''; + return language.formatString( + 'trackPage.socialEmbed.body' + + [hasArtists && '.withArtists', hasCoverArtists && '.withCoverArtists'] + .filter(Boolean) + .join(''), + Object.fromEntries( + [ + hasArtists && ['artists', getArtistString(track.artistContribs)], + hasCoverArtists && [ + 'coverArtists', + getArtistString(track.coverArtistContribs), + ], + ].filter(Boolean) + ) + ); + }; + + const page = { + page: () => { + return { + title: language.$('trackPage.title', {track: track.name}), + stylesheet: getAlbumStylesheet(album, {to}), + + themeColor: track.color, + theme: + getThemeString(track.color, { + additionalVariables: [ + `--album-directory: ${album.directory}`, + `--track-directory: ${track.directory}`, + ] + }), + + socialEmbed: { + heading: language.$('trackPage.socialEmbed.heading', { + album: track.album.name, + }), + headingLink: absoluteTo('localized.album', album.directory), + title: language.$('trackPage.socialEmbed.title', { + track: track.name, + }), + description: getSocialEmbedDescription({getArtistString, language}), + image: '/' + getTrackCover(track, {to: urls.from('shared.root').to}), + color: track.color, + }, + + secondaryNav: generateAlbumSecondaryNav(album, track, { + getLinkThemeString, + html, + language, + link, + }), + }; + }, + }; +*/ diff --git a/src/content/dependencies/generateTrackInfoPageContent.js b/src/content/dependencies/generateTrackInfoPageContent.js deleted file mode 100644 index 43f8e689..00000000 --- a/src/content/dependencies/generateTrackInfoPageContent.js +++ /dev/null @@ -1,654 +0,0 @@ -import {empty} from '../../util/sugar.js'; -import {sortFlashesChronologically} from '../../util/wiki-data.js'; - -export default { - contentDependencies: [ - 'generateAdditionalFilesShortcut', - 'generateAlbumAdditionalFilesList', - 'generateContentHeading', - 'generateTrackCoverArtwork', - 'generateTrackList', - 'generateTrackListDividedByGroups', - 'linkAlbum', - 'linkContribution', - 'linkExternal', - 'linkFlash', - 'linkTrack', - 'transformContent', - ], - - extraDependencies: ['html', 'language', 'wikiData'], - - sprawl({wikiInfo}) { - return { - divideTrackListsByGroups: wikiInfo.divideTrackListsByGroups, - enableFlashesAndGames: wikiInfo.enableFlashesAndGames, - }; - }, - - relations(relation, sprawl, track) { - const {album} = track; - - const relations = {}; - const sections = relations.sections = {}; - - const contributionLinksRelation = contribs => - contribs - .slice(0, 4) - .map(contrib => - relation('linkContribution', contrib.who, contrib.what)); - - const additionalFilesSection = additionalFiles => ({ - heading: relation('generateContentHeading'), - list: relation('generateAlbumAdditionalFilesList', album, additionalFiles), - }); - - if (track.hasUniqueCoverArt || album.hasCoverArt) { - relations.cover = - relation('generateTrackCoverArtwork', track); - } - - // Section: Release info - - const releaseInfo = sections.releaseInfo = {}; - - releaseInfo.artistContributionLinks = - contributionLinksRelation(track.artistContribs); - - if (track.hasUniqueCoverArt) { - releaseInfo.coverArtistContributionLinks = - contributionLinksRelation(track.coverArtistContribs); - } - - // Section: Listen on - - const listen = sections.listen = {}; - - if (!empty(track.urls)) { - listen.externalLinks = - track.urls.map(url => - relation('linkExternal', url)); - } - - // Section: Extra links - - const extra = sections.extra = {}; - - if (!empty(track.additionalFiles)) { - extra.additionalFilesShortcut = - relation('generateAdditionalFilesShortcut', track.additionalFiles); - } - - // Section: Other releases - - if (!empty(track.otherReleases)) { - const otherReleases = sections.otherReleases = {}; - - otherReleases.heading = - relation('generateContentHeading'); - - otherReleases.items = - track.otherReleases.map(track => ({ - trackLink: relation('linkTrack', track), - albumLink: relation('linkAlbum', track.album), - })); - } - - // Section: Contributors - - if (!empty(track.contributorContribs)) { - const contributors = sections.contributors = {}; - - contributors.heading = - relation('generateContentHeading'); - - contributors.contributionLinks = - contributionLinksRelation(track.contributorContribs); - } - - // Section: Referenced tracks - - if (!empty(track.referencedTracks)) { - const references = sections.references = {}; - - references.heading = - relation('generateContentHeading'); - - references.list = - relation('generateTrackList', track.referencedTracks); - } - - // Section: Tracks that reference - - if (!empty(track.referencedByTracks)) { - const referencedBy = sections.referencedBy = {}; - - referencedBy.heading = - relation('generateContentHeading'); - - referencedBy.list = - relation('generateTrackListDividedByGroups', - track.referencedByTracks, - sprawl.divideTrackListsByGroups); - } - - // Section: Sampled tracks - - if (!empty(track.sampledTracks)) { - const samples = sections.samples = {}; - - samples.heading = - relation('generateContentHeading'); - - samples.list = - relation('generateTrackList', track.sampledTracks); - } - - // 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 - - 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, - - // These properties are only used for the sort. - act: flash.act, - date: flash.date, - })))); - - if (!empty(sortedFeatures)) { - const flashesThatFeature = sections.flashesThatFeature = {}; - - flashesThatFeature.heading = - relation('generateContentHeading'); - - flashesThatFeature.entries = - sortedFeatures.map(({flash, track: directlyFeaturedTrack}) => - (directlyFeaturedTrack === track - ? { - flashLink: relation('linkFlash', flash), - } - : { - flashLink: relation('linkFlash', flash), - trackLink: relation('linkTrack', directlyFeaturedTrack), - })); - } - } - - // Section: Lyrics - - if (track.lyrics) { - const lyrics = sections.lyrics = {}; - - lyrics.heading = - relation('generateContentHeading'); - - lyrics.content = - relation('transformContent', track.lyrics); - } - - // Sections: Sheet music files, MIDI/proejct files, additional files - - if (!empty(track.sheetMusicFiles)) { - sections.sheetMusicFiles = additionalFilesSection(track.sheetMusicFiles); - } - - if (!empty(track.midiProjectFiles)) { - sections.midiProjectFiles = additionalFilesSection(track.midiProjectFiles); - } - - if (!empty(track.additionalFiles)) { - sections.additionalFiles = additionalFilesSection(track.additionalFiles); - } - - // Section: Artist commentary - - if (track.commentary) { - const artistCommentary = sections.artistCommentary = {}; - - artistCommentary.heading = - relation('generateContentHeading'); - - artistCommentary.content = - relation('transformContent', track.commentary); - } - - return relations; - }, - - data(sprawl, track) { - const data = {}; - - const {album} = track; - - data.name = track.name; - data.date = track.date; - data.duration = track.duration; - - data.hasUniqueCoverArt = track.hasUniqueCoverArt; - data.hasAlbumCoverArt = album.hasCoverArt; - - if (track.hasUniqueCoverArt) { - data.albumCoverArtDirectory = album.directory; - data.trackCoverArtDirectory = track.directory; - data.coverArtFileExtension = track.coverArtFileExtension; - data.coverNeedsReveal = track.artTags.some(t => t.isContentWarning); - - if (track.coverArtDate && +track.coverArtDate !== +track.date) { - data.coverArtDate = track.coverArtDate; - } - } else if (track.album.hasCoverArt) { - data.albumCoverArtDirectory = album.directory; - data.coverArtFileExtension = album.coverArtFileExtension; - data.coverNeedsReveal = album.artTags.some(t => t.isContentWarning); - } - - if (!empty(track.additionalFiles)) { - data.numAdditionalFiles = track.additionalFiles.length; - } - - return data; - }, - - generate(data, relations, {html, language}) { - const content = {}; - - const {sections: sec} = relations; - - const formatContributions = - (stringKey, contributionLinks, {showContribution = true, showIcons = true} = {}) => - contributionLinks && - language.$(stringKey, { - artists: - language.formatConjunctionList( - contributionLinks.map(link => - link.slots({showContribution, showIcons}))), - }); - - if (data.hasUniqueCoverArt || data.hasAlbumCoverArt) { - content.cover = relations.cover - .slots({ - alt: language.$('misc.alt.trackCover'), - }); - content.coverNeedsReveal = data.coverNeedsReveal; - } else { - content.cover = null; - content.coverNeedsReveal = null; - } - - content.main = { - headingMode: 'sticky', - - content: html.tags([ - html.tag('p', { - [html.onlyIfContent]: true, - [html.joinChildren]: html.tag('br'), - }, [ - formatContributions('releaseInfo.by', sec.releaseInfo.artistContributionLinks), - formatContributions('releaseInfo.coverArtBy', sec.releaseInfo.coverArtistContributionLinks), - - data.date && - language.$('releaseInfo.released', { - date: language.formatDate(data.date), - }), - - data.coverArtDate && - language.$('releaseInfo.artReleased', { - date: language.formatDate(data.coverArtDate), - }), - - data.duration && - language.$('releaseInfo.duration', { - duration: language.formatDuration(data.duration), - }), - ]), - - html.tag('p', - (sec.listen.externalLinks - ? language.$('releaseInfo.listenOn', { - links: language.formatDisjunctionList(sec.listen.externalLinks), - }) - : language.$('releaseInfo.listenOn.noLinks', { - name: html.tag('i', data.name), - }))), - - html.tag('p', - { - [html.onlyIfContent]: true, - [html.joinChildren]: '<br>', - }, - [ - sec.sheetMusicFiles && - language.$('releaseInfo.sheetMusicFiles.shortcut', { - link: html.tag('a', - {href: '#sheet-music-files'}, - language.$('releaseInfo.sheetMusicFiles.shortcut.link')), - }), - - sec.midiProjectFiles && - language.$('releaseInfo.midiProjectFiles.shortcut', { - link: html.tag('a', - {href: '#midi-project-files'}, - language.$('releaseInfo.midiProjectFiles.shortcut.link')), - }), - - sec.additionalFiles && - sec.extra.additionalFilesShortcut, - - 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'), - }), - - html.tag('ul', - sec.otherReleases.items.map(({trackLink, albumLink}) => - html.tag('li', - language.$('releaseInfo.alsoReleasedAs.item', { - track: trackLink, - album: albumLink, - })))), - ], - - sec.contributors && [ - sec.contributors.heading - .slots({ - id: 'contributors', - title: language.$('releaseInfo.contributors'), - }), - - html.tag('ul', sec.contributors.contributionLinks.map(contributionLink => - html.tag('li', - contributionLink - .slots({ - showIcons: true, - showContribution: true, - })))), - ], - - sec.references && [ - sec.references.heading - .slots({ - id: 'references', - title: - language.$('releaseInfo.tracksReferenced', { - track: html.tag('i', data.name), - }), - }), - - sec.references.list, - ], - - sec.referencedBy && [ - sec.referencedBy.heading - .slots({ - id: 'referenced-by', - title: - language.$('releaseInfo.tracksThatReference', { - track: html.tag('i', data.name), - }), - }), - - sec.referencedBy.list, - ], - - sec.samples && [ - sec.samples.heading - .slots({ - id: 'samples', - title: - language.$('releaseInfo.tracksSampled', { - track: html.tag('i', data.name), - }), - }), - - sec.samples.list, - ], - - sec.sampledBy && [ - sec.sampledBy.heading - .slots({ - id: 'referenced-by', - title: - language.$('releaseInfo.tracksThatSample', { - track: html.tag('i', data.name), - }), - }), - - sec.sampledBy.list, - ], - sec.flashesThatFeature && [ - sec.flashesThatFeature.heading - .slots({ - id: 'featured-in', - title: - language.$('releaseInfo.flashesThatFeature', { - track: html.tag('i', data.name), - }), - }), - - 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'), - }), - - html.tag('blockquote', - sec.lyrics.content - .slot('mode', 'lyrics')), - ], - - sec.sheetMusicFiles && [ - sec.sheetMusicFiles.heading - .slots({ - id: 'sheet-music-files', - title: language.$('releaseInfo.sheetMusicFiles.heading'), - }), - - sec.sheetMusicFiles.list, - ], - - sec.midiProjectFiles && [ - sec.midiProjectFiles.heading - .slots({ - id: 'midi-project-files', - title: language.$('releaseInfo.midiProjectFiles.heading'), - }), - - 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 && [ - sec.artistCommentary.heading - .slots({ - id: 'artist-commentary', - title: language.$('releaseInfo.artistCommentary') - }), - - html.tag('blockquote', - sec.artistCommentary.content - .slot('mode', 'multiline')), - ], - ]), - }; - - return content; - }, -}; - -/* - const generateCommentary = ({language, link, transformMultiline}) => - transformMultiline([ - track.commentary, - ...otherReleases.map((track) => - track.commentary - ?.split('\n') - .filter((line) => line.replace(/<\/b>/g, '').includes(':</i>')) - .flatMap(line => [ - line, - language.$('releaseInfo.artistCommentary.seeOriginalRelease', { - original: link.track(track), - }), - ]) - .join('\n') - ), - ].filter(Boolean).join('\n')); - - const data = { - type: 'data', - path: ['track', track.directory], - data: ({ - serializeContribs, - serializeCover, - serializeGroupsForTrack, - serializeLink, - }) => ({ - name: track.name, - directory: track.directory, - dates: { - released: track.date, - originallyReleased: track.originalDate, - coverArtAdded: track.coverArtDate, - }, - duration: track.duration, - color: track.color, - cover: serializeCover(track, getTrackCover), - artistsContribs: serializeContribs(track.artistContribs), - contributorContribs: serializeContribs(track.contributorContribs), - coverArtistContribs: serializeContribs(track.coverArtistContribs || []), - album: serializeLink(track.album), - groups: serializeGroupsForTrack(track), - references: track.references.map(serializeLink), - referencedBy: track.referencedBy.map(serializeLink), - alsoReleasedAs: otherReleases.map((track) => ({ - track: serializeLink(track), - album: serializeLink(track.album), - })), - }), - }; - - const getSocialEmbedDescription = ({ - getArtistString: _getArtistString, - language, - }) => { - const hasArtists = !empty(track.artistContribs); - const hasCoverArtists = !empty(track.coverArtistContribs); - const getArtistString = (contribs) => - _getArtistString(contribs, { - // We don't want to put actual HTML tags in social embeds (sadly - // they don't get parsed and displayed, generally speaking), so - // override the link argument so that artist "links" just show - // their names. - link: {artist: (artist) => artist.name}, - }); - if (!hasArtists && !hasCoverArtists) return ''; - return language.formatString( - 'trackPage.socialEmbed.body' + - [hasArtists && '.withArtists', hasCoverArtists && '.withCoverArtists'] - .filter(Boolean) - .join(''), - Object.fromEntries( - [ - hasArtists && ['artists', getArtistString(track.artistContribs)], - hasCoverArtists && [ - 'coverArtists', - getArtistString(track.coverArtistContribs), - ], - ].filter(Boolean) - ) - ); - }; - - const page = { - page: () => { - return { - title: language.$('trackPage.title', {track: track.name}), - stylesheet: getAlbumStylesheet(album, {to}), - - themeColor: track.color, - theme: - getThemeString(track.color, { - additionalVariables: [ - `--album-directory: ${album.directory}`, - `--track-directory: ${track.directory}`, - ] - }), - - socialEmbed: { - heading: language.$('trackPage.socialEmbed.heading', { - album: track.album.name, - }), - headingLink: absoluteTo('localized.album', album.directory), - title: language.$('trackPage.socialEmbed.title', { - track: track.name, - }), - description: getSocialEmbedDescription({getArtistString, language}), - image: '/' + getTrackCover(track, {to: urls.from('shared.root').to}), - color: track.color, - }, - - secondaryNav: generateAlbumSecondaryNav(album, track, { - getLinkThemeString, - html, - language, - link, - }), - }; - }, - }; -*/ diff --git a/src/content/dependencies/linkThing.js b/src/content/dependencies/linkThing.js index 4ccdf58d..03aa9836 100644 --- a/src/content/dependencies/linkThing.js +++ b/src/content/dependencies/linkThing.js @@ -25,70 +25,68 @@ export default { }; }, - generate(data, relations, {html}) { + slots: { + // content: relations.linkTemplate.getSlotDescription('content'), + content: {type: 'html'}, + + preferShortName: {type: 'boolean', default: false}, + + tooltip: { + validate: v => v.oneOf(v.isBoolean, v.isString), + default: false, + }, + + color: { + validate: v => v.oneOf(v.isBoolean, v.isColor), + default: true, + }, + + anchor: {type: 'boolean', default: false}, + + // attributes: relations.linkTemplate.getSlotDescription('attributes'), + // hash: relations.linkTemplate.getSlotDescription('hash'), + attributes: {validate: v => v.isAttributes}, + hash: {type: 'string'}, + }, + + generate(data, relations, slots, {html}) { const path = [data.pathKey, data.directory]; - return html.template({ - annotation: 'linkThing', - - slots: { - content: relations.linkTemplate.getSlotDescription('content'), - preferShortName: {type: 'boolean', default: false}, - - tooltip: { - validate: v => v.oneOf(v.isBoolean, v.isString), - default: false, - }, - - color: { - validate: v => v.oneOf(v.isBoolean, v.isColor), - default: true, - }, - - anchor: {type: 'boolean', default: false}, - - attributes: relations.linkTemplate.getSlotDescription('attributes'), - hash: relations.linkTemplate.getSlotDescription('hash'), - }, - - content(slots) { - let content = slots.content; - - const name = - (slots.preferShortName - ? data.nameShort ?? data.name - : data.name); - - if (html.isBlank(content)) { - content = name; - } - - let color = null; - if (slots.color === true) { - color = data.color ?? null; - } else if (typeof slots.color === 'string') { - color = slots.color; - } - - let tooltip = null; - if (slots.tooltip === true) { - tooltip = name; - } else if (typeof slots.tooltip === 'string') { - tooltip = slots.tooltip; - } - - return relations.linkTemplate - .slots({ - path: slots.anchor ? [] : path, - href: slots.anchor ? '' : null, - content, - color, - tooltip, - - attributes: slots.attributes, - hash: slots.hash, - }); - }, - }); + let content = slots.content; + + const name = + (slots.preferShortName + ? data.nameShort ?? data.name + : data.name); + + if (html.isBlank(content)) { + content = name; + } + + let color = null; + if (slots.color === true) { + color = data.color ?? null; + } else if (typeof slots.color === 'string') { + color = slots.color; + } + + let tooltip = null; + if (slots.tooltip === true) { + tooltip = name; + } else if (typeof slots.tooltip === 'string') { + tooltip = slots.tooltip; + } + + return relations.linkTemplate + .slots({ + path: slots.anchor ? [] : path, + href: slots.anchor ? '' : null, + content, + color, + tooltip, + + attributes: slots.attributes, + hash: slots.hash, + }); }, } |