diff options
Diffstat (limited to 'src/content/dependencies/generateAlbumSecondaryNav.js')
-rw-r--r-- | src/content/dependencies/generateAlbumSecondaryNav.js | 226 |
1 files changed, 94 insertions, 132 deletions
diff --git a/src/content/dependencies/generateAlbumSecondaryNav.js b/src/content/dependencies/generateAlbumSecondaryNav.js index d6ff8a0a..bfa48f03 100644 --- a/src/content/dependencies/generateAlbumSecondaryNav.js +++ b/src/content/dependencies/generateAlbumSecondaryNav.js @@ -1,165 +1,127 @@ -import {sortChronologically} from '#sort'; -import {atOffset, stitchArrays} from '#sugar'; +import {stitchArrays} from '#sugar'; export default { contentDependencies: [ - 'generateColorStyleAttribute', - 'generatePreviousNextLinks', + 'generateAlbumSecondaryNavGroupPart', + 'generateAlbumSecondaryNavSeriesPart', + 'generateDotSwitcherTemplate', 'generateSecondaryNav', - 'linkAlbumDynamically', - 'linkGroup', - 'linkTrack', ], - extraDependencies: ['html', 'language'], + extraDependencies: ['html', 'wikiData'], - query(album) { + sprawl: ({groupData}) => ({ + // TODO: Series aren't their own things, so we access them weirdly. + seriesData: + groupData.flatMap(group => group.serieses), + }), + + query(sprawl, album) { const query = {}; query.groups = album.groups; - if (album.date) { - // Sort by latest first. This matches the sorting order used on group - // gallery pages, ensuring that previous/next matches moving up/down - // the gallery. Note that this makes the index offsets "backwards" - // compared to how latest-last chronological lists are accessed. - const groupAlbums = - query.groups.map(group => - sortChronologically( - group.albums.filter(album => album.date), - {latestFirst: true})); - - const groupCurrentIndex = - groupAlbums.map(albums => - albums.indexOf(album)); - - query.groupPreviousAlbum = - stitchArrays({ - albums: groupAlbums, - index: groupCurrentIndex, - }).map(({albums, index}) => - atOffset(albums, index, +1)); - - query.groupNextAlbum = - stitchArrays({ - albums: groupAlbums, - index: groupCurrentIndex, - }).map(({albums, index}) => - atOffset(albums, index, -1)); - } + query.groupSerieses = + query.groups + .map(group => + group.serieses + .filter(series => series.albums.includes(album))); + + query.disconnectedSerieses = + sprawl.seriesData + .filter(series => + series.albums.includes(album) && + !query.groups.includes(series.group)); return query; }, - relations(relation, query, album) { - const relations = {}; + relations: (relation, query, _sprawl, album) => ({ + secondaryNav: + relation('generateSecondaryNav'), - relations.secondaryNav = - relation('generateSecondaryNav'); + // Just use a generic dot switcher here. We want the common behavior, + // but the "options" may each contain multiple links (group + series), + // so this is a different use than typical interpage dot switchers. + switcher: + relation('generateDotSwitcherTemplate'), - relations.groupLinks = + groupParts: query.groups - .map(group => relation('linkGroup', group)); - - relations.colorStyles = - query.groups - .map(group => relation('generateColorStyleAttribute', group.color)); - - if (album.date) { - relations.previousNextLinks = - stitchArrays({ - previousAlbum: query.groupPreviousAlbum, - nextAlbum: query.groupNextAlbum - }).map(({previousAlbum, nextAlbum}) => - (previousAlbum || nextAlbum - ? relation('generatePreviousNextLinks') - : null)); - - relations.previousAlbumLinks = - query.groupPreviousAlbum.map(previousAlbum => - (previousAlbum - ? relation('linkAlbumDynamically', previousAlbum) - : null)); - - relations.nextAlbumLinks = - query.groupNextAlbum.map(nextAlbum => - (nextAlbum - ? relation('linkAlbumDynamically', nextAlbum) - : null)); - } - - return relations; - }, + .map(group => + relation('generateAlbumSecondaryNavGroupPart', + group, + album)), + + seriesParts: + query.groupSerieses + .map(serieses => serieses + .map(series => + relation('generateAlbumSecondaryNavSeriesPart', + series, + album))), + + disconnectedSeriesParts: + query.disconnectedSerieses + .map(series => + relation('generateAlbumSecondaryNavSeriesPart', + series, + album)), + }), slots: { mode: { validate: v => v.is('album', 'track'), default: 'album', }, + + alwaysVisible: { + type: 'boolean', + default: false, + }, }, - generate(relations, slots, {html, language}) { - const navLinksShouldShowPreviousNext = - (slots.mode === 'track' - ? Array.from(relations.previousNextLinks ?? [], () => false) - : stitchArrays({ - previousAlbumLink: relations.previousAlbumLinks ?? null, - nextAlbumLink: relations.nextAlbumLinks ?? null, - }).map(({previousAlbumLink, nextAlbumLink}) => - previousAlbumLink || - nextAlbumLink)); - - const navLinkPreviousNextLinks = - stitchArrays({ - showPreviousNext: navLinksShouldShowPreviousNext, - previousNextLinks: relations.previousNextLinks ?? null, - previousAlbumLink: relations.previousAlbumLinks ?? null, - nextAlbumLink: relations.nextAlbumLinks ?? null, - }).map(({ - showPreviousNext, - previousNextLinks, - previousAlbumLink, - nextAlbumLink, - }) => - (showPreviousNext - ? previousNextLinks.slots({ - previousLink: previousAlbumLink, - nextLink: nextAlbumLink, - id: false, - }) - : null)); - - for (const groupLink of relations.groupLinks) { - groupLink.setSlot('color', false); - } - - const navLinkContents = + generate(relations, slots, {html}) { + const groupConnectedParts = stitchArrays({ - groupLink: relations.groupLinks, - previousNextLinks: navLinkPreviousNextLinks, - }).map(({groupLink, previousNextLinks}) => [ - language.$('albumSidebar.groupBox.title', { - group: groupLink, - }), - - previousNextLinks && - `(${language.formatUnitList(previousNextLinks.content)})`, - ]); - - const navLinks = - stitchArrays({ - content: navLinkContents, - colorStyle: relations.colorStyles, - }).map(({content, colorStyle}) => - html.tag('span', {class: 'nav-link'}, - colorStyle.slot('context', 'primary-only'), - - content)); + groupPart: relations.groupParts, + seriesParts: relations.seriesParts, + }).map(({groupPart, seriesParts}) => { + for (const part of [groupPart, ...seriesParts]) { + part.setSlot('mode', slots.mode); + } + + if (html.isBlank(seriesParts)) { + return groupPart; + } else { + return ( + html.tag('span', {class: 'group-with-series'}, + {[html.joinChildren]: ''}, + + [groupPart, ...seriesParts])); + } + }); + + const allParts = [ + ...relations.disconnectedSeriesParts, + ...groupConnectedParts, + ]; return relations.secondaryNav.slots({ - class: 'nav-links-groups', - content: navLinks, + alwaysVisible: slots.alwaysVisible, + + attributes: [ + {class: 'album-secondary-nav'}, + + slots.mode === 'album' && + {class: 'with-previous-next'}, + ], + + content: + (slots.mode === 'album' + ? allParts + : relations.switcher.slot('options', allParts)), }); }, }; |