« get me outta code hell

generateTrackListDividedByGroups.js « dependencies « content « src - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content/dependencies/generateTrackListDividedByGroups.js
blob: 5ab53068c81d10d19ef2d0b2277b0a401bb480e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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;
}

export default {
  contentDependencies: [
    'generateContentHeading',
    'generateTrackList',
    'linkGroup',
  ],

  extraDependencies: ['html', 'language'],

  query: (tracks, groups) => ({
    lists:
      (empty(groups)
        ? []
        : groupTracksByGroup(tracks, groups)),
  }),

  relations(relation, query, tracks, groups) {
    if (empty(tracks)) {
      return {};
    }

    if (empty(groups)) {
      return {
        flatList:
          relation('generateTrackList', tracks),
      };
    }

    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),
          })),
    };
  },

  data: (query) => ({
    groupNames:
      Array.from(query.lists.keys())
        .map(groupOrOther =>
          (groupOrOther === 'group'
            ? null
            : groupOrOther.name)),
  }),

  slots: {
    headingString: {
      type: 'string',
    },
  },

  generate(data, relations, slots, {html, language}) {
    if (relations.flatList) {
      return relations.flatList;
    }

    return html.tag('dl',
      stitchArrays({
        groupName: data.groupNames,
        listEntry: relations.groupedLists
      }).map(({
          groupName,
          listEntry: {other, groupLink, list},
        }) => [
          (slots.headingString
            ? relations.contentHeading.clone().slots({
                tag: 'dt',

                title:
                  (other
                    ? language.$('trackList.fromOther')
                    : language.$('trackList.fromGroup', {
                        group: groupLink
                      })),

                stickyTitle:
                  (other
                    ? language.$(slots.headingString, 'sticky', 'fromOther')
                    : language.$(slots.headingString, 'sticky', 'fromGroup', {
                        group: groupName,
                      })),
              })
            : html.tag('dt',
                (other
                  ? language.$('trackList.fromOther')
                  : language.$('trackList.fromGroup', {
                      group: groupLink
                    })))),

          html.tag('dd', list),
        ]));
  },
};