From 168fd6d42dafa6832f6f5d4c52f23c6d57cba082 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 26 Jun 2023 10:23:37 -0300 Subject: content: generateArtistInfoPageArtworksChunkedList --- src/content/dependencies/generateArtistInfoPage.js | 194 ++++---------------- .../generateArtistInfoPageArtworksChunkedList.js | 200 +++++++++++++++++++++ src/util/wiki-data.js | 27 +++ 3 files changed, 262 insertions(+), 159 deletions(-) create mode 100644 src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js (limited to 'src') diff --git a/src/content/dependencies/generateArtistInfoPage.js b/src/content/dependencies/generateArtistInfoPage.js index 19cc261..561ae65 100644 --- a/src/content/dependencies/generateArtistInfoPage.js +++ b/src/content/dependencies/generateArtistInfoPage.js @@ -3,6 +3,7 @@ import {getTotalDuration} from '../../util/wiki-data.js'; export default { contentDependencies: [ + 'generateArtistInfoPageArtworksChunkedList', 'generateArtistInfoPageTracksChunkedList', 'generateArtistNavLinks', 'generateContentHeading', @@ -86,73 +87,35 @@ export default { const tracks = sections.tracks = {}; tracks.heading = relation('generateContentHeading'); tracks.list = relation('generateArtistInfoPageTracksChunkedList', artist); - } - - /* - const trackContributionChunks = - query.trackContributionChunks.map(({album, chunk}) => ({ - albumLink: relation('linkAlbum', album), - entries: - chunk.map(entry => ({ - // ...getContributionDescription(entry.contribs), - ...getOtherArtistLinks(entry.contribs), - trackLink: relation('linkTrack', entry.track), - })), - })); - - const trackGroupInfo = getGroupInfo(query.trackContributionEntries, 'duration'); - - if (!empty(trackContributionChunks)) { - const tracks = sections.tracks = {}; - tracks.heading = relation('generateContentHeading'); - tracks.chunks = trackContributionChunks; - if (!empty(trackGroupInfo)) { - tracks.groupInfo = trackGroupInfo; - } + // const groupInfo = getGroupInfo(query.trackContributionEntries, 'duration'); + // if (!empty(groupInfo)) { + // tracks.groupInfo = groupInfo; + // } } - // TODO: Add and integrate wallpaper and banner date fields (#90) - const artContributionEntries = [ - ...artist.albumsAsCoverArtist.map(album => ({ - kind: 'albumCover', - date: album.coverArtDate, - thing: album, - album: album, - // ...getContributionDescription(album.coverArtistContribs), - ...getOtherArtistLinks(album.coverArtistContribs), - })), - - ...artist.albumsAsWallpaperArtist.map(album => ({ - kind: 'albumWallpaper', - date: album.coverArtDate, - thing: album, - album: album, - // ...getContributionDescription(album.wallpaperArtistContribs), - ...getOtherArtistLinks(album.wallpaperArtistContribs), - })), + if ( + !empty(artist.albumsAsCoverArtist) || + !empty(artist.albumsAsWallpaperArtist) || + !empty(artist.albumsAsBannerArtist) || + !empty(artist.tracksAsCoverArtist) + ) { + const artworks = sections.artworks = {}; + artworks.heading = relation('generateContentHeading'); + artworks.list = relation('generateArtistInfoPageArtworksChunkedList', artist); - ...artist.albumsAsBannerArtist.map(album => ({ - kind: 'albumBanner', - date: album.coverArtDate, - thing: album, - album: album, - // ...getContributionDescription(album.bannerArtistContribs), - ...getOtherArtistLinks(album.bannerArtistContribs), - })), + if (!empty(artist.albumsAsCoverArtist) || !empty(artist.tracksAsCoverArtist)) { + artworks.artistGalleryLink = + relation('linkArtistGallery', artist); + } - ...artist.tracksAsCoverArtist.map(track => ({ - kind: 'trackCover', - date: track.coverArtDate, - thing: track, - album: track.album, - rerelease: track.originalReleaseTrack !== null, - trackLink: relation('linkTrack', track), - // ...getContributionDescription(track.coverArtistContribs), - ...getOtherArtistLinks(track.coverArtistContribs), - })), - ]; + // const groupInfo = getGroupInfo(artContributionEntries, 'count'); + // if (!empty(groupInfo)) { + // artworks.groupInfo = groupInfo; + // } + } + /* sortContributionEntries(artContributionEntries, sortAlbumsTracksChronologically); const artContributionChunks = @@ -170,27 +133,9 @@ export default { 'trackLink', ])), })); + */ - const artGroupInfo = getGroupInfo(artContributionEntries, 'count'); - - if (!empty(artContributionChunks)) { - const artworks = sections.artworks = {}; - artworks.heading = relation('generateContentHeading'); - artworks.chunks = artContributionChunks; - - if ( - !empty(artist.albumsAsCoverArtist) || - !empty(artist.tracksAsCoverArtist) - ) { - artworks.artistGalleryLink = - relation('linkArtistGallery', artist); - } - - if (!empty(artGroupInfo)) { - artworks.groupInfo = artGroupInfo; - } - } - + /* // Flashes and games can list multiple contributors as collaborative // credits, but we don't display these on the artist page, since they // usually involve many artists crediting a larger team where collaboration @@ -296,34 +241,7 @@ export default { data.totalTrackCount = allTracks.length; data.totalDuration = getTotalDuration(allTracks, {originalReleasesOnly: true}); - /* - data.trackContributionInfo = - query.trackContributionChunks - .map(({date, chunk}) => ({ - date: +date, - duration: accumulateSum(chunk, ({track}) => track.duration), - tracks: chunk.map(({track, contribs}) => ({ - ...getContributionDescription(contribs), - rerelease: track.originalReleaseTrack !== null, - duration: track.duration, - })) - })) - */ - return data; - - /* - function getContributionDescription(contribs) { - const ownContrib = - contribs.find(({who}) => who === artist); - - if (!ownContrib) { - return {}; - } - - return {contributionDescription: ownContrib.what}; - } - */ }, generate(data, relations, {html, language}) { @@ -412,6 +330,7 @@ export default { }), })), + /* sec.tracks.groupInfo && html.tag('p', language.$('artistPage.musicGroupsLine', { @@ -428,61 +347,11 @@ export default { count: language.countContributions(count), })))), })), + */ sec.tracks.list, - - /* - html.tag('dl', - stitchArrays({ - chunkAlbumLink: relations.sections.tracks.chunkAlbumLink, - trackLinks: relations.sections.tracks.trackLinks, - trackOtherArtistLinks: relations.sections.tracks.trackOtherArtistLinks, - chunkDate: data.sections.tracks.chunkDates, - chunkDuration: data.sections.tracks.chunkDurations, - chunkApproximate: data.sections.tracks.chunkApproximates, - trackDurations: data.sections.tracks.trackDurations, - }).map(({ - chunkAlbumLink, - trackLinks, - trackOtherArtistLinks, - chunkDate, - chunkDuration, - chunkApproximate, - trackDurations, - }) => [ - html.tag('dt', - addAccentsToAlbumLink({ - albumLink: chunkAlbumLink, - date: chunkDate, - duration: chunkDuration, - approximate: chunkApproximate, - })), - - html.tag('dd', - html.tag('ul', - stitchArrays({ - trackLink: trackLinks, - otherArtistLinks: trackOtherArtistLinks, - duration: trackDurations, - }).map(({trackLink, duration, ...properties}) => ({ - entry: - (duration - ? language.$('artistPage.creditList.entry.track.withDuration', { - track: trackLink, - duration: language.formatDuration(duration), - }) - : language.$('artistPage.creditList.entry.track', { - track: trackLink, - })), - ...properties, - })) - .map(addAccentsToEntry) - .map(entry => html.tag('li', entry)))), - ])), - */ ], - /* sec.artworks && [ sec.artworks.heading .slots({ @@ -499,6 +368,9 @@ export default { }), })), + sec.artworks.list, + + /* sec.artworks.groupInfo && html.tag('p', language.$('artistPage.artGroupsLine', { @@ -511,7 +383,9 @@ export default { language.countContributions(count), }))), })), + */ + /* html.tag('dl', sec.artworks.chunks.map(({albumLink, date, entries}) => [ html.tag('dt', @@ -537,8 +411,10 @@ export default { .map(addAccentsToEntry) .map(entry => html.tag('li', entry)))), ])), + */ ], + /* sec.flashes && [ sec.flashes.heading .slots({ diff --git a/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js new file mode 100644 index 0000000..b551412 --- /dev/null +++ b/src/content/dependencies/generateArtistInfoPageArtworksChunkedList.js @@ -0,0 +1,200 @@ +import {stitchArrays} from '../../util/sugar.js'; + +import { + chunkByProperties, + sortAlbumsTracksChronologically, + sortEntryThingPairs, +} from '../../util/wiki-data.js'; + +export default { + contentDependencies: [ + 'generateArtistInfoPageChunk', + 'generateArtistInfoPageChunkItem', + 'generateArtistInfoPageOtherArtistLinks', + 'linkAlbum', + 'linkTrack', + ], + + extraDependencies: ['html', 'language'], + + query(artist) { + // TODO: Add and integrate wallpaper and banner date fields (#90) + // This will probably only happen once all artworks follow a standard + // shape (#70) and get their own sorting function. Read for more info: + // https://github.com/hsmusic/hsmusic-wiki/issues/90#issuecomment-1607422961 + + const entries = [ + ...artist.albumsAsCoverArtist.map(album => ({ + thing: album, + entry: { + type: 'albumCover', + album: album, + date: album.coverArtDate, + contribs: album.coverArtistContribs, + }, + // ...getContributionDescription(album.coverArtistContribs), + // ...getOtherArtistLinks(album.coverArtistContribs), + })), + + ...artist.albumsAsWallpaperArtist.map(album => ({ + thing: album, + entry: { + type: 'albumWallpaper', + album: album, + date: album.coverArtDate, + contribs: album.wallpaperArtistContribs, + }, + // ...getContributionDescription(album.wallpaperArtistContribs), + // ...getOtherArtistLinks(album.wallpaperArtistContribs), + })), + + ...artist.albumsAsBannerArtist.map(album => ({ + thing: album, + entry: { + type: 'albumBanner', + album: album, + date: album.coverArtDate, + contribs: album.bannerArtistContribs, + }, + // ...getContributionDescription(album.bannerArtistContribs), + // ...getOtherArtistLinks(album.bannerArtistContribs), + })), + + ...artist.tracksAsCoverArtist.map(track => ({ + thing: track, + entry: { + type: 'trackCover', + album: track.album, + date: track.coverArtDate, + track: track, + contribs: track.coverArtistContribs, + }, + // rerelease: track.originalReleaseTrack !== null, + // trackLink: relation('linkTrack', track), + // ...getContributionDescription(track.coverArtistContribs), + // ...getOtherArtistLinks(track.coverArtistContribs), + })), + ]; + + sortEntryThingPairs(entries, + things => sortAlbumsTracksChronologically(things, { + getDate: thing => thing.coverArtDate, + })); + + const chunks = + chunkByProperties( + entries.map(({entry}) => entry), + ['album', 'date']); + + return {chunks}; + }, + + relations(relation, query, artist) { + return { + chunks: + query.chunks.map(() => relation('generateArtistInfoPageChunk')), + + albumLinks: + query.chunks.map(({album}) => relation('linkAlbum', album)), + + items: + query.chunks.map(({chunk}) => + chunk.map(() => relation('generateArtistInfoPageChunkItem'))), + + itemTrackLinks: + query.chunks.map(({chunk}) => + chunk.map(({track}) => track ? relation('linkTrack', track) : null)), + + itemOtherArtistLinks: + query.chunks.map(({chunk}) => + chunk.map(({contribs}) => relation('generateArtistInfoPageOtherArtistLinks', contribs, artist))), + }; + }, + + data(query, artist) { + return { + chunkDates: + query.chunks.map(({date}) => date), + + itemTypes: + query.chunks.map(({chunk}) => + chunk.map(({type}) => type)), + + itemTrackRereleases: + query.chunks.map(({chunk}) => + chunk.map(({track}) => track ? !!track.originalReleaseTrack : null)), + + itemContributions: + query.chunks.map(({chunk}) => + chunk.map(({contribs}) => + contribs + .find(({who}) => who === artist) + .what)), + }; + }, + + generate(data, relations, {html, language}) { + return html.tag('dl', + stitchArrays({ + chunk: relations.chunks, + albumLink: relations.albumLinks, + date: data.chunkDates, + + items: relations.items, + itemTrackLinks: relations.itemTrackLinks, + itemOtherArtistLinks: relations.itemOtherArtistLinks, + itemTypes: data.itemTypes, + itemTrackRereleases: data.itemTrackRereleases, + itemContributions: data.itemContributions, + }).map(({ + chunk, + albumLink, + date, + + items, + itemTrackLinks, + itemOtherArtistLinks, + itemTypes, + itemTrackRereleases, + itemContributions, + }) => + chunk.slots({ + albumLink, + date, + + items: + stitchArrays({ + item: items, + trackLink: itemTrackLinks, + otherArtistLinks: itemOtherArtistLinks, + type: itemTypes, + contribution: itemContributions, + rerelease: itemTrackRereleases, + }).map(({ + item, + trackLink, + otherArtistLinks, + type, + contribution, + rerelease, + }) => + item.slots({ + otherArtistLinks, + contribution, + rerelease, + + content: + (type === 'trackCover' + ? language.$('artistPage.creditList.entry.track', { + track: trackLink, + }) + : html.tag('i', + language.$('artistPage.creditList.entry.album.' + { + albumWallpaper: 'wallpaperArt', + albumBanner: 'bannerArt', + albumCover: 'coverArt', + }[type]))), + })), + }))); + }, +}; diff --git a/src/util/wiki-data.js b/src/util/wiki-data.js index 382f162..da8312f 100644 --- a/src/util/wiki-data.js +++ b/src/util/wiki-data.js @@ -343,6 +343,33 @@ export function sortEntryThingPairs(data, sortFunction) { return data; } +/* +// Alternate draft version of sortEntryThingPairs. +// See: https://github.com/hsmusic/hsmusic-wiki/issues/90#issuecomment-1607412168 + +// Maps the provided "preparation" function across a list of arbitrary values, +// building up a list of sortable values; sorts these with the provided sorting +// function; and reorders the sources to match their corresponding prepared +// values. As usual, if multiple source items correspond to the same sorting +// data, this retains the source relative positioning. +export function prepareAndSort(sources, prepareForSort, sortFunction) { + const prepared = []; + const preparedToSource = new Map(); + + for (const original of originals) { + const prep = prepareForSort(source); + prepared.push(prep); + preparedToSource.set(prep, source); + } + + sortFunction(prepared); + + sources.splice(0, ...sources.length, prepared.map(prep => preparedToSource.get(prep))); + + return sources; +} +*/ + // Highly contextual sort functions - these are only for very specific types // of Things, and have appropriately hard-coded behavior. -- cgit 1.3.0-6-gf8a5