From 6b35077eb1542eaf9a89534d6920c35fee86cc04 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 15 Apr 2023 12:22:48 -0300 Subject: content: generateAlbumSidebar + misc fixes This restores the CSS for sticky sidebars, but removes the specific lines applying that effect (for the album sidebar). There's also an experimental new splitter for the joined group info box but we might go back on that or do something different. No tests for the new stuff here yet! --- src/content/dependencies/generateAlbumSidebar.js | 241 +++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 src/content/dependencies/generateAlbumSidebar.js (limited to 'src/content/dependencies/generateAlbumSidebar.js') diff --git a/src/content/dependencies/generateAlbumSidebar.js b/src/content/dependencies/generateAlbumSidebar.js new file mode 100644 index 00000000..223b1b7c --- /dev/null +++ b/src/content/dependencies/generateAlbumSidebar.js @@ -0,0 +1,241 @@ +import {empty} from '../../util/sugar.js'; + +function groupRelationships(album) { + return album.groups.map(group => { + const albums = group.albums.filter(album => album.date); + const index = albums.indexOf(album); + + const previousAlbum = (index > 0) && albums[index - 1]; + const nextAlbum = (index < albums.length - 1) && albums[index + 1]; + + return {group, previousAlbum, nextAlbum}; + }); +} + +export default { + contentDependencies: [ + 'linkAlbum', + 'linkExternal', + 'linkGroup', + 'linkTrack', + ], + + extraDependencies: [ + 'getColors', + 'html', + 'language', + 'transformMultiline', + ], + + relations(relation, album, track) { + const relations = {}; + + relations.albumLink = + relation('linkAlbum', album); + + relations.trackLinks = + album.trackSections.map(trackSection => + trackSection.tracks.map(track => + relation('linkTrack', track))); + + relations.groupLinks = + groupRelationships(album) + .map(({group, previousAlbum, nextAlbum}) => ({ + groupLink: + relation('linkGroup', group), + + externalLinks: + group.urls.map(url => + relation('linkExternal', url)), + + previousAlbumLink: + previousAlbum && + relation('linkAlbum', previousAlbum), + + nextAlbumLink: + nextAlbum && + relation('linkAlbum', nextAlbum), + })) + + return relations; + }, + + data(album, track) { + const data = {}; + + data.isAlbumPage = !track; + data.isTrackPage = !!track; + + data.hasTrackNumbers = album.hasTrackNumbers; + + data.trackSectionInfo = + album.trackSections.map(trackSection => ({ + name: trackSection.name, + color: trackSection.color, + isDefaultTrackSection: trackSection.isDefaultTrackSection, + + firstTrackNumber: trackSection.startIndex + 1, + lastTrackNumber: trackSection.startIndex + trackSection.tracks.length, + + includesCurrentTrack: track && trackSection.tracks.includes(track), + currentTrackIndex: trackSection.tracks.indexOf(track), + })); + + data.groupInfo = + album.groups.map(group => ({ + description: group.descriptionShort, + })); + + return data; + }, + + generate(data, relations, { + getColors, + html, + language, + transformMultiline, + }) { + const {isTrackPage, isAlbumPage} = data; + + const trackListPart = html.tags([ + html.tag('h1', relations.albumLink), + data.trackSectionInfo.map( + ({ + name, + color, + isDefaultTrackSection, + + firstTrackNumber, + lastTrackNumber, + + includesCurrentTrack, + currentTrackIndex, + }, index) => { + const trackLinks = relations.trackLinks[index]; + + const sectionName = + html.tag('span', {class: 'group-name'}, + (isDefaultTrackSection + ? language.$('albumSidebar.trackList.fallbackSectionName') + : name)); + + let style; + if (color) { + const {primary} = getColors(color); + style = `--primary-color: ${primary}`; + } + + const trackListItems = + trackLinks.map((trackLink, index) => + html.tag('li', + { + class: + includesCurrentTrack && + index === currentTrackIndex && + 'current', + }, + language.$('albumSidebar.trackList.item', { + track: trackLink, + }))); + + return html.tag('details', + { + class: includesCurrentTrack && 'current', + + open: ( + // Leave sidebar track sections collapsed on album info page, + // since there's already a view of the full track listing + // in the main content area. + isTrackPage && + + // Only expand the track section which includes the track + // currently being viewed by default. + includesCurrentTrack), + }, + [ + html.tag('summary', {style}, + html.tag('span', + (data.hasTrackNumbers + ? language.$('albumSidebar.trackList.group.withRange', { + group: sectionName, + range: `${firstTrackNumber}–${lastTrackNumber}` + }) + : language.$('albumSidebar.trackList.group', { + group: sectionName, + })))), + + (data.hasTrackNumbers + ? html.tag('ol', + {start: firstTrackNumber}, + trackListItems) + : html.tag('ul', trackListItems)), + ]); + }), + ]); + + const groupParts = data.groupInfo.map( + ({description}, index) => { + const links = relations.groupLinks[index]; + + return html.tags([ + html.tag('h1', + language.$('albumSidebar.groupBox.title', { + group: links.groupLink, + })), + + isAlbumPage && + transformMultiline(description), + + !empty(links.externalLinks) && + html.tag('p', + language.$('releaseInfo.visitOn', { + links: language.formatDisjunctionList(links.externalLinks), + })), + + isAlbumPage && + links.nextAlbumLink && + html.tag('p', {class: 'group-chronology-link'}, + language.$('albumSidebar.groupBox.next', { + album: links.nextAlbumLink, + })), + + isAlbumPage && + links.previousAlbumLink && + html.tag('p', {class: 'group-chronology-link'}, + language.$('albumSidebar.groupBox.previous', { + album: links.previousAlbumLink, + })), + ]); + }); + + if (isAlbumPage) { + return { + // leftSidebarStickyMode: 'last', + leftSidebarMultiple: [ + ...groupParts.map(groupPart => ({content: groupPart})), + {content: trackListPart}, + ], + }; + } else { + return { + // leftSidebarStickyMode: 'column', + leftSidebarMultiple: [ + {content: trackListPart}, + // ...groupParts.map(groupPart => ({content: groupPart})), + { + content: + groupParts + .flatMap((part, i) => [ + part, + i < groupParts.length - 1 && + html.tag('hr', { + style: `border-color: var(--primary-color); border-style: none none dotted none` + }) + ]) + .filter(Boolean), + }, + ], + }; + } + }, +}; -- cgit 1.3.0-6-gf8a5