summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/common/sharing.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/common/sharing.js')
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/common/sharing.js428
1 files changed, 428 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/common/sharing.js b/node_modules/@jet-app/app-store/tmp/src/common/sharing.js
new file mode 100644
index 0000000..65c73b5
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/common/sharing.js
@@ -0,0 +1,428 @@
+//
+// sharing.ts
+// AppStoreKit
+//
+// Created by Sam Vafaee on 6/16/17.
+// Copyright (c) 2016 Apple Inc. All rights reserved.
+//
+import { isNothing, isSome } from "@jet/environment";
+import * as validation from "@jet/environment/json/validation";
+import * as models from "../api/models";
+import * as serverData from "../foundation/json-parsing/server-data";
+import * as mediaAttributes from "../foundation/media/attributes";
+import { Parameters, ShareURLParameters } from "../foundation/network/url-constants";
+import * as urls from "../foundation/network/urls";
+import * as dateUtil from "../foundation/util/date-util";
+import * as client from "../foundation/wrappers/client";
+import * as contentArtwork from "./content/artwork/artwork";
+import * as contentAttributes from "./content/attributes";
+import * as content from "./content/content";
+import * as metricsHelpersClicks from "./metrics/helpers/clicks";
+import * as offers from "./offers/offers";
+import { productVariantDataForData, productVariantIDForVariantData } from "./product-page/product-page-variants";
+import { cardDisplayStyleFromData, editorialArtKeyPathForCardDisplayStyle, todayCardArtworkFromArtworkData, todayCardHeroArtForData, } from "./today/today-card-util";
+import { HeroMediaDisplayContext } from "./today/today-types";
+import { dataHasDeviceFamily, dataOnlyHasDeviceFamily } from "./content/device-family";
+// region Data helpers
+export function adamIdForShareSheetGiftActivityFromProductData(objectGraph, data) {
+ if (!objectGraph.bag.isContentGiftingEnabled) {
+ return null;
+ }
+ if (serverData.isNull(data)) {
+ return null;
+ }
+ const offer = offers.offerDataFromData(objectGraph, data);
+ if (serverData.isNull(offer)) {
+ return null;
+ }
+ // Disable gifting for pre-orders
+ const isPreorder = mediaAttributes.attributeAsBoolean(data, "isPreorder");
+ if (isPreorder) {
+ return null;
+ }
+ const price = serverData.asNumber(offer, "price");
+ if (price > 0) {
+ return data.id;
+ }
+ return null;
+}
+/**
+ * Return the url for sharing for given product
+ * @param objectGraph Dependency soup
+ * @param data Apps Resource data for product
+ */
+function shareUrlForProductData(objectGraph, data, urlKey) {
+ const rawUrl = mediaAttributes.attributeAsString(data, urlKey);
+ if (serverData.isNullOrEmpty(rawUrl)) {
+ return null;
+ }
+ const url = new urls.URL(rawUrl);
+ // Add client specifier to url so apps are shown in the same client they were shared from
+ let clientSpecifier = null;
+ const clientIdentifier = objectGraph.host.clientIdentifier;
+ switch (clientIdentifier) {
+ case client.messagesIdentifier:
+ clientSpecifier = "messages";
+ break;
+ case client.watchIdentifier:
+ clientSpecifier = "watch";
+ break;
+ default:
+ break;
+ }
+ if (clientSpecifier) {
+ url.param(ShareURLParameters.clientSpecifier, clientSpecifier);
+ }
+ // Custom product page variant id must be added to `url` for MAPI resource caching constraints.
+ const productVariantData = productVariantDataForData(objectGraph, data);
+ const productVariantID = productVariantIDForVariantData(productVariantData);
+ if (serverData.isDefinedNonNull(productVariantID)) {
+ url.param(Parameters.productVariantID, productVariantID);
+ }
+ return url.toString();
+}
+function notesMetadataFromProductData(objectGraph, data) {
+ return validation.context("notesMetadataFromProductData", () => {
+ var _a;
+ if (serverData.isNull(data)) {
+ return null;
+ }
+ const itemName = mediaAttributes.attributeAsString(data, "name");
+ // Require name
+ if (isNothing(itemName) || itemName.length === 0) {
+ return null;
+ }
+ const url = shareUrlForProductData(objectGraph, data, "url");
+ const developer = mediaAttributes.attributeAsString(data, "artistName");
+ const category = mediaAttributes.attributeAsString(data, "genreNames.0");
+ const fileSize = (_a = content.combinedFileSizeFromData(objectGraph, data)) === null || _a === void 0 ? void 0 : _a.fileSizeByDevice;
+ let mediaType;
+ switch (data.type) {
+ case "apps": {
+ mediaType = "app";
+ break;
+ }
+ case "app-bundles": {
+ mediaType = "bundle";
+ break;
+ }
+ case "in-apps": {
+ mediaType = "iap";
+ break;
+ }
+ default: {
+ mediaType = null;
+ }
+ }
+ return new models.ShareSheetNotesMetadata(itemName, url, developer, category, fileSize, mediaType);
+ });
+}
+function copyLinkShareSheetActivityForURL(objectGraph, url, title) {
+ if (serverData.isNullOrEmpty(url)) {
+ return null;
+ }
+ const copyTextAction = new models.CopyTextAction(url);
+ copyTextAction.title = title !== null && title !== void 0 ? title : objectGraph.loc.string("ShareSheet.CopyLink.Title");
+ copyTextAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://link");
+ const copyLinkActionActivity = new models.ShareSheetActivity("com.apple.AppStore.copyLinkActivity", copyTextAction);
+ return copyLinkActionActivity;
+}
+function openInGameCenterShareSheetActivityForURL(url, title) {
+ if (serverData.isNullOrEmpty(url)) {
+ return undefined;
+ }
+ const openURLAction = new models.ExternalUrlAction(url);
+ openURLAction.title = title;
+ const activity = new models.ShareSheetActivity("com.apple.AppStore.openInGameCenterActivity", openURLAction);
+ return activity;
+}
+// endregion
+// region Article
+export function shareSheetDataForArticle(objectGraph, text, url, shortUrl, articleArtwork, data) {
+ // Sharing is currently not supported on watchOS.
+ if (serverData.isNull(data) || objectGraph.client.isWatch) {
+ return null;
+ }
+ return validation.context("shareSheetDataForArticle", () => {
+ let artwork = articleArtwork;
+ if (isNothing(artwork) && isSome(data)) {
+ artwork = shareSheetArtForData(objectGraph, data);
+ }
+ const subtitle = objectGraph.loc.string("ShareSheet.Story.Subtitle");
+ const articleMetadata = new models.ShareSheetArticleMetadata(data.id, text, subtitle, artwork);
+ return new models.ShareSheetData(articleMetadata, url, shortUrl);
+ });
+}
+/**
+ * Determines the artwork to use in share sheets.
+ * @param {Data} data The data from which to retrieve the artwork.
+ * @returns {Artwork} The artwork suitable for display in the share sheet.
+ */
+export function shareSheetArtForData(objectGraph, data) {
+ const cardDisplayStyle = cardDisplayStyleFromData(data);
+ if (!objectGraph.client.isVision && !preprocessor.GAMES_TARGET) {
+ const heroArt = todayCardHeroArtForData(objectGraph, data, HeroMediaDisplayContext.Article, cardDisplayStyle);
+ if (serverData.isDefinedNonNull(heroArt)) {
+ return heroArt;
+ }
+ }
+ let cropCode;
+ if (objectGraph.client.isVision) {
+ cropCode = "SCS.ApDPCS01";
+ }
+ const artKeyPath = editorialArtKeyPathForCardDisplayStyle(objectGraph, cardDisplayStyle);
+ return todayCardArtworkFromArtworkData(objectGraph, mediaAttributes.attributeAsDictionary(data, artKeyPath), cropCode);
+}
+export function shareSheetActivitiesForArticle(objectGraph, shareUrl, todayCardPreviewUrl, storyID) {
+ const shareSheetActivities = [];
+ if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
+ const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
+ if (serverData.isDefinedNonNull(copyLinkActivity)) {
+ shareSheetActivities.push(copyLinkActivity);
+ }
+ }
+ if ((todayCardPreviewUrl === null || todayCardPreviewUrl === void 0 ? void 0 : todayCardPreviewUrl.length) > 0) {
+ const copyCardPreviewLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, todayCardPreviewUrl, "Copy Card Preview Link");
+ if (serverData.isDefinedNonNull(copyCardPreviewLinkActivity)) {
+ shareSheetActivities.push(copyCardPreviewLinkActivity);
+ }
+ }
+ if (isSome(storyID)) {
+ let activity;
+ if (objectGraph.featureFlags.isGSEUIEnabled("de7bbd8e") &&
+ objectGraph.featureFlags.isEnabled("open_in_story_share_sheet")) {
+ activity = openInGameCenterShareSheetActivityForURL(`games:///story/id${storyID}`, objectGraph.loc.string("ShareSheet.OpenInGameCenter.Title"));
+ }
+ if (serverData.isDefinedNonNull(activity)) {
+ shareSheetActivities.push(activity);
+ }
+ }
+ return shareSheetActivities;
+}
+// endregion
+// region App Events
+export function shareSheetDataForAppEvent(objectGraph, text, subtitle, url, shortUrl, appEventArtwork) {
+ return validation.context("shareSheetDataForAppEvent", () => {
+ const artwork = appEventArtwork;
+ const appEventMetadata = new models.ShareSheetAppEventMetadata(text, subtitle, artwork);
+ return new models.ShareSheetData(appEventMetadata, url, shortUrl);
+ });
+}
+export function shareSheetActivitiesForAppEvent(objectGraph, appEvent, shareUrl) {
+ var _a;
+ const shareSheetActivities = [];
+ // Copy link action
+ if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
+ const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
+ if (serverData.isDefinedNonNull) {
+ shareSheetActivities.push(copyLinkActivity);
+ }
+ }
+ // If the event has already started, remove the option to create a calendar event
+ if (appEvent.startDate.getTime() <= Date.now()) {
+ return shareSheetActivities;
+ }
+ // Creating events is not supported in the product page extension
+ if (objectGraph.host.clientIdentifier === client.productPageExtensionIdentifier) {
+ return shareSheetActivities;
+ }
+ // Not authorized action
+ const notAuthorizedAction = new models.AlertAction("default");
+ notAuthorizedAction.title = objectGraph.loc.string("APP_EVENTS_CALENDAR_NOT_AUTHORIZED_TITLE");
+ notAuthorizedAction.message = objectGraph.loc.string("APP_EVENTS_CALENDAR_NOT_AUTHORIZED_DETAIL");
+ notAuthorizedAction.isCancelable = true;
+ notAuthorizedAction.buttonTitles = [objectGraph.loc.string("ACTION_SETTINGS")];
+ // NOTE: This URL only works on iOS. If this feature is expanded beyond iOS, this code will need to be split per-platform.
+ notAuthorizedAction.buttonActions = [new models.ExternalUrlAction("prefs:root=Privacy&path=CALENDARS", true)];
+ let isAllDay = false;
+ if (serverData.isDefinedNonNull(appEvent.endDate)) {
+ // If the start and end date are > 6 hours apart, and spans over multiple days, then mark as all-day
+ const startMidnight = dateUtil.convertLocalDateToLocalMidnight(appEvent.startDate);
+ const endMidnight = dateUtil.convertLocalDateToLocalMidnight(appEvent.endDate);
+ const difference = appEvent.endDate.getTime() - appEvent.startDate.getTime();
+ const sixHoursDifference = 1000 * 60 * 60 * 6;
+ if (endMidnight.getTime() > startMidnight.getTime() && difference > sixHoursDifference) {
+ isAllDay = true;
+ }
+ // If the start and end date are on the same day, and the event runs for 23 hours & 59 mins
+ // then mark as all-day. This effectively ignores the seconds portion as calendar ignores
+ // this anyway.
+ const fullDayDifference = 1000 * 60 * 60 * 23 + 1000 * 60 * 59;
+ if (startMidnight.getTime() === endMidnight.getTime() && difference >= fullDayDifference) {
+ isAllDay = true;
+ }
+ }
+ // Create calendar event activity
+ const createCalendarEventAction = new models.CreateCalendarEventAction(appEvent.startDate, appEvent.endDate, isAllDay, appEvent.title, (_a = appEvent.lockup) === null || _a === void 0 ? void 0 : _a.title, appEvent.detail, shareUrl, notAuthorizedAction, "free");
+ createCalendarEventAction.title = objectGraph.loc.string("SHARE_SHEET_ADD_TO_CALENDAR");
+ createCalendarEventAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://calendar.circle");
+ const createCalendarEventActivity = new models.ShareSheetActivity("com.apple.AppStore.createCalendarEventActivity", createCalendarEventAction);
+ // Create Calendar Event should be at the beginning.
+ shareSheetActivities.unshift(createCalendarEventActivity);
+ return shareSheetActivities;
+}
+// endregion
+// region Products
+export function shareSheetDataForProductFromProductData(objectGraph, data, clientIdentifierOverride) {
+ return validation.context("shareSheetDataForProductFromProductData", () => {
+ // Sharing is currently not supported on watchOS or the web client.
+ if (serverData.isNull(data) || objectGraph.client.isWatch || objectGraph.client.isWeb) {
+ return null;
+ }
+ // required attributes
+ const url = shareUrlForProductData(objectGraph, data, "url");
+ const title = mediaAttributes.attributeAsString(data, "name");
+ const developerName = mediaAttributes.attributeAsString(data, "artistName");
+ const adamId = data.id;
+ const storeFrontIdentifier = objectGraph.client.storefrontIdentifier;
+ // Sanity check
+ if (!url || !title || !developerName || !adamId) {
+ return null;
+ }
+ // optional attributes
+ const shortUrl = shareUrlForProductData(objectGraph, data, "shortUrl");
+ let artwork = null;
+ let notesMetadata = null;
+ const screenshots = content.screenshotsFromData(objectGraph, data, 4 /* content.ArtworkUseCase.LockupScreenshots */);
+ const videos = content.videoPreviewsFromData(objectGraph, data);
+ const subtitle = contentAttributes.contentAttributeAsString(objectGraph, data, "subtitle") || developerName;
+ const genreName = null;
+ const isMessagesOnlyApp = false;
+ const messagesAppIcon = null;
+ // Platform
+ let platform;
+ const isMacOnlyApp = dataOnlyHasDeviceFamily(objectGraph, data, "mac");
+ const isMacApp = dataHasDeviceFamily(objectGraph, data, "mac");
+ if (isMacOnlyApp || (objectGraph.client.isMac && isMacApp)) {
+ platform = "Mac";
+ }
+ else {
+ platform = "iOS";
+ }
+ // Add product info
+ if (serverData.isDefinedNonNull(data) && mediaAttributes.attributeAsString(data, "url")) {
+ artwork = content.iconFromData(objectGraph, data, {
+ useCase: 1 /* content.ArtworkUseCase.LockupIconSmall */,
+ }, clientIdentifierOverride);
+ notesMetadata = notesMetadataFromProductData(objectGraph, data);
+ }
+ const productMetadata = new models.ShareSheetProductMetadata(adamId, storeFrontIdentifier, title, platform, artwork, screenshots, videos, isMessagesOnlyApp, subtitle, genreName, messagesAppIcon, notesMetadata);
+ return new models.ShareSheetData(productMetadata, url, shortUrl);
+ });
+}
+export function shareProductActionFromData(objectGraph, data, metricsPageInformation, metricsLocationTracker, clientIdentifierOverride) {
+ return validation.context(`shareActionFromData: ${data.type}`, () => {
+ var _a;
+ const id = data.id;
+ switch (objectGraph.client.deviceType) {
+ case "mac": {
+ const shareSheetData = shareSheetDataForProductFromProductData(objectGraph, data);
+ // Share action
+ if (shareSheetData) {
+ const shareAction = new models.ShareSheetAction(shareSheetData, []);
+ metricsHelpersClicks.addClickEventToAction(objectGraph, shareAction, {
+ targetType: "button",
+ id: id,
+ actionType: "share",
+ pageInformation: metricsPageInformation,
+ locationTracker: metricsLocationTracker,
+ });
+ return shareAction;
+ }
+ break;
+ }
+ case "phone":
+ case "pad":
+ case "vision": {
+ const shareSheetData = shareSheetDataForProductFromProductData(objectGraph, data, clientIdentifierOverride);
+ const shareSheetActivities = [];
+ // Copy link action
+ if (((_a = shareSheetData === null || shareSheetData === void 0 ? void 0 : shareSheetData.url) === null || _a === void 0 ? void 0 : _a.length) > 0) {
+ const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareSheetData.url);
+ if (serverData.isDefinedNonNull) {
+ shareSheetActivities.push(copyLinkActivity);
+ }
+ }
+ // Gift action
+ const giftAdamId = adamIdForShareSheetGiftActivityFromProductData(objectGraph, data);
+ if (giftAdamId) {
+ const giftAction = new models.FlowAction("finance");
+ giftAction.presentationContext = "presentModal";
+ giftAction.title = objectGraph.loc.string("SHARE_GIFT_APP");
+ giftAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://app.gift");
+ giftAction.pageUrl = `gift/${giftAdamId}`;
+ metricsHelpersClicks.addClickEventToAction(objectGraph, giftAction, {
+ targetType: "button",
+ id: id,
+ actionType: "gift",
+ actionContext: "shareSheet",
+ pageInformation: metricsPageInformation,
+ locationTracker: metricsLocationTracker,
+ });
+ const giftActionActivity = new models.ShareSheetActivity("com.apple.AppStore.giftActivity", giftAction);
+ shareSheetActivities.push(giftActionActivity);
+ }
+ if (shareSheetData) {
+ // Share action
+ const shareSheetStyle = "expanded";
+ const shareAction = new models.ShareSheetAction(shareSheetData, shareSheetActivities, shareSheetStyle);
+ shareAction.title = objectGraph.loc.string("SHARE_APP");
+ shareAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://square.and.arrow.up");
+ metricsHelpersClicks.addClickEventToAction(objectGraph, shareAction, {
+ targetType: "button",
+ id: id,
+ actionType: "share",
+ actionContext: "shareSheet",
+ pageInformation: metricsPageInformation,
+ locationTracker: metricsLocationTracker,
+ });
+ return shareAction;
+ }
+ else if (shareSheetActivities.length > 0) {
+ // Map ActionActivity[] to Action[] as we're not dealing with a share sheet
+ const sheetActions = shareSheetActivities.map((activity) => activity.action);
+ // Create action sheet instead of share sheet
+ const sheetAction = new models.SheetAction(sheetActions);
+ sheetAction.isCancelable = true;
+ sheetAction.isCustom = true;
+ metricsHelpersClicks.addClickEventToAction(objectGraph, sheetAction, {
+ targetType: "button",
+ id: id,
+ actionType: "actionSheet",
+ pageInformation: metricsPageInformation,
+ locationTracker: metricsLocationTracker,
+ });
+ return sheetAction;
+ }
+ break;
+ }
+ default: {
+ // These device types do not support sharing, so we don't create any share actions.
+ break;
+ }
+ }
+ return null;
+ });
+}
+// region Generic Pages
+export function shareSheetDataForGenericPage(objectGraph, text, url, subtitle, shortUrl, artwork) {
+ return validation.context("shareSheetDataForGenericPage", () => {
+ if (serverData.isNullOrEmpty(url)) {
+ return null;
+ }
+ const metadata = new models.ShareSheetGenericMetadata(text, subtitle, artwork !== null && artwork !== void 0 ? artwork : undefined);
+ return new models.ShareSheetData(metadata, url, shortUrl);
+ });
+}
+export function shareSheetActivitiesForGenericPage(objectGraph, shareUrl) {
+ const shareSheetActivities = [];
+ if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
+ const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
+ if (serverData.isDefinedNonNull) {
+ shareSheetActivities.push(copyLinkActivity);
+ }
+ }
+ return shareSheetActivities;
+}
+// endregion
+//# sourceMappingURL=sharing.js.map \ No newline at end of file