« 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/Track.js88
-rw-r--r--src/data/things/album/Album.js26
-rw-r--r--src/data/yaml.js10
3 files changed, 87 insertions, 37 deletions
diff --git a/src/data/things/Track.js b/src/data/things/Track.js
index 876a6542..fbcc57d4 100644
--- a/src/data/things/Track.js
+++ b/src/data/things/Track.js
@@ -10,6 +10,7 @@ import Thing from '#thing';
 import {compareKebabCase} from '#wiki-data';
 
 import {
+  is,
   isBoolean,
   isColor,
   isContentString,
@@ -22,6 +23,7 @@ import {
 import {
   parseAdditionalFiles,
   parseAdditionalNames,
+  parseAlwaysReferenceByDirectory,
   parseAnnotatedReferences,
   parseArtwork,
   parseCommentary,
@@ -143,26 +145,31 @@ export class Track extends Thing {
       exposeDependency('#trackSection.suffixTrackDirectories'),
     ],
 
-    // Controls how find.track works - it'll never be matched by
-    // a reference just to the track's name, which means you don't
-    // have to always reference some *other* (much more commonly
-    // referenced) track by directory instead of more naturally by name.
-    alwaysReferenceByDirectory: [
+    referenceByDirectory: [
       exposeUpdateValueOrContinue({
-        validate: input.value(isBoolean),
+        validate: input.value(
+          is(...[
+            'always',
+            'outside album',
+            // 'outside groups',
+            'normally',
+          ])),
       }),
 
-      withPropertyFromObject('album', V('alwaysReferenceTracksByDirectory')),
+      withPropertyFromObject('album', V('referenceTracksByDirectory')),
 
-      // Falsy mode means this exposes true if the album's property is true,
-      // but continues if the property is false (which is also the default).
-      exposeDependencyOrContinue({
-        dependency: '#album.alwaysReferenceTracksByDirectory',
-        mode: input.value('falsy'),
-      }),
+      {
+        dependencies: ['#album.referenceTracksByDirectory'],
+        compute: (continuation, {
+          ['#album.referenceTracksByDirectory']: referenceTracksByDirectory,
+        }) =>
+          (referenceTracksByDirectory === 'normally'
+            ? continuation()
+            : referenceTracksByDirectory),
+      },
 
-      exitWithoutDependency('_mainRelease', V(false)),
-      exitWithoutDependency('mainReleaseTrack', V(false)),
+      exitWithoutDependency('_mainRelease', V('normally')),
+      exitWithoutDependency('mainReleaseTrack', V('normally')),
 
       withPropertyFromObject('mainReleaseTrack', V('name')),
 
@@ -172,7 +179,9 @@ export class Track extends Thing {
           ['name']: name,
           ['#mainReleaseTrack.name']: mainReleaseName,
         }) =>
-          compareKebabCase(name, mainReleaseName),
+          (compareKebabCase(name, mainReleaseName)
+            ? 'always'
+            : 'normally'),
       },
     ],
 
@@ -888,7 +897,14 @@ export class Track extends Thing {
       'Track Text': {property: 'nameText'},
       'Directory': {property: 'directory'},
       'Suffix Directory': {property: 'suffixDirectoryFromAlbum'},
-      'Always Reference By Directory': {property: 'alwaysReferenceByDirectory'},
+
+      'Reference By Directory': {property: 'referenceByDirectory'},
+
+      'Always Reference By Directory': {
+        property: 'referenceByDirectory',
+        transform: parseAlwaysReferenceByDirectory,
+      },
+
       'Main Release': {property: 'mainRelease'},
 
       'Bandcamp Track ID': {
@@ -1096,10 +1112,12 @@ export class Track extends Thing {
 
       bindTo: 'trackData',
 
+      // When referencing without any particular context, all values
+      // except for 'normally' count against referencing by name.
       getMatchableNames: track =>
-        (track.alwaysReferenceByDirectory
-          ? []
-          : [track.name]),
+        (track.referenceByDirectory === 'normally'
+          ? [track.name]
+          : []),
     },
 
     trackMainReleasesOnly: {
@@ -1109,14 +1127,11 @@ export class Track extends Thing {
       include: track =>
         !CacheableObject.getUpdateValue(track, 'mainRelease'),
 
-      // It's still necessary to check alwaysReferenceByDirectory here, since
-      // it may be set manually (with `Always Reference By Directory: true`),
-      // and these shouldn't be matched by name (as per usual).
-      // See the definition for that property for more information.
+      // This is an acontextual reference.
       getMatchableNames: track =>
-        (track.alwaysReferenceByDirectory
-          ? []
-          : [track.name]),
+        (track.referenceByDirectory === 'normally'
+          ? [track.name]
+          : []),
     },
 
     trackReference: {
@@ -1146,8 +1161,9 @@ export class Track extends Thing {
         const referencedName = fullRef;
 
         for (const track of referencingTrack.album.tracks) {
-          // Totally ignore alwaysReferenceByDirectory here.
-          // void track.alwaysReferenceByDirectory;
+          if (track.referenceByDirectory === 'always') {
+            continue;
+          }
 
           if (track.name === referencedName) {
             if (track.isSecondaryRelease) {
@@ -1174,10 +1190,11 @@ export class Track extends Thing {
       include: track =>
         track.hasUniqueCoverArt,
 
+      // This is an acontextual reference.
       getMatchableNames: track =>
-        (track.alwaysReferenceByDirectory
-          ? []
-          : [track.name]),
+        (track.referenceByDirectory === 'normally'
+          ? [track.name]
+          : []),
     },
 
     trackPrimaryArtwork: {
@@ -1196,10 +1213,11 @@ export class Track extends Thing {
         artwork.thing.isTrack &&
         artwork === artwork.thing.trackArtworks[0],
 
+      // This is an acontextual reference.
       getMatchableNames: ({thing: track}) =>
-        (track.alwaysReferenceByDirectory
-          ? []
-          : [track.name]),
+        (track.referenceByDirectory === 'normally'
+          ? [track.name]
+          : []),
 
       getMatchableDirectories: ({thing: track}) =>
         [track.directory],
diff --git a/src/data/things/album/Album.js b/src/data/things/album/Album.js
index 8dcc6854..61420e52 100644
--- a/src/data/things/album/Album.js
+++ b/src/data/things/album/Album.js
@@ -7,6 +7,7 @@ import {is, isContributionList, isDate, isDirectory, isNumber}
 import {
   parseAdditionalFiles,
   parseAdditionalNames,
+  parseAlwaysReferenceByDirectory,
   parseAnnotatedReferences,
   parseArtwork,
   parseCommentary,
@@ -100,7 +101,21 @@ export class Album extends Thing {
     ],
 
     alwaysReferenceByDirectory: flag(V(false)),
-    alwaysReferenceTracksByDirectory: flag(V(false)),
+
+    referenceTracksByDirectory: [
+      exposeUpdateValueOrContinue({
+        validate: input.value(
+          is(...[
+            'always',
+            'outside album',
+            // 'outside groups',
+            'normally',
+          ])),
+      }),
+
+      exposeConstant(V('normally')),
+    ],
+
     suffixTrackDirectories: flag(V(false)),
 
     style: [
@@ -567,7 +582,14 @@ export class Album extends Thing {
       'Directory Suffix': {property: 'directorySuffix'},
       'Suffix Track Directories': {property: 'suffixTrackDirectories'},
       'Always Reference By Directory': {property: 'alwaysReferenceByDirectory'},
-      'Always Reference Tracks By Directory': {property: 'alwaysReferenceTracksByDirectory'},
+
+      'Reference Tracks By Directory': {property: 'referenceTracksByDirectory'},
+
+      'Always Reference Tracks By Directory': {
+        property: 'referenceTracksByDirectory',
+        transform: parseAlwaysReferenceByDirectory,
+      },
+
       'Style': {property: 'style'},
 
       'Bandcamp Album ID': {
diff --git a/src/data/yaml.js b/src/data/yaml.js
index 7ba6d559..0519986b 100644
--- a/src/data/yaml.js
+++ b/src/data/yaml.js
@@ -640,6 +640,16 @@ export function parseDuration(string) {
   }
 }
 
+export function parseAlwaysReferenceByDirectory(value) {
+  if (value === true) {
+    return 'always';
+  } else if (value === false) {
+    return 'normally';
+  } else {
+    return value;
+  }
+}
+
 export const extractAccentRegex =
   /^(?<main>.*?)(?: \((?<accent>.*)\))?$/;