From 60b6715b38d137f8d6d0ce3c537a546a507ecf1f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 20 Aug 2023 21:22:15 -0300 Subject: content: listArtistsByName: divide by main groups --- src/content/dependencies/listArtistsByName.js | 123 ++++++++++++++++++++------ 1 file changed, 94 insertions(+), 29 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listArtistsByName.js b/src/content/dependencies/listArtistsByName.js index 6c0ad836..d83150e8 100644 --- a/src/content/dependencies/listArtistsByName.js +++ b/src/content/dependencies/listArtistsByName.js @@ -1,51 +1,116 @@ -import {stitchArrays} from '#sugar'; +import {empty, stitchArrays, unique} from '#sugar'; import {getArtistNumContributions, sortAlphabetically} from '#wiki-data'; export default { - contentDependencies: ['generateListingPage', 'linkArtist'], + contentDependencies: ['generateListingPage', 'linkArtist', 'linkGroup'], extraDependencies: ['language', 'wikiData'], - sprawl({artistData}) { - return {artistData}; + sprawl({artistData, wikiInfo}) { + return {artistData, wikiInfo}; }, - query({artistData}, spec) { - return { - spec, + query(sprawl, spec) { + const artists = sortAlphabetically(sprawl.artistData.slice()); + const groups = sprawl.wikiInfo.divideTrackListsByGroups; - artists: sortAlphabetically(artistData.slice()), - }; + if (empty(groups)) { + return {spec, artists}; + } + + const artistGroups = + artists.map(artist => + unique( + unique([ + ...artist.albumsAsAny, + ...artist.tracksAsAny.map(track => track.album), + ]).flatMap(album => album.groups))) + + const artistsByGroup = + groups.map(group => + artists.filter((artist, index) => artistGroups[index].includes(group))); + + return {spec, groups, artistsByGroup}; }, relations(relation, query) { - return { - page: relation('generateListingPage', query.spec), + const relations = {}; - artistLinks: + relations.page = + relation('generateListingPage', query.spec); + + if (query.artists) { + relations.artistLinks = query.artists - .map(artist => relation('linkArtist', artist)), - }; + .map(artist => relation('linkArtist', artist)); + } + + if (query.artistsByGroup) { + relations.groupLinks = + query.groups + .map(group => relation('linkGroup', group)); + + relations.artistLinksByGroup = + query.artistsByGroup + .map(artists => artists + .map(artist => relation('linkArtist', artist))); + } + + return relations; }, data(query) { - return { - counts: + const data = {}; + + if (query.artists) { + data.counts = query.artists - .map(artist => getArtistNumContributions(artist)), - }; + .map(artist => getArtistNumContributions(artist)); + } + + if (query.artistsByGroup) { + data.countsByGroup = + query.artistsByGroup + .map(artists => artists + .map(artist => getArtistNumContributions(artist))); + } + + return data; }, generate(data, relations, {language}) { - return relations.page.slots({ - type: 'rows', - rows: - stitchArrays({ - link: relations.artistLinks, - count: data.counts, - }).map(({link, count}) => ({ - artist: link, - contributions: language.countContributions(count, {unit: true}), - })), - }); + return ( + (relations.artistLinksByGroup + ? relations.page.slots({ + type: 'chunks', + + chunkTitles: + relations.groupLinks.map(groupLink => ({ + group: groupLink, + })), + + chunkRows: + stitchArrays({ + artistLinks: relations.artistLinksByGroup, + counts: data.countsByGroup, + }).map(({artistLinks, counts}) => + stitchArrays({ + link: artistLinks, + count: counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + }))), + }) + : relations.page.slots({ + type: 'rows', + rows: + stitchArrays({ + link: relations.artistLinks, + count: data.counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + })), + }))); }, }; -- cgit 1.3.0-6-gf8a5 From e035dab576875bca12485f60a1aeb257c394c723 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 20 Aug 2023 22:07:05 -0300 Subject: content: generateListingPage: "skip to a section" --- src/content/dependencies/generateListingPage.js | 38 +++++++++++++++++++++++-- src/content/dependencies/listArtistsByName.js | 19 ++++++++++++- 2 files changed, 53 insertions(+), 4 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 08eb40c6..4de2d006 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -7,6 +7,7 @@ export default { 'generatePageLayout', 'linkListing', 'linkListingIndex', + 'linkTemplate', ], extraDependencies: ['html', 'language', 'wikiData'], @@ -26,6 +27,9 @@ export default { relations.chunkHeading = relation('generateContentHeading'); + relations.showSkipToSectionLinkTemplate = + relation('linkTemplate'); + if (listing.target.listings.length > 1) { relations.sameTargetListingLinks = listing.target.listings @@ -65,6 +69,9 @@ export default { chunkTitles: {validate: v => v.strictArrayOf(v.isObject)}, chunkRows: {validate: v => v.strictArrayOf(v.isObject)}, + showSkipToSection: {type: 'boolean', default: false}, + chunkIDs: {validate: v => v.strictArrayOf(v.isString)}, + listStyle: { validate: v => v.is('ordered', 'unordered'), default: 'unordered', @@ -128,16 +135,40 @@ export default { formatListingString('item', row)))), slots.type === 'chunks' && - html.tag('dl', + html.tag('dl', [ + slots.showSkipToSection && [ + html.tag('dt', + language.$('listingPage.skipToSection')), + + html.tag('dd', + html.tag('ul', + stitchArrays({ + title: slots.chunkTitles, + id: slots.chunkIDs, + }).filter(({id}) => id) + .map(({title, id}) => + html.tag('li', + relations.showSkipToSectionLinkTemplate + .clone() + .slots({ + hash: id, + content: + formatListingString('chunk.title', title) + .replace(/:$/, ''), + }))))), + ], + stitchArrays({ title: slots.chunkTitles, rows: slots.chunkRows, - }).map(({title, rows}) => [ + id: slots.chunkIDs, + }).map(({title, rows, id}) => [ relations.chunkHeading .clone() .slots({ tag: 'dt', title: formatListingString('chunk.title', title), + id, }), html.tag('dd', @@ -146,7 +177,8 @@ export default { html.tag('li', {class: row.stringsKey === 'rerelease' && 'rerelease'}, formatListingString('chunk.item', row))))), - ])), + ]), + ]), slots.type === 'custom' && slots.content, diff --git a/src/content/dependencies/listArtistsByName.js b/src/content/dependencies/listArtistsByName.js index d83150e8..3778b9e3 100644 --- a/src/content/dependencies/listArtistsByName.js +++ b/src/content/dependencies/listArtistsByName.js @@ -1,5 +1,10 @@ import {empty, stitchArrays, unique} from '#sugar'; -import {getArtistNumContributions, sortAlphabetically} from '#wiki-data'; + +import { + filterMultipleArrays, + getArtistNumContributions, + sortAlphabetically, +} from '#wiki-data'; export default { contentDependencies: ['generateListingPage', 'linkArtist', 'linkGroup'], @@ -29,6 +34,9 @@ export default { groups.map(group => artists.filter((artist, index) => artistGroups[index].includes(group))); + filterMultipleArrays(groups, artistsByGroup, + (group, artists) => !empty(artists)); + return {spec, groups, artistsByGroup}; }, @@ -68,6 +76,10 @@ export default { } if (query.artistsByGroup) { + data.groupDirectories = + query.groups + .map(group => group.directory); + data.countsByGroup = query.artistsByGroup .map(artists => artists @@ -83,6 +95,11 @@ export default { ? relations.page.slots({ type: 'chunks', + showSkipToSection: true, + chunkIDs: + data.groupDirectories + .map(directory => `contributed-to-${directory}`), + chunkTitles: relations.groupLinks.map(groupLink => ({ group: groupLink, -- cgit 1.3.0-6-gf8a5 From f12605331f60796da178f3d4b7bbc096f02b0d48 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 28 Aug 2023 09:34:29 -0300 Subject: content: move new "Artists - by Name" implementation to "by Group" --- src/content/dependencies/listArtistsByGroup.js | 133 ++++++++++++++++++++++ src/content/dependencies/listArtistsByName.js | 151 ++++++------------------- 2 files changed, 165 insertions(+), 119 deletions(-) create mode 100644 src/content/dependencies/listArtistsByGroup.js (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listArtistsByGroup.js b/src/content/dependencies/listArtistsByGroup.js new file mode 100644 index 00000000..3778b9e3 --- /dev/null +++ b/src/content/dependencies/listArtistsByGroup.js @@ -0,0 +1,133 @@ +import {empty, stitchArrays, unique} from '#sugar'; + +import { + filterMultipleArrays, + getArtistNumContributions, + sortAlphabetically, +} from '#wiki-data'; + +export default { + contentDependencies: ['generateListingPage', 'linkArtist', 'linkGroup'], + extraDependencies: ['language', 'wikiData'], + + sprawl({artistData, wikiInfo}) { + return {artistData, wikiInfo}; + }, + + query(sprawl, spec) { + const artists = sortAlphabetically(sprawl.artistData.slice()); + const groups = sprawl.wikiInfo.divideTrackListsByGroups; + + if (empty(groups)) { + return {spec, artists}; + } + + const artistGroups = + artists.map(artist => + unique( + unique([ + ...artist.albumsAsAny, + ...artist.tracksAsAny.map(track => track.album), + ]).flatMap(album => album.groups))) + + const artistsByGroup = + groups.map(group => + artists.filter((artist, index) => artistGroups[index].includes(group))); + + filterMultipleArrays(groups, artistsByGroup, + (group, artists) => !empty(artists)); + + return {spec, groups, artistsByGroup}; + }, + + relations(relation, query) { + const relations = {}; + + relations.page = + relation('generateListingPage', query.spec); + + if (query.artists) { + relations.artistLinks = + query.artists + .map(artist => relation('linkArtist', artist)); + } + + if (query.artistsByGroup) { + relations.groupLinks = + query.groups + .map(group => relation('linkGroup', group)); + + relations.artistLinksByGroup = + query.artistsByGroup + .map(artists => artists + .map(artist => relation('linkArtist', artist))); + } + + return relations; + }, + + data(query) { + const data = {}; + + if (query.artists) { + data.counts = + query.artists + .map(artist => getArtistNumContributions(artist)); + } + + if (query.artistsByGroup) { + data.groupDirectories = + query.groups + .map(group => group.directory); + + data.countsByGroup = + query.artistsByGroup + .map(artists => artists + .map(artist => getArtistNumContributions(artist))); + } + + return data; + }, + + generate(data, relations, {language}) { + return ( + (relations.artistLinksByGroup + ? relations.page.slots({ + type: 'chunks', + + showSkipToSection: true, + chunkIDs: + data.groupDirectories + .map(directory => `contributed-to-${directory}`), + + chunkTitles: + relations.groupLinks.map(groupLink => ({ + group: groupLink, + })), + + chunkRows: + stitchArrays({ + artistLinks: relations.artistLinksByGroup, + counts: data.countsByGroup, + }).map(({artistLinks, counts}) => + stitchArrays({ + link: artistLinks, + count: counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + }))), + }) + : relations.page.slots({ + type: 'rows', + rows: + stitchArrays({ + link: relations.artistLinks, + count: data.counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + })), + }))); + }, +}; diff --git a/src/content/dependencies/listArtistsByName.js b/src/content/dependencies/listArtistsByName.js index 3778b9e3..554b4587 100644 --- a/src/content/dependencies/listArtistsByName.js +++ b/src/content/dependencies/listArtistsByName.js @@ -1,133 +1,46 @@ -import {empty, stitchArrays, unique} from '#sugar'; - -import { - filterMultipleArrays, - getArtistNumContributions, - sortAlphabetically, -} from '#wiki-data'; +import {stitchArrays} from '#sugar'; +import {getArtistNumContributions, sortAlphabetically} from '#wiki-data'; export default { contentDependencies: ['generateListingPage', 'linkArtist', 'linkGroup'], extraDependencies: ['language', 'wikiData'], - sprawl({artistData, wikiInfo}) { - return {artistData, wikiInfo}; - }, - - query(sprawl, spec) { - const artists = sortAlphabetically(sprawl.artistData.slice()); - const groups = sprawl.wikiInfo.divideTrackListsByGroups; - - if (empty(groups)) { - return {spec, artists}; - } - - const artistGroups = - artists.map(artist => - unique( - unique([ - ...artist.albumsAsAny, - ...artist.tracksAsAny.map(track => track.album), - ]).flatMap(album => album.groups))) - - const artistsByGroup = - groups.map(group => - artists.filter((artist, index) => artistGroups[index].includes(group))); - - filterMultipleArrays(groups, artistsByGroup, - (group, artists) => !empty(artists)); - - return {spec, groups, artistsByGroup}; - }, - - relations(relation, query) { - const relations = {}; + sprawl: ({artistData, wikiInfo}) => + ({artistData, wikiInfo}), - relations.page = - relation('generateListingPage', query.spec); + query: (sprawl, spec) => ({ + spec, - if (query.artists) { - relations.artistLinks = - query.artists - .map(artist => relation('linkArtist', artist)); - } + artists: + sortAlphabetically(sprawl.artistData.slice()), + }), - if (query.artistsByGroup) { - relations.groupLinks = - query.groups - .map(group => relation('linkGroup', group)); + relations: (relation, query) => ({ + page: + relation('generateListingPage', query.spec), - relations.artistLinksByGroup = - query.artistsByGroup - .map(artists => artists - .map(artist => relation('linkArtist', artist))); - } + artistLinks: + query.artists + .map(artist => relation('linkArtist', artist)), + }), - return relations; - }, - - data(query) { - const data = {}; - - if (query.artists) { - data.counts = - query.artists - .map(artist => getArtistNumContributions(artist)); - } - - if (query.artistsByGroup) { - data.groupDirectories = - query.groups - .map(group => group.directory); - - data.countsByGroup = - query.artistsByGroup - .map(artists => artists - .map(artist => getArtistNumContributions(artist))); - } - - return data; - }, + data: (query) => ({ + counts: + query.artists + .map(artist => getArtistNumContributions(artist)), + }), generate(data, relations, {language}) { - return ( - (relations.artistLinksByGroup - ? relations.page.slots({ - type: 'chunks', - - showSkipToSection: true, - chunkIDs: - data.groupDirectories - .map(directory => `contributed-to-${directory}`), - - chunkTitles: - relations.groupLinks.map(groupLink => ({ - group: groupLink, - })), - - chunkRows: - stitchArrays({ - artistLinks: relations.artistLinksByGroup, - counts: data.countsByGroup, - }).map(({artistLinks, counts}) => - stitchArrays({ - link: artistLinks, - count: counts, - }).map(({link, count}) => ({ - artist: link, - contributions: language.countContributions(count, {unit: true}), - }))), - }) - : relations.page.slots({ - type: 'rows', - rows: - stitchArrays({ - link: relations.artistLinks, - count: data.counts, - }).map(({link, count}) => ({ - artist: link, - contributions: language.countContributions(count, {unit: true}), - })), - }))); + return relations.page.slots({ + type: 'rows', + rows: + stitchArrays({ + link: relations.artistLinks, + count: data.counts, + }).map(({link, count}) => ({ + artist: link, + contributions: language.countContributions(count, {unit: true}), + })), + }); }, }; -- cgit 1.3.0-6-gf8a5 From 168425e7a3dd3a268cfdbd2a395e11ac72eaa3b2 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 28 Aug 2023 09:57:50 -0300 Subject: content: generateListingPage: don't mutate options in slots --- src/content/dependencies/generateListingPage.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 4de2d006..3c50bd59 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -91,12 +91,13 @@ export default { const parts = [baseStringsKey, contextStringsKey]; - if (options.stringsKey) { + const {stringsKey, ...passOptions} = options; + + if (stringsKey) { parts.push(options.stringsKey); - delete options.stringsKey; } - return language.formatString(parts.join('.'), options); + return language.formatString(parts.join('.'), passOptions); }; return relations.layout.slots({ -- cgit 1.3.0-6-gf8a5 From 6b76c7a0c852b87b3ff2e4f3a11fe15424618511 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 28 Aug 2023 09:58:22 -0300 Subject: content: listArtistsByContributions: use updated chunk layout --- .../dependencies/listArtistsByContributions.js | 116 ++++++++++----------- 1 file changed, 54 insertions(+), 62 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listArtistsByContributions.js b/src/content/dependencies/listArtistsByContributions.js index 86c8cfa2..58c51a40 100644 --- a/src/content/dependencies/listArtistsByContributions.js +++ b/src/content/dependencies/listArtistsByContributions.js @@ -1,5 +1,11 @@ -import {stitchArrays, unique} from '#sugar'; -import {filterByCount, sortAlphabetically, sortByCount} from '#wiki-data'; +import {empty, stitchArrays, unique} from '#sugar'; + +import { + filterByCount, + filterMultipleArrays, + sortAlphabetically, + sortByCount, +} from '#wiki-data'; export default { contentDependencies: ['generateListingPage', 'linkArtist'], @@ -96,68 +102,54 @@ export default { return data; }, - generate(data, relations, {html, language}) { - const lists = Object.fromEntries( - ([ - ['tracks', [ - relations.artistLinksByTrackContributions, - data.countsByTrackContributions, - 'countTracks', - ]], - - ['artworks', [ - relations.artistLinksByArtworkContributions, - data.countsByArtworkContributions, - 'countArtworks', - ]], - - data.enableFlashesAndGames && - ['flashes', [ - relations.artistLinksByFlashContributions, - data.countsByFlashContributions, - 'countFlashes', - ]], - ]).filter(Boolean) - .map(([key, [artistLinks, counts, countFunction]]) => [ - key, - html.tag('ul', - stitchArrays({ - artistLink: artistLinks, - count: counts, - }).map(({artistLink, count}) => - html.tag('li', - language.$('listingPage.listArtists.byContribs.item', { - artist: artistLink, - contributions: language[countFunction](count, {unit: true}), - })))), - ])); + generate(data, relations, {language}) { + const listChunkIDs = ['tracks', 'artworks', 'flashes']; + const listTitleStringsKeys = ['trackContributors', 'artContributors', 'flashContributors']; + const listCountFunctions = ['countTracks', 'countArtworks', 'countFlashes']; + + const listArtistLinks = [ + relations.artistLinksByTrackContributions, + relations.artistLinksByArtworkContributions, + relations.artistLinksByFlashContributions, + ]; + + const listArtistCounts = [ + data.countsByTrackContributions, + data.countsByArtworkContributions, + data.countsByFlashContributions, + ]; + + filterMultipleArrays( + listChunkIDs, + listTitleStringsKeys, + listCountFunctions, + listArtistLinks, + listArtistCounts, + (_chunkID, _titleStringsKey, _countFunction, artistLinks, _artistCounts) => + !empty(artistLinks)); return relations.page.slots({ - type: 'custom', - content: - html.tag('div', {class: 'content-columns'}, [ - html.tag('div', {class: 'column'}, [ - html.tag('h2', - language.$('listingPage.misc.trackContributors')), - - lists.tracks, - ]), - - html.tag('div', {class: 'column'}, [ - html.tag('h2', - language.$( - 'listingPage.misc.artContributors')), - - lists.artworks, - - lists.flashes && [ - html.tag('h2', - language.$('listingPage.misc.flashContributors')), - - lists.flashes, - ], - ]), - ]), + type: 'chunks', + + showSkipToSection: true, + chunkIDs: listChunkIDs, + + chunkTitles: + listTitleStringsKeys.map(stringsKey => ({stringsKey})), + + chunkRows: + stitchArrays({ + artistLinks: listArtistLinks, + artistCounts: listArtistCounts, + countFunction: listCountFunctions, + }).map(({artistLinks, artistCounts, countFunction}) => + stitchArrays({ + artistLink: artistLinks, + artistCount: artistCounts, + }).map(({artistLink, artistCount}) => ({ + artist: artistLink, + contributions: language[countFunction](artistCount, {unit: true}), + }))), }); }, }; -- cgit 1.3.0-6-gf8a5 From 715bd8eff86c20b3773a66e96e9c9d6ae8602644 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 28 Aug 2023 19:19:39 -0300 Subject: content: listArtistsByLatestContribution: chunk-based rework --- .../listArtistsByLatestContribution.js | 594 ++++++++++----------- 1 file changed, 275 insertions(+), 319 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listArtistsByLatestContribution.js b/src/content/dependencies/listArtistsByLatestContribution.js index b6ea8e96..edb02e0d 100644 --- a/src/content/dependencies/listArtistsByLatestContribution.js +++ b/src/content/dependencies/listArtistsByLatestContribution.js @@ -1,15 +1,16 @@ -import {transposeArrays, empty, stitchArrays} from '#sugar'; +import {empty, stitchArrays} from '#sugar'; +import T from '#things'; import { chunkMultipleArrays, - compareCaseLessSensitive, - compareDates, - filterMultipleArrays, - reduceMultipleArrays, sortAlphabetically, + sortAlbumsTracksChronologically, + sortFlashesChronologically, sortMultipleArrays, } from '#wiki-data'; +const {Album, Flash} = T; + export default { contentDependencies: [ 'generateListingPage', @@ -20,348 +21,303 @@ export default { extraDependencies: ['html', 'language', 'wikiData'], - sprawl({artistData, wikiInfo}) { - return { - artistData, - enableFlashesAndGames: wikiInfo.enableFlashesAndGames, - }; - }, + sprawl: ({albumData, artistData, flashData, trackData, wikiInfo}) => + ({albumData, artistData, flashData, trackData, + enableFlashesAndGames: wikiInfo.enableFlashesAndGames}), query(sprawl, spec) { - const query = { - spec, - enableFlashesAndGames: sprawl.enableFlashesAndGames, - }; - - const queryContributionInfo = ( - artistsKey, - chunkThingsKey, - datesKey, - datelessArtistsKey, - fn, - ) => { - const artists = sortAlphabetically(sprawl.artistData.slice()); - - // Each value stored in dateLists, corresponding to each artist, - // is going to be a list of dates and nulls. Any nulls represent - // a contribution which isn't associated with a particular date. - const [chunkThingLists, dateLists] = - transposeArrays(artists.map(artist => fn(artist))); - - // Scrap artists who don't even have any relevant contributions. - // These artists may still have other contributions across the wiki, but - // they weren't returned by the callback and so aren't relevant to this - // list. - filterMultipleArrays( - artists, - chunkThingLists, - dateLists, - (artists, chunkThings, dates) => !empty(dates)); - - // Also exclude artists whose remaining contributions are all dateless. - // But keep track of the artists removed here, since they'll be displayed - // in an additional list in the final listing page. - const {removed: [datelessArtists]} = - filterMultipleArrays( - artists, - chunkThingLists, - dateLists, - (artist, chunkThings, dates) => !empty(dates.filter(Boolean))); - - // Cut out dateless contributions. They're not relevant to finding the - // latest date. - for (const [chunkThings, dates] of transposeArrays([chunkThingLists, dateLists])) { - filterMultipleArrays(chunkThings, dates, (chunkThing, date) => date); + // + // First main step is to get the latest thing each artist has contributed + // to, and the date associated with that contribution! Some notes: + // + // * Album and track contributions are considered before flashes, so + // they'll take priority if an artist happens to have multiple contribs + // landing on the same date to both an album and a flash. + // + // * The final (album) contribution list is chunked by album, but also by + // date, because an individual album can cover a variety of dates. + // + // * If an artist has contributed both artworks and tracks to the album + // containing their latest contribution, then that will be indicated + // in an annotation, but *only if* those contributions were also on + // the same date. + // + // * If an artist made contributions to multiple albums on the same date, + // then the first of the *albums* sorted chronologically (latest first) + // is the one that will count. + // + // * Same for artists who've contributed to multiple flashes which were + // released on the same date. + // + // * The map may exclude artists none of whose contributions were dated. + // + + const artistLatestContribMap = new Map(); + + const considerDate = (artist, date, thing, contribution) => { + if (!date) { + return; } - const [chunkThings, dates] = - transposeArrays( - transposeArrays([chunkThingLists, dateLists]) - .map(([chunkThings, dates]) => - reduceMultipleArrays( - chunkThings, dates, - (accChunkThing, accDate, chunkThing, date) => - (date && date > accDate - ? [chunkThing, date] - : [accChunkThing, accDate])))); - - sortMultipleArrays(artists, dates, chunkThings, - (artistA, artistB, dateA, dateB, chunkThingA, chunkThingB) => { - const dateComparison = compareDates(dateA, dateB, {latestFirst: true}); - if (dateComparison !== 0) { - return dateComparison; - } - - // TODO: Compare alphabetically, not just by directory. - return compareCaseLessSensitive(chunkThingA.directory, chunkThingB.directory); - }); - - const chunks = - chunkMultipleArrays(artists, dates, chunkThings, - (artist, lastArtist, date, lastDate, chunkThing, lastChunkThing) => - +date !== +lastDate || chunkThing !== lastChunkThing); + if (artistLatestContribMap.has(artist)) { + const latest = artistLatestContribMap.get(artist); + if (latest.date > date) { + return; + } - query[chunkThingsKey] = - chunks.map(([artists, dates, chunkThings]) => chunkThings[0]); - - query[datesKey] = - chunks.map(([artists, dates, chunkThings]) => dates[0]); + if (latest.date === date) { + if (latest.thing === thing) { + // May combine differnt contributions to the same thing and date. + latest.contribution.add(contribution); + } - query[artistsKey] = - chunks.map(([artists, dates, chunkThings]) => artists); + // Earlier-processed things of same date take priority. + return; + } + } - query[datelessArtistsKey] = datelessArtists; + // First entry for artist or more recent contribution than latest date. + artistLatestContribMap.set(artist, { + date, + thing, + contribution: new Set([contribution]), + }); }; - queryContributionInfo( - 'artistsByTrackContributions', - 'albumsByTrackContributions', - 'datesByTrackContributions', - 'datelessArtistsByTrackContributions', - artist => { - const tracks = - [...artist.tracksAsArtist, ...artist.tracksAsContributor] - .filter(track => !track.originalReleaseTrack); - - const albums = tracks.map(track => track.album); - const dates = tracks.map(track => track.date); + const getArtists = (thing, key) => thing[key].map(({who}) => who); - return [albums, dates]; - }); + const albumsLatestFirst = sortAlbumsTracksChronologically(sprawl.albumData.slice()); + const tracksLatestFirst = sortAlbumsTracksChronologically(sprawl.trackData.slice()); + const flashesLatestFirst = sortFlashesChronologically(sprawl.flashData.slice()); - queryContributionInfo( - 'artistsByArtworkContributions', - 'albumsByArtworkContributions', - 'datesByArtworkContributions', - 'datelessArtistsByArtworkContributions', - artist => [ - [ - ...artist.tracksAsCoverArtist.map(track => track.album), - ...artist.albumsAsCoverArtist, - ...artist.albumsAsWallpaperArtist, - ...artist.albumsAsBannerArtist, - ], - [ - // TODO: Per-artwork dates, see #90. - ...artist.tracksAsCoverArtist.map(track => track.coverArtDate), - ...artist.albumsAsCoverArtist.map(album => album.coverArtDate), - ...artist.albumsAsWallpaperArtist.map(album => album.coverArtDate), - ...artist.albumsAsBannerArtist.map(album => album.coverArtDate), - ], - ]); - - if (sprawl.enableFlashesAndGames) { - queryContributionInfo( - 'artistsByFlashContributions', - 'flashesByFlashContributions', - 'datesByFlashContributions', - 'datelessArtistsByFlashContributions', - artist => [ - [ - ...artist.flashesAsContributor, - ], - [ - ...artist.flashesAsContributor.map(flash => flash.date), - ], - ]); + for (const album of albumsLatestFirst) { + for (const artist of new Set([ + ...getArtists(album, 'coverArtistContribs'), + ...getArtists(album, 'wallpaperArtistContribs'), + ...getArtists(album, 'bannerArtistContribs'), + ])) { + // Might combine later with 'track' of the same album and date. + considerDate(artist, album.coverArtDate, album, 'artwork'); + } } - return query; - }, - - relations(relation, query) { - const relations = {}; - - relations.page = - relation('generateListingPage', query.spec); - - // Track contributors - - relations.albumLinksByTrackContributions = - query.albumsByTrackContributions - .map(album => relation('linkAlbum', album)); - - relations.artistLinksByTrackContributions = - query.artistsByTrackContributions - .map(artists => - artists.map(artist => relation('linkArtist', artist))); - - relations.datelessArtistLinksByTrackContributions = - query.datelessArtistsByTrackContributions - .map(artist => relation('linkArtist', artist)); - - // Artwork contributors - - relations.albumLinksByArtworkContributions = - query.albumsByArtworkContributions - .map(album => relation('linkAlbum', album)); + for (const track of tracksLatestFirst) { + for (const artist of getArtists(track, 'coverArtistContribs')) { + // No special effect if artist already has 'artwork' for the same album and date. + considerDate(artist, track.coverArtDate, track.album, 'artwork'); + } - relations.artistLinksByArtworkContributions = - query.artistsByArtworkContributions - .map(artists => - artists.map(artist => relation('linkArtist', artist))); + for (const artist of new Set([ + ...getArtists(track, 'artistContribs'), + ...getArtists(track, 'contributorContribs'), + ])) { + // Might be combining with 'artwork' of the same album and date. + considerDate(artist, track.date, track.album, 'track'); + } + } - relations.datelessArtistLinksByArtworkContributions = - query.datelessArtistsByArtworkContributions - .map(artist => relation('linkArtist', artist)); + for (const flash of flashesLatestFirst) { + for (const artist of getArtists(flash, 'contributorContribs')) { + // Won't take priority above album contributions of the same date. + considerDate(artist, flash.date, flash, 'flash'); + } + } - // Flash contributors + // + // Next up is to sort all the processed artist information! + // + // Entries with the same album/flash and the same date go together first, + // with the following rules for sorting artists therein: + // + // * If the contributions are different, which can only happen for albums, + // then it's tracks-only first, tracks + artworks next, and artworks-only + // last. + // + // * If the contributions are the same, then sort alphabetically. + // + // Entries with different albums/flashes follow another set of rules: + // + // * Later dates come before earlier dates. + // + // * On the same date, albums come before flashes. + // + // * Things of the same type *and* date are sorted alphabetically. + // + + const artistsAlphabetically = + sortAlphabetically(sprawl.artistData.slice()); + + const artists = + Array.from(artistLatestContribMap.keys()); + + const artistContribEntries = + Array.from(artistLatestContribMap.values()); + + const artistThings = + artistContribEntries.map(({thing}) => thing); + + const artistDates = + artistContribEntries.map(({date}) => date); + + const artistContributions = + artistContribEntries.map(({contribution}) => contribution); + + sortMultipleArrays(artistThings, artistDates, artistContributions, artists, + (thing1, thing2, date1, date2, contrib1, contrib2, artist1, artist2) => { + if (date1 === date2 && thing1 === thing2) { + // Move artwork-only contribs after contribs with tracks. + if (!contrib1.has('track') && contrib2.has('track')) return 1; + if (!contrib2.has('track') && contrib1.has('track')) return -1; + + // Move track-only contribs before tracks with tracks and artwork. + if (!contrib1.has('artwork') && contrib2.has('artwork')) return -1; + if (!contrib2.has('artwork') && contrib1.has('artwork')) return 1; + + // Sort artists of the same type of contribution alphabetically, + // referring to a previous sort. + const index1 = artistsAlphabetically.indexOf(artist1); + const index2 = artistsAlphabetically.indexOf(artist2); + return index1 - index2; + } else { + // Move later dates before earlier ones. + if (date1 !== date2) return date2 - date1; + + // Move albums before flashes. + if (thing1 instanceof Album && thing2 instanceof Flash) return -1; + if (thing1 instanceof Flash && thing2 instanceof Album) return 1; + + // Sort two albums or two flashes alphabetically, referring to a + // previous sort (which was chronological but includes the correct + // ordering for things released on the same date). + const thingsLatestFirst = + (thing1 instanceof Album + ? albumsLatestFirst + : flashesLatestFirst); + const index1 = thingsLatestFirst.indexOf(thing1); + const index2 = thingsLatestFirst.indexOf(thing2); + return index2 - index1; + } + }); - if (query.enableFlashesAndGames) { - relations.flashLinksByFlashContributions = - query.flashesByFlashContributions - .map(flash => relation('linkFlash', flash)); + // Last off, turn the flat sorted list into a proper chunked list, now that + // entries going in the same chunk are sorted correctly next to each other. + // Then extract the parts that are useful for displaying on the listing! - relations.artistLinksByFlashContributions = - query.artistsByFlashContributions - .map(artists => - artists.map(artist => relation('linkArtist', artist))); + const chunks = + chunkMultipleArrays(artistThings, artistDates, artistContributions, artists, + (thing, lastThing, date, lastDate) => + thing !== lastThing || + +date !== +lastDate); - relations.datelessArtistLinksByFlashContributions = - query.datelessArtistsByFlashContributions - .map(artist => relation('linkArtist', artist)); - } + const chunkThings = + chunks.map(([artistThings, , , ]) => artistThings[0]); - return relations; - }, + const chunkDates = + chunks.map(([, artistDates, , ]) => artistDates[0]); - data(query) { - const data = {}; + const chunkArtistContributions = + chunks.map(([, , artistContributions, ]) => artistContributions); - data.enableFlashesAndGames = query.enableFlashesAndGames; + const chunkArtists = + chunks.map(([, , , artists]) => artists); - data.datesByTrackContributions = query.datesByTrackContributions; - data.datesByArtworkContributions = query.datesByArtworkContributions; + // And one bonus step - keep track of all the artists whose contributions + // were all without date. - if (query.enableFlashesAndGames) { - data.datesByFlashContributions = query.datesByFlashContributions; - } + const datelessArtists = + artistsAlphabetically + .filter(artist => !artists.includes(artist)); - return data; + return { + spec, + chunkThings, + chunkDates, + chunkArtistContributions, + chunkArtists, + datelessArtists, + }; }, - generate(data, relations, {html, language}) { - const chunkTitles = Object.fromEntries( - ([ - ['tracks', [ - 'album', - relations.albumLinksByTrackContributions, - data.datesByTrackContributions, - ]], - - ['artworks', [ - 'album', - relations.albumLinksByArtworkContributions, - data.datesByArtworkContributions, - ]], - - data.enableFlashesAndGames && - ['flashes', [ - 'flash', - relations.flashLinksByFlashContributions, - data.datesByFlashContributions, - ]], - ]).filter(Boolean) - .map(([key, [stringsKey, links, dates]]) => [ - key, - stitchArrays({link: links, date: dates}) - .map(({link, date}) => - html.tag('dt', - language.$(`listingPage.listArtists.byLatest.chunk.title.${stringsKey}`, { - [stringsKey]: link, - date: language.formatDate(date), - }))), - ])); - - const chunkItems = Object.fromEntries( - ([ - ['tracks', relations.artistLinksByTrackContributions], - ['artworks', relations.artistLinksByArtworkContributions], - data.enableFlashesAndGames && - ['flashes', relations.artistLinksByFlashContributions], - ]).filter(Boolean) - .map(([key, artistLinkLists]) => [ - key, - artistLinkLists.map(artistLinks => - html.tag('dd', - html.tag('ul', - artistLinks.map(artistLink => - html.tag('li', - language.$('listingPage.listArtists.byLatest.chunk.item', { - artist: artistLink, - })))))), - ])); - - const lists = Object.fromEntries( - ([ - ['tracks', [ - chunkTitles.tracks, - chunkItems.tracks, - relations.datelessArtistLinksByTrackContributions, - ]], - - ['artworks', [ - chunkTitles.artworks, - chunkItems.artworks, - relations.datelessArtistLinksByArtworkContributions, - ]], - - data.enableFlashesAndGames && - ['flashes', [ - chunkTitles.flashes, - chunkItems.flashes, - relations.datelessArtistLinksByFlashContributions, - ]], - ]).filter(Boolean) - .map(([key, [titles, items, datelessArtistLinks]]) => [ - key, - html.tags([ - html.tag('dl', - stitchArrays({ - title: titles, - items: items, - }).map(({title, items}) => [title, items])), - - !empty(datelessArtistLinks) && [ - html.tag('p', - language.$('listingPage.listArtists.byLatest.dateless.title')), - - html.tag('ul', - datelessArtistLinks.map(artistLink => - html.tag('li', - language.$('listingPage.listArtists.byLatest.dateless.item', { - artist: artistLink, - })))), - ], - ]), - ])); - + relations: (relation, query) => ({ + page: + relation('generateListingPage', query.spec), + + chunkAlbumLinks: + query.chunkThings + .map(thing => + (thing instanceof Album + ? relation('linkAlbum', thing) + : null)), + + chunkFlashLinks: + query.chunkThings + .map(thing => + (thing instanceof Flash + ? relation('linkFlash', thing) + : null)), + + chunkArtistLinks: + query.chunkArtists + .map(artists => artists + .map(artist => relation('linkArtist', artist))), + + datelessArtistLinks: + query.datelessArtists + .map(artist => relation('linkArtist', artist)), + }), + + data: (query) => ({ + chunkDates: query.chunkDates, + chunkArtistContributions: query.chunkArtistContributions, + }), + + generate(data, relations, {language}) { return relations.page.slots({ - type: 'custom', - content: - html.tag('div', {class: 'content-columns'}, [ - html.tag('div', {class: 'column'}, [ - html.tag('h2', - language.$('listingPage.misc.trackContributors')), - - lists.tracks, - ]), - - html.tag('div', {class: 'column'}, [ - html.tag('h2', - language.$( - 'listingPage.misc.artContributors')), - - lists.artworks, - - lists.flashes && [ - html.tag('h2', - language.$('listingPage.misc.flashContributors')), - - lists.flashes, - ], - ]), - ]), + type: 'chunks', + + chunkTitles: + stitchArrays({ + albumLink: relations.chunkAlbumLinks, + flashLink: relations.chunkFlashLinks, + date: data.chunkDates, + }).map(({albumLink, flashLink, date}) => ({ + date: language.formatDate(date), + ...(albumLink + ? {stringsKey: 'album', album: albumLink} + : {stringsKey: 'flash', flash: flashLink}), + })) + .concat( + (empty(relations.datelessArtistLinks) + ? [] + : [{stringsKey: 'dateless'}])), + + chunkRows: + stitchArrays({ + artistLinks: relations.chunkArtistLinks, + contributions: data.chunkArtistContributions, + }).map(({artistLinks, contributions}) => + stitchArrays({ + artistLink: artistLinks, + contribution: contributions, + }).map(({artistLink, contribution}) => ({ + artist: artistLink, + stringsKey: + (contribution.has('track') && contribution.has('artwork') + ? 'tracksAndArt' + : contribution.has('track') + ? 'tracks' + : contribution.has('artwork') + ? 'art' + : null), + }))) + .concat( + (empty(relations.datelessArtistLinks) + ? [] + : [ + relations.datelessArtistLinks.map(artistLink => ({ + artist: artistLink, + })), + ])), }); }, }; -- cgit 1.3.0-6-gf8a5 From c4ef4ced62d659d217873c6c48dd8038dbf765af Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 31 Aug 2023 10:49:03 -0300 Subject: content: generateListingPage: show custom content above auto content This is towards enabling custom controls and/or accents on listings which are otherwise represented by rows or chunks. --- src/content/dependencies/generateListingPage.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 3c50bd59..f527f16f 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -129,6 +129,8 @@ export default { listings: language.formatUnitList(relations.seeAlsoLinks), })), + slots.content, + slots.type === 'rows' && html.tag(listTag, slots.rows.map(row => @@ -180,9 +182,6 @@ export default { formatListingString('chunk.item', row))))), ]), ]), - - slots.type === 'custom' && - slots.content, ], navLinkStyle: 'hierarchical', -- cgit 1.3.0-6-gf8a5 From c59545f5faafc826ff24ff779c20318ef14ae123 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 29 Oct 2023 09:27:23 -0300 Subject: content, client: generalize "random pages" listing to wiki dividing groups --- .../generateListRandomPageLinksGroupSection.js | 9 +++---- src/content/dependencies/listRandomPageLinks.js | 28 +++++++--------------- 2 files changed, 12 insertions(+), 25 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListRandomPageLinksGroupSection.js b/src/content/dependencies/generateListRandomPageLinksGroupSection.js index 2a684b19..74872724 100644 --- a/src/content/dependencies/generateListRandomPageLinksGroupSection.js +++ b/src/content/dependencies/generateListRandomPageLinksGroupSection.js @@ -23,10 +23,7 @@ export default { .map(() => relation('generateColorStyleVariables')), }), - data: (query, sprawl, group) => ({ - groupDirectory: - group.directory, - + data: (query) => ({ albumColors: query.albums .map(album => album.color), @@ -48,12 +45,12 @@ export default { randomAlbum: html.tag('a', - {href: '#', 'data-random': 'album-in-' + data.groupDirectory}, + {href: '#', 'data-random': 'album-in-group-dl'}, language.$('listingPage.other.randomPages.group.randomAlbum')), randomTrack: html.tag('a', - {href: '#', 'data-random': 'track-in-' + data.groupDirectory}, + {href: '#', 'data-random': 'track-in-group-dl'}, language.$('listingPage.other.randomPages.group.randomTrack')), })), diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 43bf7dd5..57ecb044 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -6,19 +6,16 @@ export default { extraDependencies: ['html', 'language', 'wikiData'], - sprawl({groupData}) { - return {groupData}; + sprawl({wikiInfo}) { + return {wikiInfo}; }, query(sprawl, spec) { - const group = directory => - sprawl.groupData.find(group => group.directory === directory); - return { spec, - officialGroup: group('official'), - fandomGroup: group('fandom'), - beyondGroup: group('beyond'), + + groups: + sprawl.wikiInfo.divideTrackListsByGroups, }; }, @@ -26,14 +23,9 @@ export default { return { page: relation('generateListingPage', query.spec), - officialSection: - relation('generateListRandomPageLinksGroupSection', query.officialGroup), - - fandomSection: - relation('generateListRandomPageLinksGroupSection', query.fandomGroup), - - beyondSection: - relation('generateListRandomPageLinksGroupSection', query.beyondGroup), + groupSections: + query.groups + .map(group => relation('generateListRandomPageLinksGroupSection', group)), }; }, @@ -81,9 +73,7 @@ export default { language.$('listingPage.other.randomPages.misc.randomTrackWholeSite'))), ])), - relations.officialSection, - relations.fandomSection, - relations.beyondSection, + relations.groupSections, ]), ], }); -- cgit 1.3.0-6-gf8a5 From 777fbd3535f80fb8fb28d80a5dc53efe44c6cb82 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 29 Oct 2023 09:49:56 -0300 Subject: content: linkTemplate: append provided style to own style --- src/content/dependencies/linkTemplate.js | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/linkTemplate.js b/src/content/dependencies/linkTemplate.js index d9af726c..a361a4e7 100644 --- a/src/content/dependencies/linkTemplate.js +++ b/src/content/dependencies/linkTemplate.js @@ -64,6 +64,14 @@ export default { style = `--primary-color: ${primary}; --dim-color: ${dim}`; } + if (slots.attributes?.style) { + if (style) { + style += '; ' + slots.attributes.style; + } else { + style = slots.attributes.style; + } + } + if (slots.tooltip) { title = slots.tooltip; } -- cgit 1.3.0-6-gf8a5 From d2903c800b6a005a447cc26f9431fe5fe4fb08b6 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 29 Oct 2023 09:51:01 -0300 Subject: content: adapt "random pages" to wikis without dividing groups --- .../generateListRandomPageLinksAlbumLink.js | 18 +++++++++ .../generateListRandomPageLinksAllAlbumsSection.js | 35 ++++++++++++++++ .../generateListRandomPageLinksGroupSection.js | 47 +++++----------------- src/content/dependencies/listRandomPageLinks.js | 40 +++++++++--------- 4 files changed, 85 insertions(+), 55 deletions(-) create mode 100644 src/content/dependencies/generateListRandomPageLinksAlbumLink.js create mode 100644 src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListRandomPageLinksAlbumLink.js b/src/content/dependencies/generateListRandomPageLinksAlbumLink.js new file mode 100644 index 00000000..b3560aca --- /dev/null +++ b/src/content/dependencies/generateListRandomPageLinksAlbumLink.js @@ -0,0 +1,18 @@ +export default { + contentDependencies: ['linkAlbum'], + + data: (album) => + ({directory: album.directory}), + + relations: (relation, album) => + ({albumLink: relation('linkAlbum', album)}), + + generate: (data, relations) => + relations.albumLink.slots({ + anchor: true, + attributes: { + 'data-random': 'track-in-album', + 'style': `--album-directory: ${data.directory}`, + }, + }), +}; diff --git a/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js b/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js new file mode 100644 index 00000000..e03252c9 --- /dev/null +++ b/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js @@ -0,0 +1,35 @@ +import {sortChronologically} from '#wiki-data'; + +export default { + contentDependencies: ['generateListRandomPageLinksAlbumLink', 'linkGroup'], + extraDependencies: ['html', 'language', 'wikiData'], + + sprawl: ({albumData}) => ({albumData}), + + query: (sprawl) => ({ + albums: + sortChronologically(sprawl.albumData.slice()) + .filter(album => album.tracks.length > 1), + }), + + relations: (relation, query) => ({ + albumLinks: + query.albums + .map(album => relation('generateListRandomPageLinksAlbumLink', album)), + }), + + generate: (relations, {html, language}) => + html.tags([ + html.tag('dt', + language.$('listingPage.other.randomPages.fromAlbum')), + + html.tag('dd', + html.tag('ul', + relations.albumLinks + .map(albumLink => + html.tag('li', + language.$('listingPage.other.randomPages.album', { + album: albumLink, + }))))), + ]), +}; diff --git a/src/content/dependencies/generateListRandomPageLinksGroupSection.js b/src/content/dependencies/generateListRandomPageLinksGroupSection.js index 74872724..d05be8f7 100644 --- a/src/content/dependencies/generateListRandomPageLinksGroupSection.js +++ b/src/content/dependencies/generateListRandomPageLinksGroupSection.js @@ -1,8 +1,7 @@ -import {stitchArrays} from '#sugar'; import {sortChronologically} from '#wiki-data'; export default { - contentDependencies: ['generateColorStyleVariables', 'linkGroup'], + contentDependencies: ['generateListRandomPageLinksAlbumLink', 'linkGroup'], extraDependencies: ['html', 'language', 'wikiData'], sprawl: ({albumData}) => ({albumData}), @@ -18,61 +17,35 @@ export default { groupLink: relation('linkGroup', group), - albumColorVariables: + albumLinks: query.albums - .map(() => relation('generateColorStyleVariables')), + .map(album => relation('generateListRandomPageLinksAlbumLink', album)), }), - data: (query) => ({ - albumColors: - query.albums - .map(album => album.color), - - albumDirectories: - query.albums - .map(album => album.directory), - - albumNames: - query.albums - .map(album => album.name), - }), - - generate: (data, relations, {html, language}) => + generate: (relations, {html, language}) => html.tags([ html.tag('dt', - language.$('listingPage.other.randomPages.group', { + language.$('listingPage.other.randomPages.fromGroup', { group: relations.groupLink, randomAlbum: html.tag('a', {href: '#', 'data-random': 'album-in-group-dl'}, - language.$('listingPage.other.randomPages.group.randomAlbum')), + language.$('listingPage.other.randomPages.fromGroup.randomAlbum')), randomTrack: html.tag('a', {href: '#', 'data-random': 'track-in-group-dl'}, - language.$('listingPage.other.randomPages.group.randomTrack')), + language.$('listingPage.other.randomPages.fromGroup.randomTrack')), })), html.tag('dd', html.tag('ul', - stitchArrays({ - colorVariables: relations.albumColorVariables, - color: data.albumColors, - directory: data.albumDirectories, - name: data.albumNames, - }).map(({colorVariables, color, directory, name}) => + relations.albumLinks + .map(albumLink => html.tag('li', language.$('listingPage.other.randomPages.album', { - album: - html.tag('a', { - href: '#', - 'data-random': 'track-in-album', - style: - colorVariables.slot('color', color).content + - '; ' + - `--album-directory: ${directory}`, - }, name), + album: albumLink, }))))), ]), }; diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 57ecb044..ce90a153 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -1,33 +1,36 @@ +import {empty} from '#sugar'; + export default { contentDependencies: [ 'generateListingPage', + 'generateListRandomPageLinksAllAlbumsSection', 'generateListRandomPageLinksGroupSection', ], extraDependencies: ['html', 'language', 'wikiData'], - sprawl({wikiInfo}) { - return {wikiInfo}; - }, + sprawl: ({wikiInfo}) => ({wikiInfo}), - query(sprawl, spec) { - return { - spec, + query: ({wikiInfo: {divideTrackListsByGroups: groups}}, spec) => ({ + spec, + groups, + divideByGroups: !empty(groups), + }), - groups: - sprawl.wikiInfo.divideTrackListsByGroups, - }; - }, + relations: (relation, query) => ({ + page: relation('generateListingPage', query.spec), - relations(relation, query) { - return { - page: relation('generateListingPage', query.spec), + allAlbumsSection: + (query.divideByGroups + ? null + : relation('generateListRandomPageLinksAllAlbumsSection')), - groupSections: - query.groups - .map(group => relation('generateListRandomPageLinksGroupSection', group)), - }; - }, + groupSections: + (query.divideByGroups + ? query.groups + .map(group => relation('generateListRandomPageLinksGroupSection', group)) + : null), + }), generate(relations, {html, language}) { return relations.page.slots({ @@ -73,6 +76,7 @@ export default { language.$('listingPage.other.randomPages.misc.randomTrackWholeSite'))), ])), + relations.allAlbumsSection, relations.groupSections, ]), ], -- cgit 1.3.0-6-gf8a5 From e71230340181a3b7b38ff05ba23504b264f5b26c Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 29 Oct 2023 10:00:52 -0300 Subject: content: listRandomPageLinks: update chooseLinkLine wording --- src/content/dependencies/listRandomPageLinks.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index ce90a153..599a82d3 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -37,7 +37,15 @@ export default { type: 'custom', content: [ html.tag('p', - language.$('listingPage.other.randomPages.chooseLinkLine')), + language.$('listingPage.other.randomPages.chooseLinkLine', { + fromPart: + (empty(relations.groupSections) + ? language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.notDividedByGroups') + : language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.dividedByGroups')), + + browserSupportPart: + language.$('listingPage.other.randomPages.chooseLinkLine.browserSupportPart'), + })), html.tag('p', {class: 'js-hide-once-data'}, -- cgit 1.3.0-6-gf8a5 From 9bf4b59f608022ab0ca2cadc4acff7bb6760ebd2 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 8 Nov 2023 19:54:01 -0400 Subject: content, repl: minor fixes and tweaks --- src/content/dependencies/generatePageLayout.js | 3 ++- src/content/dependencies/linkExternal.js | 25 ++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index cd831ba7..72dfbae5 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -449,7 +449,8 @@ export default { {[html.onlyIfContent]: true, class: 'skipper-list'}, processSkippers([ {id: 'tracks', string: 'tracks'}, - {id: 'art', string: 'flashes'}, + {id: 'art', string: 'artworks'}, + {id: 'flashes', string: 'flashes'}, {id: 'contributors', string: 'contributors'}, {id: 'references', string: 'references'}, {id: 'referenced-by', string: 'referencedBy'}, diff --git a/src/content/dependencies/linkExternal.js b/src/content/dependencies/linkExternal.js index 73c656e3..5de612e2 100644 --- a/src/content/dependencies/linkExternal.js +++ b/src/content/dependencies/linkExternal.js @@ -3,10 +3,20 @@ const BANDCAMP_DOMAINS = ['bc.s3m.us', 'music.solatrux.com']; const MASTODON_DOMAINS = ['types.pl']; export default { - extraDependencies: ['html', 'language'], + extraDependencies: ['html', 'language', 'wikiData'], - data(url) { - return {url}; + sprawl: ({wikiInfo}) => ({wikiInfo}), + + data(sprawl, url) { + const data = {url}; + + const {canonicalBase} = sprawl.wikiInfo; + if (canonicalBase) { + const {hostname: canonicalDomain} = new URL(canonicalBase); + Object.assign(data, {canonicalDomain}); + } + + return data; }, slots: { @@ -20,6 +30,7 @@ export default { let isLocal; let domain; let pathname; + try { const url = new URL(data.url); domain = url.hostname; @@ -28,6 +39,14 @@ export default { // No support for relative local URLs yet, sorry! (I.e, local URLs must // be absolute relative to the domain name in order to work.) isLocal = true; + domain = null; + pathname = null; + } + + // isLocal also applies for URLs which match the 'Canonical Base' under + // wiki-info.yaml, if present. + if (data.canonicalDomain && domain === data.canonicalDomain) { + isLocal = true; } const link = html.tag('a', -- cgit 1.3.0-6-gf8a5 From 150c414044662134ddf785e7411560e3a6051a03 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 14:50:13 -0400 Subject: content: listRandomPageLinks: don't hard-code parentheses --- src/content/dependencies/listRandomPageLinks.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 599a82d3..87e5f5aa 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -61,17 +61,18 @@ export default { html.tag('dd', html.tag('ul', [ - html.tag('li', [ - html.tag('a', - {href: '#', 'data-random': 'artist'}, - language.$('listingPage.other.randomPages.misc.randomArtist')), - - '(' + - html.tag('a', - {href: '#', 'data-random': 'artist-more-than-one-contrib'}, - language.$('listingPage.other.randomPages.misc.atLeastTwoContributions')) + - ')', - ]), + html.tag('li', + language.$('listingPage.other.randomPages.misc.randomArtist', { + mainLink: + html.tag('a', + {href: '#', 'data-random': 'artist'}, + language.$('listingPage.other.randomPages.misc.randomArtist.mainLink')), + + atLeastTwoContributions: + html.tag('a', + {href: '#', 'data-random': 'artist-more-than-one-contrib'}, + language.$('listingPage.other.randomPages.misc.randomArtist.atLeastTwoContributions')), + })), html.tag('li', html.tag('a', -- cgit 1.3.0-6-gf8a5 From 443c2e42ad2731e63f40c9575e2c27001ed55bae Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 15:48:36 -0400 Subject: content: generateListingPage: add chunkRowAttributes slot This refactors out the hard-coded 'rerelease' behavior. --- src/content/dependencies/generateListingPage.js | 24 ++++++++++++++++++------ src/content/dependencies/listTracksByDate.js | 9 ++++++++- 2 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 45b7dc1b..403f891f 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -68,6 +68,7 @@ export default { chunkTitles: {validate: v => v.strictArrayOf(v.isObject)}, chunkRows: {validate: v => v.strictArrayOf(v.isObject)}, + chunkRowAttributes: {validate: v => v.strictArrayOf(v.optional(v.isObject))}, showSkipToSection: {type: 'boolean', default: false}, chunkIDs: {validate: v => v.strictArrayOf(v.isString)}, @@ -165,9 +166,17 @@ export default { stitchArrays({ title: slots.chunkTitles, - rows: slots.chunkRows, id: slots.chunkIDs, - }).map(({title, rows, id}) => [ + + rows: slots.chunkRows, + rowAttributes: slots.chunkRowAttributes, + }).map(({ + title, + id, + + rows, + rowAttributes, + }) => [ relations.chunkHeading .clone() .slots({ @@ -178,10 +187,13 @@ export default { html.tag('dd', html.tag(listTag, - rows.map(row => - html.tag('li', - {class: row.stringsKey === 'rerelease' && 'rerelease'}, - formatListingString('chunk.item', row))))), + stitchArrays({ + row: rows, + attributes: rowAttributes ?? rows.map(() => null), + }).map(({row, attributes}) => + html.tag('li', + attributes, + formatListingString('chunk.item', row))))), ]), ]), ], diff --git a/src/content/dependencies/listTracksByDate.js b/src/content/dependencies/listTracksByDate.js index d6546e67..25beb739 100644 --- a/src/content/dependencies/listTracksByDate.js +++ b/src/content/dependencies/listTracksByDate.js @@ -71,8 +71,15 @@ export default { rerelease: rereleases, }).map(({trackLink, rerelease}) => (rerelease - ? {track: trackLink, stringsKey: 'rerelease'} + ? {stringsKey: 'rerelease', track: trackLink} : {track: trackLink}))), + + chunkRowAttributes: + data.rereleases.map(rereleases => + rereleases.map(rerelease => + (rerelease + ? {class: 'rerelease'} + : null))), }); }, }; -- cgit 1.3.0-6-gf8a5 From 44cebe7bfaf8f69ff6806e98524d3b5955f2cef2 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 15:49:31 -0400 Subject: content: generateListingPage: specially handle 'href' row attribute But not that specially. --- src/content/dependencies/generateListingPage.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 403f891f..4c86431d 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -191,9 +191,14 @@ export default { row: rows, attributes: rowAttributes ?? rows.map(() => null), }).map(({row, attributes}) => - html.tag('li', - attributes, - formatListingString('chunk.item', row))))), + (attributes?.href + ? html.tag('li', + html.tag('a', + attributes, + formatListingString('chunk.item', row))) + : html.tag('li', + attributes, + formatListingString('chunk.item', row)))))), ]), ]), ], -- cgit 1.3.0-6-gf8a5 From 2a7c3b90a8d66cea9b0f041a33f4c145628587eb Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 15:58:50 -0400 Subject: content: generateListingPage: code cleanup, add rowAttributes slot --- src/content/dependencies/generateListingPage.js | 90 +++++++++++++++---------- 1 file changed, 53 insertions(+), 37 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 4c86431d..3878d0eb 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -62,16 +62,38 @@ export default { }, slots: { - type: {validate: v => v.is('rows', 'chunks', 'custom')}, + type: { + validate: v => v.is('rows', 'chunks', 'custom'), + }, + + rows: { + validate: v => v.strictArrayOf(v.isObject), + }, + + rowAttributes: { + validate: v => v.strictArrayOf(v.optional(v.isObject)) + }, + + chunkTitles: { + validate: v => v.strictArrayOf(v.isObject), + }, + + chunkRows: { + validate: v => v.strictArrayOf(v.isObject), + }, - rows: {validate: v => v.strictArrayOf(v.isObject)}, + chunkRowAttributes: { + validate: v => v.strictArrayOf(v.optional(v.isObject)), + }, - chunkTitles: {validate: v => v.strictArrayOf(v.isObject)}, - chunkRows: {validate: v => v.strictArrayOf(v.isObject)}, - chunkRowAttributes: {validate: v => v.strictArrayOf(v.optional(v.isObject))}, + showSkipToSection: { + type: 'boolean', + default: false, + }, - showSkipToSection: {type: 'boolean', default: false}, - chunkIDs: {validate: v => v.strictArrayOf(v.isString)}, + chunkIDs: { + validate: v => v.strictArrayOf(v.isString), + }, listStyle: { validate: v => v.is('ordered', 'unordered'), @@ -82,11 +104,6 @@ export default { }, generate(data, relations, slots, {html, language}) { - const listTag = - (slots.listStyle === 'ordered' - ? 'ol' - : 'ul'); - const formatListingString = (contextStringsKey, options = {}) => { const baseStringsKey = `listingPage.${data.stringsKey}`; @@ -101,6 +118,24 @@ export default { return language.formatString(parts.join('.'), passOptions); }; + const formatRow = ({row, attributes}) => + (attributes?.href + ? html.tag('li', + html.tag('a', + attributes, + formatListingString('chunk.item', row))) + : html.tag('li', + attributes, + formatListingString('chunk.item', row))); + + const formatRowList = ({rows, rowAttributes}) => + html.tag( + (slots.listStyle === 'ordered' ? 'ol' : 'ul'), + stitchArrays({ + row: rows, + attributes: rowAttributes ?? rows.map(() => null), + }).map(formatRow)); + return relations.layout.slots({ title: formatListingString('title'), headingMode: 'sticky', @@ -133,10 +168,10 @@ export default { slots.content, slots.type === 'rows' && - html.tag(listTag, - slots.rows.map(row => - html.tag('li', - formatListingString('item', row)))), + formatRowList({ + rows: slots.rows, + rowAttributes: slots.rowAttributes, + }), slots.type === 'chunks' && html.tag('dl', [ @@ -167,16 +202,9 @@ export default { stitchArrays({ title: slots.chunkTitles, id: slots.chunkIDs, - rows: slots.chunkRows, rowAttributes: slots.chunkRowAttributes, - }).map(({ - title, - id, - - rows, - rowAttributes, - }) => [ + }).map(({title, id, rows, rowAttributes}) => [ relations.chunkHeading .clone() .slots({ @@ -186,19 +214,7 @@ export default { }), html.tag('dd', - html.tag(listTag, - stitchArrays({ - row: rows, - attributes: rowAttributes ?? rows.map(() => null), - }).map(({row, attributes}) => - (attributes?.href - ? html.tag('li', - html.tag('a', - attributes, - formatListingString('chunk.item', row))) - : html.tag('li', - attributes, - formatListingString('chunk.item', row)))))), + formatRowList({rows, rowAttributes})), ]), ]), ], -- cgit 1.3.0-6-gf8a5 From 7166db580d57504b5ec42d9d07078ea24f0b1149 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 16:01:05 -0400 Subject: content: listRandomPageLinks: port to chunks layout --- .../generateListRandomPageLinksAllAlbumsSection.js | 35 ---- .../generateListRandomPageLinksGroupSection.js | 51 ------ src/content/dependencies/listRandomPageLinks.js | 181 ++++++++++++++------- 3 files changed, 125 insertions(+), 142 deletions(-) delete mode 100644 src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js delete mode 100644 src/content/dependencies/generateListRandomPageLinksGroupSection.js (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js b/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js deleted file mode 100644 index e03252c9..00000000 --- a/src/content/dependencies/generateListRandomPageLinksAllAlbumsSection.js +++ /dev/null @@ -1,35 +0,0 @@ -import {sortChronologically} from '#wiki-data'; - -export default { - contentDependencies: ['generateListRandomPageLinksAlbumLink', 'linkGroup'], - extraDependencies: ['html', 'language', 'wikiData'], - - sprawl: ({albumData}) => ({albumData}), - - query: (sprawl) => ({ - albums: - sortChronologically(sprawl.albumData.slice()) - .filter(album => album.tracks.length > 1), - }), - - relations: (relation, query) => ({ - albumLinks: - query.albums - .map(album => relation('generateListRandomPageLinksAlbumLink', album)), - }), - - generate: (relations, {html, language}) => - html.tags([ - html.tag('dt', - language.$('listingPage.other.randomPages.fromAlbum')), - - html.tag('dd', - html.tag('ul', - relations.albumLinks - .map(albumLink => - html.tag('li', - language.$('listingPage.other.randomPages.album', { - album: albumLink, - }))))), - ]), -}; diff --git a/src/content/dependencies/generateListRandomPageLinksGroupSection.js b/src/content/dependencies/generateListRandomPageLinksGroupSection.js deleted file mode 100644 index d05be8f7..00000000 --- a/src/content/dependencies/generateListRandomPageLinksGroupSection.js +++ /dev/null @@ -1,51 +0,0 @@ -import {sortChronologically} from '#wiki-data'; - -export default { - contentDependencies: ['generateListRandomPageLinksAlbumLink', 'linkGroup'], - extraDependencies: ['html', 'language', 'wikiData'], - - sprawl: ({albumData}) => ({albumData}), - - query: (sprawl, group) => ({ - albums: - sortChronologically(sprawl.albumData.slice()) - .filter(album => album.groups.includes(group)) - .filter(album => album.tracks.length > 1), - }), - - relations: (relation, query, sprawl, group) => ({ - groupLink: - relation('linkGroup', group), - - albumLinks: - query.albums - .map(album => relation('generateListRandomPageLinksAlbumLink', album)), - }), - - generate: (relations, {html, language}) => - html.tags([ - html.tag('dt', - language.$('listingPage.other.randomPages.fromGroup', { - group: relations.groupLink, - - randomAlbum: - html.tag('a', - {href: '#', 'data-random': 'album-in-group-dl'}, - language.$('listingPage.other.randomPages.fromGroup.randomAlbum')), - - randomTrack: - html.tag('a', - {href: '#', 'data-random': 'track-in-group-dl'}, - language.$('listingPage.other.randomPages.fromGroup.randomTrack')), - })), - - html.tag('dd', - html.tag('ul', - relations.albumLinks - .map(albumLink => - html.tag('li', - language.$('listingPage.other.randomPages.album', { - album: albumLink, - }))))), - ]), -}; diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 87e5f5aa..5e74b4ac 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -1,47 +1,102 @@ import {empty} from '#sugar'; +import {sortChronologically} from '#wiki-data'; export default { contentDependencies: [ 'generateListingPage', - 'generateListRandomPageLinksAllAlbumsSection', - 'generateListRandomPageLinksGroupSection', + 'generateListRandomPageLinksAlbumLink', + 'linkGroup', ], extraDependencies: ['html', 'language', 'wikiData'], sprawl: ({wikiInfo}) => ({wikiInfo}), - query: ({wikiInfo: {divideTrackListsByGroups: groups}}, spec) => ({ - spec, - groups, - divideByGroups: !empty(groups), - }), + query(sprawl, spec) { + const query = {spec}; - relations: (relation, query) => ({ - page: relation('generateListingPage', query.spec), + const groups = sprawl.wikiInfo.divideTrackListsByGroups; - allAlbumsSection: - (query.divideByGroups - ? null - : relation('generateListRandomPageLinksAllAlbumsSection')), + query.divideByGroups = !empty(groups); - groupSections: - (query.divideByGroups - ? query.groups - .map(group => relation('generateListRandomPageLinksGroupSection', group)) - : null), - }), + if (query.divideByGroups) { + query.groups = groups; + + query.groupAlbums = + groups + .map(group => + group.albums.filter(album => album.tracks.length > 1)); + } else { + query.undividedAlbums = + sortChronologically(sprawl.albumData.slice()) + .filter(album => album.tracks.length > 1); + } + + return query; + }, + + relations(relation, query) { + const relations = {}; + + relations.page = + relation('generateListingPage', query.spec); + + if (query.divideByGroups) { + relations.groupLinks = + query.groups + .map(group => relation('linkGroup', group)); + + relations.groupAlbumLinks = + query.groupAlbums + .map(albums => albums + .map(album => + relation('generateListRandomPageLinksAlbumLink', album))); + } else { + relations.undividedAlbumLinks = + query.undividedAlbums + .map(album => + relation('generateListRandomPageLinksAlbumLink', album)); + } + + return relations; + }, generate(relations, {html, language}) { + const miscellaneousChunkRows = [ + { + stringsKey: 'randomArtist', + + mainLink: + html.tag('a', + {href: '#', 'data-random': 'artist'}, + language.$('listingPage.other.randomPages.chunk.item.randomArtist.mainLink')), + + atLeastTwoContributions: + html.tag('a', + {href: '#', 'data-random': 'artist-more-than-one-contrib'}, + language.$('listingPage.other.randomPages.chunk.item.randomArtist.atLeastTwoContributions')), + }, + + {stringsKey: 'randomAlbumWholeSite'}, + {stringsKey: 'randomTrackWholeSite'}, + ]; + + const miscellaneousChunkRowAttributes = [ + null, + {href: '#', 'data-random': 'album'}, + {href: '#','data-random': 'track'}, + ]; + return relations.page.slots({ - type: 'custom', + type: 'chunks', + content: [ html.tag('p', language.$('listingPage.other.randomPages.chooseLinkLine', { fromPart: - (empty(relations.groupSections) - ? language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.notDividedByGroups') - : language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.dividedByGroups')), + (relations.groupLinks + ? language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.dividedByGroups') + : language.$('listingPage.other.randomPages.chooseLinkLine.fromPart.notDividedByGroups')), browserSupportPart: language.$('listingPage.other.randomPages.chooseLinkLine.browserSupportPart'), @@ -54,40 +109,54 @@ export default { html.tag('p', {class: 'js-show-once-data'}, language.$('listingPage.other.randomPages.dataLoadedLine')), + ], + + chunkTitles: [ + {stringsKey: 'misc'}, + + ... + (relations.groupLinks + ? relations.groupLinks.map(groupLink => ({ + stringsKey: 'fromGroup', + + group: groupLink, + + randomAlbum: + html.tag('a', + {href: '#', 'data-random': 'album-in-group-dl'}, + language.$('listingPage.other.randomPages.chunk.title.fromGroup.randomAlbum')), + + randomTrack: + html.tag('a', + {href: '#', 'data-random': 'track-in-group-dl'}, + language.$('listingPage.other.randomPages.chunk.title.fromGroup.randomTrack')), + })) + : [{stringsKey: 'fromAlbum'}]), + ], + + chunkRows: [ + miscellaneousChunkRows, + + ... + (relations.groupAlbumLinks + ? relations.groupAlbumLinks.map(albumLinks => + albumLinks.map(albumLink => ({ + stringsKey: 'album', + album: albumLink, + }))) + : relations.albumLinks.map(albumLink => ({ + stringsKey: 'album', + album: albumLink, + }))), + ], - html.tag('dl', [ - html.tag('dt', - language.$('listingPage.other.randomPages.misc')), - - html.tag('dd', - html.tag('ul', [ - html.tag('li', - language.$('listingPage.other.randomPages.misc.randomArtist', { - mainLink: - html.tag('a', - {href: '#', 'data-random': 'artist'}, - language.$('listingPage.other.randomPages.misc.randomArtist.mainLink')), - - atLeastTwoContributions: - html.tag('a', - {href: '#', 'data-random': 'artist-more-than-one-contrib'}, - language.$('listingPage.other.randomPages.misc.randomArtist.atLeastTwoContributions')), - })), - - html.tag('li', - html.tag('a', - {href: '#', 'data-random': 'album'}, - language.$('listingPage.other.randomPages.misc.randomAlbumWholeSite'))), - - html.tag('li', - html.tag('a', - {href: '#', 'data-random': 'track'}, - language.$('listingPage.other.randomPages.misc.randomTrackWholeSite'))), - ])), - - relations.allAlbumsSection, - relations.groupSections, - ]), + chunkRowAttributes: [ + miscellaneousChunkRowAttributes, + ... + (relations.groupAlbumLinks + ? relations.groupAlbumLinks.map(albumLinks => + albumLinks.map(() => null)) + : [relations.albumLinks.map(() => null)]), ], }); }, -- cgit 1.3.0-6-gf8a5 From b8e612f9723ef1b890a1af8745e3f165220ce9d1 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Tue, 7 Nov 2023 20:31:57 -0400 Subject: content, client, css: accents in content headings --- src/content/dependencies/generateContentHeading.js | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateContentHeading.js b/src/content/dependencies/generateContentHeading.js index ccaf1076..56f68cb3 100644 --- a/src/content/dependencies/generateContentHeading.js +++ b/src/content/dependencies/generateContentHeading.js @@ -1,19 +1,39 @@ export default { extraDependencies: ['html'], + contentDependencies: ['generateColorStyleVariables'], + + relations: (relation) => ({ + colorVariables: relation('generateColorStyleVariables'), + }), slots: { title: {type: 'html'}, + accent: {type: 'html'}, + + color: {validate: v => v.isColor}, + id: {type: 'string'}, tag: {type: 'string', default: 'p'}, }, - generate(slots, {html}) { + generate(relations, slots, {html}) { return html.tag(slots.tag, { class: 'content-heading', id: slots.id, tabindex: '0', - }, - slots.title); + + style: + slots.color && + relations.colorVariables + .slot('color', slots.color) + .content, + }, [ + slots.title, + + html.tag('span', + {[html.onlyIfContent]: true, class: 'content-heading-accent'}, + slots.accent), + ]); } } -- cgit 1.3.0-6-gf8a5 From 869548723002ebf2f3a501c4105cdf6db7ac8aa7 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 16:33:20 -0400 Subject: content: generateListingPage: formatListingString cleanup --- src/content/dependencies/generateListingPage.js | 54 +++++++++++++++++-------- 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 3878d0eb..6eee45b8 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -104,29 +104,43 @@ export default { }, generate(data, relations, slots, {html, language}) { - const formatListingString = (contextStringsKey, options = {}) => { - const baseStringsKey = `listingPage.${data.stringsKey}`; - - const parts = [baseStringsKey, contextStringsKey]; - - const {stringsKey, ...passOptions} = options; + function formatListingString({ + context, + provided = {}, + }) { + const parts = ['listingPage', data.stringsKey]; + + if (Array.isArray(context)) { + parts.push(...context); + } else { + parts.push(context); + } - if (stringsKey) { - parts.push(options.stringsKey); + if (provided.stringsKey) { + parts.push(provided.stringsKey); } - return language.formatString(parts.join('.'), passOptions); - }; + const options = {...provided}; + delete options.stringsKey; + + return language.formatString(...parts, options); + } const formatRow = ({row, attributes}) => (attributes?.href ? html.tag('li', html.tag('a', attributes, - formatListingString('chunk.item', row))) + formatListingString({ + context: 'chunk.item', + provided: row, + }))) : html.tag('li', attributes, - formatListingString('chunk.item', row))); + formatListingString({ + context: 'chunk.item', + provided: row, + }))); const formatRowList = ({rows, rowAttributes}) => html.tag( @@ -137,7 +151,8 @@ export default { }).map(formatRow)); return relations.layout.slots({ - title: formatListingString('title'), + title: formatListingString({context: 'title'}), + headingMode: 'sticky', mainContent: [ @@ -193,8 +208,10 @@ export default { hash: id, content: html.normalize( - formatListingString('chunk.title', title) - .toString() + formatListingString({ + context: 'chunk.title', + provided: title, + }).toString() .replace(/:$/, '')), }))))), ], @@ -209,8 +226,13 @@ export default { .clone() .slots({ tag: 'dt', - title: formatListingString('chunk.title', title), id, + + title: + formatListingString({ + context: 'chunk.title', + provided: title, + }), }), html.tag('dd', -- cgit 1.3.0-6-gf8a5 From f187e32c858e46af9ee2717a20ae4095f0fef325 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 16:34:15 -0400 Subject: content: generateListingPage: add chunkTitleAccents slot --- src/content/dependencies/generateListingPage.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 6eee45b8..b3d6899d 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -78,6 +78,10 @@ export default { validate: v => v.strictArrayOf(v.isObject), }, + chunkTitleAccents: { + validate: v => v.strictArrayOf(v.optional(v.isObject)), + }, + chunkRows: { validate: v => v.strictArrayOf(v.isObject), }, @@ -218,10 +222,11 @@ export default { stitchArrays({ title: slots.chunkTitles, + titleAccent: slots.chunkTitleAccents, id: slots.chunkIDs, rows: slots.chunkRows, rowAttributes: slots.chunkRowAttributes, - }).map(({title, id, rows, rowAttributes}) => [ + }).map(({title, titleAccent, id, rows, rowAttributes}) => [ relations.chunkHeading .clone() .slots({ @@ -233,6 +238,13 @@ export default { context: 'chunk.title', provided: title, }), + + accent: + titleAccent && + formatListingString({ + context: ['chunk.title', title.stringsKey, 'accent'], + provided: titleAccent, + }), }), html.tag('dd', -- cgit 1.3.0-6-gf8a5 From 082f693274a62c9f826fd84def417f243c21d612 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 16:35:10 -0400 Subject: content: listRandomPageLinks: use chunk title accents --- src/content/dependencies/listRandomPageLinks.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 5e74b4ac..089289f7 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -118,20 +118,28 @@ export default { (relations.groupLinks ? relations.groupLinks.map(groupLink => ({ stringsKey: 'fromGroup', - group: groupLink, + })) + : [{stringsKey: 'fromAlbum'}]), + ], + chunkTitleAccents: [ + null, + + ... + (relations.groupLinks + ? relations.groupLinks.map(() => ({ randomAlbum: html.tag('a', {href: '#', 'data-random': 'album-in-group-dl'}, - language.$('listingPage.other.randomPages.chunk.title.fromGroup.randomAlbum')), + language.$('listingPage.other.randomPages.chunk.title.fromGroup.accent.randomAlbum')), randomTrack: html.tag('a', {href: '#', 'data-random': 'track-in-group-dl'}, - language.$('listingPage.other.randomPages.chunk.title.fromGroup.randomTrack')), + language.$('listingPage.other.randomPages.chunk.title.fromGroup.accent.randomTrack')), })) - : [{stringsKey: 'fromAlbum'}]), + : [null]), ], chunkRows: [ -- cgit 1.3.0-6-gf8a5 From f6a0bf1d7b4652a7dd04ed3340010ee2a6e47b7f Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 9 Nov 2023 16:40:18 -0400 Subject: content: listRandomPageLinks: show skip to section --- src/content/dependencies/generateListingPage.js | 2 +- src/content/dependencies/listRandomPageLinks.js | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index b3d6899d..95c039eb 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -96,7 +96,7 @@ export default { }, chunkIDs: { - validate: v => v.strictArrayOf(v.isString), + validate: v => v.strictArrayOf(v.optional(v.isString)), }, listStyle: { diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 089289f7..375a72d7 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -61,7 +61,19 @@ export default { return relations; }, - generate(relations, {html, language}) { + data(query) { + const data = {}; + + if (query.divideByGroups) { + data.groupDirectories = + query.groups + .map(group => group.directory); + } + + return data; + }, + + generate(data, relations, {html, language}) { const miscellaneousChunkRows = [ { stringsKey: 'randomArtist', @@ -111,6 +123,13 @@ export default { language.$('listingPage.other.randomPages.dataLoadedLine')), ], + showSkipToSection: true, + + chunkIDs: [ + null, + ...data.groupDirectories, + ], + chunkTitles: [ {stringsKey: 'misc'}, -- cgit 1.3.0-6-gf8a5 From 6f9d122f9d1ad5bb7e0aad917bbc1ff218e9b4df Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 Nov 2023 17:46:45 -0400 Subject: content: listRandomPageLinks: general syntax/slot fixes --- src/content/dependencies/listRandomPageLinks.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/listRandomPageLinks.js b/src/content/dependencies/listRandomPageLinks.js index 375a72d7..0b904019 100644 --- a/src/content/dependencies/listRandomPageLinks.js +++ b/src/content/dependencies/listRandomPageLinks.js @@ -10,7 +10,7 @@ export default { extraDependencies: ['html', 'language', 'wikiData'], - sprawl: ({wikiInfo}) => ({wikiInfo}), + sprawl: ({albumData, wikiInfo}) => ({albumData, wikiInfo}), query(sprawl, spec) { const query = {spec}; @@ -125,10 +125,10 @@ export default { showSkipToSection: true, - chunkIDs: [ - null, - ...data.groupDirectories, - ], + chunkIDs: + (data.groupDirectories + ? [null, ...data.groupDirectories] + : null), chunkTitles: [ {stringsKey: 'misc'}, @@ -171,10 +171,12 @@ export default { stringsKey: 'album', album: albumLink, }))) - : relations.albumLinks.map(albumLink => ({ - stringsKey: 'album', - album: albumLink, - }))), + : [ + relations.undividedAlbumLinks.map(albumLink => ({ + stringsKey: 'album', + album: albumLink, + })), + ]), ], chunkRowAttributes: [ @@ -183,7 +185,7 @@ export default { (relations.groupAlbumLinks ? relations.groupAlbumLinks.map(albumLinks => albumLinks.map(() => null)) - : [relations.albumLinks.map(() => null)]), + : [relations.undividedAlbumLinks.map(() => null)]), ], }); }, -- cgit 1.3.0-6-gf8a5 From 2de59682e52cd9121e53aec94a27ba78a09abb3e Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 Nov 2023 17:47:16 -0400 Subject: content: generateFlashActSidebar: try to behave without hsmusic data --- src/content/dependencies/generateFlashActSidebar.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateFlashActSidebar.js b/src/content/dependencies/generateFlashActSidebar.js index bd6063c9..80072483 100644 --- a/src/content/dependencies/generateFlashActSidebar.js +++ b/src/content/dependencies/generateFlashActSidebar.js @@ -1,5 +1,6 @@ import find from '#find'; import {stitchArrays} from '#sugar'; +import {filterMultipleArrays} from '#wiki-data'; export default { contentDependencies: ['linkFlash', 'linkFlashAct', 'linkFlashIndex'], @@ -11,10 +12,12 @@ export default { query(sprawl, act, flash) { const findFlashAct = directory => - find.flashAct(directory, sprawl.flashActData, {mode: 'error'}); + find.flashAct(directory, sprawl.flashActData, {mode: 'quiet'}); + + const homestuckSide1 = findFlashAct('flash-act:a1'); const sideFirstActs = [ - findFlashAct('flash-act:a1'), + sprawl.flashActData[0], findFlashAct('flash-act:a6a1'), findFlashAct('flash-act:hiveswap'), findFlashAct('flash-act:cool-and-new-web-comic'), @@ -22,7 +25,9 @@ export default { ]; const sideNames = [ - `Side 1 (Acts 1-5)`, + (homestuckSide1 + ? `Side 1 (Acts 1-5)` + : `All flashes & games`), `Side 2 (Acts 6-7)`, `Additional Canon`, `Fan Adventures`, @@ -30,13 +35,18 @@ export default { ]; const sideColors = [ - '#4ac925', + (homestuckSide1 + ? '#4ac925' + : null), '#3796c6', '#f2a400', '#c466ff', '#32c7fe', ]; + filterMultipleArrays(sideFirstActs, sideNames, sideColors, + firstAct => firstAct); + const sideFirstActIndexes = sideFirstActs .map(act => sprawl.flashActData.indexOf(act)); -- cgit 1.3.0-6-gf8a5 From ad943caefcacf62347199a73a90dc704cd8e369c Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 Nov 2023 17:47:44 -0400 Subject: content: generateListingPage: fix row-based listings... oops... --- src/content/dependencies/generateListingPage.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateListingPage.js b/src/content/dependencies/generateListingPage.js index 95c039eb..2050d62d 100644 --- a/src/content/dependencies/generateListingPage.js +++ b/src/content/dependencies/generateListingPage.js @@ -1,4 +1,4 @@ -import {empty, stitchArrays} from '#sugar'; +import {bindOpts, empty, stitchArrays} from '#sugar'; export default { contentDependencies: [ @@ -130,29 +130,33 @@ export default { return language.formatString(...parts, options); } - const formatRow = ({row, attributes}) => + const formatRow = ({context, row, attributes}) => (attributes?.href ? html.tag('li', html.tag('a', attributes, formatListingString({ - context: 'chunk.item', + context, provided: row, }))) : html.tag('li', attributes, formatListingString({ - context: 'chunk.item', + context, provided: row, }))); - const formatRowList = ({rows, rowAttributes}) => + const formatRowList = ({context, rows, rowAttributes}) => html.tag( (slots.listStyle === 'ordered' ? 'ol' : 'ul'), stitchArrays({ row: rows, attributes: rowAttributes ?? rows.map(() => null), - }).map(formatRow)); + }).map( + bindOpts(formatRow, { + [bindOpts.bindIndex]: 0, + context, + }))); return relations.layout.slots({ title: formatListingString({context: 'title'}), @@ -188,6 +192,7 @@ export default { slots.type === 'rows' && formatRowList({ + context: 'item', rows: slots.rows, rowAttributes: slots.rowAttributes, }), @@ -248,7 +253,11 @@ export default { }), html.tag('dd', - formatRowList({rows, rowAttributes})), + formatRowList({ + context: 'chunk.item', + rows, + rowAttributes, + })), ]), ]), ], -- cgit 1.3.0-6-gf8a5 From f7007f0a090f22929b450ac816757c49e17b9ef1 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 Nov 2023 17:48:07 -0400 Subject: content: generatePageLayout: don't assume custom footer content --- src/content/dependencies/generatePageLayout.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generatePageLayout.js b/src/content/dependencies/generatePageLayout.js index 72dfbae5..5fa6e751 100644 --- a/src/content/dependencies/generatePageLayout.js +++ b/src/content/dependencies/generatePageLayout.js @@ -85,8 +85,10 @@ export default { relations.stickyHeadingContainer = relation('generateStickyHeadingContainer'); - relations.defaultFooterContent = - relation('transformContent', sprawl.footerContent); + if (sprawl.footerContent) { + relations.defaultFooterContent = + relation('transformContent', sprawl.footerContent); + } relations.colorStyleRules = relation('generateColorStyleRules'); @@ -231,7 +233,7 @@ export default { let footerContent = slots.footerContent; - if (html.isBlank(footerContent)) { + if (html.isBlank(footerContent) && relations.defaultFooterContent) { footerContent = relations.defaultFooterContent .slot('mode', 'multiline'); } -- cgit 1.3.0-6-gf8a5 From 3f236319355b093b336e70119a7127bd23693ec2 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Fri, 10 Nov 2023 17:48:26 -0400 Subject: content: generateWikiHomeAlbumsRow: support albums without covers --- src/content/dependencies/generateWikiHomeAlbumsRow.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateWikiHomeAlbumsRow.js b/src/content/dependencies/generateWikiHomeAlbumsRow.js index cb0860f5..2c6a147e 100644 --- a/src/content/dependencies/generateWikiHomeAlbumsRow.js +++ b/src/content/dependencies/generateWikiHomeAlbumsRow.js @@ -11,7 +11,7 @@ export default { 'transformContent', ], - extraDependencies: ['wikiData'], + extraDependencies: ['language', 'wikiData'], sprawl({albumData}, row) { const sprawl = {}; @@ -90,12 +90,14 @@ export default { data.paths = sprawl.albums .map(album => - ['media.albumCover', album.directory, album.coverArtFileExtension]); + (album.hasCoverArt + ? ['media.albumCover', album.directory, album.coverArtFileExtension] + : null)); return data; }, - generate(data, relations) { + generate(data, relations, {language}) { // Grids and carousels share some slots! Very convenient. const commonSlots = {}; @@ -106,8 +108,15 @@ export default { stitchArrays({ image: relations.images, path: data.paths, - }).map(({image, path}) => - image.slot('path', path)); + name: data.names, + }).map(({image, path, name}) => + image.slots({ + path, + missingSourceContent: + language.$('misc.albumGrid.noCoverArt', { + album: name, + }), + })); commonSlots.actionLinks = (relations.actionLinks -- cgit 1.3.0-6-gf8a5 From 95b1ed2f163c1a2be7b6582499cecb8963548155 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 12 Nov 2023 15:03:21 -0400 Subject: content: generateFlashIndexPage: don't show jump links if empty --- src/content/dependencies/generateFlashIndexPage.js | 38 ++++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateFlashIndexPage.js b/src/content/dependencies/generateFlashIndexPage.js index ad1dab94..5fc62ab3 100644 --- a/src/content/dependencies/generateFlashIndexPage.js +++ b/src/content/dependencies/generateFlashIndexPage.js @@ -1,4 +1,4 @@ -import {stitchArrays} from '#sugar'; +import {empty, stitchArrays} from '#sugar'; export default { contentDependencies: [ @@ -95,23 +95,25 @@ export default { mainClasses: ['flash-index'], mainContent: [ - html.tag('p', - {class: 'quick-info'}, - language.$('misc.jumpTo')), - - html.tag('ul', - {class: 'quick-info'}, - stitchArrays({ - colorVariables: relations.jumpLinkColorVariables, - anchor: data.jumpLinkAnchors, - color: data.jumpLinkColors, - label: data.jumpLinkLabels, - }).map(({colorVariables, anchor, color, label}) => - html.tag('li', - html.tag('a', { - href: '#' + anchor, - style: colorVariables.slot('color', color).content, - }, label)))), + !empty(data.jumpLinkLabels) && [ + html.tag('p', + {class: 'quick-info'}, + language.$('misc.jumpTo')), + + html.tag('ul', + {class: 'quick-info'}, + stitchArrays({ + colorVariables: relations.jumpLinkColorVariables, + anchor: data.jumpLinkAnchors, + color: data.jumpLinkColors, + label: data.jumpLinkLabels, + }).map(({colorVariables, anchor, color, label}) => + html.tag('li', + html.tag('a', { + href: '#' + anchor, + style: colorVariables.slot('color', color).content, + }, label)))), + ], stitchArrays({ colorVariables: relations.actColorVariables, -- cgit 1.3.0-6-gf8a5 From 51097802bd2f9d58d4062235858f588a4cf58d93 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 12 Nov 2023 15:16:19 -0400 Subject: content: generateFooterLocalizationLinks: refactor + hide if empty --- .../generateFooterLocalizationLinks.js | 53 ++++++++++++++-------- 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateFooterLocalizationLinks.js b/src/content/dependencies/generateFooterLocalizationLinks.js index 5df83566..86e6c61a 100644 --- a/src/content/dependencies/generateFooterLocalizationLinks.js +++ b/src/content/dependencies/generateFooterLocalizationLinks.js @@ -1,3 +1,6 @@ +import {stitchArrays} from '#sugar'; +import {sortByName} from '#wiki-data'; + export default { extraDependencies: [ 'defaultLanguage', @@ -16,25 +19,37 @@ export default { pagePath, to, }) { - const links = Object.entries(languages) - .filter(([code, language]) => code !== 'default' && !language.hidden) - .map(([code, language]) => language) - .sort(({name: a}, {name: b}) => (a < b ? -1 : a > b ? 1 : 0)) - .map((language) => - html.tag('span', - html.tag('a', - { - href: - language === defaultLanguage - ? to( - 'localizedDefaultLanguage.' + pagePath[0], - ...pagePath.slice(1)) - : to( - 'localizedWithBaseDirectory.' + pagePath[0], - language.code, - ...pagePath.slice(1)), - }, - language.name))); + const switchableLanguages = + Object.entries(languages) + .filter(([code, language]) => code !== 'default' && !language.hidden) + .map(([code, language]) => language); + + if (switchableLanguages.length <= 1) { + return html.blank(); + } + + sortByName(switchableLanguages); + + const [pagePathSubkey, ...pagePathArgs] = pagePath; + + const linkPaths = + switchableLanguages.map(language => + (language === defaultLanguage + ? (['localizedDefaultLanguage.' + pagePathSubkey, + ...pagePathArgs]) + : (['localizedWithBaseDirectory.' + pagePathSubkey, + language.code, + ...pagePathArgs]))); + + const links = + stitchArrays({ + language: switchableLanguages, + linkPath: linkPaths, + }).map(({language, linkPath}) => + html.tag('span', + html.tag('a', + {href: to(...linkPath)}, + language.name))); return html.tag('div', {class: 'footer-localization-links'}, language.$('misc.uiLanguage', { -- cgit 1.3.0-6-gf8a5 From 52cc83065f41472a4c32c2003b0a715a66d4739a Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 13 Nov 2023 16:36:36 -0400 Subject: content: generateWikiHomeAlbumsRow: handle no names in carousel --- src/content/dependencies/generateWikiHomeAlbumsRow.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src/content/dependencies') diff --git a/src/content/dependencies/generateWikiHomeAlbumsRow.js b/src/content/dependencies/generateWikiHomeAlbumsRow.js index 2c6a147e..a19f104c 100644 --- a/src/content/dependencies/generateWikiHomeAlbumsRow.js +++ b/src/content/dependencies/generateWikiHomeAlbumsRow.js @@ -108,14 +108,15 @@ export default { stitchArrays({ image: relations.images, path: data.paths, - name: data.names, + name: data.names ?? data.paths.slice().fill(null), }).map(({image, path, name}) => image.slots({ path, missingSourceContent: - language.$('misc.albumGrid.noCoverArt', { - album: name, - }), + name && + language.$('misc.albumGrid.noCoverArt', { + album: name, + }), })); commonSlots.actionLinks = -- cgit 1.3.0-6-gf8a5