From e6038d8c07971447f444cf597328ca8d9863f8fd Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sat, 26 Aug 2023 21:18:43 -0300 Subject: data, test: Track.color inherits from track section --- src/data/things/thing.js | 2 +- src/data/things/track.js | 69 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/data/things/thing.js b/src/data/things/thing.js index 2adba5c4..f5dc786e 100644 --- a/src/data/things/thing.js +++ b/src/data/things/thing.js @@ -1127,7 +1127,7 @@ export default class Thing extends CacheableObject { // compositional step, the property will be exposed as undefined instead // of null. // - expose: (dependency, {update = false} = {}) => ({ + exposeDependency: (dependency, {update = false} = {}) => ({ annotation: `Thing.composite.expose`, flags: {expose: true, update: !!update}, diff --git a/src/data/things/track.js b/src/data/things/track.js index 8d0a7ad4..621044d5 100644 --- a/src/data/things/track.js +++ b/src/data/things/track.js @@ -46,8 +46,25 @@ export class Track extends Thing { color: Thing.composite.from(`Track.color`, [ Thing.composite.exposeUpdateValueOrContinue(), + Track.composite.withContainingTrackSection({earlyExitIfNotFound: false}), + + { + flags: {expose: true, compose: true}, + expose: { + dependencies: ['#trackSection'], + compute: ({'#trackSection': trackSection}, continuation) => + // Album.trackSections guarantees the track section will have a + // color property (inheriting from the album's own color), but only + // if it's actually present! Color will be inherited directly from + // album otherwise. + (trackSection + ? trackSection.color + : continuation()), + }, + }, + Track.composite.withAlbumProperty('color'), - Thing.composite.expose('#album.color', { + Thing.composite.exposeDependency('#album.color', { update: {validate: isColor}, }), ]), @@ -157,7 +174,7 @@ export class Track extends Thing { album: Thing.composite.from(`Track.album`, [ Track.composite.withAlbum(), - Thing.composite.expose('#album'), + Thing.composite.exposeDependency('#album'), ]), // Note - this is an internal property used only to help identify a track. @@ -183,8 +200,8 @@ export class Track extends Thing { }, }, - Track.composite.withAlbumProperties({properties: ['date']}), - Thing.composite.expose('#album.date'), + Track.composite.withAlbumProperty('date'), + Thing.composite.exposeDependency('#album.date'), ]), // Whether or not the track has "unique" cover artwork - a cover which is @@ -342,7 +359,7 @@ export class Track extends Thing { }, Track.composite.withAlbumProperty('trackCoverArtistContribs'), - Thing.composite.expose('#album.trackCoverArtistContribs'), + Thing.composite.exposeDependency('#album.trackCoverArtistContribs'), ]), referencedTracks: Thing.composite.from(`Track.referencedTracks`, [ @@ -435,7 +452,7 @@ export class Track extends Thing { ]), // Gets the track's album. Unless earlyExitIfNotFound is overridden false, - // this will early-exit with null in two cases - albumData being missing, + // this will early exit with null in two cases - albumData being missing, // or not including an album whose .tracks array includes this track. withAlbum: ({to = '#album', earlyExitIfNotFound = true} = {}) => ({ annotation: `Track.composite.withAlbum`, @@ -542,6 +559,46 @@ export class Track extends Thing { }, ]), + // Gets the track section containing this track from its album's track list. + // Unless earlyExitIfNotFound is overridden false, this will early exit if + // the album can't be found or if none of its trackSections includes the + // track for some reason. + withContainingTrackSection: ({ + to = '#trackSection', + earlyExitIfNotFound = true, + } = {}) => + Thing.composite.from(`Track.composite.withContainingTrackSection`, [ + Track.composite.withAlbumProperty('trackSections', {earlyExitIfNotFound}), + + { + flags: {expose: true, compose: true}, + expose: { + dependencies: ['this', '#album.trackSections'], + mapContinuation: {to}, + + compute({ + this: track, + '#album.trackSections': trackSections, + }, continuation) { + if (!trackSections) { + return continuation.raise({to: null}); + } + + const trackSection = + trackSections.find(({tracks}) => tracks.includes(track)); + + if (trackSection) { + return continuation.raise({to: trackSection}); + } else if (earlyExitIfNotFound) { + return continuation.exit(null); + } else { + return continuation.raise({to: null}); + } + }, + }, + }, + ]), + // Just includes the original release of this track as a dependency, or // null, if it's not a rerelease. Note that this will early exit if the // original release is specified by reference and that reference doesn't -- cgit 1.3.0-6-gf8a5