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
|
import * as validation from "@jet/environment/json/validation";
import { unsafeUnwrapOptional as unwrap } from "@jet/environment/types/optional";
import { Shelf, TopChartSegment } from "../../api/models";
import * as serverData from "../../foundation/json-parsing/server-data";
import { Path, Protocol } from "../../foundation/network/url-constants";
import { addMetricsEventsToPageWithInformation, metricsPageInformationFromMediaApiResponse, } from "../metrics/helpers/page";
import { newLocationTracker, nextPosition } from "../metrics/helpers/location";
import { lockupFromData } from "../lockups/lockups";
import { shouldFilter } from "../filtering";
import { createMediaPageToken } from "../builders/pagination";
/**
* Creates short and long display names for the top chart segment,
* using server data unless client has overrides in `locKeys.json`.
*
* @param objectGraph The dependency graph for the App Store.
* @param segmentData The top charts segment API object.
* @param context The context of the chart, e.g. Apps or Games.
* @returns Short and long display names for the top chart segment.
*/
function namesFromSegmentData(objectGraph, segmentData, context) {
const chart = serverData.asString(segmentData, "chart");
// For the web client, regardless of whether the context is Apps or Games, we show "Free" or "Paid".
if (objectGraph.client.isWeb) {
return chart === "top-free" /* TopChartType.TopFree */
? {
shortName: objectGraph.loc.string("TopCharts.Free.ShortName"),
longName: objectGraph.loc.string("TopCharts.Free.LongName"),
}
: {
shortName: objectGraph.loc.string("TopCharts.Paid.ShortName"),
longName: objectGraph.loc.string("TopCharts.Paid.LongName"),
};
}
// Use server provided names, unless we are in the Games tab or web client.
let shortName = serverData.asString(segmentData, "shortName");
let longName = serverData.asString(segmentData, "name");
if (context !== 2 /* CategoryListContext.Games */) {
return { shortName: unwrap(shortName), longName: unwrap(longName) };
}
// Override server names with client names, e.g. from "Top Free/Paid iPad Apps" to "Top Free/Paid iPad Games" / "Top Free/Paid Vision Pro Games" as needed.
const isPad = objectGraph.client.isPad;
const isVision = objectGraph.client.isVision;
switch (chart) {
case "top-free" /* TopChartType.TopFree */:
if (isPad) {
shortName = objectGraph.loc.string("TopCharts.iPadGames.Free.ShortName"); // Free
longName = objectGraph.loc.string("TopCharts.iPadGames.Free.LongName"); // Top Free iPad Games
}
else if (isVision) {
shortName = objectGraph.loc.string("TopCharts.VisionGames.Free.ShortName"); // Free
longName = objectGraph.loc.string("TopCharts.VisionGames.Free.LongName"); // Top Free Apple Vision Games
}
else {
shortName = objectGraph.loc.string("TopCharts.Games.Free.ShortName"); // Free Games
longName = objectGraph.loc.string("TopCharts.Games.Free.LongName"); // Top Free Games
}
break;
case "top-paid" /* TopChartType.TopPaid */:
if (isPad) {
shortName = objectGraph.loc.string("TopCharts.iPadGames.Paid.ShortName"); // Paid
longName = objectGraph.loc.string("TopCharts.iPadGames.Paid.LongName"); // Top Paid iPad Games
}
else if (isVision) {
shortName = objectGraph.loc.string("TopCharts.VisionGames.Paid.ShortName"); // Paid
longName = objectGraph.loc.string("TopCharts.VisionGames.Paid.LongName"); // Top Paid Apple Vision Games
}
else {
shortName = objectGraph.loc.string("TopCharts.Games.Paid.ShortName"); // Paid Games
longName = objectGraph.loc.string("TopCharts.Games.Paid.LongName"); // Top Paid Games
}
break;
default:
break;
}
return { shortName: unwrap(shortName), longName: unwrap(longName) };
}
/**
* Create a lockup from an api chart item.
* @param index The index of the lockup in the chart.
* @param data The mediaAPI chart item.
* @returns A `Lockup` object.
*/
function lockupFromApiChartItem(objectGraph, index, data, metricsPageInformation, locationTracker) {
return validation.context("lockupFromApiChartItem", () => {
return lockupFromData(objectGraph, data, {
ordinal: objectGraph.loc.decimal(index + 1),
metricsOptions: {
pageInformation: metricsPageInformation,
locationTracker: locationTracker,
},
artworkUseCase: 1 /* ArtworkUseCase.LockupIconSmall */,
});
});
}
/**
* Creates a top chart segment model object from a top chart segment API object.
*
* @param objectGraph The dependency graph for the App Store.
* @param segmentData The top chart segment API object.
* @param response The top charts API object containing all segments.
* @param genreId The genre of the chart, e.g. Developer Tools or Board.
* @param context The context of the chart, e.g. Apps or Games.
* @returns A new top chart segment model object.
*/
export function segmentFromData(objectGraph, segmentData, response, genreId, context) {
return validation.context("segmentFromData", () => {
const { shortName, longName } = namesFromSegmentData(objectGraph, segmentData, context);
const chart = serverData.asString(segmentData, "chart");
const pageDetails = `${chart} ${longName}`;
const pageInformation = metricsPageInformationFromMediaApiResponse(objectGraph, "TopChartsPage", genreId, response, pageDetails);
const locationTracker = newLocationTracker();
const items = [];
let ordinal = 0;
const missingIds = [];
for (const data of segmentData.data) {
const lockup = lockupFromApiChartItem(objectGraph, ordinal, data, pageInformation, locationTracker);
if (lockup) {
// Filter only if segment has attributes
if (shouldFilter(objectGraph, data, 68606 /* Filter.Charts */)) {
continue;
}
items.push(lockup);
nextPosition(locationTracker);
ordinal++;
}
else {
missingIds.push(data);
}
}
const shelves = [];
/// always generate a shelf else we don't load more items when we have none
const shelf = new Shelf("smallLockup");
shelf.items = items;
if (objectGraph.featureFlags.isEnabled("shelves_2_0_top_charts") ||
objectGraph.client.isiOS ||
objectGraph.client.isTV) {
shelf.title = longName;
}
shelves.push(shelf);
const segment = new TopChartSegment(shortName, longName, chart, shelves);
// On Vision, include a URL for pagination - we don't use a specific Top Charts view, so we need the
// `GenericPageMoreIntent` to be able to find this controller for loading new content.
// This can be removed once visionOS adopts `TopChartsPageMoreIntent`.
const paginationUrl = objectGraph.client.isVision
? `${Protocol.internal}:/TopChartsBuilder/${Path.lookup}`
: undefined;
const token = createMediaPageToken(objectGraph, missingIds, paginationUrl, segmentData.next, pageInformation, locationTracker);
token.metricsPageInformation = pageInformation;
token.metricsLocationTracker = locationTracker;
token.highestOrdinal = ordinal;
segment.nextPage = token;
addMetricsEventsToPageWithInformation(objectGraph, segment, pageInformation);
return segment;
});
}
//# sourceMappingURL=charts-page-model.js.map
|