« get me outta code hell

data, yaml: inherit music-related properties from original release - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/track.js
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2023-08-15 22:05:36 -0300
committer(quasar) nebula <qznebula@protonmail.com>2023-08-15 22:05:36 -0300
commit7e7117e2e1c3d72393289f63695d4f86d358e7ed (patch)
tree68d6e3c5b16328f282ce7f6b4d4536a36aa2cd70 /src/data/things/track.js
parentd908377fa3d7a90df344744a9d2429c4a4095d01 (diff)
data, yaml: inherit music-related properties from original release
When a track has 'Originally Released As', these fields are now
automatically inherited:

* Artists
* Contributors
* Referenced Tracks
* Sampled Tracks

Including any of these fields alongside 'Originally Released As'
is an error.

Corresponding properties are valid, but ignored.

This uses a new "compositional" style to define how each of these
properties inherits while retaining the original behavior for
tracks that aren't re-releases, and avoids hard-coding much of
anything!
Diffstat (limited to 'src/data/things/track.js')
-rw-r--r--src/data/things/track.js100
1 files changed, 71 insertions, 29 deletions
diff --git a/src/data/things/track.js b/src/data/things/track.js
index 98a9fdd1..36e3adbe 100644
--- a/src/data/things/track.js
+++ b/src/data/things/track.js
@@ -245,35 +245,43 @@ export class Track extends Thing {
       },
     },
 
-    artistContribs: Thing.common.dynamicInheritContribs(
-      null,
-      'artistContribsByRef',
-      'artistContribsByRef',
-      'albumData',
-      Track.findAlbum
-    ),
-
-    contributorContribs: Thing.common.dynamicContribs('contributorContribsByRef'),
-
-    coverArtistContribs: Thing.common.dynamicInheritContribs(
-      'hasCoverArt',
-      'coverArtistContribsByRef',
-      'trackCoverArtistContribsByRef',
-      'albumData',
-      Track.findAlbum
-    ),
-
-    referencedTracks: Thing.common.dynamicThingsFromReferenceList(
-      'referencedTracksByRef',
-      'trackData',
-      find.track
-    ),
-
-    sampledTracks: Thing.common.dynamicThingsFromReferenceList(
-      'sampledTracksByRef',
-      'trackData',
-      find.track
-    ),
+    artistContribs:
+      Track.inheritFromOriginalRelease('artistContribs', [],
+        Thing.common.dynamicInheritContribs(
+          null,
+          'artistContribsByRef',
+          'artistContribsByRef',
+          'albumData',
+          Track.findAlbum)),
+
+    contributorContribs:
+      Track.inheritFromOriginalRelease('contributorContribs', [],
+        Thing.common.dynamicContribs('contributorContribsByRef')),
+
+    // Cover artists aren't inherited from the original release, since it
+    // typically varies by release and isn't defined by the musical qualities
+    // of the track.
+    coverArtistContribs:
+      Thing.common.dynamicInheritContribs(
+        'hasCoverArt',
+        'coverArtistContribsByRef',
+        'trackCoverArtistContribsByRef',
+        'albumData',
+        Track.findAlbum),
+
+    referencedTracks:
+      Track.inheritFromOriginalRelease('referencedTracks', [],
+        Thing.common.dynamicThingsFromReferenceList(
+          'referencedTracksByRef',
+          'trackData',
+          find.track)),
+
+    sampledTracks:
+      Track.inheritFromOriginalRelease('sampledTracks', [],
+        Thing.common.dynamicThingsFromReferenceList(
+          'sampledTracksByRef',
+          'trackData',
+          find.track)),
 
     // Specifically exclude re-releases from this list - while it's useful to
     // get from a re-release to the tracks it references, re-releases aren't
@@ -373,6 +381,40 @@ export class Track extends Thing {
     return false;
   }
 
+  static inheritFromOriginalRelease(
+    originalProperty,
+    originalMissingValue,
+    ownPropertyDescriptor
+  ) {
+    return {
+      flags: {expose: true},
+
+      expose: {
+        dependencies: [
+          ...ownPropertyDescriptor.expose.dependencies,
+          'originalReleaseTrackByRef',
+          'trackData',
+        ],
+
+        compute(dependencies) {
+          const {
+            originalReleaseTrackByRef,
+            trackData,
+          } = dependencies;
+
+          if (originalReleaseTrackByRef) {
+            if (!trackData) return originalMissingValue;
+            const original = find.track(originalReleaseTrackByRef, trackData, {mode: 'quiet'});
+            if (!original) return originalMissingValue;
+            return original[originalProperty];
+          }
+
+          return ownPropertyDescriptor.expose.compute(dependencies);
+        },
+      },
+    };
+  }
+
   [inspect.custom]() {
     const base = Thing.prototype[inspect.custom].apply(this);