diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2023-04-15 12:22:48 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2023-04-15 12:24:22 -0300 |
commit | 6b35077eb1542eaf9a89534d6920c35fee86cc04 (patch) | |
tree | 3ff4e6bb1860b67b9b2a4f2e39cdcd76cbeaa4b9 /src/content/dependencies/generateAlbumSidebar.js | |
parent | 3a5b49cf3a10702c0dae1190c9baabd8a2c2ef3b (diff) |
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!
Diffstat (limited to 'src/content/dependencies/generateAlbumSidebar.js')
-rw-r--r-- | src/content/dependencies/generateAlbumSidebar.js | 241 |
1 files changed, 241 insertions, 0 deletions
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), + }, + ], + }; + } + }, +}; |