summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/today/cards/today-base-card-builder.js
blob: 77bd0dec45ba3ecbc1c290b1e7cb274d1f720fa5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
import * as validation from "@jet/environment/json/validation";
import { isNothing, isSome } from "@jet/environment/types/optional";
import { ExternalUrlAction, TodayCard, TodayCardActionOverlay, TodayCardMediaArtwork, } from "../../../api/models";
import { isNull } from "../../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../../foundation/media/attributes";
import { relationshipCollection } from "../../../foundation/media/relationships";
import * as contentAttributes from "../../content/attributes";
import { editorialNotesFromData, notesFromData } from "../../content/content";
import { extractEditorialClientParams } from "../../editorial-pages/editorial-data-util";
import { editorialItemActionFromData, subtitleFromData } from "../../lockups/lockups";
import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
import { addMetricsEventsToVideo } from "../../metrics/helpers/media";
import { todayCardArtworkDetails } from "../artwork/today-artwork-util";
import { isCardDataOnboardingCard } from "../onboarding-cards";
import { brandedTitleArtworkForCard, cardDisplayStyleFromData, cardStyleFromJoeColors, isCardOTDIntention, relatedCardContentsContentsFromData, todayCardArtworkTitleBackingGradientForKey, todayCardEditorialDisplayOptionsFromData, todayCardMetricsOptions, } from "../today-card-util";
import { recoMetricsFromTodayItem } from "../today-parse-util";
import { TodayCardDisplayStyle } from "../today-types";
/**
 * If the title is not supplied for app of the day we use this
 */
const appOfTheDayFallbackTitle = "FEATURED APP";
/**
 * If the title is not supplied for game of the day we use this
 */
const gameOfTheDayFallbackTitle = "FEATURED GAME";
/**
 * Creates a TodayCard used as the base for all other TodayCards
 *
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data to build the card from
 * @param cardConfig The configuration for the card
 * @param context The parse context for the over all today page
 * @param clickOptionsModifier A function that can modify the click options for the card
 * @returns The newly created TodayCard, which can then be modified by other TodayCard builders
 */
export function createTodayBaseCard(objectGraph, data, cardConfig, context, clickOptionsModifier) {
    return validation.context("createTodayBaseCard", () => {
        const baseCard = new TodayCard();
        const cardDisplayStyle = cardDisplayStyleFromData(data, cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.coercedCollectionTodayCardDisplayStyle);
        // Heading
        const heading = cardHeadingFromData(objectGraph, data, cardDisplayStyle, cardConfig);
        baseCard.heading = heading;
        // Title, title artwork
        const title = cardTitleFromData(objectGraph, data, cardConfig);
        baseCard.title = title;
        const shortTitle = contentAttributes.contentAttributeAsString(objectGraph, data, [
            "shortEditorialNotes",
            "name",
        ]);
        baseCard.shortTitle = shortTitle;
        const cardTitleArtwork = brandedTitleArtworkForCard(objectGraph, data);
        baseCard.titleArtwork = cardTitleArtwork;
        // Description
        const inlineDescription = cardDescriptionFromData(objectGraph, data);
        baseCard.inlineDescription = inlineDescription;
        const metricsOptions = todayCardMetricsOptions(objectGraph, data, cardConfig, context, title);
        metricsOptions.adSlotOverride = context.parsedCardCount;
        baseCard.clickAction = cardClickAction(objectGraph, data, cardDisplayStyle, cardConfig, context, metricsOptions, clickOptionsModifier);
        // Configure impressions
        metricsHelpersImpressions.addImpressionsFieldsToTodayCard(objectGraph, baseCard, metricsOptions, heading, cardDisplayStyle, isCardDataOnboardingCard(objectGraph, data));
        baseCard.editorialDisplayOptions = todayCardEditorialDisplayOptionsFromData(objectGraph, data, cardConfig);
        return baseCard;
    });
}
/**
 * @param objectGraph The dependency graph for the App Store
 * @param cardDisplayStyle The display style of the card
 * @param data The data to get the branded single app overlay heading from
 * @param cardConfig The configuration for the card
 * @returns The heading to use on the branded single app overlay
 */
export function cardHeadingFromData(objectGraph, data, cardDisplayStyle, cardConfig) {
    var _a, _b;
    let heading = null;
    if (cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.useOTDTextStyle) {
        if (cardConfig.isHorizontalShelfContext) {
            // We don't support branded images or titles for a cards in a horizontal shelf
            // so want to show the "APP OF THE DAY" / "GAME OF THE DAY" text as the heading instead.
            heading = mediaAttributes.attributeAsString(data, "label");
        }
        else {
            heading = null;
        }
    }
    else if (isCardOTDIntention(data, cardConfig)) {
        heading =
            (_a = mediaAttributes.attributeAsString(data, "alternateLabel")) !== null && _a !== void 0 ? _a : mediaAttributes.attributeAsString(data, "label");
        if (isNull(heading) && cardDisplayStyle === TodayCardDisplayStyle.AppOfTheDay) {
            heading = appOfTheDayFallbackTitle;
        }
        else if (isNull(heading) && cardDisplayStyle === TodayCardDisplayStyle.GameOfTheDay) {
            heading = gameOfTheDayFallbackTitle;
        }
    }
    else {
        switch (cardDisplayStyle) {
            case TodayCardDisplayStyle.AppEventCard:
                const fallbackCardContents = fallbackCardContentFromData(objectGraph, data);
                if (isSome(fallbackCardContents)) {
                    heading =
                        (_b = editorialNotesFromData(objectGraph, data, "badge", true)) !== null && _b !== void 0 ? _b : mediaAttributes.attributeAsString(fallbackCardContents, "kind");
                }
                break;
            default:
                heading = mediaAttributes.attributeAsString(data, "label");
                break;
        }
    }
    return heading;
}
/**
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data used to determine the title of this card
 * @param cardConfig The configuration for the card
 * @returns The title to use for this card
 */
function cardTitleFromData(objectGraph, data, cardConfig) {
    var _a;
    let title = null;
    if (cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.useOTDTextStyle) {
        title =
            (_a = mediaAttributes.attributeAsString(data, "ofTheDayLabel")) !== null && _a !== void 0 ? _a : mediaAttributes.attributeAsString(data, "label");
        // We need to replace \n characters with <br> tags to ensure the
        // newlines in APP OF THE DAY titles are maintained. The pattern must be a RegExp since string patterns
        // only replace the first occurrence.
        if (isSome(title)) {
            title = title.replace(/\n/g, "<br>");
        }
    }
    if (isNothing(title)) {
        title = notesFromData(objectGraph, data, "name", true);
    }
    if (isNothing(title)) {
        // Lastly fallback to the first related content title
        const fallbackCardContents = fallbackCardContentFromData(objectGraph, data);
        title = isSome(fallbackCardContents) ? mediaAttributes.attributeAsString(fallbackCardContents, "name") : null;
    }
    return title;
}
/**
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data used to determine the description of this card
 * @returns The title to use for this card
 */
function cardDescriptionFromData(objectGraph, data) {
    var _a;
    const editorialClientParams = extractEditorialClientParams(objectGraph, data);
    const ignoreShortNotes = mediaAttributes.attributeAsBooleanOrFalse(data, "ignoreITunesShortNotes");
    if (ignoreShortNotes || editorialClientParams.suppressNoteShort) {
        return null;
    }
    let description = notesFromData(objectGraph, data, "short", true);
    if (isNothing(description) && !editorialClientParams.suppressNoteTagline) {
        // Lastly fallback to the first related content title
        const fallbackCardContents = fallbackCardContentFromData(objectGraph, data);
        if (isSome(fallbackCardContents)) {
            description =
                (_a = notesFromData(objectGraph, fallbackCardContents, "tagline")) !== null && _a !== void 0 ? _a : subtitleFromData(objectGraph, fallbackCardContents);
        }
    }
    return description;
}
/**
 *
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data used to build the card
 * @returns
 */
function fallbackCardContentFromData(objectGraph, data) {
    const primaryContent = relationshipCollection(data, "primary-content");
    if ((primaryContent === null || primaryContent === void 0 ? void 0 : primaryContent.length) === 1) {
        return primaryContent[0];
    }
    // Card contents
    const cardContents = relatedCardContentsContentsFromData(objectGraph, data);
    if (cardContents.length === 1) {
        return cardContents[0];
    }
    return null;
}
/**
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data used to build the card this action is for
 * @param cardDisplayStyle The display style of the card
 * @param cardConfig The configuration for the card
 * @param context The parse context for the over all today page
 * @param baseMetricsOptions The base metrics options for the card
 * @returns The click action used for tapping on the card
 */
function cardClickAction(objectGraph, data, cardDisplayStyle, cardConfig, context, baseMetricsOptions, clickOptionsModifier) {
    var _a;
    const clickOptions = baseMetricsOptions;
    const franchise = mediaAttributes.attributeAsString(data, "label");
    // <rdar://problem/33677354> Metrics: JS: Add franchise/label to todayCard click events
    const actionDetails = {
        cardType: cardDisplayStyle,
        franchise: franchise,
    };
    const isOnboardingCard = isCardDataOnboardingCard(objectGraph, data);
    if (isOnboardingCard) {
        actionDetails["isOnboardingCard"] = isOnboardingCard;
    }
    clickOptions["actionDetails"] = actionDetails;
    if (isSome(clickOptionsModifier)) {
        clickOptionsModifier(clickOptions);
    }
    return editorialItemActionFromData(objectGraph, data, clickOptions, (_a = cardConfig === null || cardConfig === void 0 ? void 0 : cardConfig.clientIdentifierOverride) !== null && _a !== void 0 ? _a : objectGraph.host.clientIdentifier, recoMetricsFromTodayItem(context.currentTodayItem), cardConfig);
}
/**
 * @param objectGraph The dependency graph for the App Store
 * @param data The media api data used to build the base card
 * @param baseCard The base card to add the artwork media to
 * @param cropCode The crop code to use for the artwork
 * @param context The context for the page were creating the card for
 * @returns Whether or not we successfully added artwork media to the base card
 */
export function addArtworkMediaToBaseCard(objectGraph, data, baseCard, cardConfig, context) {
    return validation.context("addArtworkMediaToBaseCard", () => {
        const ignoreEditorialArt = mediaAttributes.attributeAsBooleanOrFalse(data, "ignoreEditorialArt");
        if (ignoreEditorialArt) {
            return false;
        }
        const mediaDetails = todayCardArtworkDetails(objectGraph, data, cardConfig);
        if (isNothing(mediaDetails)) {
            return false;
        }
        if (isSome(context)) {
            addMetricsEventsToVideo(objectGraph, mediaDetails === null || mediaDetails === void 0 ? void 0 : mediaDetails.videos[0], {
                pageInformation: context.pageInformation,
                locationTracker: context.locationTracker,
                id: data.id,
            });
        }
        baseCard.media = new TodayCardMediaArtwork(mediaDetails.artworks, mediaDetails.videos, mediaDetails.artworkLayoutsWithMetrics, todayCardArtworkTitleBackingGradientForKey(objectGraph, data, cardConfig));
        baseCard.style = cardStyleFromJoeColors(mediaDetails.joeColors, "bgColor");
        // External URL
        if (baseCard.clickAction instanceof ExternalUrlAction && objectGraph.client.isiOS) {
            baseCard.overlay = new TodayCardActionOverlay(baseCard.clickAction);
            baseCard.style = "white";
        }
        return true;
    });
}
//# sourceMappingURL=today-base-card-builder.js.map