diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-06-09 17:44:10 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-06-09 17:53:30 -0300 |
commit | 53c3d939e66b5ecefa8b92de757bc70c0c6c34bd (patch) | |
tree | cb7045750a651be7d30a623c1b3896dd743a7130 | |
parent | 36e2006bc9a24918ba886d9cef28d6288bf01c40 (diff) |
content: generateTrackListDividedByGroups: general logic cleanup
-rw-r--r-- | src/content/dependencies/generateTrackListDividedByGroups.js | 174 |
1 files changed, 90 insertions, 84 deletions
diff --git a/src/content/dependencies/generateTrackListDividedByGroups.js b/src/content/dependencies/generateTrackListDividedByGroups.js index 5ab53068..327865f0 100644 --- a/src/content/dependencies/generateTrackListDividedByGroups.js +++ b/src/content/dependencies/generateTrackListDividedByGroups.js @@ -1,26 +1,4 @@ -import {empty, stitchArrays} from '#sugar'; - -function groupTracksByGroup(tracks, groups) { - const lists = new Map(groups.map(group => [group, []])); - lists.set('other', []); - - for (const track of tracks) { - const group = groups.find(group => group.albums.includes(track.album)); - if (group) { - lists.get(group).push(track); - } else { - lists.get('other').push(track); - } - } - - for (const [key, tracks] of lists.entries()) { - if (empty(tracks)) { - lists.delete(key); - } - } - - return lists; -} +import {empty, filterMultipleArrays, stitchArrays} from '#sugar'; export default { contentDependencies: [ @@ -31,49 +9,67 @@ export default { extraDependencies: ['html', 'language'], - query: (tracks, groups) => ({ - lists: - (empty(groups) - ? [] - : groupTracksByGroup(tracks, groups)), - }), + query(tracks, dividingGroups) { + const groupings = new Map(); + const ungroupedTracks = []; - relations(relation, query, tracks, groups) { - if (empty(tracks)) { - return {}; + // 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); + } } - return { - contentHeading: - relation('generateContentHeading'), - - groupedLists: - Array.from(query.lists.entries()) - .map(([groupOrOther, tracks]) => ({ - ...(groupOrOther === 'other' - ? {other: true} - : {groupLink: relation('linkGroup', groupOrOther)}), - - list: - relation('generateTrackList', tracks), - })), - }; + const groups = Array.from(groupings.keys()); + const groupedTracks = Array.from(groupings.values()); + + // Drop the empty lists, so just the groups which + // at least a single track matched are left. + filterMultipleArrays( + groups, + groupedTracks, + (_group, tracks) => !empty(tracks)); + + return {groups, groupedTracks, ungroupedTracks}; }, + 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)), + }), + data: (query) => ({ groupNames: - Array.from(query.lists.keys()) - .map(groupOrOther => - (groupOrOther === 'group' - ? null - : groupOrOther.name)), + query.groups + .map(group => group.name), }), slots: { @@ -82,45 +78,55 @@ export default { }, }, - generate(data, relations, slots, {html, language}) { - if (relations.flatList) { - return relations.flatList; - } - - return html.tag('dl', + generate: (data, relations, slots, {html, language}) => + relations.flatList ?? + html.tag('dl', [ stitchArrays({ groupName: data.groupNames, - listEntry: relations.groupedLists + groupLink: relations.groupLinks, + trackList: relations.groupedTrackLists, }).map(({ groupName, - listEntry: {other, groupLink, list}, + groupLink, + trackList, }) => [ (slots.headingString ? relations.contentHeading.clone().slots({ tag: 'dt', title: - (other - ? language.$('trackList.fromOther') - : language.$('trackList.fromGroup', { - group: groupLink - })), + language.$('trackList.fromGroup', { + group: groupLink + }), stickyTitle: - (other - ? language.$(slots.headingString, 'sticky', 'fromOther') - : language.$(slots.headingString, 'sticky', 'fromGroup', { - group: groupName, - })), + language.$(slots.headingString, 'sticky', 'fromGroup', { + group: groupName, + }), }) : html.tag('dt', - (other - ? language.$('trackList.fromOther') - : language.$('trackList.fromGroup', { - group: groupLink - })))), - - html.tag('dd', list), - ])); - }, + 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), + ], + ]), }; |