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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  | 
import {empty, stitchArrays} from '#sugar';
export default {
  query(album) {
    const query = {};
    query.tracksWithCommentary =
      album.tracks
        .filter(({commentary}) => !empty(commentary));
    query.thingsWithCommentary =
      (empty(album.commentary)
        ? query.tracksWithCommentary
        : [album, ...query.tracksWithCommentary]);
    return query;
  },
  relations(relation, query, album) {
    const relations = {};
    relations.layout =
      relation('generatePageLayout');
    relations.secondaryNav =
      relation('generateAlbumSecondaryNav', album);
    relations.sidebar =
      relation('generateAlbumCommentarySidebar', album);
    relations.albumStyleTags =
      relation('generateAlbumStyleTags', album, null);
    relations.albumLink =
      relation('linkAlbum', album);
    relations.albumNavAccent =
      relation('generateAlbumNavAccent', album, null);
    if (!empty(album.commentary)) {
      relations.albumCommentaryHeading =
        relation('generateContentHeading');
      relations.albumCommentaryLink =
        relation('linkAlbum', album);
      relations.albumCommentaryListeningLinks =
        album.urls.map(url => relation('linkExternal', url));
      if (album.hasCoverArt) {
        relations.albumCommentaryCover =
          relation('generateCoverArtwork', album.coverArtworks[0]);
      }
      relations.albumCommentaryEntries =
        album.commentary
          .map(entry => relation('generateCommentaryEntry', entry));
    }
    relations.trackCommentaryHeadings =
      query.tracksWithCommentary
        .map(() => relation('generateContentHeading'));
    relations.trackCommentaryLinks =
      query.tracksWithCommentary
        .map(track => relation('linkTrack', track));
    relations.trackCommentaryListeningLinks =
      query.tracksWithCommentary
        .map(track =>
          track.urls.map(url => relation('linkExternal', url)));
    relations.trackCommentaryCovers =
      query.tracksWithCommentary
        .map(track =>
          (track.hasUniqueCoverArt
            ? relation('generateCoverArtwork', track.trackArtworks[0])
            : null));
    relations.trackCommentaryEntries =
      query.tracksWithCommentary
        .map(track =>
          track.commentary
            .map(entry => relation('generateCommentaryEntry', entry)));
    return relations;
  },
  data(query, album) {
    const data = {};
    data.name = album.name;
    data.color = album.color;
    data.date = album.date;
    data.entryCount =
      query.thingsWithCommentary
        .flatMap(({commentary}) => commentary)
        .length;
    data.wordCount =
      query.thingsWithCommentary
        .flatMap(({commentary}) => commentary)
        .map(({body}) => body)
        .join(' ')
        .split(' ')
        .length;
    data.trackCommentaryTrackDates =
      query.tracksWithCommentary
        .map(track => track.dateFirstReleased);
    data.trackCommentaryDirectories =
      query.tracksWithCommentary
        .map(track => track.directory);
    data.trackCommentaryColors =
      query.tracksWithCommentary
        .map(track =>
          (track.color === album.color
            ? null
            : track.color));
    return data;
  },
  generate: (data, relations, {html, language}) =>
    language.encapsulate('albumCommentaryPage', pageCapsule =>
      relations.layout.slots({
        title:
          language.$(pageCapsule, 'title', {
            album: data.name,
          }),
        headingMode: 'sticky',
        color: data.color,
        styleTags: relations.albumStyleTags,
        mainClasses: ['long-content'],
        mainContent: [
          html.tag('p',
            {[html.joinChildren]: html.tag('br')},
            [
              data.date &&
              data.entryCount >= 1 &&
                language.$('releaseInfo.albumReleased', {
                  date:
                    html.tag('b',
                      language.formatDate(data.date)),
                }),
              language.encapsulate(pageCapsule, 'infoLine', workingCapsule => {
                const workingOptions = {};
                if (data.entryCount >= 1) {
                  workingOptions.words =
                    html.tag('b',
                      language.formatWordCount(data.wordCount, {unit: true}));
                  workingOptions.entries =
                    html.tag('b',
                      language.countCommentaryEntries(data.entryCount, {unit: true}));
                }
                if (data.entryCount === 0) {
                  workingCapsule += '.withoutCommentary';
                }
                return language.$(workingCapsule, workingOptions);
              })
            ]),
          relations.albumCommentaryEntries &&
            language.encapsulate(pageCapsule, 'entry', entryCapsule => [
              language.encapsulate(entryCapsule, 'title.albumCommentary', titleCapsule =>
                relations.albumCommentaryHeading.slots({
                  tag: 'h3',
                  attributes: {id: 'album-commentary'},
                  color: data.color,
                  title:
                    language.$(titleCapsule, {
                      album: relations.albumCommentaryLink,
                    }),
                  stickyTitle:
                    language.$(titleCapsule, 'sticky', {
                      album: data.name,
                    }),
                  accent:
                    language.$(titleCapsule, 'accent', {
                      [language.onlyIfOptions]: ['listeningLinks'],
                      listeningLinks:
                        language.formatUnitList(
                          relations.albumCommentaryListeningLinks
                            .map(link => link.slots({
                              context: 'album',
                              tab: 'separate',
                            }))),
                    }),
                })),
              relations.albumCommentaryCover
                ?.slots({mode: 'commentary'}),
              relations.albumCommentaryEntries,
            ]),
          stitchArrays({
            heading: relations.trackCommentaryHeadings,
            link: relations.trackCommentaryLinks,
            listeningLinks: relations.trackCommentaryListeningLinks,
            directory: data.trackCommentaryDirectories,
            cover: relations.trackCommentaryCovers,
            entries: relations.trackCommentaryEntries,
            color: data.trackCommentaryColors,
            trackDate: data.trackCommentaryTrackDates,
          }).map(({
              heading,
              link,
              listeningLinks,
              directory,
              cover,
              entries,
              color,
              trackDate,
            }) =>
              language.encapsulate(pageCapsule, 'entry', entryCapsule => [
                language.encapsulate(entryCapsule, 'title.trackCommentary', titleCapsule =>
                  heading.slots({
                    tag: 'h3',
                    attributes: {id: directory},
                    color,
                    title:
                      language.$(titleCapsule, {
                        track: link,
                      }),
                    accent:
                      language.$(titleCapsule, 'accent', {
                        [language.onlyIfOptions]: ['listeningLinks'],
                        listeningLinks:
                          language.formatUnitList(
                            listeningLinks.map(link =>
                              link.slot('tab', 'separate'))),
                      }),
                  })),
              cover?.slots({
                mode: 'commentary',
                color: true,
              }),
              trackDate &&
              trackDate !== data.date &&
                html.tag('p', {class: 'track-info'},
                  language.$('releaseInfo.trackReleased', {
                    date: language.formatDate(trackDate),
                  })),
              entries.map(entry => entry.slot('color', color)),
            ])),
        ],
        navLinkStyle: 'hierarchical',
        navLinks: [
          {auto: 'home'},
          {
            html:
              relations.albumLink
                .slot('attributes', {class: 'current'}),
            accent:
              relations.albumNavAccent.slots({
                showTrackNavigation: false,
                showExtraLinks: true,
                currentExtra: 'commentary',
              }),
          },
        ],
        secondaryNav:
          relations.secondaryNav.slots({
            alwaysVisible: true,
          }),
        leftSidebar: relations.sidebar,
      })),
};
  |