diff options
Diffstat (limited to 'src/content/dependencies/generateTrackListDividedByGroups.js')
-rw-r--r-- | src/content/dependencies/generateTrackListDividedByGroups.js | 155 |
1 files changed, 117 insertions, 38 deletions
diff --git a/src/content/dependencies/generateTrackListDividedByGroups.js b/src/content/dependencies/generateTrackListDividedByGroups.js index e070ac35..327865f0 100644 --- a/src/content/dependencies/generateTrackListDividedByGroups.js +++ b/src/content/dependencies/generateTrackListDividedByGroups.js @@ -1,53 +1,132 @@ -import {empty} from '#sugar'; - -import groupTracksByGroup from '../util/groupTracksByGroup.js'; +import {empty, filterMultipleArrays, stitchArrays} from '#sugar'; export default { - contentDependencies: ['generateTrackList', 'linkGroup'], + contentDependencies: [ + 'generateContentHeading', + 'generateTrackList', + 'linkGroup', + ], + extraDependencies: ['html', 'language'], - relations(relation, tracks, groups) { - if (empty(tracks)) { - return {}; + query(tracks, dividingGroups) { + const groupings = new Map(); + const ungroupedTracks = []; + + // Entry order matters! Add blank lists for each group + // in the order that those groups are provided. + for (const group of dividingGroups) { + groupings.set(group, []); } - if (empty(groups)) { - return { - flatList: - relation('generateTrackList', tracks), - }; + for (const track of tracks) { + const firstMatchingGroup = + dividingGroups.find(group => group.albums.includes(track.album)); + + if (firstMatchingGroup) { + groupings.get(firstMatchingGroup).push(track); + } else { + ungroupedTracks.push(track); + } } - const lists = groupTracksByGroup(tracks, groups); + const groups = Array.from(groupings.keys()); + const groupedTracks = Array.from(groupings.values()); - return { - groupedLists: - Array.from(lists.entries()).map(([groupOrOther, tracks]) => ({ - ...(groupOrOther === 'other' - ? {other: true} - : {groupLink: relation('linkGroup', groupOrOther)}), + // Drop the empty lists, so just the groups which + // at least a single track matched are left. + filterMultipleArrays( + groups, + groupedTracks, + (_group, tracks) => !empty(tracks)); - list: - relation('generateTrackList', tracks), - })), - }; + return {groups, groupedTracks, ungroupedTracks}; }, - generate(relations, {html, language}) { - if (relations.flatList) { - return relations.flatList; - } + relations: (relation, query, tracks, groups) => ({ + flatList: + (empty(groups) + ? relation('generateTrackList', tracks) + : null), + + contentHeading: + relation('generateContentHeading'), + + groupLinks: + query.groups + .map(group => relation('linkGroup', group)), + + groupedTrackLists: + query.groupedTracks + .map(tracks => relation('generateTrackList', tracks)), + + ungroupedTrackList: + (empty(query.ungroupedTracks) + ? null + : relation('generateTrackList', query.ungroupedTracks)), + }), - return html.tag('dl', - relations.groupedLists.map(({other, groupLink, list}) => [ - html.tag('dt', - (other - ? language.$('trackList.group.fromOther') - : language.$('trackList.group', { - group: groupLink - }))), - - html.tag('dd', list), - ])); + data: (query) => ({ + groupNames: + query.groups + .map(group => group.name), + }), + + slots: { + headingString: { + type: 'string', + }, }, + + generate: (data, relations, slots, {html, language}) => + relations.flatList ?? + html.tag('dl', [ + stitchArrays({ + groupName: data.groupNames, + groupLink: relations.groupLinks, + trackList: relations.groupedTrackLists, + }).map(({ + groupName, + groupLink, + trackList, + }) => [ + (slots.headingString + ? relations.contentHeading.clone().slots({ + tag: 'dt', + + title: + language.$('trackList.fromGroup', { + group: groupLink + }), + + stickyTitle: + language.$(slots.headingString, 'sticky', 'fromGroup', { + group: groupName, + }), + }) + : html.tag('dt', + language.$('trackList.fromGroup', { + group: groupLink + }))), + + html.tag('dd', trackList), + ]), + + relations.ungroupedTrackList && [ + (slots.headingString + ? relations.contentHeading.clone().slots({ + tag: 'dt', + + title: + language.$('trackList.fromOther'), + + stickyTitle: + language.$(slots.headingString, 'sticky', 'fromOther'), + }) + : html.tag('dt', + language.$('trackList.fromOther'))), + + html.tag('dd', relations.ungroupedTrackList), + ], + ]), }; |