diff options
author | (quasar) nebula <qznebula@protonmail.com> | 2024-05-19 21:44:18 -0300 |
---|---|---|
committer | (quasar) nebula <qznebula@protonmail.com> | 2024-05-19 21:47:31 -0300 |
commit | 048e79a1ea83a942579ce89f797795e34cc4199e (patch) | |
tree | c810109a93bc5fe1dbae611bb6efb212846df00f /src/data/things | |
parent | 471de6e5ac73bd6c769a58392e3e49aff6d8f2cb (diff) |
data: TrackSection thing objects
Sorry this commit is kind of monolithic! It's difficult to separate out any of the changes since they're all related to track sections' basic functionality.
Diffstat (limited to 'src/data/things')
-rw-r--r-- | src/data/things/album.js | 187 |
1 files changed, 139 insertions, 48 deletions
diff --git a/src/data/things/album.js b/src/data/things/album.js index f8354962..78ecb294 100644 --- a/src/data/things/album.js +++ b/src/data/things/album.js @@ -6,15 +6,17 @@ import {input} from '#composite'; import find from '#find'; import {traverse} from '#node-utils'; import {sortAlbumsTracksChronologically, sortChronologically} from '#sort'; -import {empty} from '#sugar'; +import {accumulateSum, empty} from '#sugar'; import Thing from '#thing'; -import {isDate} from '#validators'; +import {isColor, isDate, validateWikiData} from '#validators'; import {parseAdditionalFiles, parseContributors, parseDate, parseDimensions} from '#yaml'; -import {exposeDependency, exposeUpdateValueOrContinue} +import {exitWithoutDependency, exposeDependency, exposeUpdateValueOrContinue} from '#composite/control-flow'; -import {exitWithoutContribs} from '#composite/wiki-data'; +import {withPropertyFromObject} from '#composite/data'; +import {exitWithoutContribs, withDirectory, withResolvedReference} + from '#composite/wiki-data'; import { additionalFiles, @@ -31,16 +33,24 @@ import { referenceList, simpleDate, simpleString, + singleReference, urls, wikiData, } from '#composite/wiki-properties'; -import {withTracks, withTrackSections} from '#composite/things/album'; +import {withTracks} from '#composite/things/album'; +import {withAlbum} from '#composite/things/track-section'; export class Album extends Thing { static [Thing.referenceType] = 'album'; - static [Thing.getPropertyDescriptors] = ({ArtTag, Artist, Group, Track}) => ({ + static [Thing.getPropertyDescriptors] = ({ + ArtTag, + Artist, + Group, + Track, + TrackSection, + }) => ({ // Update & expose name: name('Unnamed Album'), @@ -111,10 +121,17 @@ export class Album extends Thing { commentary: commentary(), additionalFiles: additionalFiles(), - trackSections: [ - withTrackSections(), - exposeDependency({dependency: '#trackSections'}), - ], + trackSections: { + flags: {update: true, expose: true}, + + update: { + validate: + validateWikiData({ + referenceType: + TrackSection[Thing.referenceType], + }), + }, + }, artistContribs: contributionList(), coverArtistContribs: contributionList(), @@ -155,13 +172,6 @@ export class Album extends Thing { class: input.value(Group), }), - // Only the tracks which belong to this album. - // Necessary for computing the track list, so provide this statically - // or keep it updated. - ownTrackData: wikiData({ - class: input.value(Track), - }), - // Expose only commentatorArtists: commentatorArtists(), @@ -345,7 +355,7 @@ export class Album extends Thing { headerDocumentThing: Album, entryDocumentThing: document => ('Section' in document - ? TrackSectionHelper + ? TrackSection : Track), save(results) { @@ -353,49 +363,49 @@ export class Album extends Thing { const trackData = []; for (const {header: album, entries} of results) { - // We can't mutate an array once it's set as a property value, - // so prepare the track sections that will show up in a track list - // all the way before actually applying them. (It's okay to mutate - // an individual section before applying it, since those are just - // generic objects; they aren't Things in and of themselves.) const trackSections = []; - const ownTrackData = []; - let currentTrackSection = { + let currentTrackSection = new TrackSection(); + let currentTrackSectionTracks = []; + + Object.assign(currentTrackSection, { name: `Default Track Section`, isDefaultTrackSection: true, - tracks: [], - }; + }); const albumRef = Thing.getReference(album); const closeCurrentTrackSection = () => { - if (!empty(currentTrackSection.tracks)) { - trackSections.push(currentTrackSection); + if (empty(currentTrackSectionTracks)) { + return; } + + currentTrackSection.tracks = + currentTrackSectionTracks + .map(track => Thing.getReference(track)); + + currentTrackSection.ownTrackData = + currentTrackSectionTracks; + + currentTrackSection.ownAlbumData = + [album]; + + trackSections.push(currentTrackSection); }; for (const entry of entries) { - if (entry instanceof TrackSectionHelper) { + if (entry instanceof TrackSection) { closeCurrentTrackSection(); - - currentTrackSection = { - name: entry.name, - color: entry.color, - dateOriginallyReleased: entry.dateOriginallyReleased, - isDefaultTrackSection: false, - tracks: [], - }; - + currentTrackSection = entry; + currentTrackSectionTracks = []; continue; } + currentTrackSectionTracks.push(entry); + trackData.push(entry); entry.dataSourceAlbum = albumRef; - - ownTrackData.push(entry); - currentTrackSection.tracks.push(Thing.getReference(entry)); } closeCurrentTrackSection(); @@ -403,7 +413,6 @@ export class Album extends Thing { albumData.push(album); album.trackSections = trackSections; - album.ownTrackData = ownTrackData; } return {albumData, trackData}; @@ -416,15 +425,97 @@ export class Album extends Thing { }); } -export class TrackSectionHelper extends Thing { +export class TrackSection extends Thing { static [Thing.friendlyName] = `Track Section`; + static [Thing.referenceType] = `track-section`; + + static [Thing.getPropertyDescriptors] = ({Album, Track}) => ({ + // Update & expose - static [Thing.getPropertyDescriptors] = () => ({ name: name('Unnamed Track Section'), - color: color(), + + unqualifiedDirectory: directory(), + + color: [ + exposeUpdateValueOrContinue({ + validate: input.value(isColor), + }), + + withAlbum(), + + withPropertyFromObject({ + object: '#album', + property: input.value('color'), + }), + + exposeDependency({dependency: '#album.color'}), + ], + dateOriginallyReleased: simpleDate(), - isDefaultTrackGroup: flag(false), - }) + + isDefaultTrackSection: flag(false), + + album: [ + withAlbum(), + exposeDependency({dependency: '#album'}), + ], + + tracks: referenceList({ + class: input.value(Track), + data: 'ownTrackData', + find: input.value(find.track), + }), + + // Update only + + ownAlbumData: wikiData({ + class: input.value(Album), + }), + + ownTrackData: wikiData({ + class: input.value(Track), + }), + + // Expose only + + startIndex: [ + withAlbum(), + + withPropertyFromObject({ + object: '#album', + property: input.value('trackSections'), + }), + + { + dependencies: ['#album.trackSections', input.myself()], + compute: (continuation, { + ['#album.trackSections']: trackSections, + [input.myself()]: myself, + }) => continuation({ + ['#index']: + trackSections.indexOf(myself), + }), + }, + + exitWithoutDependency({ + dependency: '#index', + mode: input.value('index'), + value: input.value(0), + }), + + { + dependencies: ['#album.trackSections', '#index'], + compute: ({ + ['#album.trackSections']: trackSections, + ['#index']: index, + }) => + accumulateSum( + trackSections + .slice(0, index) + .map(section => section.tracks.length)), + }, + ], + }); static [Thing.yamlDocumentSpec] = { fields: { |