« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/data/things/thing.js4
-rw-r--r--src/data/things/track.js2
-rw-r--r--src/data/yaml.js4
-rw-r--r--src/misc-templates.js65
-rw-r--r--src/page/album.js53
-rw-r--r--src/page/track.js74
-rw-r--r--src/strings-default.json8
-rwxr-xr-xsrc/upd8.js6
8 files changed, 162 insertions, 54 deletions
diff --git a/src/data/things/thing.js b/src/data/things/thing.js
index b9fa60c6..5ab15c0e 100644
--- a/src/data/things/thing.js
+++ b/src/data/things/thing.js
@@ -148,6 +148,10 @@ export default class Thing extends CacheableObject {
     additionalFiles: () => ({
       flags: {update: true, expose: true},
       update: {validate: isAdditionalFileList},
+      expose: {
+        transform: (additionalFiles) =>
+          additionalFiles ?? [],
+      },
     }),
 
     // A reference list! Keep in mind this is for general references to wiki
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 6b1e958b..aecc876f 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -98,6 +98,8 @@ export class Track extends Thing {
     commentary: Thing.common.commentary(),
     lyrics: Thing.common.simpleString(),
     additionalFiles: Thing.common.additionalFiles(),
+    sheetMusicFiles: Thing.common.additionalFiles(),
+    midiProjectFiles: Thing.common.additionalFiles(),
 
     // Update only
 
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 9c3a4b88..01cb5501 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -251,6 +251,8 @@ export const processTrackDocument = makeProcessDocument(T.Track, {
     'Cover Artists': parseContributors,
 
     'Additional Files': parseAdditionalFiles,
+    'Sheet Music Files': parseAdditionalFiles,
+    'MIDI Project Files': parseAdditionalFiles,
   },
 
   propertyFieldMapping: {
@@ -278,6 +280,8 @@ export const processTrackDocument = makeProcessDocument(T.Track, {
     lyrics: 'Lyrics',
 
     additionalFiles: 'Additional Files',
+    sheetMusicFiles: 'Sheet Music Files',
+    midiProjectFiles: 'MIDI Project Files',
   },
 });
 
diff --git a/src/misc-templates.js b/src/misc-templates.js
index 8a61bf7f..1c6dda55 100644
--- a/src/misc-templates.js
+++ b/src/misc-templates.js
@@ -49,46 +49,31 @@ function unbound_generateAdditionalFilesList(additionalFiles, {
 }) {
   if (empty(additionalFiles)) return [];
 
-  const fileCount = additionalFiles.flatMap((g) => g.files).length;
-
-  return html.fragment([
-    html.tag('p',
-      {
-        id: 'additional-files',
-        class: ['content-heading'],
-      },
-      language.$('releaseInfo.additionalFiles.heading', {
-        additionalFiles: language.countAdditionalFiles(fileCount, {
-          unit: true,
-        }),
-      })),
-
-    html.tag('dl',
-      additionalFiles.flatMap(({title, description, files}) => [
-        html.tag('dt',
-          (description
-            ? language.$('releaseInfo.additionalFiles.entry.withDescription', {
-                title,
-                description,
-              })
-            : language.$('releaseInfo.additionalFiles.entry', {title}))),
-
-        html.tag('dd',
-          html.tag('ul',
-            files.map((file) => {
-              const size = getFileSize(file);
-              return html.tag('li',
-                (size
-                  ? language.$('releaseInfo.additionalFiles.file.withSize', {
-                      file: linkFile(file),
-                      size: language.formatFileSize(size),
-                    })
-                  : language.$('releaseInfo.additionalFiles.file', {
-                      file: linkFile(file),
-                    })));
-            }))),
-      ])),
-  ]);
+  return html.tag('dl',
+    additionalFiles.flatMap(({title, description, files}) => [
+      html.tag('dt',
+        (description
+          ? language.$('releaseInfo.additionalFiles.entry.withDescription', {
+              title,
+              description,
+            })
+          : language.$('releaseInfo.additionalFiles.entry', {title}))),
+
+      html.tag('dd',
+        html.tag('ul',
+          files.map((file) => {
+            const size = (getFileSize && getFileSize(file));
+            return html.tag('li',
+              (size
+                ? language.$('releaseInfo.additionalFiles.file.withSize', {
+                    file: linkFile(file),
+                    size: language.formatFileSize(size),
+                  })
+                : language.$('releaseInfo.additionalFiles.file', {
+                    file: linkFile(file),
+                  })))
+          }))),
+    ]));
 }
 
 // Artist strings
diff --git a/src/page/album.js b/src/page/album.js
index 897e5110..f4578ace 100644
--- a/src/page/album.js
+++ b/src/page/album.js
@@ -50,6 +50,8 @@ export function write(album, {wikiData}) {
   };
 
   const hasAdditionalFiles = !empty(album.additionalFiles);
+  const numAdditionalFiles = album.additionalFiles.flatMap((g) => g.files).length;
+
   const albumDuration = getTotalDuration(album.tracks);
 
   const displayTrackSections =
@@ -336,18 +338,22 @@ export function write(album, {wikiData}) {
               ]),
 
             ...html.fragment(
-              hasAdditionalFiles &&
-                generateAdditionalFilesList(album.additionalFiles, {
-                  // TODO: Kinda near the metal here...
-                  getFileSize: (file) =>
-                    getSizeOfAdditionalFile(
-                      urls.from('media.root').to(
-                        'media.albumAdditionalFile',
-                        album.directory,
-                        file)),
-                  linkFile: (file) =>
-                    link.albumAdditionalFile({album, file}),
-                })),
+              hasAdditionalFiles && [
+                html.tag('p',
+                  {id: 'additional-files', class: ['content-heading']},
+                  language.$('releaseInfo.additionalFiles.heading', {
+                    additionalFiles: language.countAdditionalFiles(numAdditionalFiles, {
+                      unit: true,
+                    }),
+                  })),
+
+                generateAlbumAdditionalFilesList(album, album.additionalFiles, {
+                  generateAdditionalFilesList,
+                  getSizeOfAdditionalFile,
+                  link,
+                  urls,
+                }),
+              ]),
 
             ...html.fragment(
               album.commentary && [
@@ -834,3 +840,26 @@ export function generateAlbumChronologyLinks(album, currentTrack, {
         })),
     ]);
 }
+
+export function generateAlbumAdditionalFilesList(album, additionalFiles, {
+  fileSize = true,
+
+  generateAdditionalFilesList,
+  getSizeOfAdditionalFile,
+  link,
+  urls,
+}) {
+  return generateAdditionalFilesList(additionalFiles, {
+    getFileSize:
+      (fileSize
+        ? (file) =>
+            // TODO: Kinda near the metal here...
+            getSizeOfAdditionalFile(
+              urls
+                .from('media.root')
+                .to('media.albumAdditionalFile', album.directory, file))
+        : () => null),
+    linkFile: (file) =>
+      link.albumAdditionalFile({album, file}),
+  });
+}
diff --git a/src/page/track.js b/src/page/track.js
index caba3668..b9038bac 100644
--- a/src/page/track.js
+++ b/src/page/track.js
@@ -5,6 +5,7 @@ import {
   generateAlbumNavLinks,
   generateAlbumSecondaryNav,
   generateAlbumSidebar,
+  generateAlbumAdditionalFilesList as unbound_generateAlbumAdditionalFilesList,
 } from './album.js';
 
 import {
@@ -73,6 +74,11 @@ export function write(track, {wikiData}) {
   const hasCommentary =
     track.commentary || otherReleases.some((t) => t.commentary);
 
+  const hasAdditionalFiles = !empty(track.additionalFiles);
+  const hasSheetMusicFiles = !empty(track.sheetMusicFiles);
+  const hasMidiProjectFiles = !empty(track.midiProjectFiles);
+  const numAdditionalFiles = album.additionalFiles.flatMap((g) => g.files).length;
+
   const generateCommentary = ({language, link, transformMultiline}) =>
     transformMultiline([
       track.commentary,
@@ -161,12 +167,15 @@ export function write(track, {wikiData}) {
     page: ({
       absoluteTo,
       fancifyURL,
+      generateAdditionalFilesList,
+      generateAdditionalFilesShortcut,
       generateChronologyLinks,
       generateNavigationLinks,
       generateTrackListDividedByGroups,
       getAlbumStylesheet,
       getArtistString,
       getLinkThemeString,
+      getSizeOfAdditionalFile,
       getThemeString,
       getTrackCover,
       html,
@@ -184,6 +193,14 @@ export function write(track, {wikiData}) {
         link,
       });
 
+      const generateAlbumAdditionalFilesList = bindOpts(unbound_generateAlbumAdditionalFilesList, {
+        [bindOpts.bindIndex]: 2,
+        generateAdditionalFilesList,
+        getSizeOfAdditionalFile,
+        link,
+        urls,
+      });
+
       return {
         title: language.$('trackPage.title', {track: track.name}),
         stylesheet: getAlbumStylesheet(album, {to}),
@@ -274,6 +291,30 @@ export function write(track, {wikiData}) {
               ]),
 
             html.tag('p',
+              {
+                [html.onlyIfContent]: true,
+                [html.joinChildren]: '<br>',
+              },
+              [
+                hasSheetMusicFiles &&
+                  language.$('releaseInfo.sheetMusicFiles.shortcut', {
+                    link: html.tag('a',
+                      {href: '#sheet-music-files'},
+                      language.$('releaseInfo.sheetMusicFiles.shortcut.link')),
+                  }),
+
+                hasMidiProjectFiles &&
+                  language.$('releaseInfo.midiProjectFiles.shortcut', {
+                    link: html.tag('a',
+                      {href: '#midi-project-files'},
+                      language.$('releaseInfo.midiProjectFiles.shortcut.link')),
+                  }),
+
+                hasAdditionalFiles &&
+                  generateAdditionalFilesShortcut(track.additionalFiles),
+              ]),
+
+            html.tag('p',
               (empty(track.urls)
                 ? language.$('releaseInfo.listenOn.noLinks')
                 : language.$('releaseInfo.listenOn', {
@@ -378,6 +419,39 @@ export function write(track, {wikiData}) {
               ]),
 
             ...html.fragment(
+              hasSheetMusicFiles && [
+                html.tag('p',
+                  {id: 'sheet-music-files', class: ['content-heading']},
+                  language.$('releaseInfo.sheetMusicFiles.heading')),
+
+                generateAlbumAdditionalFilesList(album, track.sheetMusicFiles, {
+                  fileSize: false,
+                }),
+              ]),
+
+            ...html.fragment(
+              hasMidiProjectFiles && [
+                html.tag('p',
+                  {id: 'midi-project-files', class: ['content-heading']},
+                  language.$('releaseInfo.midiProjectFiles.heading')),
+
+                generateAlbumAdditionalFilesList(album, track.midiProjectFiles),
+              ]),
+
+            ...html.fragment(
+              hasAdditionalFiles && [
+                html.tag('p',
+                  {id: 'additional-files', class: ['content-heading']},
+                  language.$('releaseInfo.additionalFiles.heading', {
+                    additionalFiles: language.countAdditionalFiles(numAdditionalFiles, {
+                      unit: true,
+                    }),
+                  })),
+
+                generateAlbumAdditionalFilesList(album, track.additionalFiles),
+              ]),
+
+            ...html.fragment(
               hasCommentary && [
                 html.tag('p', {class: ['content-heading']},
                   language.$('releaseInfo.artistCommentary')),
diff --git a/src/strings-default.json b/src/strings-default.json
index 0faa4f7c..5d6935e1 100644
--- a/src/strings-default.json
+++ b/src/strings-default.json
@@ -118,11 +118,17 @@
   "releaseInfo.artTags.inline": "Tags: {TAGS}",
   "releaseInfo.additionalFiles.shortcut": "{ANCHOR_LINK} {TITLES}",
   "releaseInfo.additionalFiles.shortcut.anchorLink": "Additional files:",
-  "releaseInfo.additionalFiles.heading": "Has {ADDITIONAL_FILES}:",
+  "releaseInfo.additionalFiles.heading": "View or download {ADDITIONAL_FILES}:",
   "releaseInfo.additionalFiles.entry": "{TITLE}",
   "releaseInfo.additionalFiles.entry.withDescription": "{TITLE}: {DESCRIPTION}",
   "releaseInfo.additionalFiles.file": "{FILE}",
   "releaseInfo.additionalFiles.file.withSize": "{FILE} ({SIZE})",
+  "releaseInfo.sheetMusicFiles.shortcut": "Download {LINK}.",
+  "releaseInfo.sheetMusicFiles.shortcut.link": "sheet music files",
+  "releaseInfo.sheetMusicFiles.heading": "Print or download sheet music files:",
+  "releaseInfo.midiProjectFiles.shortcut": "Download {LINK}.",
+  "releaseInfo.midiProjectFiles.shortcut.link": "MIDI/project files",
+  "releaseInfo.midiProjectFiles.heading": "Download MIDI/project files:",
   "releaseInfo.note": "Note:",
   "trackList.section.withDuration": "{SECTION} ({DURATION}):",
   "trackList.group": "{GROUP}:",
diff --git a/src/upd8.js b/src/upd8.js
index 39372833..fd565228 100755
--- a/src/upd8.js
+++ b/src/upd8.js
@@ -627,7 +627,11 @@ async function main() {
     ...wikiData.albumData.flatMap((album) =>
       [
         ...(album.additionalFiles ?? []),
-        ...album.tracks.flatMap((track) => track.additionalFiles ?? []),
+        ...album.tracks.flatMap((track) => [
+          ...(track.additionalFiles ?? []),
+          ...(track.sheetMusicFiles ?? []),
+          ...(track.midiProjectFiles ?? []),
+        ]),
       ]
         .flatMap((fileGroup) => fileGroup.files)
         .map((file) => ({