« get me outta code hell

generateAlbumSecondaryNav.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/generateAlbumSecondaryNav.js
blob: 2585e1712891770717e8e7c534d321e6c9301322 (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
import {stitchArrays} from '#sugar';

export default {
  contentDependencies: [
    'generateAlbumSecondaryNavGroupPart',
    'generateAlbumSecondaryNavSeriesPart',
    'generateDotSwitcherTemplate',
    'generateSecondaryNav',
  ],

  extraDependencies: ['html', 'wikiData'],

  sprawl: ({groupData}) => ({
    // TODO: Series aren't their own things, so we access them weirdly.
    seriesData:
      groupData.flatMap(group => group.serieses),
  }),

  query(sprawl, album) {
    const query = {};

    query.groups =
      album.groups;

    query.groupSerieses =
      query.groups
        .map(group =>
          group.serieses
            .filter(series => series.albums.includes(album)));

    query.disconnectedSerieses =
      sprawl.seriesData
        .filter(series =>
          series.albums.includes(album) &&
          !query.groups.includes(series.group));

    return query;
  },

  relations: (relation, query, _sprawl, album) => ({
    secondaryNav:
      relation('generateSecondaryNav'),

    // Just use a generic dot switcher here. We want the common behavior,
    // but the "options" may each contain multiple links (group + series),
    // so this is a different use than typical interpage dot switchers.
    switcher:
      relation('generateDotSwitcherTemplate'),

    groupParts:
      query.groups
        .map(group =>
          relation('generateAlbumSecondaryNavGroupPart',
            group,
            album)),

    seriesParts:
      query.groupSerieses
        .map(serieses => serieses
          .map(series =>
            relation('generateAlbumSecondaryNavSeriesPart',
              series,
              album))),

    disconnectedSeriesParts:
      query.disconnectedSerieses
        .map(series =>
          relation('generateAlbumSecondaryNavSeriesPart',
            series,
            album)),
  }),

  slots: {
    mode: {
      validate: v => v.is('album', 'track'),
      default: 'album',
    },

    alwaysVisible: {
      type: 'boolean',
      default: false,
    },
  },

  generate(relations, slots, {html}) {
    const groupConnectedParts =
      stitchArrays({
        groupPart: relations.groupParts,
        seriesParts: relations.seriesParts,
      }).map(({groupPart, seriesParts}) => {
          for (const part of [groupPart, ...seriesParts]) {
            part.setSlot('mode', slots.mode);
          }

          if (html.isBlank(seriesParts)) {
            return groupPart;
          } else {
            return (
              html.tag('span', {class: 'group-with-series'},
                [groupPart, ...seriesParts]));
          }
        });

    const allParts = [
      ...relations.disconnectedSeriesParts,
      ...groupConnectedParts,
    ];

    return relations.secondaryNav.slots({
      alwaysVisible: slots.alwaysVisible,

      attributes: [
        {class: 'album-secondary-nav'},

        slots.mode === 'album' &&
          {class: 'with-previous-next'},
      ],

      content:
        (slots.mode === 'album'
          ? allParts
          : relations.switcher.slot('options', allParts)),
    });
  },
};