« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/data/composite/wiki-properties/hasArtwork.js95
-rw-r--r--src/data/things/Track.js142
-rw-r--r--src/data/things/album/Album.js36
3 files changed, 114 insertions, 159 deletions
diff --git a/src/data/composite/wiki-properties/hasArtwork.js b/src/data/composite/wiki-properties/hasArtwork.js
index e403a7e2..398766c1 100644
--- a/src/data/composite/wiki-properties/hasArtwork.js
+++ b/src/data/composite/wiki-properties/hasArtwork.js
@@ -1,14 +1,7 @@
 import {input, templateCompositeFrom, V} from '#composite';
-import {isContributionList, isThing, strictArrayOf} from '#validators';
-
-import {fillMissingListItems, withFlattenedList, withPropertyFromList}
-  from '#composite/data';
-
-import {
-  exitWithoutDependency,
-  exposeWhetherDependencyAvailable,
-  withResultOfAvailabilityCheck,
-} from '#composite/control-flow';
+import {empty} from '#sugar';
+import {isBoolean, isContributionList, isThing, strictArrayOf}
+  from '#validators';
 
 export default templateCompositeFrom({
   annotation: 'hasArtwork',
@@ -30,61 +23,53 @@ export default templateCompositeFrom({
     }),
   },
 
+  update: {
+    validate: isBoolean,
+  },
+
   compose: false,
 
   steps: () => [
-    withResultOfAvailabilityCheck({
-      from: input('contribs'),
-      mode: input.value('empty'),
-    }),
-
     {
-      dependencies: ['#availability'],
-      compute: (continuation, {
-        ['#availability']: availability,
-      }) =>
-        (availability
-          ? true
-          : continuation()),
+      transform(value, continuation) {
+        if (value === true) {
+          return true;
+        }
+
+        if (value === false) {
+          return false;
+        }
+
+        return continuation();
+      },
     },
 
     {
-      dependencies: [input('artwork'), input('artworks')],
-      compute: (continuation, {
+      dependencies: [
+        input('contribs'),
+        input('artwork'),
+        input('artworks'),
+      ],
+
+      compute({
+        [input('contribs')]: contribs,
         [input('artwork')]: artwork,
         [input('artworks')]: artworks,
-      }) =>
-        continuation({
-          ['#artworks']:
-            (artwork && artworks
-              ? [artwork, ...artworks]
-           : artwork
-              ? [artwork]
-           : artworks
-              ? artworks
-              : []),
-        }),
-    },
-
-    exitWithoutDependency('#artworks', {
-      value: input.value(false),
-      mode: input.value('empty'),
-    }),
+      }) {
+        if (!empty(contribs)) {
+          return true;
+        }
 
-    withPropertyFromList('#artworks', {
-      property: input.value('artistContribs'),
-      internal: input.value(true),
-    }),
-
-    // Since we're getting the update value for each artwork's artistContribs,
-    // it may not be set at all, and in that case won't be exposing as [].
-    fillMissingListItems('#artworks.artistContribs', V([])),
+        if (artwork) {
+          return true;
+        }
 
-    withFlattenedList('#artworks.artistContribs'),
+        if (!empty(artworks)) {
+          return true;
+        }
 
-    exposeWhetherDependencyAvailable({
-      dependency: '#flattenedList',
-      mode: input.value('empty'),
-    }),
+        return false;
+      },
+    },
   ],
-});
\ No newline at end of file
+});
diff --git a/src/data/things/Track.js b/src/data/things/Track.js
index 19d111e9..8cee520d 100644
--- a/src/data/things/Track.js
+++ b/src/data/things/Track.js
@@ -4,7 +4,7 @@ import CacheableObject from '#cacheable-object';
 import {colors} from '#cli';
 import {input, V} from '#composite';
 import find, {keyRefRegex} from '#find';
-import {onlyItem} from '#sugar';
+import {empty, onlyItem} from '#sugar';
 import {sortByDate, sortFlashesChronologically} from '#sort';
 import Thing from '#thing';
 import {compareKebabCase, getKebabCase} from '#wiki-data';
@@ -349,7 +349,56 @@ export class Track extends Thing {
 
     showInReferenceLists: flag(V(true)),
 
-    disableUniqueCoverArt: flag(V(false)),
+    // This property doesn't resolve any references, i.e. doesn't interact
+    // with find/reverse, so it's safe to depend on when constituting artworks
+    // (or elsewhere while loading data).
+    hasUniqueCoverArt: {
+      flags: {update: true, expose: true},
+
+      update: {validate: isBoolean},
+
+      expose: {
+        dependencies: [
+           'album',
+          '_trackArtworks',
+          '_coverArtistContribs',
+        ],
+
+        transform(hasUniqueCoverArtUpdateValue, {
+          [ 'album']: album,
+          ['_trackArtworks']: trackArtworksUpdateValue,
+          ['_coverArtistContribs']: coverArtistContribsUpdateValue,
+        }) {
+          if (hasUniqueCoverArtUpdateValue === true) {
+            return true;
+          }
+
+          if (hasUniqueCoverArtUpdateValue === false) {
+            return false;
+          }
+
+          if (!empty(trackArtworksUpdateValue)) {
+            return true;
+          }
+
+          if (!empty(coverArtistContribsUpdateValue)) {
+            return true;
+          }
+
+          if (album) {
+            const trackCoverArtistContribsUpdateValue =
+              CacheableObject.getUpdateValue(album, 'trackCoverArtistContribs');
+
+            if (!empty(trackCoverArtistContribsUpdateValue)) {
+              return true;
+            }
+          }
+
+          return false;
+        },
+      },
+    },
+
     disableDate: flag(V(false)),
 
     // > Update & expose - General metadata
@@ -760,84 +809,6 @@ export class Track extends Thing {
       },
     ],
 
-    // Whether or not the track has "unique" cover artwork - a cover which is
-    // specifically associated with this track in particular, rather than with
-    // the track's album as a whole. This is typically used to select between
-    // displaying the track artwork and a fallback, such as the album artwork
-    // or a placeholder. (This property is named hasUniqueCoverArt instead of
-    // the usual hasCoverArt to emphasize that it does not inherit from the
-    // album.)
-    //
-    // hasUniqueCoverArt is based only around the presence of *specified*
-    // cover artist contributions, not whether the references to artists on those
-    // contributions actually resolve to anything. It completely evades interacting
-    // with find/replace.
-    hasUniqueCoverArt: [
-      {
-        dependencies: ['disableUniqueCoverArt'],
-        compute: (continuation, {disableUniqueCoverArt}) =>
-          (disableUniqueCoverArt
-            ? false
-            : continuation()),
-      },
-
-      withResultOfAvailabilityCheck({
-        from: '_coverArtistContribs',
-        mode: input.value('empty'),
-      }),
-
-      {
-        dependencies: ['#availability'],
-        compute: (continuation, {
-          ['#availability']: availability,
-        }) =>
-          (availability
-            ? true
-            : continuation()),
-      },
-
-      withPropertyFromObject('album', {
-        property: input.value('trackCoverArtistContribs'),
-        internal: input.value(true),
-      }),
-
-      withResultOfAvailabilityCheck({
-        from: '#album.trackCoverArtistContribs',
-        mode: input.value('empty'),
-      }),
-
-      {
-        dependencies: ['#availability'],
-        compute: (continuation, {
-          ['#availability']: availability,
-        }) =>
-          (availability
-            ? true
-            : continuation()),
-      },
-
-      exitWithoutDependency('_trackArtworks', {
-        value: input.value(false),
-        mode: input.value('empty'),
-      }),
-
-      withPropertyFromList('_trackArtworks', {
-        property: input.value('artistContribs'),
-        internal: input.value(true),
-      }),
-
-      // Since we're getting the update value for each artwork's artistContribs,
-      // it may not be set at all, and in that case won't be exposing as [].
-      fillMissingListItems('#trackArtworks.artistContribs', V([])),
-
-      withFlattenedList('#trackArtworks.artistContribs'),
-
-      exposeWhetherDependencyAvailable({
-        dependency: '#flattenedList',
-        mode: input.value('empty'),
-      }),
-    ],
-
     isMainRelease:
       exposeWhetherDependencyAvailable({
         dependency: 'mainReleaseTrack',
@@ -1151,15 +1122,8 @@ export class Track extends Thing {
       'Count In Artist Totals': {property: 'countInArtistTotals'},
       'Show In Reference Lists': {property: 'showInReferenceLists'},
 
-      'Has Cover Art': {
-        property: 'disableUniqueCoverArt',
-        transform: flipBoolean,
-      },
-
-      'Has Date': {
-        property: 'disableDate',
-        transform: flipBoolean,
-      },
+      'Has Cover Art': {property: 'hasUniqueCoverArt'},
+      'Has Date': {property: 'disableDate', transform: flipBoolean},
 
       // General metadata
 
diff --git a/src/data/things/album/Album.js b/src/data/things/album/Album.js
index 372cddb1..621c34ba 100644
--- a/src/data/things/album/Album.js
+++ b/src/data/things/album/Album.js
@@ -227,6 +227,11 @@ export class Album extends Thing {
         .call(this, 'Cover Artwork'),
     ],
 
+    hasCoverArt: hasArtwork({
+      contribs: '_coverArtistContribs',
+      artworks: '_coverArtworks',
+    }),
+
     coverArtistContribs: contributionList({
       date: 'coverArtDate',
       artistProperty: input.value('albumCoverArtistContributions'),
@@ -315,6 +320,11 @@ export class Album extends Thing {
         .call(this, 'Wallpaper Artwork'),
     ],
 
+    hasWallpaperArt: hasArtwork({
+      contribs: '_wallpaperArtistContribs',
+      artwork: '_wallpaperArtwork',
+    }),
+
     wallpaperArtistContribs: contributionList({
       class: input.value(AlbumWallpaperArtistContribution),
       date: 'coverArtDate',
@@ -358,6 +368,11 @@ export class Album extends Thing {
         .call(this, 'Banner Artwork'),
     ],
 
+    hasBannerArt: hasArtwork({
+      contribs: '_bannerArtistContribs',
+      artwork: '_bannerArtwork',
+    }),
+
     bannerArtistContribs: contributionList({
       class: input.value(AlbumBannerArtistContribution),
       date: 'coverArtDate',
@@ -428,21 +443,6 @@ export class Album extends Thing {
 
     commentatorArtists: commentatorArtists(),
 
-    hasCoverArt: hasArtwork({
-      contribs: '_coverArtistContribs',
-      artworks: '_coverArtworks',
-    }),
-
-    hasWallpaperArt: hasArtwork({
-      contribs: '_wallpaperArtistContribs',
-      artwork: '_wallpaperArtwork',
-    }),
-
-    hasBannerArt: hasArtwork({
-      contribs: '_bannerArtistContribs',
-      artwork: '_bannerArtwork',
-    }),
-
     tracks: [
       exitWithoutDependency('trackSections', V([])),
 
@@ -737,6 +737,8 @@ export class Album extends Thing {
           }),
       },
 
+      'Has Cover Art': {property: 'hasCoverArt'},
+
       'Cover Artists': {
         property: 'coverArtistContribs',
         transform: parseContributors,
@@ -767,6 +769,8 @@ export class Album extends Thing {
         transform: parseDimensions,
       },
 
+      'Has Wallpaper Art': {property: 'hasWallpaperArt'},
+
       'Wallpaper Artists': {
         property: 'wallpaperArtistContribs',
         transform: parseContributors,
@@ -779,6 +783,8 @@ export class Album extends Thing {
         transform: parseWallpaperParts,
       },
 
+      'Has Banner Art': {property: 'hasBannerArt'},
+
       'Banner Artists': {
         property: 'bannerArtistContribs',
         transform: parseContributors,