diff options
Diffstat (limited to 'src/content/dependencies/generateArtistCredit.js')
-rw-r--r-- | src/content/dependencies/generateArtistCredit.js | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/content/dependencies/generateArtistCredit.js b/src/content/dependencies/generateArtistCredit.js new file mode 100644 index 00000000..6bdbeb23 --- /dev/null +++ b/src/content/dependencies/generateArtistCredit.js @@ -0,0 +1,180 @@ +import {compareArrays, empty} from '#sugar'; + +export default { + contentDependencies: [ + 'generateArtistCreditWikiEditsPart', + 'linkContribution', + ], + + extraDependencies: ['html', 'language'], + + query: (creditContributions, contextContributions) => { + const query = {}; + + const featuringFilter = contribution => + contribution.annotation === 'featuring'; + + const wikiEditFilter = contribution => + contribution.annotation?.startsWith('edits for wiki'); + + const normalFilter = contribution => + !featuringFilter(contribution) && + !wikiEditFilter(contribution); + + query.normalContributions = + creditContributions.filter(normalFilter); + + query.featuringContributions = + creditContributions.filter(featuringFilter); + + query.wikiEditContributions = + creditContributions.filter(wikiEditFilter); + + const contextNormalContributions = + contextContributions.filter(normalFilter); + + // Note that the normal contributions will implicitly *always* + // "differ from context" if no context contributions are given, + // as in release info lines. + query.normalContributionsDifferFromContext = + !compareArrays( + query.normalContributions.map(({artist}) => artist), + contextNormalContributions.map(({artist}) => artist), + {checkOrder: false}); + + return query; + }, + + relations: (relation, query, _creditContributions, _contextContributions) => ({ + normalContributionLinks: + query.normalContributions + .map(contrib => relation('linkContribution', contrib)), + + featuringContributionLinks: + query.featuringContributions + .map(contrib => relation('linkContribution', contrib)), + + wikiEditsPart: + relation('generateArtistCreditWikiEditsPart', + query.wikiEditContributions), + }), + + data: (query, _creditContributions, _contextContributions) => ({ + normalContributionsDifferFromContext: + query.normalContributionsDifferFromContext, + + hasWikiEdits: + !empty(query.wikiEditContributions), + }), + + slots: { + // This string is mandatory. + normalStringKey: {type: 'string'}, + + // This string is optional. + // Without it, there's no special behavior for "featuring" credits. + normalFeaturingStringKey: {type: 'string'}, + + // This string is optional. + // Without it, "featuring" credits will always be alongside main credits. + // It won't be used if contextContributions isn't provided. + featuringStringKey: {type: 'string'}, + + additionalStringOptions: {validate: v => v.isObject}, + + showAnnotation: {type: 'boolean', default: false}, + showExternalLinks: {type: 'boolean', default: false}, + showChronology: {type: 'boolean', default: false}, + showWikiEdits: {type: 'boolean', default: false}, + + trimAnnotation: {type: 'boolean', default: false}, + + chronologyKind: {type: 'string'}, + }, + + generate(data, relations, slots, {html, language}) { + if (!slots.normalStringKey) return html.blank(); + + for (const link of [ + ...relations.normalContributionLinks, + ...relations.featuringContributionLinks, + ]) { + link.setSlots({ + showExternalLinks: slots.showExternalLinks, + showChronology: slots.showChronology, + trimAnnotation: slots.trimAnnotation, + chronologyKind: slots.chronologyKind, + }); + } + + for (const link of relations.normalContributionLinks) { + link.setSlots({ + showAnnotation: slots.showAnnotation, + }); + } + + for (const link of relations.featuringContributionLinks) { + link.setSlots({ + showAnnotation: + (slots.featuringStringKey || slots.normalFeaturingStringKey + ? false + : slots.showAnnotation), + }); + } + + if (empty(relations.normalContributionLinks)) { + return html.blank(); + } + + const artistsList = + (data.hasWikiEdits && slots.showWikiEdits + ? language.$('misc.artistLink.withEditsForWiki', { + artists: + language.formatConjunctionList(relations.normalContributionLinks), + + edits: + relations.wikiEditsPart.slots({ + showAnnotation: slots.showAnnotation, + }), + }) + : language.formatConjunctionList(relations.normalContributionLinks)); + + const featuringList = + language.formatConjunctionList(relations.featuringContributionLinks); + + const everyoneList = + language.formatConjunctionList([ + ...relations.normalContributionLinks, + ...relations.featuringContributionLinks, + ]); + + if (empty(relations.featuringContributionLinks)) { + if (data.normalContributionsDifferFromContext) { + return language.$(slots.normalStringKey, { + ...slots.additionalStringOptions, + artists: artistsList, + }); + } else { + return html.blank(); + } + } + + if (data.normalContributionsDifferFromContext && slots.normalFeaturingStringKey) { + return language.$(slots.normalFeaturingStringKey, { + ...slots.additionalStringOptions, + artists: artistsList, + featuring: featuringList, + }); + } else if (slots.featuringStringKey) { + return language.$(slots.featuringStringKey, { + ...slots.additionalStringOptions, + artists: featuringList, + }); + } else { + return language.$(slots.normalStringKey, { + ...slots.additionalStringOptions, + artists: everyoneList, + }); + } + }, +}; |