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
  | 
import {sortChronologically} from '#sort';
export default {
  query(series) {
    const query = {};
    query.albums =
      sortChronologically(series.albums.slice(), {latestFirst: true});
    query.allAlbumsDated =
      series.albums.every(album => album.date);
    query.anyAlbumNotFromThisGroup =
      series.albums.some(album => !album.groups.includes(series.group));
    query.latestAlbum =
      query.albums
        .filter(album => album.date)
        .at(0) ??
      null;
    query.earliestAlbum =
      query.albums
        .filter(album => album.date)
        .at(-1) ??
      null;
    return query;
  },
  relations: (relation, query, series) => ({
    contentHeading:
      relation('generateContentHeading'),
    grid:
      relation('generateGroupGalleryPageAlbumGrid',
        query.albums,
        series.group),
  }),
  data: (query, series) => ({
    name:
      series.name,
    groupName:
      series.group.name,
    albums:
      series.albums.length,
    tracks:
      series.albums
        .flatMap(album => album.tracks)
        .length,
    allAlbumsDated:
      query.allAlbumsDated,
    anyAlbumNotFromThisGroup:
      query.anyAlbumNotFromThisGroup,
    earliestAlbumDate:
      (query.earliestAlbum
        ? query.earliestAlbum.date
        : null),
    latestAlbumDate:
      (query.latestAlbum
        ? query.latestAlbum.date
        : null),
  }),
  generate: (data, relations, {html, language}) =>
    language.encapsulate('groupGalleryPage.albumSection', capsule =>
      html.tags([
        relations.contentHeading.slots({
          tag: 'h2',
          title: language.sanitize(data.name),
        }),
        relations.grid.slots({
          cutIndex: 4,
          bottomCaption:
            language.encapsulate(capsule, 'caption', captionCapsule =>
              html.tags([
                data.anyAlbumNotFromThisGroup &&
                  language.$(captionCapsule, 'seriesAlbumsNotFromGroup', {
                    marker:
                      language.$('misc.coverGrid.details.notFromThisGroup.marker'),
                    series:
                      html.tag('i', data.name),
                    group: data.groupName,
                  }),
                language.encapsulate(captionCapsule, workingCapsule => {
                  const workingOptions = {};
                  workingOptions.tracks =
                    html.tag('b',
                      language.countTracks(data.tracks, {unit: true}));
                  workingOptions.albums =
                    html.tag('b',
                      language.countAlbums(data.albums, {unit: true}));
                  if (data.allAlbumsDated) {
                    const earliestDate = data.earliestAlbumDate;
                    const latestDate = data.latestAlbumDate;
                    const earliestYear = earliestDate.getFullYear();
                    const latestYear = latestDate.getFullYear();
                    if (earliestYear === latestYear) {
                      if (data.albums === 1) {
                        workingCapsule += '.withDate';
                        workingOptions.date =
                          language.formatDate(earliestDate);
                      } else {
                        workingCapsule += '.withYear';
                        workingOptions.year =
                          language.formatYear(earliestDate);
                      }
                    } else {
                      workingCapsule += '.withYearRange';
                      workingOptions.yearRange =
                        language.formatYearRange(earliestDate, latestDate);
                    }
                  }
                  return language.$(workingCapsule, workingOptions);
                }),
              ], {[html.joinChildren]: html.tag('br')})),
        }),
      ])),
};
  |