This commit is contained in:
janisslsm committed 2026-11-01 12:12:55 +02:00
1 parent 1781d25a15
commit 732c0ad767
33051 files changed
+2591613 -3019689

No files matched your search

@@ -0,0 +1,25 @@
// Metro module 8746 (f8747).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useCurrentUser } from "../hooks/useCurrentUser";
import { useShopProductItems } from "../hooks/useShopProductItems";
import { intl, t } from "../../../intl/index.native";
import { Avatar, AvatarSizes } from "../../../design/void/native";
const useStyles = createStyles({
fullSizePreview: {
flex: 1,
alignItems: "center",
justifyContent: "center"
}
});
export default function AvatarDecorationProductPreview(props) {
const product = props.product;
const styles = useStyles();
const currentUser = useCurrentUser();
const firstAvatarDecoration = useShopProductItems(product).firstAvatarDecoration;
return firstAvatarDecoration != null ? <View style={styles.fullSizePreview} pointerEvents="box-none" accessibilityLabel={intl.formatToPlainString(t.Do2lxE, {
a11y_text: firstAvatarDecoration.label
})} accessibilityRole="image" accessible>
<Avatar user={currentUser} guildId={void 0} size={AvatarSizes.GIFT_START} avatarDecoration={firstAvatarDecoration} animate />
</View> : null;
};
@@ -0,0 +1,43 @@
// Metro module 8067 (f8068).
import { Image as Image2, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import Module38 from "../../../_bundle/Module38";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import Module8068 from "../../../_bundle/Module8068";
import CutoutableAvatarDecoration from "./components/CutoutableAvatarDecoration";
let c5115_8 = 0.8333333333333334;
const useStyles = createStyles((a0) => ({
avatar: {
position: "absolute",
height: a0 * c5115_8,
width: a0 * c5115_8,
borderRadius: a0 * c5115_8 / 2,
opacity: 0.8,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER
},
solidAvatar: {
opacity: 1
},
avatarDecoration: {
position: "absolute"
}
}));
export default function AvatarDecorationSampleV2(props) {
const { item, size } = props;
let avatarSource = props.avatarSource;
const { animate, threeTierBundle } = props;
const styles = useStyles(size);
Module38(item.type === CollectiblesItemType.AVATAR_DECORATION, "Item must be Avatar Decoration");
const style = [styles.avatar, (avatarSource != null || threeTierBundle === true) && styles.solidAvatar];
if (avatarSource == null) {
avatarSource = Module8068;
}
return <>
<Image2 style={style} resizeMode="contain" source={avatarSource} accessible={false} />
<View style={styles.avatarDecoration} accessibilityLabel={item.label}>
<CutoutableAvatarDecoration avatarDecoration={item} size={size} animate={animate} />
</View>
</>;
};
export const avatarPlaceholderSizeRatio = 0.8333333333333334;
@@ -0,0 +1,145 @@
// Metro module 8742 (f8743).
import { useCallback, useLayoutEffect, useMemo, useState, memo } from "react";
import { Pressable, ScrollView, View } from "react-native";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import CollectiblesItemMiniPreview from "./CollectiblesItemMiniPreview";
import { GestureDetector, Gesture } from "../../../_bundle/Module5273";
import { intl, t } from "../../../intl/index.native";
import { getCollectibleTypeLabel } from "../CollectiblesUtils";
import { IndividualProductPreview } from "./IndividualProductPreview";
import { Text } from "../../../design/components/Text/native/Text";
let Component2;
const useStyles = createStyles({
previewContainer: {
paddingTop: Module712.space.PX_16,
paddingBottom: Module712.space.PX_16,
gap: Module712.space.PX_16
},
bundleThumbnail: {
width: 56,
height: 56,
borderRadius: Module712.radii.sm,
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
overflow: "hidden"
},
selectedRing: {
position: "absolute",
top: -2,
left: -2,
right: -2,
bottom: -2,
borderRadius: Module712.radii.sm + 2,
borderWidth: 2,
borderColor: Module712.colors.BORDER_STRONG
},
bundleThumbnailRow: {
flexDirection: "row",
gap: Module712.space.PX_12,
paddingVertical: Module712.space.PX_4,
paddingHorizontal: 2
},
bundleContainer: {
paddingHorizontal: Module712.space.PX_16,
gap: Module712.space.PX_16
},
bundleInfoContainer: {
gap: Module712.space.PX_8
}
});
let Component = memo(function(a0) {
const { item, index } = a0;
let isSelected = a0.isSelected;
const { setSelected, label, trackedSkuId, onTrackPress } = a0;
const callback = useCallback(() => {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.BUNDLE_VIEW_PRODUCT, trackedSkuId);
}
setSelected(index);
}, [setSelected, index, onTrackPress, trackedSkuId]);
const styles = useStyles();
const props = {
role: "radio",
"aria-checked": isSelected,
onPress: callback,
"aria-label": label,
children: null
};
const children = [<View style={styles.bundleThumbnail}>
<CollectiblesItemMiniPreview item={item} size={56} />
</View>, ,];
if (isSelected) {
isSelected = <View style={styles.selectedRing} pointerEvents="none" />;
}
children[1] = isSelected;
props.children = children;
return <Pressable {...props} />;
});
Component2 = memo(function({ items, bundledProducts, activeIndex, onSelect, onTrackPress: onTrackPress2 }) {
const styles = useStyles();
return <GestureDetector gesture={useMemo(() => Gesture.Native().disallowInterruption(true), [])}>
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.bundleThumbnailRow} role="radiogroup" aria-label={intl.string(t.cTbdgu)}>
{items.map((a0, a1) => {
let label = bundledProducts == null ? void 0 : bundledProducts[a1]?.name;
if (label == null) {
label = a0.skuId;
}
let trackedSkuId2 = bundledProducts == null ? void 0 : bundledProducts[a1]?.skuId;
if (trackedSkuId2 == null) {
trackedSkuId2 = a0.skuId;
}
return <Component key={a0.skuId} item={a0} index={a1} isSelected={a1 === activeIndex} setSelected={onSelect} label={label} trackedSkuId={trackedSkuId2} onTrackPress={onTrackPress2} />;
})}
</ScrollView>
</GestureDetector>;
});
export default function BundleProductDetailsActionSheetPreview(props) {
const { product, width, handlePreviewPress, onTrackPress: onTrackPress3, onActiveItemChange } = props;
const styles = useStyles();
let [activeIndex2, onSelect2] = useState(0);
const [state, setState] = useState(product.skuId);
const { items, bundledProducts: bundledProducts2 } = product;
if (product.skuId !== state) {
setState(product.skuId);
onSelect2(0);
activeIndex2 = 0;
}
const r43 = items[activeIndex2];
let c16761_1 = r43;
useLayoutEffect(() => {
if (onActiveItemChange != null) {
onActiveItemChange(c16761_1);
}
}, [r43, onActiveItemChange]);
let r16 = (bundledProducts2 == null ? void 0 : bundledProducts2[activeIndex2])?.name;
if (r16 == null) {
r16 = r43.skuId;
}
const collectibleTypeLabel = getCollectibleTypeLabel(r43.type);
const r66 = [<IndividualProductPreview product={useMemo(() => ({
skuId: c16761_1.skuId,
type: c16761_1.type,
items: [c16761_1]
}), [r43])} width={width} handlePreviewPress={handlePreviewPress} onTrackPress={onTrackPress3} />, ,];
r66[1] = <View style={styles.bundleContainer}>
<View style={styles.bundleInfoContainer}>
<Text variant="heading-xl/bold">{product.name}</Text>
<Text variant="text-sm/medium" color="text-default">
{intl.formatToPlainString(t["/0Yndu"], {
num: items.length
})}
</Text>
</View>
<View style={styles.bundleInfoContainer}>
<Component2 items={items} bundledProducts={bundledProducts2} activeIndex={activeIndex2} onSelect={onSelect2} onTrackPress={onTrackPress3} />
<Text variant="text-sm/medium" color="text-default">
{r16}
{collectibleTypeLabel != null && <Text variant="text-sm/medium" color="text-muted">
{` - ${collectibleTypeLabel}`}
</Text>}
</Text>
</View>
</View>;
return <View style={styles.previewContainer}>{r66}</View>;
};
@@ -0,0 +1,196 @@
// Metro module 8056 (f8057).
import { PixelRatio, View, StyleSheet } from "react-native";
import { BUNDLE_PREVIEW_CONFIG } from "./CollectiblesPreviewConstants";
import FastImage from "../../../components_native/common/FastImage";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import Module38 from "../../../_bundle/Module38";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { getNameplateData } from "../nameplates/utils";
import ProfileEffectSampleV2 from "./ProfileEffectSampleV2";
import AvatarDecorationSampleV2 from "./AvatarDecorationSampleV2";
import { NameplateDummyUserPreview } from "../nameplates/native/NameplateDummyUserPreview";
import { AvatarSizes } from "../../../design/void/native";
import { useCollectiblesMobileFlexibleBundlesExperiment } from "../experiments/CollectiblesMobileFlexibleBundlesExperiment";
let styles, useStyles, BundleSampleV2Composed, BundleSampleV2StaticPreview;
const BundleStaticPreviewContent = function BundleStaticPreviewContent(props) {
const { previewAssets, disableBackground, mutedBackground, targetSize } = props;
const { bgStatic, fgStatic } = previewAssets;
const r1 = bgStatic != null;
let r11 = null;
if (r1) {
let uri = bgStatic;
if (targetSize != null) {
const r34 = bgStatic.startsWith("https://cdn.discordapp.com");
uri = bgStatic;
if (r34) {
const r38 = Math.min(PixelRatio.get(), 2);
const r17 = Math.round(targetSize.width * r38);
const r16 = Math.round(targetSize.height * r38);
uri = `${bgStatic}${bgStatic.includes("?") ? "&" : "?"}width=${r17}&height=${r16}`;
}
}
r11 = <FastImage source={{
uri
}} style={styles.bgImage} resizeMode="cover" accessibilityElementsHidden importantForAccessibility="no-hide-descendants" />;
}
const r71 = [(disableBackground ? !disableBackground : r11 != null) && <View style={styles.bgBleedClip} pointerEvents="none">
{mutedBackground ? <View style={styles.bgMutedWrap} pointerEvents="none">{r11}</View> : r11}
</View>, ,];
let r72 = fgStatic != null;
if (r72) {
let uri2 = fgStatic;
if (targetSize != null) {
const r84 = fgStatic.startsWith("https://cdn.discordapp.com");
uri2 = fgStatic;
if (r84) {
const r92 = Math.min(PixelRatio.get(), 2);
const r19 = Math.round(targetSize.width * r92);
const r101 = Math.round(targetSize.height * r92);
uri2 = `${fgStatic}${fgStatic.includes("?") ? "&" : "?"}width=${r19}&height=${r101}`;
}
}
r72 = <View style={styles.fgClip} pointerEvents="none">
<FastImage source={{
uri: uri2
}} style={styles.fgImage} resizeMode="cover" accessibilityElementsHidden importantForAccessibility="no-hide-descendants" />
</View>;
}
r71[1] = r72;
return <View style={styles.container}>{r71}</View>;
};
BundleSampleV2Composed = function BundleSampleV2Composed(props) {
const { deco, pfx, nameplate, size = "small" } = props;
const styles2 = useStyles(size);
const r1 = nameplate != null;
let nameplate2 = void 0;
if (r1) {
Module38(nameplate.type === CollectiblesItemType.NAMEPLATE, "Item must be Nameplate");
nameplate2 = getNameplateData(nameplate);
}
const r33 = BUNDLE_PREVIEW_CONFIG[size];
const size2 = nameplate2 != null ? r33.avatarDecorationSizeTriple : r33.avatarDecorationSize;
return <View style={styles2.bundle}>
{pfx != null && <View style={styles2.pfx}>
<ProfileEffectSampleV2 item={pfx} />
</View>}
{deco != null && <View style={[nameplate2 != null ? styles2.avatarWithNameplate : styles2.avatar]}>
<AvatarDecorationSampleV2 item={deco} size={size2} threeTierBundle={nameplate2 != null} />
</View>}
{nameplate2 != null ? <View style={styles2.nameplate}>
<NameplateDummyUserPreview width={r33.nameplatePreviewWidth} avatarSize={size === "large" ? AvatarSizes.NORMAL : AvatarSizes.XSMALL_20} nameplate={nameplate2} />
</View> : null}
</View>;
};
BundleSampleV2StaticPreview = function BundleSampleV2StaticPreview(props) {
const { previewAssets, disableStaticBackground, mutedStaticBackground, targetSize, composedFallbackProps } = props;
return useCollectiblesMobileFlexibleBundlesExperiment(props.exposureLocation).enabled ? <BundleStaticPreviewContent previewAssets={previewAssets} disableBackground={disableStaticBackground} mutedBackground={mutedStaticBackground} targetSize={targetSize} /> : <BundleSampleV2Composed {...composedFallbackProps} />;
};
styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
overflow: "hidden"
},
bgBleedClip: {
...StyleSheet.absoluteFillObject,
overflow: "hidden",
justifyContent: "center",
alignItems: "center"
},
bgMutedWrap: {
...StyleSheet.absoluteFillObject,
opacity: 0.8
},
bgImage: {
width: "100%",
height: "100%"
},
fgClip: {
...StyleSheet.absoluteFillObject,
overflow: "hidden",
justifyContent: "center",
alignItems: "center"
},
fgImage: {
...StyleSheet.absoluteFillObject
}
});
useStyles = createStyles((a0) => {
const r5 = BUNDLE_PREVIEW_CONFIG[a0];
return {
bundle: {
width: r5.bundleWidth,
height: r5.bundleHeight,
borderRadius: Module712.radii.xs
},
pfx: {
position: "absolute",
top: r5.pfxTop,
left: r5.pfxLeft,
width: r5.pfxWidth,
height: r5.pfxHeight,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
transform: [{
rotate: "-8deg"
}],
zIndex: 0,
overflow: "hidden",
borderRadius: Module712.radii.xs
},
avatar: {
position: "absolute",
top: r5.avatarTop,
right: r5.avatarRight,
transform: [{
rotate: "8deg"
}],
zIndex: 1,
alignItems: "center",
justifyContent: "center"
},
avatarWithNameplate: {
position: "absolute",
top: r5.avatarWithNameplateTop,
right: r5.avatarWithNameplateRight,
transform: [{
rotate: "8deg"
}],
zIndex: 1,
alignItems: "center",
justifyContent: "center",
shadowColor: Module712.colors.BLACK,
shadowOffset: {
width: 0,
height: 4
},
shadowOpacity: 0.5,
shadowRadius: 4
},
nameplate: {
position: "absolute",
bottom: r5.nameplateBottom,
marginHorizontal: 10,
width: "90%",
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWER,
zIndex: 2,
borderRadius: Module712.radii.sm,
shadowColor: Module712.colors.BLACK,
shadowOffset: {
width: 0,
height: 4
},
shadowOpacity: 0.5,
shadowRadius: 4
}
};
});
export default function BundleSampleV2(props) {
const { deco, pfx, nameplate, size = "small", previewAssets, disableStaticBackground = false, mutedStaticBackground = false, targetSize, exposureLocation = "CollectiblesShopCardAssetTileV2" } = props;
const composedFallbackProps = {
deco,
pfx,
nameplate,
size
};
return previewAssets?.fgStatic != null ? <BundleSampleV2StaticPreview previewAssets={previewAssets} disableStaticBackground={disableStaticBackground} mutedStaticBackground={mutedStaticBackground} targetSize={targetSize} composedFallbackProps={composedFallbackProps} exposureLocation={exposureLocation} /> : <BundleSampleV2Composed {...composedFallbackProps} />;
};
@@ -0,0 +1,118 @@
// Metro module 7967 (f7968).
import { View } from "react-native";
import { PremiumTypes } from "../../premium/PremiumConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import PremiumFeaturesBackground from "../../user_settings/premium/native/PremiumFeaturesBackground";
import { LockIcon } from "../../../design/components/Icon/native/redesign/generated/LockIcon";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
const useStyles = createStyles({
badgeTextUppercase: {
textTransform: "uppercase"
},
badgeSurfaceDarkMode: {
backgroundColor: Module712.colors.WHITE
},
badgeSurfaceLightMode: {
backgroundColor: Module712.colors.BADGE_BACKGROUND_BRAND
},
newIconBadge: {
backgroundColor: Module712.colors.BACKGROUND_BRAND,
borderRadius: Module712.radii.round,
paddingHorizontal: 6,
paddingVertical: 2
},
limitedTimeBadge: {
backgroundColor: Module712.colors.WHITE,
borderRadius: Module712.radii.md,
paddingHorizontal: Module712.space.PX_8,
paddingVertical: Module712.space.PX_4
},
lockIconBadge: {
backgroundColor: Module712.colors.ICON_OVERLAY_DARK,
padding: 5,
borderRadius: Module712.radii.round
},
newLockIconBadge: {
backgroundColor: Module712.unsafe_rawColors.PREMIUM_TIER_2_PINK_FOR_GRADIENTS_2,
flexDirection: "row",
paddingHorizontal: 5,
paddingVertical: 3,
borderRadius: Module712.radii.round,
alignItems: "center",
gap: 2
},
badgePill: {
paddingHorizontal: Module712.space.PX_4,
paddingVertical: 1.5,
borderRadius: Module712.radii.round,
flexShrink: 1
},
iconTextBadge: {
flexDirection: "row",
alignItems: "center",
gap: 4,
paddingHorizontal: Module712.space.PX_8,
paddingVertical: 2,
borderRadius: Module712.radii.round
}
});
export function NewBadge(props) {
const style = props.style;
const styles = useStyles();
return <View style={[styles.newIconBadge, style]}>
<Text variant="text-sm/bold" color="text-overlay-light" style={styles.badgeTextUppercase}>
{intl.string(t.y2b7CA)}
</Text>
</View>;
}
export function LockBadge(props) {
const { isNew = false, style } = props;
const styles = useStyles();
return isNew ? <PremiumFeaturesBackground premiumType={PremiumTypes.TIER_2} style={[styles.newLockIconBadge, style]}>
<LockIcon size="xxs" color={Module712.colors.WHITE} />
<Text variant="text-xs/bold" color="text-overlay-light" style={styles.badgeTextUppercase}>
{intl.string(t.y2b7CA)}
</Text>
</PremiumFeaturesBackground> : <View style={[styles.lockIconBadge, style]}>
<LockIcon size="sm" color={Module712.colors.WHITE} />
</View>;
}
export function PremiumBadge(props) {
const { isNew = false, style } = props;
const styles = useStyles();
return isNew ? <PremiumFeaturesBackground premiumType={PremiumTypes.TIER_2} style={[styles.newLockIconBadge, style]}>
<NitroWheelIcon size="xxs" color={Module712.colors.WHITE} />
<Text variant="text-xs/bold" color="text-overlay-light" style={styles.badgeTextUppercase}>
{intl.string(t.y2b7CA)}
</Text>
</PremiumFeaturesBackground> : <View style={[styles.lockIconBadge, style]}>
<NitroWheelIcon size="sm" color={Module712.colors.WHITE} />
</View>;
}
export function LimitedTimeBadge(props) {
const style = props.style;
const styles = useStyles();
return <View style={[styles.limitedTimeBadge, style]}>
<Text variant="text-xs/bold" color="text-overlay-dark" style={styles.badgeTextUppercase}>
{intl.string(t["h/uBCR"])}
</Text>
</View>;
}
export function IconBadgePill(props) {
const { icon: Icon, accessibilityLabel, isDark } = props;
const styles = useStyles();
return <View style={[styles.badgePill, isDark ? styles.badgeSurfaceDarkMode : styles.badgeSurfaceLightMode]} accessibilityLabel={accessibilityLabel}>
<Icon size="xs" color={isDark ? "black" : "white"} />
</View>;
}
export function IconTextBadge(props) {
const { icon: Icon, label, isDark } = props;
const styles = useStyles();
return <View style={[styles.iconTextBadge, isDark ? styles.badgeSurfaceDarkMode : styles.badgeSurfaceLightMode]}>
<Icon size="xs" color={isDark ? "black" : "white"} />
<Text variant="text-xs/bold" color={isDark ? "text-overlay-dark" : "text-overlay-light"} style={styles.badgeTextUppercase}>{label}</Text>
</View>;
}
@@ -0,0 +1,46 @@
// Metro module 14614 (f14615).
import { createContext, useContext, useRef, useCallback, useMemo } from "react";
import { NOOP } from "../../../_bundle/Module505";
const context = createContext({
registerDismiss: () => NOOP,
handleDismissCoachmarkOnScroll: void 0
});
export function useCollectiblesCoachmarkScrollDismissContext() {
return useContext(context);
}
export function CollectiblesCoachmarkScrollDismissProvider(props) {
let callback2;
const children = props.children;
callback2 = void 0;
const ref = useRef(null);
const ref2 = useRef(null);
const callback = useCallback((a0) => {
ref.current = a0;
ref2.current = null;
return () => {
if (ref.current === a0) {
ref.current = null;
ref2.current = null;
}
};
}, []);
callback2 = useCallback((a0) => {
const current = ref.current;
if (current != null) {
const contentOffset = a0.nativeEvent.contentOffset;
if (ref2.current != null) {
if (Math.abs(contentOffset.x - ref2.current) >= 16) {
ref.current = null;
ref2.current = null;
current();
}
} else {
ref2.current = contentOffset.x;
}
}
}, []);
return <context.Provider value={useMemo(() => ({
registerDismiss: callback,
handleDismissCoachmarkOnScroll: callback2
}), [callback, callback2])}>{children}</context.Provider>;
}
@@ -0,0 +1,136 @@
// Metro module 7964 (f7965).
import { useCallback } from "react";
import { View } from "react-native";
import UserStore from "../../../stores/UserStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { triggerHapticFeedback } from "../../haptics/HapticUtils.native";
import HapticFeedbackTypes from "../../haptics/HapticFeedbackTypes";
import { Icon, IconSizes } from "../../../design/void/native";
import Module7965 from "../../../_bundle/Module7965";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import Module7966 from "../../../_bundle/Module7966";
import { NewBadge, LockBadge, PremiumBadge } from "./CollectiblesBadges";
import { useStateFromStores } from "../../../_bundle/Module589";
import PremiumUtils from "../../../utils/PremiumUtils";
import useCollectiblesData from "../hooks/useCollectiblesData";
import * as _CollectiblesUtils from "../CollectiblesUtils";
import { isPremiumCollectiblesProduct, isPremiumCollectiblesPurchase } from "../CollectiblesUtils";
let useStyles;
const EditCollectibleListItem = function EditCollectibleListItem(props) {
const { size, isSelected, children, style, onPress: onPress2, onLongPress, accessibilityLabel, accessibilityRole = "button" } = props;
const styles = useStyles();
return <PressableOpacity style={styles.pressable} disabled={isSelected} onPress={function onPress() {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
onPress2();
}} onLongPress={onLongPress} accessibilityRole={accessibilityRole} accessibilityLabel={accessibilityLabel} accessibilityState={{
selected: isSelected
}}>
<View style={[styles.item, isSelected ? styles.selected : null, {
width: size,
height: size
}, style]}>{children}</View>
</PressableOpacity>;
};
useStyles = createStyles({
pressable: {
marginTop: 10,
borderRadius: Module712.radii.sm
},
item: {
borderWidth: 2,
borderColor: Module712.colors.BORDER_SUBTLE,
borderRadius: Module712.radii.sm,
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH,
alignItems: "center",
justifyContent: "center"
},
selected: {
borderColor: Module712.colors.BUTTON_OUTLINE_BRAND_BORDER_ACTIVE
},
optionCell: {
justifyContent: "center",
alignItems: "center"
},
optionCellText: {
marginTop: 4
},
newIcon: {
position: "absolute",
top: -12,
right: 5
},
lockIcon: {
position: "absolute",
top: -12,
right: -10
}
});
export { EditCollectibleListItem };
export function EditCollectiblesListItemNone(props) {
const styles = useStyles();
return <EditCollectibleListItem style={styles.optionCell} {...props}>
<Icon source={Module7965} size={IconSizes.LARGE} />
<Text variant="text-sm/medium" color="mobile-text-heading-primary" style={styles.optionCellText}>
{props.asDefault ? intl.string(t.CHf9iJ) : intl.string(t.PoWNfe)}
</Text>
</EditCollectibleListItem>;
}
export function EditCollectiblesListItemShop(props) {
const { analyticsSource, ...props2 } = props;
const styles = useStyles();
const analyticsLocations = useAnalyticsLocations(analyticsSource).analyticsLocations;
return <EditCollectibleListItem style={styles.optionCell} isSelected={false} onPress={useCallback(() => {
openCollectiblesShopMobile({
analyticsLocations,
analyticsSource,
screen: CollectiblesMobileShopScreen.FEATURED_PAGE
});
ActionSheetActionCreators.hideActionSheet();
}, [analyticsLocations, analyticsSource])} {...props2}>
<Icon source={Module7966} size={IconSizes.LARGE} />
<Text variant="text-sm/medium" color="mobile-text-heading-primary" style={styles.optionCellText}>
{intl.string(t.pWG4ze)}
</Text>
<NewBadge style={styles.newIcon} />
</EditCollectibleListItem>;
}
export function EditCollectiblesListItemProduct(props) {
let r57, r58;
const { isSelected, isTryItOut, skuId, children, ...props2 } = props;
const styles = useStyles();
const canUseCollectibles = PremiumUtils.canUseCollectibles(useStateFromStores([UserStore], () => UserStore.getCurrentUser()));
const collectiblesData = useCollectiblesData(skuId);
const { product, purchase } = collectiblesData;
const isProductNew = _CollectiblesUtils.isProductNew(skuId);
const r16 = isPremiumCollectiblesProduct(product) || isPremiumCollectiblesPurchase(purchase);
const r52 = [children, ,];
if (purchase == null && !r16) {
r57 = <LockBadge style={styles.lockIcon} isNew={isProductNew} />;
} else {
L10: {
r58 = null;
if (r16) {
r58 = null;
if (!isTryItOut) {
if (purchase != null) {
r58 = null;
if (canUseCollectibles) {
break L10;
}
}
r58 = <PremiumBadge style={styles.lockIcon} isNew={isProductNew} />;
}
}
}
r57 = r58;
}
r52[1] = r57;
return <EditCollectibleListItem isSelected={isSelected} {...props2}>{r52}</EditCollectibleListItem>;
}
@@ -0,0 +1,96 @@
// Metro module 8743 (f8744).
import { memo } from "react";
import { View } from "react-native";
import { isAvatarDecorationRecord } from "../records/AvatarDecorationRecord";
import { isNameplateRecord } from "../records/NameplateRecord";
import { isProfileEffectRecord } from "../records/ProfileEffectRecord";
import { isProfileFrameRecord } from "../records/ProfileFrameRecord";
import { PROFILE_FRAME_ASPECT_RATIO } from "../profile_frames/native/ProfileFrameConstants";
import { SAMPLE_PROFILE_ASPECT_RATIO } from "./CollectiblesPreviewConstants";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import AvatarDecorationSampleV2 from "./AvatarDecorationSampleV2";
import ProfileFrameSamplePreview from "../profile_frames/native/previews/ProfileFrameSamplePreview";
import FastImage from "../../../components_native/common/FastImage";
import Module8695 from "../../../_bundle/Module8695";
import ProfileEffect from "../profile_effects/native/ProfileEffect";
import { getNameplateData } from "../nameplates/utils";
import Nameplate from "../nameplates/native/Nameplate";
const PX_8 = Module712.space.PX_8;
const useStyles = createStyles({
tile: {
overflow: "hidden",
alignItems: "center",
justifyContent: "center"
},
framePreview: {
width: "100%",
height: "100%",
paddingVertical: PX_8,
overflow: "hidden",
alignItems: "center",
justifyContent: "center"
},
profileEffect: {
overflow: "hidden",
width: "100%",
height: "100%",
borderRadius: Module712.radii.sm
},
sampleProfile: {
aspectRatio: SAMPLE_PROFILE_ASPECT_RATIO,
width: "100%"
},
nameplate: {
overflow: "hidden",
borderTopRightRadius: Module712.radii.xs,
borderBottomRightRadius: Module712.radii.xs
},
nameplateTile: {
alignItems: "flex-start"
},
nameplateStrip: {
width: "90%",
aspectRatio: 1.6,
position: "relative"
}
});
const r70 = memo(function CollectiblesItemMiniPreview(props) {
const { item, size } = props;
const styles = useStyles();
const style = [styles.tile, {
width: size,
height: size
}];
if (isAvatarDecorationRecord(item)) {
return <View style={style}>
<AvatarDecorationSampleV2 item={item} size={0.75 * size} />
</View>;
}
if (isProfileFrameRecord(item)) {
return <View style={style}>
<View style={styles.framePreview}>
<ProfileFrameSamplePreview profileFrame={item} previewWidth={size * PROFILE_FRAME_ASPECT_RATIO} previewHeight={size - 2 * PX_8} profileBackgroundColor={Module712.colors.BACKGROUND_BASE_LOW} />
</View>
</View>;
}
if (isProfileEffectRecord(item)) {
return <View style={style}>
<View style={styles.profileEffect} accessible={false} importantForAccessibility="no">
<FastImage source={{
uri: Module8695
}} style={styles.sampleProfile} resizeMode="cover" />
<ProfileEffect skuId={item.skuId} bannerAdjustment={0} useThumbnail />
</View>
</View>;
}
if (isNameplateRecord(item)) {
return <View style={[style, styles.nameplateTile]}>
<View style={styles.nameplateStrip}>
<Nameplate nameplate={getNameplateData(item)} fullOpacity style={styles.nameplate} />
</View>
</View>;
}
return null;
});
export default r70;
@@ -0,0 +1,157 @@
// Metro module 15772 (f15773).
import { useRef, useEffect, useCallback, useMemo } from "react";
import { Image as Image2, View, StyleSheet } from "react-native";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { ACTION_SHEET_MAX_WIDTH } from "../../action_sheet/native/ActionSheetConstants";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import { useBottomSheet } from "../../../_bundle/Module5245";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import ReanimatedRexport, { useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import Module15773 from "../../../_bundle/Module15773";
import { Text } from "../../../design/components/Text/native/Text";
import * as _index_native from "../../../intl/index.native";
import { intl } from "../../../intl/index.native";
import { useProfileFramesMarketing } from "../hooks/useProfileFramesMarketing";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { BottomSheet } from "../../../design/components/Sheet/native/BottomSheet.native";
import Module15776 from "../../../_bundle/Module15776";
import { PaintIllocon, HeartIllocon, ShopIllocon } from "../../../design/assets/native";
import { Button } from "../../../design/components/Button/native/Button.native";
let useStyles, __initData, FeatureRow;
const CatEarsBackdrop = function CatEarsBackdrop() {
const styles = useStyles();
const width = useWindowDimensions_native().width;
const animatedPosition = useBottomSheet().animatedPosition;
const top = useSafeAreaInsets_native().top;
const r28 = Math.min(width, ACTION_SHEET_MAX_WIDTH);
const left = (width - r28) / 2;
const r31 = r28 / 1200;
const t = () => ({
transform: [{
translateY: animatedPosition.get() + top - 60
}]
});
t.__closure = {
animatedPosition,
safeAreaTop: top,
MASCOT_SAFE_AREA_NUDGE: 60
};
t.__workletHash = 6274760278164;
t.__initData = __initData;
const style = [styles.mascotContainer, {
left,
right: left
}, useAnimatedStyle(t)];
const style2 = [styles.mascotLayer, ,];
const left2 = -(56 * r31);
style2[1] = {
top: -138 * r31,
left: left2,
right: left2
};
return <ReanimatedRexport.View style={style}>
<View style={style2}>
<Image2 source={{
uri: Module15773
}} style={styles.mascotImage} accessibilityElementsHidden importantForAccessibility="no-hide-descendants" />
</View>
</ReanimatedRexport.View>;
};
FeatureRow = function FeatureRow(props) {
const { icon, text } = props;
const styles = useStyles();
return <View style={styles.featureRow}>
{icon}
<Text variant="text-sm/medium" color="text-subtle" style={styles.featureText}>{text}</Text>
</View>;
};
useStyles = createStyles({
mascotContainer: {
...StyleSheet.absoluteFillObject,
pointerEvents: "none"
},
mascotLayer: {
...StyleSheet.absoluteFillObject
},
mascotImage: {
width: "100%",
aspectRatio: 1.8324022346368716
},
framePreviewImage: {
width: "100%",
aspectRatio: 3.25,
resizeMode: "contain"
},
container: {
padding: Module712.space.PX_16,
paddingTop: Module712.space.PX_24,
gap: Module712.space.PX_16
},
headerText: {
textAlign: "center"
},
featureRow: {
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_16
},
featureText: {
flex: 1
},
featureRows: {
gap: Module712.space.PX_32
}
});
__initData = {
code: "function CollectiblesMobileAnnouncementActionSheetTsx1(){const{animatedPosition,safeAreaTop,MASCOT_SAFE_AREA_NUDGE}=this.__closure;return{transform:[{translateY:animatedPosition.get()+safeAreaTop-MASCOT_SAFE_AREA_NUDGE}]};}"
};
export default function CollectiblesMobileAnnouncementActionSheet(props) {
const markAsDismissed = props.markAsDismissed;
const styles = useStyles();
const profileFramesMarketing = useProfileFramesMarketing("CollectiblesMobileAnnouncementActionSheet");
const text2 = profileFramesMarketing.showEaPremiumMarketing ? intl.string(_index_native.t["7cmcJI"]) : intl.string(_index_native.t.MkVbBY);
const { showGiftingMarketing, showEaPremiumMarketing, showEaNonPremiumMarketing } = profileFramesMarketing;
const text = showGiftingMarketing ? intl.string(_index_native.t["/4bQuG"]) : showEaPremiumMarketing ? intl.string(_index_native.t["5UI+bw"]) : showEaNonPremiumMarketing ? intl.string(_index_native.t["4a7pVU"]) : intl.string(_index_native.t["+9vaAT"]);
const ref = useRef(false);
const ref2 = useRef(markAsDismissed);
useEffect(() => {
ref2.current = markAsDismissed;
}, [markAsDismissed]);
useEffect(() => () => {
if (!ref.current) {
ref2.current(ContentDismissActionType.AUTO_DISMISS);
}
}, []);
const callback = useCallback(() => {
ref.current = true;
markAsDismissed(ContentDismissActionType.PRIMARY);
openCollectiblesShopMobile({
screen: CollectiblesMobileShopScreen.FEATURED_PAGE,
analyticsLocations: [],
analyticsSource: AnalyticsLocation.ACTION_SHEET
});
}, [markAsDismissed]);
return <BottomSheet onDismiss={useCallback(() => {
ref.current = true;
markAsDismissed(ContentDismissActionType.USER_DISMISS);
}, [markAsDismissed])} backdropChildren={useMemo(() => <CatEarsBackdrop />, [])}>
<View style={styles.container}>
<Image2 source={{
uri: Module15776
}} style={styles.framePreviewImage} accessibilityElementsHidden importantForAccessibility="no-hide-descendants" />
<Text variant="heading-xl/bold" color="text-strong" accessibilityRole="header" style={styles.headerText}>
{intl.string(_index_native.t.vRCvqo)}
</Text>
<View style={styles.featureRows}>
<FeatureRow icon={<PaintIllocon size={32} />} text={intl.string(_index_native.t["6ZWB0C"])} />
<FeatureRow icon={<HeartIllocon size={32} />} text={text2} />
<FeatureRow icon={<ShopIllocon size={32} />} text={text} />
</View>
<Button size="lg" text={intl.string(_index_native.t.S9hXPI)} onPress={callback} />
</View>
</BottomSheet>;
};
@@ -0,0 +1,36 @@
// Metro module 8039 (f8040).
export const SAMPLE_PROFILE_ASPECT_RATIO = 0.5113636363636364;
export const BUNDLE_PREVIEW_CONFIG = {
small: {
bundleWidth: 140,
bundleHeight: 280,
pfxWidth: 80,
pfxHeight: 120,
pfxTop: 70,
pfxLeft: 16,
avatarTop: 130,
avatarRight: 40,
avatarWithNameplateTop: 110,
avatarWithNameplateRight: 40,
nameplateBottom: 110,
nameplatePreviewWidth: 80,
avatarDecorationSize: 80,
avatarDecorationSizeTriple: 60
},
large: {
bundleWidth: 300,
bundleHeight: 340,
pfxWidth: 160,
pfxHeight: 280,
pfxTop: 10,
pfxLeft: 25,
avatarTop: 130,
avatarRight: 40,
avatarWithNameplateTop: 120,
avatarWithNameplateRight: 70,
nameplateBottom: 90,
nameplatePreviewWidth: 130,
avatarDecorationSize: 140,
avatarDecorationSizeTriple: 140
}
};
@@ -0,0 +1,19 @@
// Metro module 14643 (f14644).
import { StyleSheet, View } from "react-native";
import ReanimatedRexport, { useSharedValue, Easing } from "../../reanimated/ReanimatedRexport";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
export function CollectiblesProgressiveImage(props) {
const { source, style, ...props2 } = props;
const sharedValue = useSharedValue(0);
return <View style={style}>
<ReanimatedRexport.Image {...props2} source={source} style={{
...StyleSheet.absoluteFillObject,
opacity: sharedValue
}} onLoad={function onLoad() {
sharedValue.set(withTiming(1, {
duration: 500,
easing: Easing.inOut(Easing.ease)
}));
}} />
</View>;
}
@@ -0,0 +1,170 @@
// Metro module 8712 (f8713).
import * as Module19 from "react";
import { useMemo } from "react";
import { View, StyleSheet } from "react-native";
import { EXTERNAL_PRODUCT_SKU_IDS } from "../CollectiblesShopConstants";
import { COLLECTIBLES_SHOP_CARD_WIDTH, COLLECTIBLES_SHOP_CARD_HEIGHT } from "./CollectiblesShopCardV2";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { CheckmarkLargeBoldIcon } from "../../../design/components/Icon/native/redesign/generated/CheckmarkLargeBoldIcon";
import { LockIcon } from "../../../design/components/Icon/native/redesign/generated/LockIcon";
import { getProductType, getSelectedProduct } from "../utils/CollectiblesProductUtils";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { useShopProductItems } from "../hooks/useShopProductItems";
import BundleSampleV2 from "./BundleSampleV2";
import FastImage from "../../../components_native/common/FastImage";
import Module8713 from "../../../_bundle/Module8713";
import { FractionalPremiumSKUsSets } from "../../../_bundle/Module679";
import { FractionalNitroCoinIllustration, FRACTIONAL_NITRO_COIN_SIZE } from "./FractionalNitroCoinIllustration";
import AvatarDecorationSampleV2 from "./AvatarDecorationSampleV2";
import ProfileEffectSampleV2 from "./ProfileEffectSampleV2";
import ProfileFrameSamplePreview from "../profile_frames/native/previews/ProfileFrameSamplePreview";
import NameplateCardPreview from "../nameplates/native/NameplateCardPreview";
import { hexToRgbaString, hexWithOpacity } from "../../../utils/ColorUtils";
import { useToken } from "../../../design/tokens/native/useToken";
import { useDefaultVariantIndex } from "../hooks/useDefaultVariantIndex";
let previewHeight, useStyles, DisabledAssetOverlay, ProductPreview, ProductPreviewInner, AssetTileInternal;
const PurchasedAssetOverlay = function PurchasedAssetOverlay() {
const styles = useStyles();
return <View style={styles.overlayContainer}>
<CheckmarkLargeBoldIcon size="lg" style={styles.overlayIcon} />
</View>;
};
DisabledAssetOverlay = function DisabledAssetOverlay() {
const styles = useStyles();
return <View style={styles.overlayContainer}>
<LockIcon size="lg" style={styles.overlayIcon} />
</View>;
};
ProductPreview = function ProductPreview(props) {
const product = props.product;
let isPurchased = props.isPurchased;
const { isDisabled, disableBundleStaticBackground, muteBundleStaticBackground, cardWidth: cardWidth2 } = props;
const styles = useStyles();
const productType = getProductType(product);
const height = productType !== CollectiblesItemType.PROFILE_EFFECT && productType !== CollectiblesItemType.PROFILE_FRAME ? product.type === CollectiblesItemType.BUNDLE ? "100%" : "75%" : "100%";
const style = [styles.overlayContainer, , ,];
if (!isPurchased) {
isPurchased = isDisabled;
}
if (isPurchased) {
isPurchased = styles.purchasedOrDisabled;
}
style[1] = isPurchased;
style[2] = {
height
};
return <View style={style} renderToHardwareTextureAndroid needsOffscreenAlphaCompositing>
<ProductPreviewInner product={product} disableBundleStaticBackground={disableBundleStaticBackground} muteBundleStaticBackground={muteBundleStaticBackground} cardWidth={cardWidth2} />
</View>;
};
ProductPreviewInner = function ProductPreviewInner(props) {
const { product, disableBundleStaticBackground, muteBundleStaticBackground, cardWidth } = props;
const styles = useStyles();
const shopProductItems = useShopProductItems(product);
const { firstProfileEffect, firstAvatarDecoration, firstNameplate } = shopProductItems;
const memo = useMemo(() => {
let width = cardWidth;
if (cardWidth == null) {
width = COLLECTIBLES_SHOP_CARD_WIDTH;
}
return {
width,
height: COLLECTIBLES_SHOP_CARD_HEIGHT
};
}, [cardWidth]);
if (product.type === CollectiblesItemType.BUNDLE) {
return <BundleSampleV2 deco={firstAvatarDecoration} pfx={firstProfileEffect} nameplate={firstNameplate} size="small" previewAssets={product.previewAssets} disableStaticBackground={disableBundleStaticBackground} mutedStaticBackground={muteBundleStaticBackground} targetSize={memo} />;
}
if (product.skuId === EXTERNAL_PRODUCT_SKU_IDS.ORB_PROFILE_BADGE) {
return <FastImage source={{
uri: Module8713
}} style={styles.externalProductImage} />;
}
if (FractionalPremiumSKUsSets.ALL.has(product.skuId)) {
return <FractionalNitroCoinIllustration skuId={product.skuId} width={FRACTIONAL_NITRO_COIN_SIZE.CARD} height={FRACTIONAL_NITRO_COIN_SIZE.CARD} />;
}
const [item] = product.items;
const type = item?.type;
if (CollectiblesItemType.AVATAR_DECORATION === type) {
return <AvatarDecorationSampleV2 item={item} size={100} />;
}
if (CollectiblesItemType.PROFILE_EFFECT === type) {
return <View style={styles.profileEffectContainer}>
<ProfileEffectSampleV2 item={item} hideBackground />
</View>;
}
if (CollectiblesItemType.PROFILE_FRAME === type) {
return <View style={styles.profileFrameContainer}>
<ProfileFrameSamplePreview profileFrame={item} previewWidth={COLLECTIBLES_SHOP_CARD_WIDTH - Module712.space.PX_32} previewHeight={previewHeight} profileBackgroundColor={Module712.colors.BACKGROUND_BASE_LOW} />
</View>;
}
if (CollectiblesItemType.NAMEPLATE === type) {
return <NameplateCardPreview item={item} />;
}
return null;
};
AssetTileInternal = function AssetTileInternal(props) {
const { children, solidBackground = false } = props;
return <View style={[useStyles().assetContainer, {
backgroundColor: hexToRgbaString(hexWithOpacity(useToken(Module712.colors.BACKGROUND_BASE_LOW), solidBackground ? 1 : 0.8))
}]} importantForAccessibility="no-hide-descendants" accessibilityElementsHidden>{children}</View>;
};
previewHeight = COLLECTIBLES_SHOP_CARD_HEIGHT - 2 * Module712.space.PX_16;
useStyles = createStyles({
assetContainer: {
display: "flex",
justifyContent: "center",
alignItems: "center",
overflow: "hidden",
height: "100%",
width: "100%",
borderRadius: Module712.radii.sm
},
overlayContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: "center",
alignItems: "center",
width: "100%",
height: "75%"
},
profileEffectContainer: {
width: "100%",
height: "100%",
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
profileFrameContainer: {
width: "100%",
height: previewHeight,
alignItems: "center"
},
externalProductImage: {
width: 80,
height: 80,
resizeMode: "contain"
},
purchasedOrDisabled: {
opacity: 0.4
},
overlayIcon: {
position: "absolute",
opacity: 1,
color: Module712.colors.ICON_STRONG,
fontWeight: "bold"
}
});
const r76 = Module19.memo(function AssetTileV2(props) {
const { product, isPurchased, solidBackground } = props;
let isDisabled = props.isDisabled;
const { disableBundleStaticBackground, muteBundleStaticBackground, cardWidth: cardWidth2 } = props;
const r28 = [<ProductPreview product={getSelectedProduct(product, useDefaultVariantIndex(product))} isPurchased={isPurchased} isDisabled={isDisabled} disableBundleStaticBackground={disableBundleStaticBackground} muteBundleStaticBackground={muteBundleStaticBackground} cardWidth={cardWidth2} />, isPurchased && <PurchasedAssetOverlay />, ,];
if (isDisabled) {
isDisabled = !isPurchased;
}
if (isDisabled) {
isDisabled = <DisabledAssetOverlay />;
}
r28[2] = isDisabled;
return <AssetTileInternal solidBackground={solidBackground}>{r28}</AssetTileInternal>;
});
export default r76;
@@ -0,0 +1,181 @@
// Metro module 8715 (f8716).
import * as Module19 from "react";
import { useMemo } from "react";
import { View } from "react-native";
import IAPStore_android from "../../../stores/native/IAPStore.android";
import { CurrencyCodes, VerticalGradient } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useDefaultVariantIndex } from "../hooks/useDefaultVariantIndex";
import { getSelectedProduct, getProductOrbPrice, getProductType } from "../utils/CollectiblesProductUtils";
import { getFormattedPriceForCollectiblesProduct } from "./CollectiblesUtils";
import { getProductDiscount, DISCOUNT_DISPLAY_MINIMUM_THRESHOLD, ShopDiscountSource, getShopDiscountSource } from "../CollectiblesUtils";
import { useFetchVirtualCurrencyBalance } from "../../virtual_currency/hooks/index";
import { CollectiblesShopPricePlaceholder } from "./CollectiblesShopPricePlaceholder";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { OrbsIcon } from "../../../design/components/Icon/native/redesign/generated/OrbsIcon";
import { isAndroid } from "../../../utils/PlatformUtils";
import { TagIcon } from "../../../design/components/Icon/native/redesign/generated/TagIcon";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
import { useCurrentUser } from "../hooks/useCurrentUser";
import { useIsProfileFramesEarlyAccessPhase } from "../hooks/useCanPurchaseFrames";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import PremiumUtils from "../../../utils/PremiumUtils";
import { useToken } from "../../../design/tokens/native/useToken";
import { hexToRgbaString, hexWithOpacity } from "../../../utils/ColorUtils";
import { getProductName } from "../utils/getProductName";
import { useStateFromStores } from "../../../_bundle/Module589";
import Module4611 from "../../../_bundle/Module4611";
import CollectiblesShopCardVariants from "./CollectiblesShopCardVariants";
const useStyles = createStyles({
regularMetadataContainer: {
position: "absolute",
height: "45%",
width: "100%",
padding: 10,
flex: 1,
bottom: 0,
overflow: "hidden",
borderBottomLeftRadius: Module712.radii.sm,
borderBottomRightRadius: Module712.radii.sm,
display: "flex",
flexDirection: "column",
justifyContent: "flex-end"
},
assetName: {
marginBottom: 4
},
priceVariantsContainer: {
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
gap: Module712.space.PX_4
},
priceDescription: {
display: "flex",
flexDirection: "row",
alignItems: "center",
flex: 1
},
text: {
flexShrink: 1
},
discountPercentage: {
paddingLeft: 3
},
wheelIcon: {
marginTop: 0,
marginRight: 3
},
androidTextPadding: {
paddingBottom: 2
}
});
let Component = Module19.memo(({ product, hasShopDiscount, discountSource, styles, collectibleProductState, isFetchingGoogleSkus, preferVCPrice, isDisabled }) => {
let r172, props;
let balance;
balance = void 0;
const selectedProduct = getSelectedProduct(product, useDefaultVariantIndex(product));
const formattedPriceForCollectiblesProduct = getFormattedPriceForCollectiblesProduct(selectedProduct, hasShopDiscount, true);
const memo = useMemo(() => getProductOrbPrice({
product: selectedProduct,
hasShopDiscount
}), [selectedProduct, hasShopDiscount]);
const memo3 = useMemo(() => getProductDiscount(selectedProduct, hasShopDiscount).discountPercentage, [selectedProduct, hasShopDiscount]);
const memo2 = useMemo(() => getProductDiscount(selectedProduct, hasShopDiscount, CurrencyCodes.DISCORD_ORB).discountPercentage, [selectedProduct, hasShopDiscount]);
balance = useFetchVirtualCurrencyBalance().balance;
const memo4 = useMemo(() => memo == null ? null : balance == null ? null : memo.amount <= balance, [balance, memo]);
if (isFetchingGoogleSkus && formattedPriceForCollectiblesProduct == null) {
return <CollectiblesShopPricePlaceholder />;
}
if (collectibleProductState === "partiallyOwnedBundle") {
return <View style={styles.priceDescription}>
<Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={styles.text}>
{intl.string(t.BEjTij)}
</Text>
</View>;
}
if (collectibleProductState === "purchased") {
return <View style={styles.priceDescription}>
<Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={styles.text}>
{intl.string(t["6cfuDj"])}
</Text>
</View>;
}
if (collectibleProductState === "nitroUpsell") {
return <View style={styles.priceDescription}>
<Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={styles.text}>
{intl.string(t.sEAnVH)}
</Text>
</View>;
}
if (collectibleProductState === "nitroClaim") {
return <View style={styles.priceDescription}>
<Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={styles.text}>
{intl.string(t.rt69oo)}
</Text>
</View>;
}
if (isDisabled) {
r172 = <View style={styles.priceDescription}>
<Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={styles.text}>
{intl.string(t.wu4gyV)}
</Text>
</View>;
} else {
L33: {
L21: {
if (memo != null && balance != null) {
if (preferVCPrice !== true && !memo4 && formattedPriceForCollectiblesProduct != null) {
break L21;
}
const style = [styles.priceDescription, {
opacity: memo4 === false ? 0.5 : 1
}];
props = {
style,
children: [<OrbsIcon size="xxs" color="mobile-text-heading-primary" style={styles.wheelIcon} />, <Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} accessibilityLabel={intl.formatToPlainString(t.W4DfeF, {
orbAmount: memo.amount
})} style={[styles.text, isAndroid() && styles.androidTextPadding]}>{memo.amount}</Text>, memo2 >= DISCOUNT_DISPLAY_MINIMUM_THRESHOLD && <Text style={[styles.discountPercentage, styles.text, isAndroid() ? styles.androidTextPadding : void 0]} color="text-feedback-positive" variant="text-xs/semibold" lineClamp={1}>
{`-${memo2}%`}
</Text>]
};
break L33;
}
}
props = {
style: styles.priceDescription,
children: [hasShopDiscount ? discountSource === ShopDiscountSource.THIRDPARTY ? <TagIcon size="xs" color="mobile-text-heading-primary" style={styles.wheelIcon} /> : <NitroWheelIcon size="xs" color="mobile-text-heading-primary" style={styles.wheelIcon} /> : hasShopDiscount, <Text variant="text-xs/semibold" color="mobile-text-heading-primary" lineClamp={1} style={[styles.text, isAndroid() && styles.androidTextPadding]}>{formattedPriceForCollectiblesProduct}</Text>, memo3 >= DISCOUNT_DISPLAY_MINIMUM_THRESHOLD && <Text style={[styles.discountPercentage, styles.text, isAndroid() ? styles.androidTextPadding : void 0]} color="text-feedback-positive" variant="text-xs/semibold" lineClamp={1}>
{`-${memo3}%`}
</Text>]
};
}
r172 = <View {...props} />;
}
return r172;
});
Component.displayName = "PriceDescription";
const r59 = Module19.memo(function CardDetailsV2(props) {
const { product, collectibleProductState, preferVCPrice, isDisabled, hidePrice } = props;
const styles = useStyles();
const currentUser = useCurrentUser();
const r31 = useIsProfileFramesEarlyAccessPhase("CollectiblesShopCardCardDetailsV2") && getProductType(product) === CollectiblesItemType.PROFILE_FRAME;
const hasShopDiscount2 = PremiumUtils.canUseShopDiscounts(currentUser) || r31;
const shopDiscountSource = getShopDiscountSource(currentUser);
const token = useToken(Module712.colors.BACKGROUND_BASE_LOW);
const r15 = hexToRgbaString(hexWithOpacity(token, 0.9));
const r23 = hexToRgbaString(hexWithOpacity(token, 0));
const productName = getProductName(product);
const stateFromStores = useStateFromStores([IAPStore_android], () => IAPStore_android.isFetchingGoogleSkus());
return <Module4611 style={[styles.regularMetadataContainer]} colors={[r23, r15, token]} locations={[0, 0.4, 1]} start={VerticalGradient.START} end={VerticalGradient.END}>
<Text style={styles.assetName} variant="heading-sm/bold" color="mobile-text-heading-primary" lineClamp={1} accessibilityRole="header">{productName}</Text>
{hidePrice ? !hidePrice : <View style={styles.priceVariantsContainer}>
<Component product={product} hasShopDiscount={hasShopDiscount2} discountSource={shopDiscountSource} styles={styles} collectibleProductState={collectibleProductState} isFetchingGoogleSkus={stateFromStores} preferVCPrice={preferVCPrice} isDisabled={isDisabled} />
<CollectiblesShopCardVariants product={product} />
</View>}
</Module4611>;
});
export default r59;
@@ -0,0 +1,290 @@
// Metro module 8660 (f8661).
import * as Module19 from "react";
import { useCallback, useMemo } from "react";
import { View, PixelRatio } from "react-native";
import ThemeStore from "../../user_settings/ThemeStore";
import { EXTERNAL_PRODUCT_SKU_IDS, ShopCtaEnum } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useDefaultVariantIndex } from "../hooks/useDefaultVariantIndex";
import { getSelectedProduct, getProductType, isDynamicProduct, isOrbsExclusiveProduct } from "../utils/CollectiblesProductUtils";
import { useTrackShopCardImpression } from "./hooks/useTrackShopCardImpression";
import { useCurrentUser } from "../hooks/useCurrentUser";
import * as _CollectiblesWishlistUtils from "../../wishlists/CollectiblesWishlistUtils";
import useWishlistNUXActionSheet from "./useWishlistNUXActionSheet";
import { intl, t } from "../../../intl/index.native";
import ToastActionCreators from "../../toast/native/ToastActionCreators";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import { useTrackShopCardClick } from "../hooks/useTrackShopCardClick";
import { useWishlistButtonState } from "../hooks/useWishlistButtonState";
import { useIsProfileFramesEarlyAccessPhase } from "../hooks/useCanPurchaseFrames";
import { useStateFromStores } from "../../../_bundle/Module589";
import { isThemeDark } from "../../../design/shared";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import * as _CollectiblesUtils from "../CollectiblesUtils";
import { isPremiumCollectiblesProduct, isFreeCollectiblesProduct } from "../CollectiblesUtils";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
import { Text } from "../../../design/components/Text/native/Text";
import { IconBadgePill } from "./CollectiblesBadges";
import { DiceIcon } from "../../../design/components/Icon/native/redesign/generated/DiceIcon";
import LimitedTimeBadge from "./LimitedTimeBadge";
import { OrbsIcon } from "../../../design/components/Icon/native/redesign/generated/OrbsIcon";
import { WishlistButtonBase } from "./WishlistButton";
import CollectiblesShopCardAssetTileV2 from "./CollectiblesShopCardAssetTileV2";
import CollectiblesShopCardCardDetailsV2 from "./CollectiblesShopCardCardDetailsV2";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { openProductDetailsActionSheet } from "./openProductDetailsActionSheet";
import { useIsShopCardImpressionMobileEnabled } from "../experiments/CollectiblesShopCardImpressionMobileExperiment";
import { useTrackProductCardImpression } from "../hooks/useTrackProductCardImpression";
import PremiumUtils from "../../../utils/PremiumUtils";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import { useProductDisableState } from "../hooks/useProductDisableState";
import { useOneDayFractionalNitroEnabled } from "../experiments/OneDayFractionalNitroExperiment";
import VisibilitySensor from "./VisibilitySensor";
import { v4 } from "../../../_bundle/Module514";
import { HermesBuiltin } from "../../../_hermes/prelude";
let useStyles, CollectiblesShopCardV2Inner;
const CollectiblesShopCardInternalV2 = function CollectiblesShopCardInternalV2(props) {
let r227;
let content, trackShopCardClick, isWishlisted, handleToggle, c16697_8;
const { product: product2, onPress: onPress2, unpublishedAt, collectibleProductState, solidBackground, preferVCPrice, isDisabled = false, cardWidth, cardStyle, hideWishlistButton = false, hidePrice = false, isShopCardImpressionEnabled = false, disableBundleStaticBackground, muteBundleStaticBackground } = props;
content = void 0;
trackShopCardClick = void 0;
isWishlisted = void 0;
handleToggle = void 0;
c16697_8 = void 0;
const styles = useStyles();
const selectedProduct = getSelectedProduct(product2, useDefaultVariantIndex(product2));
const trackShopCardImpression = useTrackShopCardImpression(product2, selectedProduct, isShopCardImpressionEnabled);
const r38 = cardWidth != null ? {
width: cardWidth
} : {
width: 150
};
const currentUser = useCurrentUser();
const isWishlistableCollectiblesProduct = _CollectiblesWishlistUtils.isWishlistableCollectiblesProduct(selectedProduct);
const wishlistNUXActionSheet = useWishlistNUXActionSheet();
const { shouldShowWishlistNUXActionSheet, showWishlistNUXActionSheet } = wishlistNUXActionSheet;
const callback = useCallback(() => {
if (shouldShowWishlistNUXActionSheet) {
showWishlistNUXActionSheet(selectedProduct);
}
}, [shouldShowWishlistNUXActionSheet, showWishlistNUXActionSheet, selectedProduct]);
content = intl.string(t.F8FvUy);
const callback2 = useCallback(() => {
ToastActionCreators.open({
key: "WISHLIST_ERROR",
content
});
}, [content]);
trackShopCardClick = useTrackShopCardClick({
product: product2,
analyticsLocations: useAnalyticsLocations().analyticsLocations
});
const wishlistButtonState = useWishlistButtonState({
userId: currentUser.id,
skuId: selectedProduct.skuId,
onAddSuccess: callback,
onError: callback2
});
isWishlisted = wishlistButtonState.isWishlisted;
const isBusy = wishlistButtonState.isBusy;
handleToggle = wishlistButtonState.handleToggle;
let isPurchased2 = collectibleProductState === "purchased";
const r95 = isPurchased2 ? isPurchased2 : hideWishlistButton;
let r96 = !r95;
const disabled = !isWishlistableCollectiblesProduct;
const r1 = (r95 ? r96 : !disabled) && !isBusy;
c16697_8 = r1;
const memo = useMemo(() => c16697_8 ? [{
name: "toggleWishlist",
label: isWishlisted ? intl.string(t.yr9TTf) : intl.string(t["8DkMEQ"])
}] : void 0, [r1, isWishlisted]);
const callback3 = useCallback((a0) => {
if (a0.nativeEvent.actionName === "toggleWishlist") {
handleToggle();
}
}, [handleToggle]);
const isProfileFramesEarlyAccessPhase = useIsProfileFramesEarlyAccessPhase("CollectiblesShopCardV2");
const stateFromStores = useStateFromStores([ThemeStore], () => isThemeDark(ThemeStore.theme));
const props2 = {
ref: trackShopCardImpression,
style: [styles.card, r38, cardStyle],
onPress: () => {
trackShopCardClick(ShopCtaEnum.OPEN_DETAILS);
if (onPress2 != null) {
onPress2();
}
},
activeOpacity: 0.8,
accessibilityRole: "button",
accessibilityActions: memo,
onAccessibilityAction: callback3,
children: null
};
const shouldShowLimitedTimeBadge = _CollectiblesUtils.shouldShowLimitedTimeBadge(unpublishedAt);
const badgeOverride = product2.badgeOverride;
const r136 = getProductType(product2) === CollectiblesItemType.PROFILE_FRAME && isProfileFramesEarlyAccessPhase;
const r138 = product2.hideBadge ? null : r136 ? <View style={[styles.badgePill, stateFromStores ? styles.badgePillDarkMode : styles.badgePillLightMode]} accessibilityLabel={intl.string(t["1m6qcO"])}>
<NitroWheelIcon size="xs" color={stateFromStores ? "black" : "white"} />
</View> : badgeOverride != null ? <View style={[styles.badgePill, stateFromStores ? styles.badgePillDarkMode : styles.badgePillLightMode]}>
<Text variant="text-xs/bold" color={stateFromStores ? "text-overlay-dark" : "text-overlay-light"} allowFontScaling={false} style={styles.badgeOverrideText} lineClamp={1}>{badgeOverride}</Text>
</View> : isDynamicProduct(selectedProduct) ? <IconBadgePill icon={DiceIcon} accessibilityLabel={intl.string(t["+drfVi"])} isDark={stateFromStores} /> : shouldShowLimitedTimeBadge ? <LimitedTimeBadge unpublishedAt={unpublishedAt} style={styles.badge} /> : collectibleProductState === "nitroClaim" ? <NitroWheelIcon color="mobile-text-heading-primary" /> : isOrbsExclusiveProduct(selectedProduct) ? <IconBadgePill icon={OrbsIcon} accessibilityLabel={intl.string(t["0TmQRG"])} isDark={stateFromStores} /> : null;
L53: {
if (r138 == null) {
r227 = null;
if (r95) {
break L53;
}
}
const r231 = [r138, ,];
if (!r95) {
r96 = <WishlistButtonBase style={styles.wishlistButton} isWishlisted={isWishlisted} onPress={handleToggle} busy={isBusy} disabled={disabled} accessibilityHidden onTrackPress={trackShopCardClick} />;
}
r231[1] = r96;
r227 = <View style={styles.topRowOverlay}>{r231}</View>;
}
const children = [r227, , ,];
if (!isPurchased2) {
isPurchased2 = collectibleProductState === "partiallyOwnedBundle";
}
children[1] = <CollectiblesShopCardAssetTileV2 solidBackground={solidBackground} product={product2} isPurchased={isPurchased2} isDisabled={isDisabled} disableBundleStaticBackground={disableBundleStaticBackground} muteBundleStaticBackground={muteBundleStaticBackground} cardWidth={cardWidth} />;
children[2] = <CollectiblesShopCardCardDetailsV2 product={product2} collectibleProductState={collectibleProductState} preferVCPrice={preferVCPrice} isDisabled={isDisabled} hidePrice={hidePrice} />;
props2.children = children;
return <PressableOpacity {...props2} />;
};
CollectiblesShopCardV2Inner = function CollectiblesShopCardV2Inner(props) {
let isPurchased, isPartiallyOwnedBundle, c16698_6, canUseCollectibles;
const { product, unpublishedAt, solidBackground, preferVCPrice, cardWidth, cardStyle, hideWishlistButton, hidePrice } = props;
let onPress3 = props.onPress;
const { disableBundleStaticBackground, muteBundleStaticBackground } = props;
isPurchased = void 0;
isPartiallyOwnedBundle = void 0;
c16698_6 = void 0;
canUseCollectibles = void 0;
const defaultVariantIndex = useDefaultVariantIndex(product);
const selectedProduct2 = getSelectedProduct(product, defaultVariantIndex);
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
const callback = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
let shopAnalyticsContext = collectiblesAnalyticsContext;
if (collectiblesAnalyticsContext == null) {
shopAnalyticsContext = void 0;
}
openProductDetailsActionSheet({
product,
initialVariantIndex: defaultVariantIndex,
analyticsLocations,
shopAnalyticsContext
});
}, [analyticsLocations, product, defaultVariantIndex, collectiblesAnalyticsContext]);
const isShopCardImpressionMobileEnabled = useIsShopCardImpressionMobileEnabled("CollectiblesShopCardV2");
const handleCardVisibilityChange = useTrackProductCardImpression(product.skuId).handleCardVisibilityChange;
const canUseCollectibles2 = PremiumUtils.canUseCollectibles(useCurrentUser());
const productPurchaseState = useProductPurchaseState(selectedProduct2);
isPurchased = productPurchaseState.isPurchased;
isPartiallyOwnedBundle = productPurchaseState.isPartiallyOwnedBundle;
const isDisabled = useProductDisableState(selectedProduct2.skuId).isDisabled;
const oneDayFractionalNitroEnabled = useOneDayFractionalNitroEnabled("product_card");
let r79 = isPremiumCollectiblesProduct(selectedProduct2);
let r83 = isFreeCollectiblesProduct(selectedProduct2);
const r84 = (r79 ? !canUseCollectibles2 : r79) && !r83;
c16698_6 = r84;
if (!r83) {
if (r79) {
r79 = canUseCollectibles2;
}
r83 = r79;
}
canUseCollectibles = r83;
const memo = useMemo(() => {
if (isPurchased === true) {
return "purchased";
}
if (isPartiallyOwnedBundle === true) {
return "partiallyOwnedBundle";
}
if (c16698_6 === true) {
return "nitroUpsell";
}
if (canUseCollectibles === true) {
return "nitroClaim";
}
return null;
}, [canUseCollectibles, isPartiallyOwnedBundle, isPurchased, r84]);
if (product.skuId === EXTERNAL_PRODUCT_SKU_IDS.FRACTIONAL_PREMIUM_1_DAY && !oneDayFractionalNitroEnabled) {
return null;
}
if (onPress3 == null) {
onPress3 = callback;
}
const r96 = <CollectiblesShopCardInternalV2 product={product} onPress={onPress3} collectibleProductState={memo} unpublishedAt={unpublishedAt} solidBackground={solidBackground} preferVCPrice={preferVCPrice} isDisabled={isDisabled} cardWidth={cardWidth} cardStyle={cardStyle} hideWishlistButton={hideWishlistButton} hidePrice={hidePrice} isShopCardImpressionEnabled={isShopCardImpressionMobileEnabled} disableBundleStaticBackground={disableBundleStaticBackground} muteBundleStaticBackground={muteBundleStaticBackground} />;
return isShopCardImpressionMobileEnabled ? r96 : <VisibilitySensor onChange={handleCardVisibilityChange} resetKey={product.skuId}>{r96}</VisibilitySensor>;
};
const height = PixelRatio.getFontScale() >= 1.78 ? 302 : 170;
useStyles = createStyles({
card: {
position: "relative",
height,
width: 150,
display: "flex",
borderWidth: 1,
borderColor: Module712.colors.BORDER_SUBTLE,
borderRadius: Module712.radii.sm,
overflow: "hidden"
},
topRowOverlay: {
position: "absolute",
top: 6,
left: 6,
right: 6,
zIndex: 2,
display: "flex",
flexDirection: "row",
gap: 4,
justifyContent: "space-between",
alignItems: "flex-start"
},
badge: {
flexShrink: 1
},
badgePill: {
paddingHorizontal: Module712.space.PX_4,
paddingVertical: 1.5,
borderRadius: Module712.radii.round,
flexShrink: 1
},
badgeOverrideText: {
textTransform: "uppercase"
},
badgePillDarkMode: {
backgroundColor: Module712.colors.WHITE
},
badgePillLightMode: {
backgroundColor: Module712.colors.BADGE_BACKGROUND_BRAND
},
wishlistButton: {
marginLeft: "auto",
flexShrink: 0
}
});
const r76 = Module19.memo(function CollectiblesShopCardV2(props) {
if (props == null) {
HermesBuiltin.throwTypeError("Cannot destructure 'undefined' or 'null'.");
throw new Error("unreachable");
}
const props2 = HermesBuiltin.copyDataProperties({}, props, void 0);
return <CollectiblesAnalyticsProvider newValue={useMemo(() => ({
cardId: v4()
}), [props2.product.skuId])}>
<CollectiblesShopCardV2Inner {...props2} />
</CollectiblesAnalyticsProvider>;
});
export default r76;
export { height as COLLECTIBLES_SHOP_CARD_HEIGHT };
export const COLLECTIBLES_SHOP_CARD_WIDTH = 150;
export const COLLECTIBLES_SHOP_CARD_MAX_WIDTH = 180;
export const COLLECTIBLES_SHOP_CARD_GAP = 16;
@@ -0,0 +1,86 @@
// Metro module 8727 (f8728).
import { memo } from "react";
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import useIsVariantColorLight from "../hooks/useIsVariantColorLight";
import { CheckmarkSmallIcon } from "../../../design/components/Icon/native/redesign/generated/CheckmarkSmallIcon";
import { PlusSmallIcon } from "../../../design/components/Icon/native/redesign/generated/PlusSmallIcon";
import { useDefaultVariantIndex } from "../hooks/useDefaultVariantIndex";
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
let useStyles, useStyles2, VariantCheckmark, VariantOverflowOption;
const VariantOption = function VariantOption(props) {
const { variant, zIndex } = props;
const styles2 = useStyles2(props.isSelected);
return <View style={[styles2.variantOption, {
zIndex
}]}>
<View style={[styles2.variantOptionInner, {
backgroundColor: variant.variantValue
}]}>
{useProductPurchaseState(variant).isPurchased && <VariantCheckmark variant={variant} />}
</View>
</View>;
};
VariantCheckmark = function VariantCheckmark(props) {
return <CheckmarkSmallIcon color={useIsVariantColorLight(props.variant) ? Module712.colors.BLACK : Module712.colors.WHITE} size="xxs" />;
};
VariantOverflowOption = function VariantOverflowOption(props) {
const zIndex = props.zIndex;
const styles2 = useStyles2(props.isSelected);
return <View style={[styles2.variantOption, {
zIndex
}]}>
<View style={[styles2.variantOptionInner, styles2.variantOverflowInner]}>
<PlusSmallIcon color={Module712.colors.WHITE} size="xxs" />
</View>
</View>;
};
useStyles = createStyles({
variantsContainer: {
display: "flex",
flexDirection: "row",
alignItems: "center",
paddingStart: Module712.space.PX_4
}
});
useStyles2 = createStyles((a0) => ({
variantOption: {
marginStart: -Module712.space.PX_4,
width: 14,
height: 14,
borderWidth: 1,
borderColor: Module712.colors.BACKGROUND_BASE_LOW,
borderRadius: Module712.radii.round,
justifyContent: "center",
alignItems: "center"
},
variantOptionInner: {
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center",
borderRadius: Module712.radii.round,
borderWidth: a0 ? 1 : 0,
borderColor: Module712.colors.BUTTON_OUTLINE_PRIMARY_TEXT
},
variantOverflowInner: {
backgroundColor: Module712.colors.ICON_MUTED
}
}));
const r42 = memo(function CardProductVariants(props) {
const product = props.product;
const styles = useStyles();
const defaultVariantIndex = useDefaultVariantIndex(product);
if (getIsVariantProduct(product)) {
const length = product.variants.length;
const r24 = length > 4 ? 3 : length;
return <View style={styles.variantsContainer}>
{product.variants.slice(0, r24).map((item, index) => <VariantOption key={item.variantValue} variant={item} isSelected={index === defaultVariantIndex} zIndex={4 - Math.abs(defaultVariantIndex - index)} />)}
{r24 !== length && <VariantOverflowOption isSelected={defaultVariantIndex >= 3} zIndex={defaultVariantIndex >= 3 ? 4 : 0} />}
</View>;
}
return null;
});
export default r42;
@@ -0,0 +1,49 @@
// Metro module 14621 (f14622).
import { useMemo } from "react";
import { ScrollView, View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_GAP } from "./CollectiblesShopCardV2";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { useCardLayout } from "./hooks/useCardLayout";
import Module12 from "../../../_bundle/Module12";
let useStyles;
const ShopCardGridItem = function ShopCardGridItem(props) {
const { product, index, cardWidth: cardWidth2, preferVCPrice: preferVCPrice2, unpublishedAt, disableBundleStaticBackground: disableBundleStaticBackground2, muteBundleStaticBackground: muteBundleStaticBackground2 } = props;
return <CollectiblesAnalyticsProvider newValue={useMemo(() => ({
tilePosition: index
}), [index])}>
<CollectiblesShopCardV2 unpublishedAt={unpublishedAt} product={product} cardWidth={cardWidth2} preferVCPrice={preferVCPrice2} disableBundleStaticBackground={disableBundleStaticBackground2} muteBundleStaticBackground={muteBundleStaticBackground2} />
</CollectiblesAnalyticsProvider>;
};
useStyles = createStyles({
rowContainer: {
justifyContent: "center",
flexDirection: "row",
gap: COLLECTIBLES_SHOP_CARD_GAP
}
});
export default function CollectiblesShopCardsGrid(props) {
const { products, accessibilityLabel, category, preferVCPrice, scrollEnabled = false, onScroll, paddingTop, paddingBottom, disableBundleStaticBackground, muteBundleStaticBackground } = props;
const styles = useStyles();
const cardLayout = useCardLayout();
const { columns, cardWidth } = cardLayout;
return <ScrollView accessibilityLabel={accessibilityLabel} accessibilityRole="list" scrollEnabled={scrollEnabled} showsVerticalScrollIndicator={false} onScroll={onScroll} contentContainerStyle={{
gap: COLLECTIBLES_SHOP_CARD_GAP,
paddingTop,
paddingBottom
}}>
{useMemo(() => Module12.chunk(products, columns), [products, columns]).map((a0, a1) => {
let c27784_0 = a1;
return <View key={a1} style={styles.rowContainer}>
{a0.map((item, a1) => {
let r8 = category;
if (category == null) {
r8 = CollectiblesCategoryStore.getCategoryForProduct(item.skuId);
}
return <ShopCardGridItem key={item.skuId} product={item} index={c27784_0 * columns + a1} cardWidth={cardWidth} unpublishedAt={r8?.unpublishedAt} preferVCPrice={preferVCPrice} disableBundleStaticBackground={disableBundleStaticBackground} muteBundleStaticBackground={muteBundleStaticBackground} />;
})}
</View>;
})}
</ScrollView>;
};
@@ -0,0 +1,310 @@
// Metro module 11884 (f11885).
import { useMemo } from "react";
import { View } from "react-native";
import { EXTERNAL_PRODUCT_SKU_IDS } from "../CollectiblesShopConstants";
import { BUNDLE_PREVIEW_CONFIG, SAMPLE_PROFILE_ASPECT_RATIO } from "./CollectiblesPreviewConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useProfileEffect from "../profile_effects/useProfileEffect";
import FastImage from "../../../components_native/common/FastImage";
import Module11885 from "../../../_bundle/Module11885";
import useMaybeFetchProfileFrame from "../profile_frames/hooks/useMaybeFetchProfileFrame";
import ProfileFrameSamplePreview from "../profile_frames/native/previews/ProfileFrameSamplePreview";
import { useShopProductItems } from "../hooks/useShopProductItems";
import { useCollectiblesMobileFlexibleBundlesExperiment } from "../experiments/CollectiblesMobileFlexibleBundlesExperiment";
import BundleSampleV2 from "./BundleSampleV2";
import { getNameplateData } from "../nameplates/utils";
import Nameplate from "../nameplates/native/Nameplate";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { FractionalPremiumSKUsSets } from "../../../_bundle/Module679";
import { FractionalNitroCoinIllustration, FRACTIONAL_NITRO_COIN_SIZE } from "./FractionalNitroCoinIllustration";
import Module8713 from "../../../_bundle/Module8713";
import AvatarDecorationSampleV2 from "./AvatarDecorationSampleV2";
import { intl, t } from "../../../intl/index.native";
import { Text } from "../../../design/components/Text/native/Text";
import { getProductOrbPrice } from "../utils/CollectiblesProductUtils";
import { getFormattedPriceForCollectiblesProduct } from "./CollectiblesUtils";
import OrbCheckoutAmountTag from "../../virtual_currency/native/OrbCheckoutAmountTag";
import { useCurrentUser } from "../hooks/useCurrentUser";
import PremiumUtils from "../../../utils/PremiumUtils";
import { getProductNameAndTypeLabel } from "../utils/getProductName";
let useStyles, useStyles2, useStyles3, useStyles4, ProfileFrameAssetPreview, BundleAssetPreview, NameplateAssetPreview, CollectibleProductPreview, CollectibleProductPreviewContent, ProductDetails, ProductPriceAmountTag;
const ProfileEffectAssetPreview = function ProfileEffectAssetPreview(props) {
const item = props.item;
const styles3 = useStyles3();
const profileEffect = useProfileEffect(item.skuId);
return profileEffect != null ? <View style={styles3.profileEffectContainer}>
<FastImage source={{
uri: Module11885
}} alt={profileEffect.accessibilityLabel} style={styles3.profileEffect} resizeMode="cover" />
<FastImage style={styles3.profileEffect} source={{
uri: profileEffect.thumbnailPreviewSrc
}} alt={profileEffect.title} resizeMode="cover" />
</View> : null;
};
ProfileFrameAssetPreview = function ProfileFrameAssetPreview(props) {
const { item, width: width2, height: height3 } = props;
const maybeFetchProfileFrame = useMaybeFetchProfileFrame(item.skuId, "CollectiblesShopCheckoutDetails");
return maybeFetchProfileFrame != null ? <ProfileFrameSamplePreview profileFrame={maybeFetchProfileFrame} previewWidth={width2} previewHeight={height3} profileBackgroundColor={Module712.colors.BACKGROUND_BASE_LOW} /> : null;
};
BundleAssetPreview = function BundleAssetPreview(props) {
const { product: product4, width, height } = props;
const styles = useStyles();
const shopProductItems = useShopProductItems(product4);
const { firstProfileEffect, firstAvatarDecoration, firstNameplate } = shopProductItems;
const enabled = useCollectiblesMobileFlexibleBundlesExperiment("CollectiblesShopCheckoutDetails").enabled;
const bundleWidth = BUNDLE_PREVIEW_CONFIG.small.bundleWidth;
const height2 = enabled ? bundleWidth : Math.round(1.1494252873563218 * bundleWidth);
const scale = width / height2;
return <View style={useMemo(() => [styles.bundlePreviewContainer, {
width,
height
}], [styles.bundlePreviewContainer, width, height])}>
<View style={useMemo(() => [styles.bundlePreviewScale, {
width: bundleWidth,
height: height2,
transform: [{
scale
}]
}], [styles.bundlePreviewScale, bundleWidth, height2, scale])}>
<BundleSampleV2 deco={firstAvatarDecoration} pfx={firstProfileEffect} nameplate={firstNameplate} previewAssets={product4.previewAssets} disableStaticBackground size="small" targetSize={useMemo(() => ({
width,
height
}), [width, height])} exposureLocation="CollectiblesShopCheckoutDetails" />
</View>
</View>;
};
NameplateAssetPreview = function NameplateAssetPreview(props) {
const item = props.item;
const styles4 = useStyles4();
return <Nameplate nameplate={getNameplateData(item)} fullOpacity isSquarePreview style={styles4.nameplate} />;
};
CollectibleProductPreview = function CollectibleProductPreview(props) {
const { product: product4, recipientUser } = props;
const styles2 = useStyles();
const width2 = product4.type !== CollectiblesItemType.PROFILE_EFFECT ? product4.type === CollectiblesItemType.PROFILE_FRAME ? 42 : 55 : 42;
return <View style={[styles2.productPreviewContainer, {
height: 55,
width: width2
}]}>
<CollectibleProductPreviewContent product={product4} width={width2} height={55} userAvatarSource={recipientUser == null ? void 0 : recipientUser.getAvatarSource(void 0, false, width2)} />
</View>;
};
CollectibleProductPreviewContent = function CollectibleProductPreviewContent(props) {
const { product: product4, width: width2, height: height3, userAvatarSource } = props;
const styles2 = useStyles();
if (FractionalPremiumSKUsSets.ALL.has(product4.skuId)) {
return <FractionalNitroCoinIllustration skuId={product4.skuId} width={FRACTIONAL_NITRO_COIN_SIZE.CHECKOUT} height={FRACTIONAL_NITRO_COIN_SIZE.CHECKOUT} />;
}
if (product4.skuId === EXTERNAL_PRODUCT_SKU_IDS.ORB_PROFILE_BADGE) {
return <FastImage source={{
uri: Module8713
}} style={styles2.externalProductImage} />;
}
const type = product4.type;
if (CollectiblesItemType.AVATAR_DECORATION === type) {
return <AvatarDecorationSampleV2 item={product4.items[0]} size={width2} avatarSource={userAvatarSource} animate={false} />;
}
if (CollectiblesItemType.PROFILE_EFFECT === type) {
return <ProfileEffectAssetPreview item={product4.items[0]} />;
}
if (CollectiblesItemType.NAMEPLATE === type) {
return <NameplateAssetPreview item={product4.items[0]} />;
}
if (CollectiblesItemType.PROFILE_FRAME === type) {
return <ProfileFrameAssetPreview item={product4.items[0]} width={width2} height={height3} />;
}
if (CollectiblesItemType.BUNDLE === type) {
return <BundleAssetPreview product={product4} width={width2} height={height3} />;
}
return null;
};
ProductDetails = function ProductDetails(props) {
const { product, recipientUser } = props;
const styles2 = useStyles();
const memo = useMemo(() => {
if (FractionalPremiumSKUsSets.ALL.has(product.skuId)) {
return intl.string(t.DFMPWS);
}
if (product.skuId === EXTERNAL_PRODUCT_SKU_IDS.ORB_PROFILE_BADGE) {
return intl.string(t["0+rBWT"]);
}
const type = product.type;
if (CollectiblesItemType.AVATAR_DECORATION === type) {
return intl.string(t["7v0T9P"]);
}
if (CollectiblesItemType.PROFILE_EFFECT === type) {
return intl.string(t.wR5wOo);
}
if (CollectiblesItemType.NAMEPLATE === type) {
return intl.string(t.x5CoXR);
}
if (CollectiblesItemType.PROFILE_FRAME === type) {
return intl.string(t.GWrZOd);
}
if (CollectiblesItemType.BUNDLE === type) {
return intl.string(t.Zr5tjn);
}
return null;
}, [product.type, product.skuId]);
return memo == null ? <View style={styles2.productDetails}>
<Text variant="text-md/semibold">{product.name}</Text>
</View> : <View style={styles2.productDetails}>
<CollectibleProductPreview product={product} recipientUser={recipientUser} />
<View style={styles2.productDetailsTextContainer}>
<Text variant="text-md/semibold">{product.name}</Text>
<Text variant="text-sm/medium">{memo}</Text>
</View>
</View>;
};
ProductPriceAmountTag = function ProductPriceAmountTag(props) {
const { product: product2, hasShopDiscount, useOrbPrice } = props;
const memo = useMemo(() => {
let orbPrice, priceText;
if (useOrbPrice) {
orbPrice = getProductOrbPrice({
product: product2,
hasShopDiscount
});
priceText = void 0;
} else {
priceText = getFormattedPriceForCollectiblesProduct(product2, hasShopDiscount, true);
orbPrice = void 0;
}
return {
orbPrice,
priceText
};
}, [product2, hasShopDiscount, useOrbPrice]);
const { orbPrice, priceText } = memo;
return useOrbPrice ? <OrbCheckoutAmountTag orbAmount={orbPrice?.amount} /> : <Text variant="text-md/semibold">{priceText}</Text>;
};
useStyles = createStyles({
externalProductImage: {
width: 45,
height: 45
},
bundlePreviewContainer: {
alignItems: "center",
justifyContent: "center",
overflow: "hidden",
borderRadius: Module712.radii.xs
},
bundlePreviewScale: {
overflow: "hidden",
alignItems: "center",
justifyContent: "center"
},
productContainer: {
borderRadius: Module712.radii.lg,
flexDirection: "column",
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE
},
productDetailsContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: Module712.space.PX_16,
paddingVertical: Module712.space.PX_16
},
productPreviewContainer: {
justifyContent: "center",
alignItems: "center"
},
productDetails: {
display: "flex",
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_12
},
productDetailsTextContainer: {
gap: Module712.space.PX_4
},
errorContainer: {
height: 36,
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH,
justifyContent: "center",
paddingHorizontal: Module712.space.PX_16,
borderBottomLeftRadius: Module712.radii.lg,
borderBottomRightRadius: Module712.radii.lg
}
});
useStyles2 = createStyles((a0) => ({
giftProductContainer: {
borderWidth: 2,
borderColor: a0 ? Module712.colors.BACKGROUND_BRAND : Module712.colors.BORDER_FEEDBACK_CRITICAL,
marginHorizontal: Module712.space.PX_16,
backgroundColor: void 0
}
}));
useStyles3 = createStyles({
profileEffectContainer: {
position: "relative",
width: "100%",
height: "100%",
borderRadius: Module712.radii.xs,
overflow: "hidden"
},
profileEffect: {
position: "absolute",
width: "100%",
aspectRatio: SAMPLE_PROFILE_ASPECT_RATIO,
top: 0
}
});
useStyles4 = createStyles({
nameplate: {
borderRadius: Module712.radii.xs
}
});
export default function CollectiblesShopCheckoutDetails(props) {
const { product: product3, recipientUser, isValidRecipient = false, useOrbPrice: useOrbPrice2 = false } = props;
let c19252_1 = useOrbPrice2;
let isGift = props.isGift;
if (isGift === void 0) {
isGift = false;
}
const styles2 = useStyles();
const styles22 = useStyles2(isValidRecipient);
const canUseShopDiscounts = PremiumUtils.canUseShopDiscounts(useCurrentUser());
const memo = useMemo(() => {
let r19;
const productNameAndTypeLabel = getProductNameAndTypeLabel(product3);
if (c19252_1) {
const W4DfeF = t.W4DfeF;
let orbAmount = getProductOrbPrice({
product: product3,
hasShopDiscount: canUseShopDiscounts
})?.amount;
if (orbAmount == null) {
orbAmount = "";
}
r19 = intl.formatToPlainString(W4DfeF, {
orbAmount
});
} else {
r19 = getFormattedPriceForCollectiblesProduct(product3, canUseShopDiscounts, true);
if (r19 == null) {
r19 = "";
}
}
return `${productNameAndTypeLabel}, ${r19}`;
}, [product3, useOrbPrice2, canUseShopDiscounts]);
const style = [styles2.productContainer, isGift ? styles22.giftProductContainer : isGift];
const r47 = [<View style={styles2.productDetailsContainer} accessibilityLabel={memo} accessible>
<ProductDetails product={product3} recipientUser={recipientUser} />
<ProductPriceAmountTag product={product3} hasShopDiscount={canUseShopDiscounts} useOrbPrice={useOrbPrice2} />
</View>, ,];
if (isGift) {
isGift = !isValidRecipient;
}
if (isGift) {
isGift = <View style={styles2.errorContainer}>
<Text variant="text-xs/semibold" color="text-feedback-critical">
{intl.string(t["3YfczA"])}
</Text>
</View>;
}
r47[1] = isGift;
return <View style={style}>{r47}</View>;
};
@@ -0,0 +1,57 @@
// Metro module 15626 (f15627).
import CollectiblesMarketingsStore from "../CollectiblesMarketingsStore";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { useSelectedVersionedDismissibleContent } from "../../dismissible_content/hooks/useSelectedDismissibleContent";
import { DismissibleContent } from "../../../_bundle/Module1358";
import YouScreenNavIcon from "../../main_tabs_v2/native/tabs/you/YouScreenNavIcon";
import { ShopIcon } from "../../../design/components/Icon/native/redesign/generated/ShopIcon";
import { intl, t } from "../../../intl/index.native";
import MobileShopButtonCoachmark from "./MobileShopButtonCoachmark";
import { useStateFromStores } from "../../../_bundle/defaultAreStatesEqual";
import { CollectiblesMarketingSurface } from "../../../_bundle/Module13124";
import { CollectiblesMarketingType } from "../../../_bundle/Module5822";
import SelectedDismissibleContent, { SelectedVersionedDismissibleContent } from "../../dismissible_content/native/SelectedDismissibleContent";
const CoachmarkVariant = function CoachmarkVariant(props) {
const { marketing, navigateToShop, shopButtonRef: shopButtonRef2 } = props;
const [r31, onDismiss] = useSelectedVersionedDismissibleContent(DismissibleContent.COLLECTIBLES_SHOP_ENTRY_MARKETING, marketing.version, void 0, true);
let c22254_1 = onDismiss;
const showRedDot = r31 === DismissibleContent.COLLECTIBLES_SHOP_ENTRY_MARKETING;
let c22254_2 = showRedDot;
return <>
<YouScreenNavIcon ref={shopButtonRef2} IconComponent={ShopIcon} accessibilityLabel={intl.string(t.pWG4ze)} onPress={() => {
if (c22254_2) {
c22254_1(ContentDismissActionType.TAKE_ACTION);
}
navigateToShop();
}} showRedDot={showRedDot} />
<MobileShopButtonCoachmark marketing={marketing} shopButtonRef={shopButtonRef2} navigateToShop={navigateToShop} visible={showRedDot} onDismiss={onDismiss} />
</>;
};
export default function CollectiblesShopEntryButton(props) {
let r48;
const { navigateToShop: navigateToShop2, shopButtonRef } = props;
const stateFromStores = useStateFromStores([CollectiblesMarketingsStore], () => CollectiblesMarketingsStore.getMarketingBySurface(CollectiblesMarketingSurface.MOBILE_SHOP_BUTTON));
const r1 = stateFromStores != null && "dismissibleContent" in stateFromStores && stateFromStores.dismissibleContent === DismissibleContent.COLLECTIBLES_SHOP_ENTRY_MARKETING;
if (stateFromStores?.type === CollectiblesMarketingType.COACHMARK) {
return <CoachmarkVariant marketing={stateFromStores} navigateToShop={navigateToShop2} shopButtonRef={shopButtonRef} />;
}
const content = function content({ visibleContent, markAsDismissed }) {
return <YouScreenNavIcon ref={shopButtonRef} IconComponent={ShopIcon} accessibilityLabel={intl.string(t.pWG4ze)} onPress={() => {
navigateToShop2();
if (visibleContent != null) {
markAsDismissed(ContentDismissActionType.PRIMARY);
}
}} showRedDot={visibleContent != null} />;
};
if (r1) {
const contentType = stateFromStores?.type === CollectiblesMarketingType.BADGE ? DismissibleContent.COLLECTIBLES_SHOP_ENTRY_MARKETING : null;
let latestVersion = stateFromStores?.version;
if (latestVersion == null) {
latestVersion = 0;
}
r48 = <SelectedVersionedDismissibleContent contentType={contentType} latestVersion={latestVersion}>{content}</SelectedVersionedDismissibleContent>;
} else {
r48 = <SelectedDismissibleContent contentTypes={stateFromStores?.type === CollectiblesMarketingType.BADGE ? stateFromStores?.dismissibleContent != null ? [stateFromStores.dismissibleContent] : [] : []}>{content}</SelectedDismissibleContent>;
}
return r48;
};
@@ -0,0 +1,23 @@
// Metro module 14611 (f14612).
import { View } from "react-native";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { EmptyState } from "../../../design/void/native";
import { NoResults } from "../../../design/components/Illustration/native/redesign/generated/NoResults";
import { intl, t } from "../../../intl/index.native";
import ShopBlockItem from "./ShopBlockItem";
const useStyles = createStyles({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
export default ({ shopBlock, fetchShopHomeError, framesBannerBlock }) => {
const styles = useStyles();
return fetchShopHomeError === null && shopBlock !== void 0 ? <ShopBlockItem block={shopBlock} screen={CollectiblesMobileShopScreen.FEATURED_PAGE} framesBannerBlock={framesBannerBlock} /> : <View style={styles.container}>
<EmptyState style={{
marginTop: 42
}} Illustration={NoResults} body={intl.string(t.eAn6z2)} />
</View>;
};
@@ -0,0 +1,64 @@
// Metro module 11901 (f11902).
import { useCallback } from "react";
import { Pressable, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { ModalScreen } from "../../../design/components/Modal/native/ModalScreen.native";
import { intl, t } from "../../../intl/index.native";
import { XSmallIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallIcon";
import { Text } from "../../../design/components/Text/native/Text";
import GiftingBadge_messages from "../../premium/gifting/GiftingBadge.messages";
import GiftBadgePostPurchase from "../../premium/native/gifting/GiftBadgePostPurchase";
const useStyles = createStyles((a0) => ({
header: {
position: "absolute",
top: 0,
left: 0,
right: 0,
height: a0 + 56,
paddingTop: a0,
zIndex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center"
},
closeButton: {
position: "absolute",
left: 0,
top: a0,
bottom: 0,
paddingHorizontal: Module712.space.PX_16,
justifyContent: "center"
},
closeIcon: {
tintColor: Module712.colors.MOBILE_TEXT_HEADING_PRIMARY
}
}));
export default function CollectiblesShopGiftBadgePostPurchaseModal(props) {
const giftBadgeProgress = props.giftBadgeProgress;
const styles = useStyles(useSafeAreaInsets_native().top);
const callback2 = useCallback(() => {
ModalActionCreators.pop();
}, []);
const callback = useCallback(() => {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.GIFTING_BADGE_POST_PURCHASE],
analyticsSource: AnalyticsLocation.GIFTING_BADGE_POST_PURCHASE
});
}, []);
return <ModalScreen>
<View style={styles.header}>
<Pressable onPress={callback2} accessibilityRole="button" accessibilityLabel={intl.string(t.cpT0Cq)} style={styles.closeButton}>
<XSmallIcon size="md" style={styles.closeIcon} />
</Pressable>
<Text accessibilityRole="header" aria-level="1" lineClamp={1} variant="redesign/heading-18/bold" color="mobile-text-heading-primary">
{intl.string(GiftingBadge_messages.roVAey)}
</Text>
</View>
<GiftBadgePostPurchase currentProgress={giftBadgeProgress} onSendGift={callback} />
</ModalScreen>;
};
@@ -0,0 +1,37 @@
// Metro module 8770 (f8771).
import { useEffect, useCallback } from "react";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { COLLECTIBLES_APPLICATION_ID } from "../../../Constants";
import { GiftingBadgeExperiment } from "../../premium/gifting/experiments/GiftingBadgeExperiment";
import { fetchBadge } from "../../badges/BadgeDirectoryActionCreators";
import { BadgeId } from "../../../_bundle/Module8106";
import { useStateFromStores } from "../../../_bundle/Module589";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { isNullOrEmpty } from "../../../utils/StringUtils";
import { validateCollectiblesRecipient } from "../CollectiblesActionCreators";
import { isCollectibleGiftingSupported } from "../../device/BillingPlatformUtils";
import UnsupportedFeatureModal from "../../billing/native/UnsupportedFeatureModal";
import { intl, t } from "../../../intl/index.native";
import UnifiedGiftModal from "../../checkout/native/gifting/UnifiedGiftModal";
import CollectiblesShopCheckoutDetails from "./CollectiblesShopCheckoutDetails";
import CollectiblesShopGiftPurchaseSection from "./CollectiblesShopGiftPurchaseSection";
export default function CollectiblesShopGiftModal(props) {
let stateFromStores, skuId2;
const { skuId, analyticsLocations, lockedRecipientUser, onGiftModalDismiss, giftingOrigin } = props;
stateFromStores = void 0;
skuId2 = void 0;
const enabled = GiftingBadgeExperiment.useConfig({
location: "CollectiblesShopGiftModal"
}).enabled;
useEffect(() => {
if (enabled) {
fetchBadge(BadgeId.GIFTING);
}
}, [enabled]);
stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.getProduct(skuId), [skuId]);
const analyticsLocations2 = useAnalyticsLocations([...analyticsLocations, AnalyticsLocation.COLLECTIBLES_MOBILE_GIFT_MODAL]).analyticsLocations;
skuId2 = stateFromStores?.skuId;
const callback = useCallback((a0) => isNullOrEmpty(skuId2) ? Promise.resolve(false) : validateCollectiblesRecipient(a0, skuId2), [skuId2]);
return stateFromStores == null ? null : isCollectibleGiftingSupported() ? <UnifiedGiftModal skuId={stateFromStores.skuId} applicationId={COLLECTIBLES_APPLICATION_ID} analyticsLocations={analyticsLocations2} lockedRecipientUser={lockedRecipientUser} onGiftModalDismiss={onGiftModalDismiss} giftingOrigin={giftingOrigin} validateRecipient={callback} renderProductDetails={(a0) => <CollectiblesShopCheckoutDetails product={stateFromStores} recipientUser={a0.recipientUser} isValidRecipient={a0.isValidRecipient} isGift />} renderPurchaseSection={(a0) => <CollectiblesShopGiftPurchaseSection product={stateFromStores} isPurchaseDisabled={a0.isPurchaseDisabled} giftOptions={a0.giftOptions} baseAnalyticsFields={a0.baseAnalyticsFields} giftingOrigin={giftingOrigin} onGiftModalDismiss={onGiftModalDismiss} />} /> : <UnsupportedFeatureModal onDismiss={onGiftModalDismiss} title={intl.string(t["JCFN/y"])} />;
};
@@ -0,0 +1,196 @@
// Metro module 11887 (f11888).
import { useState, useEffect, useCallback } from "react";
import { View } from "react-native";
import BadgeDirectoryStore from "../../badges/BadgeDirectoryStore";
import { useNativeCheckoutStore } from "../../checkout/native/NativeCheckoutStore";
import { AnalyticEvents, MarketingURLs } from "../../../Constants";
import { GiftingOrigin, PremiumGiftStyles } from "../../premium/PremiumConstants";
import { PaymentGateways } from "../../../_bundle/Module505";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useSafeAreaInsetsKeyboardAware_native from "../../safe_area/useSafeAreaInsetsKeyboardAware.native";
import { GiftingBadgeExperiment } from "../../premium/gifting/experiments/GiftingBadgeExperiment";
import { useStateFromStoresObject } from "../../../_bundle/Module589";
import { BadgeId } from "../../../_bundle/Module8106";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import useSyncGiftOptionsToOrder from "../../checkout/native/useSyncGiftOptionsToOrder";
import useMobileCollectiblesPurchaseSKU_android from "./hooks/useMobileCollectiblesPurchaseSKU.android";
import Dispatcher from "../../../Dispatcher";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import AlertActionCreators from "../../../actions/native/AlertActionCreators";
import { isIOS } from "../../../utils/PlatformUtils";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import GiftingBadgeProgressBanner from "../../premium/gifting/native/views/GiftingBadgeProgressBanner";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { Button } from "../../../design/components/Button/native/Button.native";
import { GiftACOMOrderExperiment } from "../../billing/native/ACOMExperiments";
import { useAndroidShopOrdersEnabled } from "../../billing/experiments/AndroidShopOrdersExperiment";
import { isGooglePlayBillingSupported } from "../../device/BillingPlatformUtils";
import useCollectiblesExternalGatewayFacet_android from "./hooks/useCollectiblesExternalGatewayFacet.android";
import { closeShopGiftModal } from "./openGiftModal";
import { NativePaymentContextProvider } from "../../payments/native/NativePaymentContext";
import NativeCheckoutStoreProvider from "../../checkout/native/stores/NativeCheckoutStoreProvider";
let useStyles, c8152_17;
const CollectiblesShopGiftPurchaseSection = function CollectiblesShopGiftPurchaseSection(props) {
let badgeProgress, state, setState, awaitSync, c19253_8;
const { product, isPurchaseDisabled, giftOptions, baseAnalyticsFields, giftingOrigin } = props;
badgeProgress = void 0;
state = void 0;
setState = void 0;
awaitSync = void 0;
c19253_8 = void 0;
const styles = useStyles(useSafeAreaInsetsKeyboardAware_native().insets.bottom);
const enabled = GiftingBadgeExperiment.useConfig({
location: "CollectiblesShopGiftPurchaseSection"
}).enabled;
const stateFromStoresObject = useStateFromStoresObject([BadgeDirectoryStore], () => ({
nextTier: BadgeDirectoryStore.getNextTier(BadgeId.GIFTING),
giftsToNextTier: BadgeDirectoryStore.getRemainingToNextTier(BadgeId.GIFTING),
badgeProgress: BadgeDirectoryStore.getSingleRequirementProgress(BadgeId.GIFTING)?.current
}));
const { nextTier, giftsToNextTier } = stateFromStoresObject;
badgeProgress = stateFromStoresObject.badgeProgress;
[state, setState] = useState(c8152_17.NOT_STARTED);
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
const nativeCheckoutStore = useNativeCheckoutStore((a0) => a0.orderRecord);
awaitSync = useSyncGiftOptionsToOrder(nativeCheckoutStore, giftOptions).awaitSync;
c19253_8 = useMobileCollectiblesPurchaseSKU_android({
product,
analyticsLocations,
orderId: nativeCheckoutStore?.id,
analyticsData: baseAnalyticsFields,
onPurchaseComplete: () => {
if (!(giftOptions.recipient_id == null || giftingOrigin !== GiftingOrigin.USER_PROFILE_WISHLIST && giftingOrigin !== GiftingOrigin.DM_CHANNEL_WISHLIST)) {
Dispatcher.dispatch({
type: "WISHLIST_GIFT_SENT",
skuId: product.skuId,
recipientId: giftOptions.recipient_id
});
}
setState(c8152_17.SUCCEEDED);
ModalActionCreators.pop();
AlertActionCreators.openLazy({
importer: () => import("../../checkout/native/gifting/UnifiedGiftModalSuccessScreen").then(({ default: Component }) => (a0) => {
let gift_style = giftOptions.gift_style;
if (gift_style == null) {
gift_style = PremiumGiftStyles.STANDARD_BOX;
}
return <Component giftStyle={gift_style} giftBadgeProgress={badgeProgress} {...a0} />;
})
});
if (isIOS()) {
AnalyticsUtils.track(AnalyticEvents.PAYMENT_FLOW_SUCCEEDED, baseAnalyticsFields);
}
},
onPurchaseError: () => {
setState(c8152_17.FAILED);
AnalyticsUtils.track(AnalyticEvents.PAYMENT_FLOW_FAILED, baseAnalyticsFields);
},
onPurchasePending: () => {},
giftParams: {
isGift: true,
options: giftOptions
}
});
useEffect(() => () => {
if (state !== c8152_17.SUCCEEDED) {
AnalyticsUtils.track(AnalyticEvents.PAYMENT_FLOW_CANCELED, baseAnalyticsFields);
}
}, []);
let r77 = null;
if (enabled) {
const r78 = nextTier != null;
r77 = null;
if (r78) {
let name = nextTier.name;
if (name == null) {
name = "";
}
r77 = <GiftingBadgeProgressBanner giftsToNextTier={giftsToNextTier} nextTierName={name} nextTierIcon={nextTier.simple_icon_url} />;
}
}
return <View style={styles.container}>
{r77}
<Text variant="text-xs/normal" style={styles.disclaimer}>
{intl.format(t.rsEdd2, {
buyButtonLabel: intl.string(t.ouo4FK),
paidServiceTermURL: MarketingURLs.PAID_TERMS,
virtualGoodsURL: MarketingURLs.PAID_TERMS_VIRTUAL_GOODS
})}
</Text>
<Button disabled={isPurchaseDisabled} loading={state === c8152_17.PURCHASING} variant="active" text={intl.string(t.ouo4FK)} onPress={async () => {
let c27204_2 = 0;
L15: {
try {
setState(c8152_17.PURCHASING);
if (await awaitSync()) {
c27204_2 = 1;
await (0, c19253_8)();
c27204_2 = 0;
break L15;
}
setState(c8152_17.FAILED);
AnalyticsUtils.track(AnalyticEvents.PAYMENT_FLOW_FAILED, baseAnalyticsFields);
} catch ($e) {
let r26 = $e;
if (c27204_2 !== 0) {
while (true) {
try {
c27204_2 = 0;
(0, setState)(c8152_17.FAILED);
break L15;
} catch ($e) {
r26 = $e;
if (c27204_2 === 0) {
break;
}
}
}
}
throw r26;
}
return void 0;
}
}} />
</View>;
};
useStyles = createStyles((a0) => ({
container: {
paddingBottom: Module712.space.PX_12 + a0,
paddingTop: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16,
gap: Module712.space.PX_8,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
...Module712.shadows.SHADOW_TOP_HIGH
},
disclaimer: {
includeFontPadding: true
}
}));
c8152_17 = {
NOT_STARTED: "not_started",
PURCHASING: "purchasing",
SUCCEEDED: "succeeded",
FAILED: "failed"
};
export default function WrappedCollectiblesShopGiftPurchaseSection(props) {
const { product: product2, isPurchaseDisabled, giftOptions: giftOptions2, baseAnalyticsFields: baseAnalyticsFields2, giftingOrigin: giftingOrigin2, onGiftModalDismiss } = props;
const enabled = GiftACOMOrderExperiment.useConfig({
location: "WrappedCollectiblesShopGiftPurchaseSection"
}).enabled;
const androidShopOrdersEnabled = useAndroidShopOrdersEnabled({
location: "WrappedCollectiblesShopGiftPurchaseSection"
});
const paymentGateway = isIOS() ? PaymentGateways.APPLE_ADVANCED_COMMERCE : PaymentGateways.GOOGLE;
return <NativePaymentContextProvider skuIDs={[]} activeSubscription={null}>
<NativeCheckoutStoreProvider key={product2.skuId} paymentGateway={paymentGateway} orderRequired={paymentGateway === PaymentGateways.APPLE_ADVANCED_COMMERCE && enabled || paymentGateway === PaymentGateways.GOOGLE && isGooglePlayBillingSupported() && androidShopOrdersEnabled} skuIds={[product2.skuId]} isGift activeSubscription={null} initialExternalGatewayFacet={useCollectiblesExternalGatewayFacet_android(product2)} onOrderRetryCancellation={useCallback(() => {
closeShopGiftModal();
if (onGiftModalDismiss != null) {
onGiftModalDismiss();
}
}, [onGiftModalDismiss])}>
<CollectiblesShopGiftPurchaseSection product={product2} isPurchaseDisabled={isPurchaseDisabled} giftOptions={giftOptions2} baseAnalyticsFields={baseAnalyticsFields2} giftingOrigin={giftingOrigin2} />
</NativeCheckoutStoreProvider>
</NativePaymentContextProvider>;
};
@@ -0,0 +1,60 @@
// Metro module 14638 (f14639).
import { useEffect, useCallback } from "react";
import { View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import { useCollectiblesAnalyticsContext } from "../CollectiblesAnalyticsContext";
import { useCollectiblesShopDeepLinkProps } from "./useCollectiblesShopDeepLinkProps";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { openProductDetailsActionSheet } from "./openProductDetailsActionSheet";
import ShopBlockItem from "./ShopBlockItem";
import { EmptyState } from "../../../design/void/native";
import { NoResults } from "../../../design/components/Illustration/native/redesign/generated/NoResults";
import { intl, t } from "../../../intl/index.native";
import ShopFlashList from "./ShopFlashList";
const useStyles = createStyles({
container: {
display: "flex",
flex: 1
}
});
export default ({ shopBlocks, fetchShopHomeError, onRenderFirstOrbsItem, getItemType }) => {
const styles = useStyles();
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
const collectiblesShopDeepLinkProps = useCollectiblesShopDeepLinkProps({});
const { initialProductSkuId, initialVariantIndex, initialCategorySkuId } = collectiblesShopDeepLinkProps;
useEffect(() => {
if (initialProductSkuId != null && initialCategorySkuId != null) {
const category = CollectiblesCategoryStore.getCategory(initialCategorySkuId);
const product = category == null ? void 0 : category.products.find((product) => product.skuId === initialProductSkuId);
if (product != null) {
ActionSheetActionCreators.hideActionSheet();
let shopAnalyticsContext = collectiblesAnalyticsContext;
if (collectiblesAnalyticsContext == null) {
shopAnalyticsContext = void 0;
}
openProductDetailsActionSheet({
product,
initialVariantIndex,
analyticsLocations,
shopAnalyticsContext
});
}
}
}, [initialProductSkuId, initialVariantIndex, initialCategorySkuId, analyticsLocations, collectiblesAnalyticsContext]);
const callback = useCallback((a0) => {
const item = a0.item;
if (a0.index === 0) {
onRenderFirstOrbsItem();
}
return <ShopBlockItem block={item} screen={CollectiblesMobileShopScreen.ORBS} preferVCPrice />;
}, [onRenderFirstOrbsItem]);
return fetchShopHomeError === null && shopBlocks.length !== 0 ? <ShopFlashList data={shopBlocks} renderItem={callback} getItemType={getItemType} /> : <View style={styles.container}>
<EmptyState style={{
marginTop: 42
}} Illustration={NoResults} body={intl.string(t.eAn6z2)} />
</View>;
};
@@ -0,0 +1,36 @@
// Metro module 8725 (f8726).
import { useEffect } from "react";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import ReanimatedRexport, { useSharedValue, withRepeat, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
const useStyles = createStyles({
skeletonContainer: {
height: 16,
flex: 1,
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.REDESIGN_BUTTON_TERTIARY_BACKGROUND
}
});
const __initData = {
code: "function CollectiblesShopPricePlaceholderTsx1(){const{opacity}=this.__closure;return{opacity:opacity.get()};}"
};
export function CollectiblesShopPricePlaceholder(props) {
const style = props.style;
const styles = useStyles();
const sharedValue = useSharedValue(0.3);
useEffect(() => {
sharedValue.set(withRepeat(withTiming(1, {
duration: 650
}), -1, true));
}, [sharedValue]);
const h = () => ({
opacity: sharedValue.get()
});
h.__closure = {
opacity: sharedValue
};
h.__workletHash = 10107093534072;
h.__initData = __initData;
return <ReanimatedRexport.View style={[styles.skeletonContainer, style, useAnimatedStyle(h)]} />;
}
@@ -0,0 +1,340 @@
// Metro module 14604 (f14605).
import { useState, useEffect, useMemo, useRef, useCallback } from "react";
import { ActivityIndicator, View } from "react-native";
import DevSettingsStore from "../../devtools/dev_settings/DevSettingsStore";
import ThemeStore from "../../user_settings/ThemeStore";
import UserStore from "../../../stores/UserStore";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { FramesBannerBlockRecord } from "../records/FramesBannerBlockRecord";
import { COLLECTIBLES_SHOP_CACHE_DURATION_MS, CollectibleShopTab, CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents, PaymentGateways } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { useCommonTriggerPoint } from "../../experiments/trigger_points/useCommonTriggerPoint";
import { CollectiblesShopOpenTriggerPoint } from "../../experiments/trigger_points/CollectiblesShopOpenTriggerPoint";
import { useStateFromStores, useStateFromStoresArray, useStateFromStoresObject } from "../../../_bundle/Module589";
import useInitialValue from "../../../hooks/useInitialValue";
import { v4 } from "../../../_bundle/Module514";
import useFetchCollectiblesCategoriesAndPurchases from "../hooks/useFetchCollectiblesCategoriesAndPurchases";
import { useMaybeFetchCollectiblesShopHome } from "../hooks/useMaybeFetchShopHome";
import * as _PlatformUtils from "../../../utils/PlatformUtils";
import { isAndroid } from "../../../utils/PlatformUtils";
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
import NativePaymentHooks_android from "../../payments/native/hooks/NativePaymentHooks.android";
import { useCurrentUserIfAvailable } from "../hooks/useCurrentUser";
import { useCurrentUserWishlist } from "../../wishlists/hooks/useWishlistHooks";
import { isThemeDark } from "../../../design/shared";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { filterHiddenCategories, filterGPlaySyncedCategories } from "./CollectiblesUtils";
import { isGooglePlayBillingSupported } from "../../device/BillingPlatformUtils";
import { useCollectiblesShopDeepLinkProps } from "./useCollectiblesShopDeepLinkProps";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { trackShopPerf, CollectiblesShopPerfCheckpoint } from "../utils/CollectiblesPerfLogging";
import maybeFetchUserProfile from "../../user_profile/maybeFetchUserProfile";
import { ShopCategory } from "./ShopCategory";
import CollectiblesShopFeaturedPage from "./CollectiblesShopFeaturedPage";
import useCollectiblesShopHeader from "./useCollectiblesShopHeader";
import SentryUtils_native from "../../../utils/SentryUtils.native";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { NativePaymentContextProvider } from "../../payments/native/NativePaymentContext";
import ShopFlashList from "./ShopFlashList";
import CollectiblesShopOrbsPage from "./CollectiblesShopOrbsPage";
import { CollectiblesCoachmarkScrollDismissProvider } from "./CollectiblesCoachmarkScrollDismissContext";
import DebugLogView from "./DebugLogView";
import * as _ReleaseChannelUtils_native from "../../../utils/ReleaseChannelUtils.native";
let useStyles, CollectiblesShopInternal;
export function CollectiblesShopV2(props) {
let r54;
const nativeIAPPayments = NativePaymentHooks_android.useNativeIAPPayments();
const { nativePaymentsConnected, storeFront } = nativeIAPPayments;
const styles = useStyles();
const stateFromStores2 = useStateFromStores([UserStore], () => UserStore.getCurrentUser());
const r27 = (stateFromStores2 == null ? void 0 : stateFromStores2.isStaff()) || (stateFromStores2 == null ? void 0 : stateFromStores2.isStaffPersonal());
let [state, setState] = useState(false);
useEffect(() => {
if (nativePaymentsConnected) {
return void 0;
}
let c27778_0 = setTimeout(() => {
setState(true);
}, 10000);
return () => clearTimeout(c27778_0);
}, [nativePaymentsConnected]);
const r46 = _PlatformUtils.isIOS() && !_ReleaseChannelUtils_native.isStable && r27;
if (!nativePaymentsConnected && (!r46 && !state)) {
r54 = <ActivityIndicator style={styles.spinner} size="large" />;
} else {
if (state) {
state = !nativePaymentsConnected;
}
if (state) {
SentryUtils_native.captureMessage("collectibles mobile shop failed to connect to native payments isIOS: " + _PlatformUtils.isIOS() + " isStable: " + _ReleaseChannelUtils_native.isStable);
}
r54 = <CollectiblesShopInternal {...props} storeFront={storeFront} screen={props.screen} />;
}
return r54;
}
useStyles = createStyles({
rootContainer: {
height: "100%",
width: "100%"
},
spinner: {
position: "absolute",
top: "50%",
left: "50%",
marginTop: -8,
marginLeft: -8
}
});
CollectiblesShopInternal = (props) => {
let r199, r241, r256, COLLECTIBLES_SHOP_INDEX_PAGE;
let bypassGoogleSkuSync, noCache, includeUnpublished, sessionId, categories, isFetchingCategories, shopBlocks, fetchShopHomeError, isFetchingGoogleSkus, currentUserIfAvailable, stateFromStores, analyticsLocations, navigation, ref, memo;
const { analyticsSource, onNavigateAway, storeFront, screen } = props;
bypassGoogleSkuSync = void 0;
noCache = void 0;
includeUnpublished = void 0;
sessionId = void 0;
categories = void 0;
isFetchingCategories = void 0;
shopBlocks = void 0;
fetchShopHomeError = void 0;
isFetchingGoogleSkus = void 0;
currentUserIfAvailable = void 0;
stateFromStores = void 0;
analyticsLocations = void 0;
navigation = void 0;
ref = void 0;
memo = void 0;
useCommonTriggerPoint(CollectiblesShopOpenTriggerPoint);
const [r52] = useStateFromStoresArray([CollectiblesCategoryStore], () => {
let lastSuccessfulFetch = CollectiblesCategoryStore.lastSuccessfulFetch;
if (lastSuccessfulFetch == null) {
lastSuccessfulFetch = 0;
}
return [lastSuccessfulFetch];
});
const stateFromStoresObject = useStateFromStoresObject([DevSettingsStore], () => ({
bypassGoogleSkuSync: DevSettingsStore.get("bypass_google_sku_sync"),
noCache: DevSettingsStore.get("shop_disable_cache"),
includeUnpublished: DevSettingsStore.get("shop_include_unpublished")
}));
bypassGoogleSkuSync = stateFromStoresObject.bypassGoogleSkuSync;
noCache = stateFromStoresObject.noCache;
includeUnpublished = stateFromStoresObject.includeUnpublished;
const styles = useStyles();
const country = storeFront?.country;
const initialValue = useInitialValue(() => ({
sessionId: v4()
}));
sessionId = initialValue.sessionId;
const memo2 = useMemo(() => {
let tab = screen;
if (screen == null) {
tab = CollectiblesMobileShopScreen.FEATURED_PAGE;
}
return {
sessionId,
tab
};
}, [sessionId, screen]);
const fetchCollectiblesCategoriesAndPurchases = useFetchCollectiblesCategoriesAndPurchases({
paymentGateway: PaymentGateways.APPLE,
...country != null ? {
countryCode: country
} : {},
logPerf: true
}, memo2);
categories = fetchCollectiblesCategoriesAndPurchases.categories;
isFetchingCategories = fetchCollectiblesCategoriesAndPurchases.isFetchingCategories;
const maybeFetchCollectiblesShopHome = useMaybeFetchCollectiblesShopHome(screen === CollectiblesMobileShopScreen.ORBS ? CollectibleShopTab.ORBS : CollectibleShopTab.HOME, {
noCache,
includeUnpublished,
logPerf: true
}, memo2);
shopBlocks = maybeFetchCollectiblesShopHome.shopBlocks;
const isFetchingShopHome = maybeFetchCollectiblesShopHome.isFetchingShopHome;
let fetchShopHomeError2 = maybeFetchCollectiblesShopHome.fetchShopHomeError;
fetchShopHomeError = fetchShopHomeError2;
const googleSkuIds = NativePaymentHooks_android.useGoogleSkuIds(useMemo(() => {
if (isFetchingCategories !== true && isAndroid() !== false) {
const r27 = [];
let c27779_0 = r27;
for (const item of categories.values()) {
item.products.forEach((product) => {
if (product.googleSkuIds !== void 0 && product.googleSkuIds !== null) {
c27779_0.push.apply(c27779_0, [...Object.values(product.googleSkuIds)]);
}
if (getIsVariantProduct(product)) {
product.variants.forEach((variant) => {
if (variant.googleSkuIds !== void 0 && variant.googleSkuIds !== null) {
c27779_0.push.apply(c27779_0, [...Object.values(variant.googleSkuIds)]);
}
});
}
});
}
return r27;
}
return [];
}, [categories, isFetchingCategories]), isFetchingCategories === true);
isFetchingGoogleSkus = googleSkuIds.isFetchingGoogleSkus;
const fetchError = googleSkuIds.fetchError;
currentUserIfAvailable = useCurrentUserIfAvailable();
useCurrentUserWishlist();
stateFromStores = useStateFromStores([ThemeStore], () => isThemeDark(ThemeStore.theme));
const r116 = [AnalyticsLocation.COLLECTIBLES_SHOP, ,];
if (CollectiblesMobileShopScreen.SHOP_ALL === screen) {
COLLECTIBLES_SHOP_INDEX_PAGE = AnalyticsLocation.COLLECTIBLES_SHOP_INDEX_PAGE;
} else if (CollectiblesMobileShopScreen.ORBS === screen) {
COLLECTIBLES_SHOP_INDEX_PAGE = AnalyticsLocation.COLLECTIBLES_SHOP_ORBS_TAB;
} else {
CollectiblesMobileShopScreen.FEATURED_PAGE;
COLLECTIBLES_SHOP_INDEX_PAGE = AnalyticsLocation.COLLECTIBLES_SHOP_HOME_SCREEN;
}
r116[1] = COLLECTIBLES_SHOP_INDEX_PAGE;
analyticsLocations = useAnalyticsLocations(r116).analyticsLocations;
navigation = useNavigation();
useEffect(() => navigation.addListener("beforeRemove", (a0) => {
if (a0.data.action.type !== "RESET" && onNavigateAway != null) {
onNavigateAway();
}
}), [navigation, onNavigateAway]);
const memo3 = useMemo(() => {
const r7 = [...categories.values()];
return filterHiddenCategories(isGooglePlayBillingSupported() ? bypassGoogleSkuSync ? r7 : isFetchingGoogleSkus ? r7 : isFetchingCategories ? r7 : filterGPlaySyncedCategories(r7) : r7);
}, [categories, bypassGoogleSkuSync, isFetchingGoogleSkus, isFetchingCategories]);
const r4 = Date.now() - r52 > COLLECTIBLES_SHOP_CACHE_DURATION_MS;
let categoryIndex = useCollectiblesShopDeepLinkProps({
categories: memo3
}).categoryIndex;
const r153 = {};
r153[CollectiblesMobileShopScreen.SHOP_ALL] = false;
r153[CollectiblesMobileShopScreen.FEATURED_PAGE] = false;
r153[CollectiblesMobileShopScreen.ORBS] = false;
ref = useRef(r153);
useEffect(() => {
let tab = screen;
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_VIEWED, {
location_stack: analyticsLocations,
page_session_id: sessionId,
source: analyticsSource,
page_type: screen == null || screen === CollectiblesMobileShopScreen.FEATURED_PAGE || screen === CollectiblesMobileShopScreen.SHOP_ALL ? "home" : screen
});
if (screen == null) {
tab = CollectiblesMobileShopScreen.FEATURED_PAGE;
}
trackShopPerf({
sessionId,
checkpoint: CollectiblesShopPerfCheckpoint.SHOP_MOUNTED,
tab,
unpublishedCategoriesShown: includeUnpublished,
cacheDisabled: noCache
});
}, [analyticsLocations, analyticsSource, sessionId, includeUnpublished, screen, noCache]);
useEffect(() => {
if (currentUserIfAvailable != null) {
maybeFetchUserProfile(currentUserIfAvailable.id);
}
}, [currentUserIfAvailable]);
memo = useMemo(() => shopBlocks == null ? void 0 : shopBlocks.find((shopBlock) => shopBlock instanceof FramesBannerBlockRecord), [shopBlocks]);
const callback = useCallback(({ item, index }) => {
if (!(index !== 0 || ref.current[CollectiblesMobileShopScreen.SHOP_ALL])) {
ref.current[CollectiblesMobileShopScreen.SHOP_ALL] = true;
trackShopPerf({
sessionId,
checkpoint: CollectiblesShopPerfCheckpoint.SHOP_RENDERED,
tab: CollectiblesMobileShopScreen.SHOP_ALL,
unpublishedCategoriesShown: includeUnpublished,
cacheDisabled: noCache
});
}
return <ShopCategory category={item} isDarkTheme={stateFromStores} index={index} />;
}, [sessionId, includeUnpublished, noCache, stateFromStores]);
const callback2 = useCallback((a0) => {
const item = a0.item;
if (!(a0.index !== 0 || ref.current[CollectiblesMobileShopScreen.FEATURED_PAGE])) {
ref.current[CollectiblesMobileShopScreen.FEATURED_PAGE] = true;
trackShopPerf({
sessionId,
checkpoint: CollectiblesShopPerfCheckpoint.SHOP_RENDERED,
tab: CollectiblesMobileShopScreen.FEATURED_PAGE,
unpublishedCategoriesShown: includeUnpublished,
cacheDisabled: noCache
});
}
let fetchShopHomeError2 = fetchShopHomeError;
if (fetchShopHomeError == null) {
fetchShopHomeError2 = null;
}
return <CollectiblesShopFeaturedPage shopBlock={item} fetchShopHomeError={fetchShopHomeError2} framesBannerBlock={memo} />;
}, [sessionId, includeUnpublished, noCache, fetchShopHomeError, memo]);
const callback3 = useCallback(() => {
if (!ref.current[CollectiblesMobileShopScreen.ORBS]) {
ref.current[CollectiblesMobileShopScreen.ORBS] = true;
trackShopPerf({
sessionId,
checkpoint: CollectiblesShopPerfCheckpoint.SHOP_RENDERED,
tab: CollectiblesMobileShopScreen.ORBS,
unpublishedCategoriesShown: includeUnpublished,
cacheDisabled: noCache
});
}
}, [sessionId, includeUnpublished, noCache]);
const callback4 = useCallback((a0) => a0.type, []);
useCollectiblesShopHeader({
currentScreen: screen
});
if (currentUserIfAvailable == null) {
return null;
}
const r192 = memo3.length === 0 || r4;
if (!(screen !== CollectiblesMobileShopScreen.FEATURED_PAGE && (screen !== CollectiblesMobileShopScreen.ORBS && screen != null)) && isFetchingShopHome) {
r199 = <ActivityIndicator style={styles.spinner} size="large" />;
} else {
L44: {
L24: {
if (r192) {
if (!isFetchingCategories && !isFetchingGoogleSkus) {
break L24;
}
r256 = <ActivityIndicator style={styles.spinner} size="large" />;
break L44;
}
}
if (r52 > 0 && isFetchingCategories === false && categories.size === 0) {
SentryUtils_native.captureMessage("collectibles mobile shop loaded empty categories");
}
if (fetchError !== null) {
SentryUtils_native.captureMessage("collectibles mobile shop failed to fetch google sku ids: " + fetchError);
}
if (screen === CollectiblesMobileShopScreen.SHOP_ALL) {
if (categoryIndex == null) {
categoryIndex = void 0;
}
r241 = <ShopFlashList data={memo3} renderItem={callback} initialScrollIndex={categoryIndex} />;
} else if (screen === CollectiblesMobileShopScreen.ORBS) {
if (fetchShopHomeError == null) {
fetchShopHomeError2 = null;
}
r241 = <CollectiblesShopOrbsPage shopBlocks={shopBlocks} fetchShopHomeError={fetchShopHomeError2} onRenderFirstOrbsItem={callback3} getItemType={callback4} />;
} else {
r241 = <CollectiblesCoachmarkScrollDismissProvider>
<ShopFlashList data={shopBlocks} renderItem={callback2} getItemType={callback4} />
</CollectiblesCoachmarkScrollDismissProvider>;
}
r256 = <AnalyticsLocationProvider value={analyticsLocations}>
<CollectiblesAnalyticsProvider newValue={initialValue}>
<View style={styles.rootContainer}>
<NativePaymentContextProvider skuIDs={[]} activeSubscription={null}>{r241}</NativePaymentContextProvider>
</View>
<DebugLogView />
</CollectiblesAnalyticsProvider>
</AnalyticsLocationProvider>;
}
r199 = r256;
}
return r199;
};
export default CollectiblesShopV2;
@@ -0,0 +1,96 @@
// Metro module 14642 (f14643).
import { memo, useCallback, useEffect } from "react";
import { StyleSheet, View } from "react-native";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useCollectiblesShopStyles_native from "../useCollectiblesShopStyles.native";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withSpring } from "../../../design/animation/reanimated/spring/spring";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { trackShopPerf, CollectiblesShopPerfCheckpoint } from "../utils/CollectiblesPerfLogging";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { NativePaymentContextProvider } from "../../payments/native/NativePaymentContext";
import { CollectiblesProgressiveImage } from "./CollectiblesProgressiveImage";
import CollectiblesShopViewAllCategoryItemsHeader from "./CollectiblesShopViewAllCategoryItemsHeader";
import CollectiblesShopCardsGrid from "./CollectiblesShopCardsGrid";
import { intl, t } from "../../../intl/index.native";
const useStyles = createStyles({
rootContainer: {
flex: 1,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
border: {
height: 1,
backgroundColor: Module712.colors.BORDER_SUBTLE
}
});
const __initData = {
code: "function CollectiblesShopViewAllCategoryItemsTsx1(){const{borderOpacity}=this.__closure;return{opacity:borderOpacity.get()};}"
};
const r47 = memo(function({ category, analyticsContext }) {
const styles = useStyles();
const { mobileBgUrl, logoUrl } = category;
const backgroundColors = useCollectiblesShopStyles_native(category.styles).backgroundColors;
const analyticsLocations = useAnalyticsLocations([AnalyticsLocation.COLLECTIBLES_SHOP_INDEX_PAGE]).analyticsLocations;
const bottom = useSafeAreaInsets_native().bottom;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: category.products
});
const sharedValue = useSharedValue(0);
const callback = useCallback((a0) => {
sharedValue.set(withSpring(a0.nativeEvent.contentOffset.y > 5 ? 1 : 0));
}, [sharedValue]);
const _ = function _() {
return {
opacity: sharedValue.get()
};
};
_.__closure = {
borderOpacity: sharedValue
};
_.__workletHash = 2446209469388;
_.__initData = __initData;
const animatedStyle = useAnimatedStyle(_);
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_VIEWED, {
location_stack: analyticsLocations,
page_session_id: analyticsContext?.sessionId,
source: AnalyticsLocation.COLLECTIBLES_SHOP,
page_type: "index",
category: category.name
});
trackShopPerf({
sessionId: analyticsContext?.sessionId,
checkpoint: CollectiblesShopPerfCheckpoint.SHOP_MOUNTED,
tab: CollectiblesMobileShopScreen.SHOP_ALL,
unpublishedCategoriesShown: false,
cacheDisabled: false
});
}, [analyticsContext?.sessionId, analyticsLocations, category.name]);
return <AnalyticsLocationProvider value={analyticsLocations}>
<CollectiblesAnalyticsProvider newValue={{
...analyticsContext,
pageCategory: category.name
}}>
<NativePaymentContextProvider skuIDs={[]} activeSubscription={null}>
<View style={styles.rootContainer}>
<CollectiblesProgressiveImage source={{
uri: mobileBgUrl
}} style={StyleSheet.absoluteFill} />
<CollectiblesShopViewAllCategoryItemsHeader logoUrl={logoUrl} buttonColor={backgroundColors == null ? void 0 : backgroundColors.label.toHexString()} categoryName={category.name} />
<ReanimatedRexport.View style={[styles.border, animatedStyle]} />
<CollectiblesShopCardsGrid category={category} products={filteredAndSortedProducts} scrollEnabled onScroll={callback} paddingTop={Module712.space.PX_16} paddingBottom={bottom + Module712.space.PX_16} muteBundleStaticBackground accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: category.name
})} />
</View>
</NativePaymentContextProvider>
</CollectiblesAnalyticsProvider>
</AnalyticsLocationProvider>;
});
export default r47;
@@ -0,0 +1,48 @@
// Metro module 14644 (f14645).
import { Image as Image2, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useStackNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useYouBarSettingsCustomHeaderPaddingTop } from "../../main_tabs_v2/native/you_bar/hooks/useYouBarSettingsSafeArea";
import { HeaderIconButton } from "../../main_tabs_v2/native/shared_components/HeaderShared";
import Module9122 from "../../../_bundle/Module9122";
import { intl, t } from "../../../intl/index.native";
const useStyles = createStyles({
headerContainer: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
paddingBottom: 12,
paddingLeft: 8
},
backButton: {
flex: 1
},
logo: {
flex: 2,
height: 36
},
dummyRightButton: {
flex: 1
}
});
export default function CollectiblesShopViewAllCategoryItemsHeader(props) {
const { logoUrl, buttonColor, categoryName } = props;
const stackNavigation = useStackNavigation();
const styles = useStyles();
return <View style={{
...styles.headerContainer,
paddingTop: useYouBarSettingsCustomHeaderPaddingTop()
}}>
<View style={styles.backButton}>
<HeaderIconButton source={Module9122} color={buttonColor} accessibilityLabel={intl.string(t["13/7kX"])} onPress={() => {
stackNavigation.goBack();
}} />
</View>
<Image2 resizeMode="contain" style={styles.logo} source={{
uri: logoUrl
}} accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: categoryName
})} accessibilityRole="header" />
<View style={styles.dummyRightButton} />
</View>;
};
@@ -0,0 +1,162 @@
// Metro module 8716 (f8717).
import { PriceSetAssignmentPurchaseTypes } from "../../../Constants";
import { formatPrice } from "../../../utils/PriceUtils";
import { isGooglePlayBillingSupported } from "../../device/BillingPlatformUtils";
import IAPStore_android from "../../../stores/native/IAPStore.android";
import * as _CollectiblesUtils from "../CollectiblesUtils";
import PremiumUtils from "../../../utils/PremiumUtils";
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
import { OrbBadges } from "../../virtual_currency/types";
import Module8718 from "../../../_bundle/Module8718";
function $mk81200($env) {
return (a0) => {
let r29;
const r4 = $env;
const r7 = r4[0];
const r6 = r4[2];
if (r7(r6[6]).getIsVariantProduct(a0)) {
r29 = a0.variants.every($mk81200(r4));
} else {
const r15 = r4[1];
const r9 = r15(r6[3]);
const googleSkuIds = a0.googleSkuIds;
const product = r9.getProduct(googleSkuIds == null ? void 0 : googleSkuIds[r4[3].MOBILE]);
const r21 = r15(r6[3]);
const googleSkuIds2 = a0.googleSkuIds;
const product2 = r21.getProduct(googleSkuIds2 == null ? void 0 : googleSkuIds2[r4[3].MOBILE_PREMIUM_TIER_2]);
r29 = product != null && product2 != null;
}
return r29;
};
}
let env5682 = {};
const hasAtLeastOneGPlaySynced = function hasAtLeastOneGPlaySynced(a0) {
return a0.products.filter((a0) => {
let r29;
const r4 = env5682;
if (getIsVariantProduct(a0)) {
r29 = a0.variants.every($mk81200(r4));
} else {
const googleSkuIds = a0.googleSkuIds;
const product = IAPStore_android.getProduct(googleSkuIds == null ? void 0 : googleSkuIds[PriceSetAssignmentPurchaseTypes.MOBILE]);
const googleSkuIds2 = a0.googleSkuIds;
const product2 = IAPStore_android.getProduct(googleSkuIds2 == null ? void 0 : googleSkuIds2[PriceSetAssignmentPurchaseTypes.MOBILE_PREMIUM_TIER_2]);
r29 = product != null && product2 != null;
}
return r29;
}).length > 0;
};
export function getFormattedPriceForCollectiblesProduct(a0, a1, a2) {
let r8, r10, r21, MOBILE_PREMIUM_TIER_2, PriceSetAssignmentPurchaseTypes2;
if (a2) {
if (a1) {
MOBILE_PREMIUM_TIER_2 = PriceSetAssignmentPurchaseTypes.MOBILE_PREMIUM_TIER_2;
PriceSetAssignmentPurchaseTypes2 = PriceSetAssignmentPurchaseTypes;
} else {
MOBILE_PREMIUM_TIER_2 = PriceSetAssignmentPurchaseTypes.MOBILE;
PriceSetAssignmentPurchaseTypes2 = PriceSetAssignmentPurchaseTypes;
}
r8 = PriceSetAssignmentPurchaseTypes2;
r10 = MOBILE_PREMIUM_TIER_2;
} else if (a1) {
r10 = PriceSetAssignmentPurchaseTypes.PREMIUM_TIER_2;
r8 = PriceSetAssignmentPurchaseTypes;
} else {
r10 = PriceSetAssignmentPurchaseTypes.DEFAULT;
r8 = PriceSetAssignmentPurchaseTypes;
}
L18: {
if (isGooglePlayBillingSupported()) {
if (r10 !== r8.MOBILE) {
const MOBILE_PREMIUM_TIER_22 = r8.MOBILE_PREMIUM_TIER_2;
r21 = null;
if (r10 !== MOBILE_PREMIUM_TIER_22) {
break L18;
}
}
const googleSkuIds = a0.googleSkuIds;
const product = IAPStore_android.getProduct(googleSkuIds == null ? void 0 : googleSkuIds[r10]);
r21 = product != null ? {
amount: product.price,
currency: product.currencyCode,
priceString: product.priceString,
tax: 0,
taxInclusive: false
} : void 0;
} else {
r21 = _CollectiblesUtils.extractPriceByPurchaseTypes(a0, r10);
}
}
return r21 == null ? null : r21.priceString != null ? r21.priceString : formatPrice(r21.amount, r21.currency);
}
export function extractPriceByPurchaseTypes(a0, a1) {
if (isGooglePlayBillingSupported()) {
if (a1 !== PriceSetAssignmentPurchaseTypes.MOBILE && a1 !== PriceSetAssignmentPurchaseTypes.MOBILE_PREMIUM_TIER_2) {
return null;
}
const googleSkuIds = a0.googleSkuIds;
const product = IAPStore_android.getProduct(googleSkuIds == null ? void 0 : googleSkuIds[a1]);
return product != null ? {
amount: product.price,
currency: product.currencyCode,
priceString: product.priceString,
tax: 0,
taxInclusive: false
} : void 0;
}
return _CollectiblesUtils.extractPriceByPurchaseTypes(a0, a1);
}
export function getCollectibleGoogleSkuId(a0, a1) {
if (a1 == null) {
return null;
}
const r12 = PremiumUtils.canUseShopDiscounts(a1) ? PriceSetAssignmentPurchaseTypes.MOBILE_PREMIUM_TIER_2 : PriceSetAssignmentPurchaseTypes.MOBILE;
const googleSkuIds = a0.googleSkuIds;
let r15 = googleSkuIds == null ? void 0 : googleSkuIds[r12];
if (r15 == null) {
r15 = null;
}
return r15;
}
export function isGPlaySynced(a0) {
const r3 = env5682;
if (getIsVariantProduct(a0)) {
return a0.variants.every($mk81200(r3));
}
const googleSkuIds = a0.googleSkuIds;
const product = IAPStore_android.getProduct(googleSkuIds == null ? void 0 : googleSkuIds[PriceSetAssignmentPurchaseTypes.MOBILE]);
const googleSkuIds2 = a0.googleSkuIds;
const product2 = IAPStore_android.getProduct(googleSkuIds2 == null ? void 0 : googleSkuIds2[PriceSetAssignmentPurchaseTypes.MOBILE_PREMIUM_TIER_2]);
return product != null && product2 != null;
}
export function filterGPlaySyncedCategories(a0) {
if (a0 == null) {
return [];
}
const r20 = [];
for (const item of a0.values()) {
if (hasAtLeastOneGPlaySynced(item)) {
r20.push(item);
}
}
return r20;
}
export function filterHiddenCategories(a0) {
return a0.filter((item) => {
let r8 = item.unpublishedAt == null || item.unpublishedAt > new Date();
const r2 = item.products.length > 0;
if (r8) {
r8 = r2;
}
return r8;
});
}
export function createOrbProfileBadge() {
return {
id: OrbBadges.ORB_PROFILE_BADGE,
icon: OrbBadges.ORB_PROFILE_BADGE,
iconSrc: Module8718,
description: "",
isPreviewMode: true
};
}
@@ -0,0 +1,84 @@
// Metro module 14639 (f14640).
import { useEffect } from "react";
import { ScrollView, TouchableOpacity, View } from "react-native";
import DevSettingsStore from "../../devtools/dev_settings/DevSettingsStore";
import { addDebugLog, useCollectiblesDebugStore } from "../CollectiblesDebugStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useStateFromStores } from "../../../_bundle/Module589";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
debugLogContainer: {
backgroundColor: "rgba(0, 0, 0, 0.8)",
padding: 10,
maxHeight: 350,
width: "100%",
position: "absolute",
bottom: 0,
left: 0,
right: 0,
zIndex: 9999,
borderTopWidth: 1,
borderTopColor: "#ff0000"
},
debugLogHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: 5
},
debugLogText: {
color: "#00ff00",
fontSize: 12,
marginBottom: 2,
fontFamily: "monospace"
},
clearButton: {
backgroundColor: "#ff0000",
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: Module712.radii.xs
},
clearButtonText: {
color: "#ffffff",
fontSize: 10,
fontWeight: "bold"
}
});
export default function DebugLogView() {
let collectiblesDebugStore2, styles, stateFromStores;
const collectiblesDebugStore = useCollectiblesDebugStore((a0) => a0.logs);
collectiblesDebugStore2 = useCollectiblesDebugStore((a0) => a0.clearLogs);
styles = useStyles();
stateFromStores = useStateFromStores([DevSettingsStore], () => DevSettingsStore.get("shop_show_debug_overlay"));
useEffect(() => {
if (collectiblesDebugStore.length === 0 && stateFromStores) {
addDebugLog("Debug log initialized");
}
}, [collectiblesDebugStore.length, stateFromStores]);
if (stateFromStores && collectiblesDebugStore.length !== 0) {
return <View style={styles.debugLogContainer}>
<View style={styles.debugLogHeader}>
<Text variant="text-xs/normal" style={{
...styles.debugLogText,
color: "#ffffff"
}}>
Debug Log (
{collectiblesDebugStore.length}
{" entries)"}
</Text>
<TouchableOpacity onPress={function onPress() {
collectiblesDebugStore2();
}} style={styles.clearButton}>
<Text variant="text-xs/bold" style={styles.clearButtonText}>Clear</Text>
</TouchableOpacity>
</View>
<ScrollView>
{collectiblesDebugStore.slice(Math.max(0, collectiblesDebugStore.length - 10)).map((item, index) => <Text key={index} variant="text-xs/normal" style={styles.debugLogText}>
{item}
</Text>)}
</ScrollView>
</View>;
}
return null;
};
@@ -0,0 +1,36 @@
// Metro module 8739 (f8740).
import { useRef, useState, useCallback, useMemo, useEffect } from "react";
import { intl, t } from "../../../intl/index.native";
import { useTooltip } from "../../../design/components/Tooltip/native/useTooltip.native";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
const hitSlop = {
top: 14,
bottom: 14,
left: 14,
right: 14
};
export function DynamicBadgeTooltip(props) {
const { children, accessibilityLabel, tooltipPosition = "bottom" } = props;
const position = tooltipPosition;
const ref = useRef(null);
const [state, setState] = useState(false);
const label = intl.string(t.dCou7i);
const callback = useCallback(() => {
setState(false);
}, []);
useTooltip(ref, useMemo(() => ({
position,
label,
visible: state,
onPress: callback
}), [position, label, state, callback]));
useEffect(() => {
if (state) {
let c26279_0 = setTimeout(() => setState(false), 2500);
return () => clearTimeout(c26279_0);
}
}, [state]);
return <PressableOpacity ref={ref} onPress={useCallback(() => {
setState((prevState) => !prevState);
}, [])} hitSlop={hitSlop} accessibilityRole="button" accessibilityLabel={accessibilityLabel} accessibilityHint={label}>{children}</PressableOpacity>;
}
@@ -0,0 +1,96 @@
// Metro module 7975 (f7976).
import * as Module19 from "react";
import { useState, useCallback, useMemo } from "react";
import { ActivityIndicator, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { GUTTER_SIZE, ROW_SIZE } from "./useCollectibleListLayout";
import { Heading } from "../../../design/components/Text/native/Text";
import { chunk } from "../../../_bundle/Module12";
import { BottomSheetFlashList } from "../../../_bundle/noop_6676";
const useStyles = createStyles({
list: {
flex: 1,
marginTop: 12
},
listContent: {
paddingBottom: 88
},
loadingContainer: {
paddingVertical: 80,
alignItems: "center"
},
header: {
paddingHorizontal: GUTTER_SIZE,
paddingTop: 10,
paddingBottom: 5
}
});
let Component = Module19.memo(function({ header }) {
return <View style={useStyles().header}>
<Heading variant="heading-sm/medium" color="mobile-text-heading-primary">{header}</Heading>
</View>;
});
export function EditCollectiblesPickerList(props) {
let props2;
let size;
const { sections, selectedSkuId, renderRow, isFetching = false } = props;
let c16138_3 = isFetching;
let contentContainerStyle = props.contentContainerStyle;
size = void 0;
const styles = useStyles();
let r0 = 0;
const [state, setState] = useState(0);
const callback = useCallback((a0) => {
setState(a0.nativeEvent.layout.width);
}, []);
if (state > 0) {
r0 = (state - 4 * GUTTER_SIZE) / ROW_SIZE;
}
size = r0;
const memo = useMemo(() => {
const r0 = [];
if (c16138_3) {
return r0;
}
let c26067_0 = r0;
sections.forEach((section) => {
c26067_0.push({
type: "header",
key: `header-${section.section}`,
header: section.header
});
chunk(section.items, ROW_SIZE).forEach((item, index) => {
c26067_0.push({
type: "row",
key: `row-${section.section}-${index}`,
items: item
});
});
});
return r0;
}, [sections, isFetching]);
const callback2 = useCallback(({ item }) => item.type === "header" ? <Component header={item.header} /> : renderRow({
items: item.items,
size,
selectedSkuId
}), [renderRow, size, selectedSkuId]);
const callback3 = useCallback((a0) => a0.type, []);
const callback4 = useCallback((a0) => a0.key, []);
const r54 = {
style: null,
children: null
};
if (isFetching) {
r54.style = styles.loadingContainer;
r54.children = <ActivityIndicator animating size="large" />;
props2 = r54;
} else {
r54.style = styles.list;
if (contentContainerStyle == null) {
contentContainerStyle = styles.listContent;
}
r54.children = <BottomSheetFlashList data={memo} renderItem={callback2} getItemType={callback3} keyExtractor={callback4} extraData={selectedSkuId} contentContainerStyle={contentContainerStyle} onLayout={callback} keyboardShouldPersistTaps="always" />;
props2 = r54;
}
return <View {...props2} />;
}
@@ -0,0 +1,42 @@
// Metro module 14623 (f14624).
import { View } from "react-native";
import Module712 from "../../../_bundle/Module712";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import FeaturedCategorySubblock from "./FeaturedCategorySubblock";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
let useStyles;
const Subblocks = function Subblocks({ featuredBlock, style }) {
return featuredBlock.subblocks.map((a0, index) => <CollectiblesAnalyticsProvider key={index} newValue={{
tilePosition: index
}}>
<View style={style}>
<FeaturedCategorySubblock subblock={a0} />
</View>
</CollectiblesAnalyticsProvider>);
};
useStyles = createStyles({
container: {
display: "flex",
width: "100%",
flexDirection: "row",
flexWrap: "wrap",
gap: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16
},
featuredSubblock: {
flex: 1,
flexBasis: 400,
maxWidth: "100%"
}
});
export default function FeaturedBlock(props) {
const featuredBlock = props.featuredBlock;
const styles = useStyles();
return <AnalyticsLocationProvider value={useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_FEATURED_BLOCK).analyticsLocations}>
<View style={styles.container}>
<Subblocks featuredBlock={featuredBlock} style={styles.featuredSubblock} />
</View>
</AnalyticsLocationProvider>;
};
@@ -0,0 +1,85 @@
// Metro module 14624 (f14625).
import { Image as Image2 } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents, UserSettingsSections } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useCollectiblesAnalyticsContext } from "../CollectiblesAnalyticsContext";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useTrackProductCardImpression } from "../hooks/useTrackProductCardImpression";
import VisibilitySensor from "./VisibilitySensor";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../intl/index.native";
import Module712 from "../../../_bundle/Module712";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { shouldShowLimitedTimeBadge } from "../CollectiblesUtils";
import { LimitedTimeBadge } from "./CollectiblesBadges";
const useStyles = createStyles({
container: {
position: "relative"
},
bannerImage: {
width: "100%",
aspectRatio: 2.237580993520518,
resizeMode: "contain"
},
limitedTimeBadge: {
position: "absolute",
bottom: "68%",
left: "3%",
zIndex: 1
}
});
export default ({ subblock }) => {
const styles = useStyles();
const navigation = useNavigation();
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
const assetUrl = subblock.assetUrl;
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.getCategoryByStoreListingId(subblock.categoryStoreListingId));
const handleCardVisibilityChange = useTrackProductCardImpression(subblock.categoryStoreListingId, "mobile_home", "featured_block").handleCardVisibilityChange;
let unpublishedAt = subblock.unpublishedAt;
if (unpublishedAt == null) {
unpublishedAt = stateFromStores?.unpublishedAt;
}
const r15 = unpublishedAt != null ? new Date(unpublishedAt) : null;
return <VisibilitySensor onChange={handleCardVisibilityChange}>
<PressableOpacity accessibilityRole="button" accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: subblock.name
})} accessibilityHint={intl.string(t.F8ma9x)} activeOpacity={0.8} androidRippleConfig={{
radius: Module712.radii.lg
}} hitSlop={8} onPress={function onPress() {
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_ELEMENT_CLICKED, {
collectibles_shop_session_id: collectiblesAnalyticsContext?.sessionId,
sku_id: subblock.categoryStoreListingId,
page_type: "mobile_home",
page_section: collectiblesAnalyticsContext?.pageSection,
page_category: collectiblesAnalyticsContext?.pageCategory,
tile_type: "FEATURED_BLOCK",
tile_position: String(collectiblesAnalyticsContext?.tilePosition),
cta_name: null
});
if (stateFromStores != null) {
if (stateFromStores.isOrbsExclusive) {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP,
screen: CollectiblesMobileShopScreen.ORBS
});
} else {
navigation.navigate(UserSettingsSections.COLLECTIBLES_SHOP_VIEW_ALL_CATEGORY_ITEMS, {
category: stateFromStores,
analyticsContext: collectiblesAnalyticsContext
});
}
}
}} style={styles.container}>
{assetUrl != null && <Image2 source={{
uri: assetUrl
}} style={styles.bannerImage} />}
{shouldShowLimitedTimeBadge(r15) && <LimitedTimeBadge style={styles.limitedTimeBadge} />}
</PressableOpacity>
</VisibilitySensor>;
};
@@ -0,0 +1,19 @@
// Metro module 14615 (f14616).
import { useRef } from "react";
import { View } from "react-native";
import WishlistButtonCoachmark from "./WishlistButtonCoachmark";
export default function FeaturedFirstCardCoachmarkAnchor(props) {
const children = props.children;
const ref = useRef(null);
return <View collapsable={false}>
<View ref={ref} style={{
position: "absolute",
top: 0,
right: 6,
width: 32,
height: 32
}} collapsable={false} />
{children}
<WishlistButtonCoachmark anchorRef={ref} />
</View>;
};
+169
View File
@@ -0,0 +1,169 @@
// Metro module 14625 (f14626).
import { useMemo } from "react";
import { Image as Image2, View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import ThemeStore from "../../user_settings/ThemeStore";
import ConsentStore from "../../../stores/ConsentStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { Consents } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useStateFromStores } from "../../../_bundle/Module589";
import { isThemeDark } from "../../../design/shared";
import useGetProductsFromSkus from "../hooks/useGetProductsFromSkus";
import { ShopHomeSortType } from "../../../_bundle/Module14626";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import { intl, t } from "../../../intl/index.native";
import { Heading, Text } from "../../../design/components/Text/native/Text";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { CircleInformationIcon } from "../../../design/components/Icon/native/redesign/generated/CircleInformationIcon";
import { Button } from "../../../design/components/Button/native/Button.native";
import FeedProductList from "./FeedProductList";
import Module14628 from "../../../_bundle/Module14628";
import { isAndroid } from "../../../utils/PlatformUtils";
import Module6208 from "../../../_bundle/Module6208";
import Module14629 from "../../../_bundle/Module14629";
import FastImage from "../../../components_native/common/FastImage";
import * as _Module14630 from "../../../_bundle/Module14630";
import * as _Module14631 from "../../../_bundle/Module14631";
const useStyles = createStyles({
feedContainer: {
display: "flex",
flexDirection: "column",
height: "100%",
gap: Module712.space.PX_16
},
feedHeader: {
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "space-between",
alignItems: "center",
gap: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16
},
feedTitle: {
display: "flex",
flexDirection: "row",
alignItems: "center",
flexShrink: 1,
gap: Module712.space.PX_8
},
feedFooter: {
display: "flex",
gap: Module712.space.PX_16,
flexDirection: "column",
justifyContent: "center",
alignItems: "center"
},
feedFooterImage: {
width: "100%",
resizeMode: "cover"
},
feedFooterOrbImage: {
width: "100%",
alignSelf: "center",
resizeMode: "contain",
height: 130
}
});
export default ({ feedBlock, screen, preferVCPrice, disableBundleStaticBackground }) => {
let r171, props;
let stateFromStores, c21264_2;
stateFromStores = void 0;
c21264_2 = void 0;
const styles = useStyles();
const stateFromStores2 = useStateFromStores([ThemeStore], () => isThemeDark(ThemeStore.theme));
stateFromStores = useStateFromStores([ConsentStore], () => ConsentStore.hasConsented(Consents.PERSONALIZATION));
const getProductsFromSkus = useGetProductsFromSkus();
c21264_2 = getProductsFromSkus;
const memo = useMemo(() => {
const sortedSkuIds = feedBlock.sortedSkuIds;
let r4 = sortedSkuIds == null ? void 0 : sortedSkuIds[ShopHomeSortType.RECOMMENDED];
if (r4 == null) {
r4 = [];
}
const sortedSkuIds2 = feedBlock.sortedSkuIds;
let r17 = sortedSkuIds2 == null ? void 0 : sortedSkuIds2[ShopHomeSortType.POPULAR];
if (r17 == null) {
r17 = [];
}
let isPersonalized = stateFromStores;
if (stateFromStores) {
isPersonalized = r4.length > 0;
}
if (isPersonalized) {
r17 = r4;
}
return {
feedProducts: c21264_2(r17),
isPersonalized
};
}, [feedBlock.sortedSkuIds, getProductsFromSkus, stateFromStores]);
const feedProducts = memo.feedProducts;
let isPersonalized = memo.isPersonalized;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: feedProducts,
maxProducts: 36,
screen
});
const ORBS = CollectiblesMobileShopScreen.ORBS;
const stateFromStores3 = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_POPULAR_PICKS).analyticsLocations;
const accessibilityLabel = isPersonalized ? intl.string(t.NSv5KV) : intl.string(t.ivaAA7);
const r92 = [<Heading variant="heading-lg/semibold">{accessibilityLabel}</Heading>, ,];
if (isPersonalized) {
isPersonalized = <PressableOpacity onPress={() => ActionSheetActionCreators.openLazy(import("./PersonalizationDisclaimerActionSheet"), "PersonalizationDisclaimerActionSheet", {})} hitSlop={14} aria-label={intl.string(t.hvVgAZ)}>
<CircleInformationIcon size="xs" />
</PressableOpacity>;
}
const goToShopAll = function goToShopAll() {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_MOBILE_SHOP_ALL_BUTTON],
analyticsSource: AnalyticsLocation.COLLECTIBLES_MOBILE_SHOP_ALL_BUTTON,
screen: CollectiblesMobileShopScreen.SHOP_ALL
});
};
const r1 = screen === ORBS;
r92[1] = isPersonalized;
const r126 = [<View style={styles.feedHeader}>
<View style={styles.feedTitle}>{r92}</View>
{r1 ? !r1 : <Button onPress={goToShopAll} text={intl.string(t.xFcotU)} variant="primary" size="sm" />}
</View>, <FeedProductList products={filteredAndSortedProducts} loadingCardsNum={36} preferVCPrice={preferVCPrice} accessibilityLabel={accessibilityLabel} disableBundleStaticBackground={disableBundleStaticBackground} />, ,];
const r147 = [<Text variant="heading-lg/bold" accessibilityRole="header">
{intl.string(t.Yr70c4)}
</Text>, <Button onPress={goToShopAll} text={intl.string(t.AfrvRD)} variant="primary" size="md" />, ,];
if (r1) {
r171 = stateFromStores3 ? <Image2 source={{
uri: Module14628
}} style={styles.feedFooterOrbImage} accessibilityElementsHidden importantForAccessibility="no-hide-descendants" /> : isAndroid() ? <Module6208 url={Module14629} autoplay style={styles.feedFooterOrbImage} accessibilityElementsHidden importantForAccessibility="no-hide-descendants" /> : <FastImage source={{
uri: Module14629
}} enableAnimation resizeMode="contain" style={styles.feedFooterOrbImage} accessibilityElementsHidden importantForAccessibility="no-hide-descendants" />;
} else {
const r163 = {
source: null,
style: null,
accessibilityElementsHidden: true,
importantForAccessibility: "no-hide-descendants"
};
if (stateFromStores2) {
r163.source = _Module14630;
r163.style = styles.feedFooterImage;
props = r163;
} else {
r163.source = _Module14631;
r163.style = styles.feedFooterImage;
props = r163;
}
r171 = <Image2 {...props} />;
}
r147[2] = r171;
r126[2] = <View style={styles.feedFooter}>{r147}</View>;
return <AnalyticsLocationProvider value={analyticsLocations}>
<View style={styles.feedContainer}>{r126}</View>
</AnalyticsLocationProvider>;
};
@@ -0,0 +1,71 @@
// Metro module 14619 (f14620).
import { View } from "react-native";
import { jsx } from "react/jsx-runtime";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { COLLECTIBLES_SHOP_CARD_GAP } from "./CollectiblesShopCardV2";
import { useCardLayout } from "./hooks/useCardLayout";
import SkeletonCard from "./SkeletonCard";
import CollectiblesShopCardsGrid from "./CollectiblesShopCardsGrid";
let useStyles;
let env10308 = {};
const SkeletonGrid = function SkeletonGrid(a0) {
let env21257 = {
$parent: env10308
};
const { loadingCardsNum, accessibilityLabel } = a0;
env21257[0] = void 0;
const styles = useStyles();
const cardLayout = useCardLayout();
const columns = cardLayout.columns;
env21257[0] = cardLayout.cardWidth;
const rowWidth = cardLayout.rowWidth;
const children = [];
let r9 = 0;
while (r9 < loadingCardsNum) {
let c21258_0 = r9;
children.push((0, jsx)(View, {
style: [styles.skeletonRow, {
width: rowWidth
}],
children: Array.from({
length: Math.min(columns, loadingCardsNum - r9)
}).map((item, index) => <SkeletonCard key={`${c21258_0}-${index}`} width={env21257[0]} style={{
marginBottom: COLLECTIBLES_SHOP_CARD_GAP
}} />)
}, `row-${r9}`));
r9 = r9 + columns;
}
return (0, jsx)(View, {
style: styles.skeletonGrid,
accessibilityRole: "list",
accessibilityLabel,
accessibilityState: {
busy: true
},
accessible: true,
children
});
};
useStyles = createStyles({
skeletonGrid: {
flex: 1,
alignItems: "center"
},
skeletonRow: {
flexDirection: "row",
gap: COLLECTIBLES_SHOP_CARD_GAP,
paddingBottom: COLLECTIBLES_SHOP_CARD_GAP,
paddingHorizontal: COLLECTIBLES_SHOP_CARD_GAP
}
});
export default function FeedProductList({ products, loadingCardsNum, preferVCPrice, accessibilityLabel, disableBundleStaticBackground }) {
return products.length === 0 ? (0, jsx)(SkeletonGrid, {
loadingCardsNum,
accessibilityLabel
}) : (0, jsx)(CollectiblesShopCardsGrid, {
products,
preferVCPrice,
accessibilityLabel,
disableBundleStaticBackground
});
};
@@ -0,0 +1,12 @@
// Metro module 8714 (f8715).
import { EXTERNAL_PRODUCT_SKU_IDS } from "../CollectiblesShopConstants";
import { NitroCoinSpotIllustration, NitroCoinStackSpotIllustration } from "../../../design/assets/native";
export const FRACTIONAL_NITRO_COIN_SIZE = {
CARD: 80,
CHECKOUT: 45,
COLLECTED_SHEET: 68
};
export function FractionalNitroCoinIllustration(props) {
const { skuId, width, height, resizeMode = "contain" } = props;
return skuId === EXTERNAL_PRODUCT_SKU_IDS.FRACTIONAL_PREMIUM_1_DAY ? <NitroCoinSpotIllustration width={width} height={height} resizeMode={resizeMode} /> : <NitroCoinStackSpotIllustration width={width} height={height} resizeMode={resizeMode} />;
}
@@ -0,0 +1,166 @@
// Metro module 11907 (f11908).
import { useMemo, useCallback } from "react";
import { ActivityIndicator, View } from "react-native";
import { HelpdeskArticles } from "../../../Constants";
import { FRACTIONAL_PREMIUM_SKU_INTERVAL_COUNTS, PremiumTypes } from "../../premium/PremiumConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { FractionalNitroCoinIllustration, FRACTIONAL_NITRO_COIN_SIZE } from "./FractionalNitroCoinIllustration";
import FastImage from "../../../components_native/common/FastImage";
import Module11908 from "../../../_bundle/Module11908";
import useTheme from "../../../hooks/useTheme";
import { useFetchFractionalPremiumInfo } from "../utils/CollectiblesUtils";
import { isThemeDark } from "../../../design/shared";
import Module6317 from "../../../_bundle/Module6317";
import Module6318 from "../../../_bundle/Module6318";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import HelpdeskUtils from "../../../utils/HelpdeskUtils";
import Linking from "../../../lib/native/Linking";
import { BottomSheet } from "../../../design/components/Sheet/native/BottomSheet.native";
import PremiumPlanActionSheetHeader from "../../premium/native/PremiumPlanActionSheetHeader";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { CircleQuestionIcon } from "../../../design/components/Icon/native/redesign/generated/CircleQuestionIcon";
import { Button } from "../../../design/components/Button/native/Button.native";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { ActionSheetHeaderBar } from "../../../design/components/Sheet/native/ActionSheetHeaderBar.native";
let useStyles;
const NitroAcquiredHeader = function NitroAcquiredHeader(props) {
const skuId2 = props.skuId;
const styles2 = useStyles();
return <View style={styles2.header}>
<FastImage source={Module11908} />
<View style={styles2.fractionNitroIcon}>
<FractionalNitroCoinIllustration skuId={skuId2} width={FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET} height={FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET} />
</View>
</View>;
};
useStyles = createStyles({
body: {
flex: 1,
padding: Module712.space.PX_16
},
content: {
flex: 1,
gap: Module712.space.PX_16,
alignItems: "center"
},
buttonContainer: {
flex: 1,
gap: Module712.space.PX_16,
alignSelf: "stretch"
},
description: {
textAlign: "center"
},
header: {
height: 112,
justifyContent: "center",
alignItems: "center",
overflow: "hidden"
},
fractionNitroIcon: {
width: FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET,
height: FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET,
position: "absolute",
top: "50%",
left: "50%",
transform: [{
translateX: -FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET / 2
}, {
translateY: -FRACTIONAL_NITRO_COIN_SIZE.COLLECTED_SHEET / 2
}]
},
questionIconContainer: {
position: "absolute",
right: Module712.space.PX_16,
top: Module712.space.PX_16,
width: 32,
height: 32,
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
justifyContent: "center",
borderRadius: Module712.radii.lg,
alignItems: "center"
},
questionIcon: {
width: 18,
height: 18
}
});
export default function FractionalNitroCollectedActionSheet(props) {
let r115, props2;
const { skuId, consumed, onPressExplorePerks, onPressViewCredits } = props;
const styles = useStyles();
const theme = useTheme();
let c19264_3 = theme;
const fetchFractionalPremiumInfo = useFetchFractionalPremiumInfo();
const { isLoading, isFractionalPremiumActive, expiresAt } = fetchFractionalPremiumInfo;
const memo = useMemo(() => consumed ? <FastImage source={isThemeDark(c19264_3) ? Module6317 : Module6318} /> : <Text variant="heading-lg/bold" color="text-default">
{intl.string(t.g5W1g8)}
</Text>, [consumed, theme]);
const memo2 = useMemo(() => {
let props;
const r15 = FRACTIONAL_PREMIUM_SKU_INTERVAL_COUNTS[skuId];
let days = r15 == null ? void 0 : r15[1];
if (days == null) {
days = 3;
}
const duration = intl.formatToPlainString(t.Cz1G97, {
days
});
const r30 = {
variant: "text-md/normal",
color: "text-default",
style: styles.description,
children: null
};
if (consumed) {
r30.children = intl.format(t["93PGOI"], {
duration,
expirationDate: expiresAt
});
props = r30;
} else {
r30.children = isFractionalPremiumActive ? intl.string(t.fBmhE9) : intl.format(t["8fyBPf"], {
duration
});
props = r30;
}
return <Text {...props} />;
}, [skuId, consumed, expiresAt, isFractionalPremiumActive, styles.description]);
const r72 = [<>
{consumed ? <PremiumPlanActionSheetHeader premiumType={PremiumTypes.TIER_2} /> : <NitroAcquiredHeader skuId={skuId} />}
<PressableOpacity style={styles.questionIconContainer} onPress={useCallback(() => {
Linking.openURL(HelpdeskUtils.getArticleURL(HelpdeskArticles.FRACTIONAL_PREMIUM_ABOUT));
}, [])}>
<CircleQuestionIcon style={styles.questionIcon} color={Module712.colors.WHITE} />
</PressableOpacity>
</>, , ,];
if (isLoading) {
r115 = <ActivityIndicator size="large" />;
} else {
const r78 = [memo, memo2, ,];
const r84 = {
size: "lg",
text: null,
onPress: null
};
if (consumed) {
r84.text = intl.string(t.ERKK6v);
r84.onPress = onPressExplorePerks;
props2 = r84;
} else {
r84.text = intl.string(t["Jr6N+s"]);
r84.onPress = onPressViewCredits;
props2 = r84;
}
r78[2] = <View style={styles.buttonContainer}>
<Button {...props2} />
<Button size="lg" variant="secondary" text={intl.string(t.TkTvBz)} onPress={() => ActionSheetActionCreators.hideActionSheet()} />
</View>;
r115 = <View style={styles.content}>{r78}</View>;
}
r72[1] = <View style={styles.body}>{r115}</View>;
r72[2] = <ActionSheetHeaderBar variant="floating" />;
return <BottomSheet handleDisabled>{r72}</BottomSheet>;
};
@@ -0,0 +1,70 @@
// Metro module 8749 (f8750).
import { View } from "react-native";
import { VerticalGradient } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { t, intl } from "../../../intl/index.native";
import Module4611 from "../../../_bundle/Module4611";
import FastImage from "../../../components_native/common/FastImage";
import Module8750 from "../../../_bundle/Module8750";
import NitroIcon from "./NitroIcon";
import { CheckmarkSmallIcon } from "../../../design/components/Icon/native/redesign/generated/CheckmarkSmallIcon";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
container: {
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
padding: Module712.space.PX_24,
borderRadius: Module712.radii.lg,
overflow: "hidden",
alignSelf: "center",
gap: Module712.space.PX_16
},
gradient: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0
},
headerImage: {
width: 211,
height: 157,
resizeMode: "cover"
},
nitroIconContainer: {
alignSelf: "flex-start"
},
benefits: {
display: "flex",
flexDirection: "column",
gap: Module712.space.PX_8
},
benefitRow: {
display: "flex",
flexDirection: "row",
gap: Module712.space.PX_8,
alignItems: "center"
}
});
export function FractionalNitroPreview() {
const styles = useStyles();
return <View style={styles.container}>
<Module4611 colors={["#000000", "#36266d"]} start={VerticalGradient.START} end={VerticalGradient.END} style={styles.gradient} />
<FastImage source={{
uri: Module8750
}} style={styles.headerImage} />
<View style={styles.nitroIconContainer}>
<NitroIcon />
</View>
<View style={styles.benefits}>
{[t.E1NP2x, t.kpMomJ, t.xT1Vfn, t.myyAEr, t.zTk8Ul].map((item, index) => <View key={index} style={styles.benefitRow}>
<CheckmarkSmallIcon color={Module712.colors.WHITE} />
<Text variant="text-sm/medium" color="text-overlay-light">
{intl.string(item)}
</Text>
</View>)}
</View>
</View>;
}
@@ -0,0 +1,90 @@
// Metro module 8738 (f8739).
import { useRef, useState, useCallback, useMemo, useEffect } from "react";
import { Pressable, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useTheme from "../../../hooks/useTheme";
import { intl, t } from "../../../intl/index.native";
import { useTooltip } from "../../../design/components/Tooltip/native/useTooltip.native";
import * as _shared from "../../../design/shared";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
import { Text } from "../../../design/components/Text/native/Text";
import { useIsProfileFramesEarlyAccessPhase } from "../hooks/useCanPurchaseFrames";
import { LayerScope } from "../../../design/components/Layers/native/LayerScope.native";
let StaticBadge;
const hitSlop = {
top: 14,
bottom: 14,
left: 14,
right: 14
};
const useStyles = createStyles({
pillBase: {
flexDirection: "row",
alignItems: "center",
borderRadius: Module712.radii.round,
paddingVertical: 2,
paddingHorizontal: Module712.space.PX_8
},
pillDark: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_PRIMARY_BACKGROUND_DEFAULT
},
pillLight: {
backgroundColor: Module712.colors.BADGE_BACKGROUND_BRAND
},
text: {
marginLeft: Module712.space.PX_8,
textTransform: "uppercase"
}
});
const BadgeWithTooltip = (props) => {
const tooltipPosition = props.tooltipPosition;
const theme = useTheme();
const styles = useStyles();
const ref = useRef(null);
const [state, setState] = useState(false);
const label = intl.string(t["L9B+ZZ"]);
const callback = useCallback(() => {
setState(false);
}, []);
useTooltip(ref, useMemo(() => ({
position: tooltipPosition,
label,
visible: state,
onPress: callback
}), [tooltipPosition, label, state, callback]));
useEffect(() => {
if (state) {
let c26278_0 = setTimeout(() => {
setState(false);
}, 3000);
return () => clearTimeout(c26278_0);
}
}, [state]);
const callback2 = useCallback(() => {
setState((prevState) => !prevState);
}, []);
const isThemeDark = _shared.isThemeDark(theme);
const r58 = isThemeDark ? styles.pillDark : styles.pillLight;
const color = isThemeDark ? "control-overlay-primary-text-default" : "text-overlay-light";
const accessibilityLabel = intl.string(t["1m6qcO"]);
return <Pressable ref={ref} onPress={callback2} hitSlop={hitSlop} accessibilityRole="button" accessibilityLabel={accessibilityLabel} accessibilityHint={label} style={[styles.pillBase, r58]}>
<NitroWheelIcon size="xs" color={color} />
<Text variant="text-sm/bold" color={color} style={styles.text}>{accessibilityLabel}</Text>
</Pressable>;
};
StaticBadge = () => {
const theme = useTheme();
const styles = useStyles();
const isThemeDark = _shared.isThemeDark(theme);
const r11 = isThemeDark ? styles.pillDark : styles.pillLight;
const color = isThemeDark ? "control-overlay-primary-text-default" : "text-overlay-light";
const accessibilityLabel = intl.string(t["1m6qcO"]);
return <View accessibilityLabel={accessibilityLabel} style={[styles.pillBase, r11]}>
<NitroWheelIcon size="xs" color={color} />
<Text variant="text-sm/bold" color={color} style={styles.text}>{accessibilityLabel}</Text>
</View>;
};
export default ({ location: location2, tooltipPosition: tooltipPosition2 = "top", inheritLayerScope = false, disablePressable = false }) => useIsProfileFramesEarlyAccessPhase(location2) ? disablePressable ? <StaticBadge /> : inheritLayerScope ? <BadgeWithTooltip tooltipPosition={tooltipPosition2} /> : <LayerScope zIndex={3}>
<BadgeWithTooltip tooltipPosition={tooltipPosition2} />
</LayerScope> : null;
@@ -0,0 +1,303 @@
// Metro module 14613 (f14614).
import { useMemo, useCallback } from "react";
import { Image as Image2, View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents, UserSettingsSections, VerticalGradient } from "../../../Constants";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_WIDTH } from "./CollectiblesShopCardV2";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import SkeletonCard from "./SkeletonCard";
import { useCollectiblesCoachmarkScrollDismissContext } from "./CollectiblesCoachmarkScrollDismissContext";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { useStateFromStores } from "../../../_bundle/Module589";
import useTheme from "../../../hooks/useTheme";
import { useTrackProductCardImpression } from "../hooks/useTrackProductCardImpression";
import useGetProductsFromSkus from "../hooks/useGetProductsFromSkus";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import FeaturedFirstCardCoachmarkAnchor from "./FeaturedFirstCardCoachmarkAnchor";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { isThemeDark } from "../../../design/shared";
import Module14617 from "../../../_bundle/Module14617";
import Module14618 from "../../../_bundle/Module14618";
import VisibilitySensor from "./VisibilitySensor";
import FramesEarlyAccessBadge from "./FramesEarlyAccessBadge";
import Module4611 from "../../../_bundle/Module4611";
import { Text } from "../../../design/components/Text/native/Text";
import { Button } from "../../../design/components/Button/native/Button.native";
import { intl, t } from "../../../intl/index.native";
import { openQuestHome } from "../../quests/native/QuestUtils.native";
import { QuestContent } from "../../../_bundle/Module5038";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { ChevronSmallRightIcon } from "../../../design/components/Icon/native/redesign/generated/ChevronSmallRightIcon";
import { LayerScope } from "../../../design/components/Layers/native/LayerScope.native";
import FeedProductList from "./FeedProductList";
import { FlashList } from "../../../_bundle/noop_6676";
let useStyles;
const SkeletonLoading = function SkeletonLoading(props) {
const accessibilityLabel = props.accessibilityLabel;
return <View style={useStyles().skeletonContainer} accessibilityRole="list" accessibilityLabel={accessibilityLabel} accessibilityState={{
busy: true
}} accessible>
{Array.from({
length: 10
}).map((item, index) => <SkeletonCard key={index} width={COLLECTIBLES_SHOP_CARD_WIDTH} />)}
</View>;
};
useStyles = createStyles({
heroContainer: {
width: "100%"
},
framesBadgeContainer: {
position: "absolute",
top: Module712.space.PX_24,
left: 0,
right: 0,
paddingHorizontal: Module712.space.PX_16,
alignItems: "flex-start",
zIndex: 2
},
framesBannerWrapper: {
marginTop: -250,
paddingTop: 240,
paddingBottom: Module712.space.PX_16,
paddingHorizontal: Module712.space.PX_16,
flexDirection: "row",
alignItems: "center",
borderRadius: Module712.radii.lg,
overflow: "hidden",
zIndex: 0
},
framesBannerBackgroundImage: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
resizeMode: "stretch",
borderRadius: Module712.radii.lg
},
framesBannerTextContainer: {
flex: 1,
paddingRight: Module712.space.PX_4,
marginTop: Module712.space.PX_24
},
framesBannerTitle: {
marginBottom: Module712.space.PX_4
},
framesBannerForegroundImage: {
width: 125,
height: 125,
resizeMode: "contain",
transform: [{
translateY: Module712.space.PX_16
}]
},
heroBannerContainer: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
maxHeight: 240 + 0.75 * COLLECTIBLES_SHOP_CARD_WIDTH,
aspectRatio: 1.4883720930232558
},
heroBannerImage: {
width: "100%",
height: "100%",
resizeMode: "cover"
},
orbsBackgroundGradient: {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0
},
heroInfoContainer: {
display: "flex",
justifyContent: "center",
flex: 1,
minWidth: "100%",
maxHeight: 240,
aspectRatio: 2.2
},
innerContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: Module712.space.PX_16,
width: "100%",
height: "100%"
},
heroLogoContainer: {
flex: 1,
maxWidth: "80%",
maxHeight: "80%"
},
heroLogo: {
resizeMode: "contain",
maxHeight: "100%",
maxWidth: "100%",
aspectRatio: 1
},
heroViewAllIcon: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
padding: Module712.space.PX_8,
borderRadius: Module712.radii.round
},
orbsInnerContainer: {
paddingHorizontal: Module712.space.PX_16,
alignItems: "flex-start",
gap: Module712.space.PX_16
},
orbsTitle: {
fontSize: 24,
lineHeight: 30
},
productCardsContainer: {
zIndex: 1
},
skeletonContainer: {
flexDirection: "row",
gap: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16
}
});
export default ({ heroBlock, bannerBlock, preferVCPrice, screen }) => {
let c21254_5, c21254_6;
c21254_5 = void 0;
c21254_6 = void 0;
const handleDismissCoachmarkOnScroll = useCollectiblesCoachmarkScrollDismissContext().handleDismissCoachmarkOnScroll;
const navigation = useNavigation();
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
let mobileHeroUrl = heroBlock.mobileHeroUrl;
if (mobileHeroUrl == null) {
mobileHeroUrl = heroBlock.heroBannerUrl;
}
const heroLogoUrl = heroBlock.heroLogoUrl;
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.getCategory(heroBlock.categorySkuId));
const bypassAndroidUnsyncedFilter = stateFromStores != null && stateFromStores.isOrbsExclusive;
const theme = useTheme();
const handleCardVisibilityChange = useTrackProductCardImpression(heroBlock.categoryStoreListingId, "mobile_home", "hero_block").handleCardVisibilityChange;
const styles = useStyles();
const getProductsFromSkus = useGetProductsFromSkus();
c21254_5 = getProductsFromSkus;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: useMemo(() => c21254_5(heroBlock.rankedSkuIds), [heroBlock.rankedSkuIds, getProductsFromSkus]),
bypassAndroidUnsyncedFilter
});
const r4 = screen === CollectiblesMobileShopScreen.FEATURED_PAGE;
c21254_6 = r4;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_HERO).analyticsLocations;
const callback = useCallback(({ item, index }) => {
const r18 = <CollectiblesShopCardV2 solidBackground product={item} unpublishedAt={stateFromStores?.unpublishedAt} preferVCPrice={preferVCPrice} />;
return <CollectiblesAnalyticsProvider newValue={{
tilePosition: index
}}>
{index === 0 ? c21254_6 ? <FeaturedFirstCardCoachmarkAnchor>{r18}</FeaturedFirstCardCoachmarkAnchor> : r18 : r18}
</CollectiblesAnalyticsProvider>;
}, [stateFromStores?.unpublishedAt, preferVCPrice, r4]);
if (stateFromStores === void 0) {
return null;
}
const r32 = heroBlock.mobileTitle != null ? heroBlock.mobileTitle : heroBlock.title;
const r33 = heroBlock.mobileSummary != null ? heroBlock.mobileSummary : heroBlock.summary;
if (bypassAndroidUnsyncedFilter) {
mobileHeroUrl = isThemeDark(theme) ? Module14617 : Module14618;
}
return <AnalyticsLocationProvider value={analyticsLocations}>
<VisibilitySensor onChange={handleCardVisibilityChange} resetKey={heroBlock.categoryStoreListingId}>
<View style={styles.heroContainer}>
<View style={styles.framesBadgeContainer}>
<FramesEarlyAccessBadge location="CollectiblesShop" disablePressable />
</View>
<View style={styles.heroBannerContainer}>
{mobileHeroUrl != null && <>
{bypassAndroidUnsyncedFilter && <Module4611 colors={["rgba(39, 30, 173, 0.3)", "transparent"]} start={VerticalGradient.START} end={VerticalGradient.END} style={styles.orbsBackgroundGradient} />}
<Image2 style={[styles.heroBannerImage]} source={{
uri: mobileHeroUrl
}} />
</>}
</View>
<View style={styles.heroInfoContainer}>
{bypassAndroidUnsyncedFilter ? <View style={styles.orbsInnerContainer}>
<View>
{r32 != null && <Text variant="display-md" color="mobile-text-heading-primary" style={styles.orbsTitle}>{r32}</Text>}
{r33 != null && r33 !== "" && <Text variant="text-md/medium">{r33}</Text>}
</View>
<Button variant="tertiary" shrink grow={false} size="sm" text={intl.string(t.ynollq)} onPress={function onPress() {
openQuestHome({
mergeExistingRoutes: true,
fromContent: QuestContent.ORBS_SHOP_HERO_CTA
});
}} />
</View> : <PressableOpacity key={stateFromStores.storeListingId} accessibilityRole="button" accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} accessibilityHint={intl.string(t.F8ma9x)} activeOpacity={0.6} androidRippleConfig={{
radius: Module712.radii.lg
}} hitSlop={8} onPress={() => {
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_ELEMENT_CLICKED, {
collectibles_shop_session_id: collectiblesAnalyticsContext?.sessionId,
sku_id: heroBlock.categoryStoreListingId,
page_type: "mobile_home",
page_section: collectiblesAnalyticsContext?.pageSection,
page_category: collectiblesAnalyticsContext?.pageCategory,
tile_type: "HERO_BLOCK",
tile_position: String(collectiblesAnalyticsContext?.tilePosition),
cta_name: null
});
navigation.navigate(UserSettingsSections.COLLECTIBLES_SHOP_VIEW_ALL_CATEGORY_ITEMS, {
category: stateFromStores,
analyticsContext: collectiblesAnalyticsContext
});
}}>
<View style={styles.innerContainer}>
{heroLogoUrl != null && <View style={styles.heroLogoContainer}>
<Image2 style={styles.heroLogo} source={{
uri: heroLogoUrl
}} />
</View>}
<View style={styles.heroViewAllIcon}>
<ChevronSmallRightIcon size="sm" color="white" />
</View>
</View>
</PressableOpacity>}
</View>
<View style={styles.productCardsContainer}>
<LayerScope>
{bypassAndroidUnsyncedFilter ? <FeedProductList products={filteredAndSortedProducts} loadingCardsNum={filteredAndSortedProducts.length !== 0 ? filteredAndSortedProducts.length : 4} preferVCPrice={preferVCPrice} accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} /> : <>
{filteredAndSortedProducts.length === 0 ? <SkeletonLoading accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} /> : <FlashList horizontal accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} accessibilityRole="list" data={filteredAndSortedProducts} onScroll={handleDismissCoachmarkOnScroll} renderItem={callback} decelerationRate="fast" snapToInterval={COLLECTIBLES_SHOP_CARD_WIDTH + Module712.space.PX_12} showsHorizontalScrollIndicator={false} ListHeaderComponent={() => <View style={{
width: Module712.space.PX_16
}} />} ListFooterComponent={() => <View style={{
width: Module712.space.PX_16
}} />} ItemSeparatorComponent={() => <View style={{
width: Module712.space.PX_12
}} />} />}
</>}
</LayerScope>
</View>
<View style={styles.framesBannerWrapper}>
{bannerBlock.mobileBackgroundImage != null && <Image2 style={styles.framesBannerBackgroundImage} source={{
uri: bannerBlock.mobileBackgroundImage
}} />}
<View style={styles.framesBannerTextContainer}>
<Text variant="text-lg/bold" color="control-overlay-secondary-text-default" style={styles.framesBannerTitle}>{bannerBlock.title}</Text>
<Text variant="text-sm/normal" color="control-overlay-secondary-text-default">{bannerBlock.body}</Text>
</View>
{bannerBlock.mobileForegroundImage != null && <Image2 style={styles.framesBannerForegroundImage} source={{
uri: bannerBlock.mobileForegroundImage
}} />}
</View>
</View>
</VisibilitySensor>
</AnalyticsLocationProvider>;
};
@@ -0,0 +1,84 @@
// Metro module 14632 (f14633).
import { useMemo, useCallback } from "react";
import { Image as Image2, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useCollectiblesCoachmarkScrollDismissContext } from "./CollectiblesCoachmarkScrollDismissContext";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import useGetProductsFromSkus from "../hooks/useGetProductsFromSkus";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_WIDTH } from "./CollectiblesShopCardV2";
import FramesEarlyAccessBadge from "./FramesEarlyAccessBadge";
import { Text } from "../../../design/components/Text/native/Text";
import { LayerScope } from "../../../design/components/Layers/native/LayerScope.native";
import { FlashList } from "../../../_bundle/noop_6676";
let useStyles, ListItemSeparator;
const ListEdgeSpacer = function ListEdgeSpacer() {
return <View style={useStyles().listEdgeSpacer} />;
};
ListItemSeparator = function ListItemSeparator() {
return <View style={useStyles().listItemSeparator} />;
};
useStyles = createStyles({
container: {
width: "100%",
marginTop: Module712.space.PX_24,
paddingTop: Module712.space.PX_24,
paddingBottom: Module712.space.PX_24,
overflow: "hidden"
},
backgroundImage: {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
minWidth: "100%",
aspectRatio: 2.5,
resizeMode: "cover"
},
header: {
paddingHorizontal: Module712.space.PX_16,
marginBottom: Module712.space.PX_16,
gap: Module712.space.PX_8,
alignItems: "flex-start",
zIndex: 1
},
listEdgeSpacer: {
width: Module712.space.PX_16
},
listItemSeparator: {
width: Module712.space.PX_12
}
});
export default ({ block, preferVCPrice }) => {
const styles = useStyles();
const handleDismissCoachmarkOnScroll = useCollectiblesCoachmarkScrollDismissContext().handleDismissCoachmarkOnScroll;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_SHELF).analyticsLocations;
const getProductsFromSkus = useGetProductsFromSkus();
let c21265_2 = getProductsFromSkus;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: useMemo(() => c21265_2(block.rankedSkuIds), [block.rankedSkuIds, getProductsFromSkus])
});
const callback = useCallback((a0) => <CollectiblesAnalyticsProvider newValue={{
tilePosition: a0.index
}}>
<CollectiblesShopCardV2 product={a0.item} preferVCPrice={preferVCPrice} />
</CollectiblesAnalyticsProvider>, [preferVCPrice]);
const callback2 = useCallback((a0) => a0.skuId, []);
return filteredAndSortedProducts.length !== 0 ? <AnalyticsLocationProvider value={analyticsLocations}>
<View style={styles.container}>
{block.mobileBackgroundImage != null && <Image2 style={styles.backgroundImage} source={{
uri: block.mobileBackgroundImage
}} />}
<View style={styles.header}>
<FramesEarlyAccessBadge location="FramesProductShelfBlock" tooltipPosition="bottom" />
<Text variant="text-sm/semibold" color="text-overlay-light">{block.title}</Text>
</View>
<LayerScope>
<FlashList horizontal accessibilityRole="list" accessibilityLabel={block.title} data={filteredAndSortedProducts} keyExtractor={callback2} onScroll={handleDismissCoachmarkOnScroll} renderItem={callback} decelerationRate="fast" snapToInterval={COLLECTIBLES_SHOP_CARD_WIDTH + Module712.space.PX_12} showsHorizontalScrollIndicator={false} ListHeaderComponent={ListEdgeSpacer} ListFooterComponent={ListEdgeSpacer} ItemSeparatorComponent={ListItemSeparator} />
</LayerScope>
</View>
</AnalyticsLocationProvider> : null;
};
+254
View File
@@ -0,0 +1,254 @@
// Metro module 14622 (f14623).
import { useMemo, useCallback } from "react";
import { Image as Image2, View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents, UserSettingsSections, VerticalGradient } from "../../../Constants";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_WIDTH } from "./CollectiblesShopCardV2";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import SkeletonCard from "./SkeletonCard";
import { useCollectiblesCoachmarkScrollDismissContext } from "./CollectiblesCoachmarkScrollDismissContext";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { useStateFromStores } from "../../../_bundle/Module589";
import useTheme from "../../../hooks/useTheme";
import { useTrackProductCardImpression } from "../hooks/useTrackProductCardImpression";
import { useToken } from "../../../design/tokens/native/useToken";
import { hexToRgbaString, hexWithOpacity } from "../../../utils/ColorUtils";
import useGetProductsFromSkus from "../hooks/useGetProductsFromSkus";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import FeaturedFirstCardCoachmarkAnchor from "./FeaturedFirstCardCoachmarkAnchor";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { isThemeDark } from "../../../design/shared";
import Module14617 from "../../../_bundle/Module14617";
import Module14618 from "../../../_bundle/Module14618";
import VisibilitySensor from "./VisibilitySensor";
import Module4611 from "../../../_bundle/Module4611";
import { Text } from "../../../design/components/Text/native/Text";
import { Button } from "../../../design/components/Button/native/Button.native";
import { intl, t } from "../../../intl/index.native";
import { openQuestHome } from "../../quests/native/QuestUtils.native";
import { QuestContent } from "../../../_bundle/Module5038";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { ChevronSmallRightIcon } from "../../../design/components/Icon/native/redesign/generated/ChevronSmallRightIcon";
import { LayerScope } from "../../../design/components/Layers/native/LayerScope.native";
import FeedProductList from "./FeedProductList";
import { FlashList } from "../../../_bundle/noop_6676";
let useStyles;
const SkeletonLoading = function SkeletonLoading(props) {
const accessibilityLabel = props.accessibilityLabel;
return <View style={useStyles().skeletonContainer} accessibilityRole="list" accessibilityLabel={accessibilityLabel} accessibilityState={{
busy: true
}} accessible>
{Array.from({
length: 10
}).map((item, index) => <SkeletonCard key={index} width={COLLECTIBLES_SHOP_CARD_WIDTH} />)}
</View>;
};
useStyles = createStyles({
heroContainer: {
width: "100%"
},
heroBannerContainer: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
maxHeight: 240 + 0.75 * COLLECTIBLES_SHOP_CARD_WIDTH,
aspectRatio: 1.4883720930232558
},
heroBannerImage: {
width: "100%",
height: "100%",
resizeMode: "cover"
},
orbsBackgroundGradient: {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0
},
fadeOutGradient: {
position: "absolute",
bottom: 0,
height: "50%",
width: "100%",
zIndex: 1
},
heroInfoContainer: {
display: "flex",
justifyContent: "center",
flex: 1,
minWidth: "100%",
maxHeight: 240,
aspectRatio: 2.2
},
innerContainer: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: Module712.space.PX_16,
width: "100%",
height: "100%"
},
heroLogoContainer: {
flex: 1,
maxWidth: "80%",
maxHeight: "80%"
},
heroLogo: {
resizeMode: "contain",
maxHeight: "100%",
maxWidth: "100%",
aspectRatio: 1
},
heroViewAllIcon: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
padding: Module712.space.PX_8,
borderRadius: Module712.radii.round
},
orbsInnerContainer: {
paddingHorizontal: Module712.space.PX_16,
alignItems: "flex-start",
gap: Module712.space.PX_16
},
orbsTitle: {
fontSize: 24,
lineHeight: 30
},
productCardsContainer: {
zIndex: 1
},
skeletonContainer: {
flexDirection: "row",
gap: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16
}
});
export default ({ heroBlock, preferVCPrice, screen }) => {
let c21261_5, c21261_6;
c21261_5 = void 0;
c21261_6 = void 0;
const handleDismissCoachmarkOnScroll = useCollectiblesCoachmarkScrollDismissContext().handleDismissCoachmarkOnScroll;
const navigation = useNavigation();
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
let mobileHeroUrl = heroBlock.mobileHeroUrl;
if (mobileHeroUrl == null) {
mobileHeroUrl = heroBlock.heroBannerUrl;
}
const heroLogoUrl = heroBlock.heroLogoUrl;
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.getCategory(heroBlock.categorySkuId));
const bypassAndroidUnsyncedFilter = stateFromStores != null && stateFromStores.isOrbsExclusive;
const theme = useTheme();
const handleCardVisibilityChange = useTrackProductCardImpression(heroBlock.categoryStoreListingId, "mobile_home", "hero_block").handleCardVisibilityChange;
const styles = useStyles();
const r37 = hexToRgbaString(hexWithOpacity(useToken(Module712.colors.BACKGROUND_BASE_LOW), 0));
const token = useToken(Module712.colors.BACKGROUND_BASE_LOWEST);
const getProductsFromSkus = useGetProductsFromSkus();
c21261_5 = getProductsFromSkus;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: useMemo(() => c21261_5(heroBlock.rankedSkuIds), [heroBlock.rankedSkuIds, getProductsFromSkus]),
bypassAndroidUnsyncedFilter
});
const r4 = screen === CollectiblesMobileShopScreen.FEATURED_PAGE;
c21261_6 = r4;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_HERO).analyticsLocations;
const callback = useCallback(({ item, index }) => {
const r18 = <CollectiblesShopCardV2 solidBackground product={item} unpublishedAt={stateFromStores?.unpublishedAt} preferVCPrice={preferVCPrice} />;
return <CollectiblesAnalyticsProvider newValue={{
tilePosition: index
}}>
{index === 0 ? c21261_6 ? <FeaturedFirstCardCoachmarkAnchor>{r18}</FeaturedFirstCardCoachmarkAnchor> : r18 : r18}
</CollectiblesAnalyticsProvider>;
}, [stateFromStores?.unpublishedAt, preferVCPrice, r4]);
if (stateFromStores === void 0) {
return null;
}
const r31 = heroBlock.mobileTitle != null ? heroBlock.mobileTitle : heroBlock.title;
const r32 = heroBlock.mobileSummary != null ? heroBlock.mobileSummary : heroBlock.summary;
if (bypassAndroidUnsyncedFilter) {
mobileHeroUrl = isThemeDark(theme) ? Module14617 : Module14618;
}
return <AnalyticsLocationProvider value={analyticsLocations}>
<VisibilitySensor onChange={handleCardVisibilityChange} resetKey={heroBlock.categoryStoreListingId}>
<View style={styles.heroContainer}>
<View style={styles.heroBannerContainer}>
{mobileHeroUrl != null && <>
{bypassAndroidUnsyncedFilter && <Module4611 colors={["rgba(39, 30, 173, 0.3)", "transparent"]} start={VerticalGradient.START} end={VerticalGradient.END} style={styles.orbsBackgroundGradient} />}
<Image2 style={[styles.heroBannerImage]} source={{
uri: mobileHeroUrl
}} />
<Module4611 colors={[r37, token]} start={VerticalGradient.START} end={VerticalGradient.END} style={styles.fadeOutGradient} />
</>}
</View>
<View style={styles.heroInfoContainer}>
{bypassAndroidUnsyncedFilter ? <View style={styles.orbsInnerContainer}>
<View>
{r31 != null && <Text variant="display-md" color="mobile-text-heading-primary" style={styles.orbsTitle}>{r31}</Text>}
{r32 != null && r32 !== "" && <Text variant="text-md/medium">{r32}</Text>}
</View>
<Button variant="tertiary" shrink grow={false} size="sm" text={intl.string(t.ynollq)} onPress={function onPress() {
openQuestHome({
mergeExistingRoutes: true,
fromContent: QuestContent.ORBS_SHOP_HERO_CTA
});
}} />
</View> : <PressableOpacity key={stateFromStores.storeListingId} accessibilityRole="button" accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} accessibilityHint={intl.string(t.F8ma9x)} activeOpacity={0.6} androidRippleConfig={{
radius: Module712.radii.lg
}} hitSlop={8} onPress={() => {
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_ELEMENT_CLICKED, {
collectibles_shop_session_id: collectiblesAnalyticsContext?.sessionId,
sku_id: heroBlock.categoryStoreListingId,
page_type: "mobile_home",
page_section: collectiblesAnalyticsContext?.pageSection,
page_category: collectiblesAnalyticsContext?.pageCategory,
tile_type: "HERO_BLOCK",
tile_position: String(collectiblesAnalyticsContext?.tilePosition),
cta_name: null
});
navigation.navigate(UserSettingsSections.COLLECTIBLES_SHOP_VIEW_ALL_CATEGORY_ITEMS, {
category: stateFromStores,
analyticsContext: collectiblesAnalyticsContext
});
}}>
<View style={styles.innerContainer}>
{heroLogoUrl != null && <View style={styles.heroLogoContainer}>
<Image2 style={styles.heroLogo} source={{
uri: heroLogoUrl
}} />
</View>}
<View style={styles.heroViewAllIcon}>
<ChevronSmallRightIcon size="sm" color="white" />
</View>
</View>
</PressableOpacity>}
</View>
<View style={styles.productCardsContainer}>
<LayerScope>
{bypassAndroidUnsyncedFilter ? <FeedProductList products={filteredAndSortedProducts} loadingCardsNum={filteredAndSortedProducts.length !== 0 ? filteredAndSortedProducts.length : 4} preferVCPrice={preferVCPrice} accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} /> : <>
{filteredAndSortedProducts.length === 0 ? <SkeletonLoading accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} /> : <FlashList horizontal accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: stateFromStores.name
})} accessibilityRole="list" data={filteredAndSortedProducts} onScroll={handleDismissCoachmarkOnScroll} renderItem={callback} decelerationRate="fast" snapToInterval={COLLECTIBLES_SHOP_CARD_WIDTH + Module712.space.PX_12} showsHorizontalScrollIndicator={false} ListHeaderComponent={() => <View style={{
width: Module712.space.PX_16
}} />} ListFooterComponent={() => <View style={{
width: Module712.space.PX_16
}} />} ItemSeparatorComponent={() => <View style={{
width: Module712.space.PX_12
}} />} />}
</>}
</LayerScope>
</View>
</View>
</VisibilitySensor>
</AnalyticsLocationProvider>;
};
@@ -0,0 +1,117 @@
// Metro module 8744 (f8745).
import { Pressable, View, StyleSheet } from "react-native";
import { EXTERNAL_PRODUCT_SKU_IDS, ShopCtaEnum } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import Module4611 from "../../../_bundle/Module4611";
import { useCurrentUser } from "../hooks/useCurrentUser";
import ProfileEffectUserPreview from "../profile_effects/native/previews/ProfileEffectUserPreview";
import ProfileFrameUserPreview from "../profile_frames/native/previews/ProfileFrameUserPreview";
import AvatarDecorationProductPreview from "./AvatarDecorationProductPreview";
import NameplateProductPreview from "../nameplates/native/NameplateProductPreview";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { FractionalPremiumSKUsSets } from "../../../_bundle/Module679";
import { FractionalNitroPreview } from "./FractionalNitroPreview";
import { OrbBadgePreview } from "./OrbBadgePreview";
let useStyles, ProfileEffectPreview, ProfileFramePreview, AvatarDecorationPreview, NameplatePreview;
const ProfilePreviewWrapper = function ProfilePreviewWrapper(props) {
const { handlePreviewPress, onTrackPress, children } = props;
const styles = useStyles();
return <Pressable onPress={() => {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.FULL_PROFILE_PREVIEW);
}
if (handlePreviewPress != null) {
handlePreviewPress();
}
}} style={styles.collectiblePreview}>
<View style={styles.profilePreviewContainer}>
{children}
<Module4611 style={styles.profilePreviewGradient} start={{
x: 0,
y: 0.6
}} end={{
x: 0,
y: 1
}} colors={[`${styles.profilePreviewGradient.color}00`, styles.profilePreviewGradient.color]} />
</View>
</Pressable>;
};
ProfileEffectPreview = function ProfileEffectPreview(props) {
const { profileEffect, profileEffectRestartKey, width, handlePreviewPress: handlePreviewPress3, onTrackPress: onTrackPress3 } = props;
const styles = useStyles();
return <ProfilePreviewWrapper handlePreviewPress={handlePreviewPress3} onTrackPress={onTrackPress3}>
<ProfileEffectUserPreview user={useCurrentUser()} profileEffect={profileEffect} profileEffectRestartKey={profileEffectRestartKey} maxWidth={width} style={styles.profilePreview} />
</ProfilePreviewWrapper>;
};
ProfileFramePreview = function ProfileFramePreview(props) {
const { profileFrame, width, handlePreviewPress: handlePreviewPress3, onTrackPress: onTrackPress3 } = props;
const styles = useStyles();
return <ProfilePreviewWrapper handlePreviewPress={handlePreviewPress3} onTrackPress={onTrackPress3}>
<ProfileFrameUserPreview profileFrame={profileFrame} user={useCurrentUser()} maxWidth={width} style={styles.profilePreview} />
</ProfilePreviewWrapper>;
};
AvatarDecorationPreview = function AvatarDecorationPreview(props) {
const { product, handlePreviewPress: handlePreviewPress2, onTrackPress: onTrackPress2 } = props;
return <Pressable onPress={() => {
if (onTrackPress2 != null) {
onTrackPress2(ShopCtaEnum.FULL_PROFILE_PREVIEW);
}
if (handlePreviewPress2 != null) {
handlePreviewPress2();
}
}} style={useStyles().collectiblePreview}>
<AvatarDecorationProductPreview product={product} />
</Pressable>;
};
NameplatePreview = function NameplatePreview(props) {
const product = props.product;
return <View style={useStyles().collectiblePreview}>
<NameplateProductPreview product={product} />
</View>;
};
useStyles = createStyles({
collectiblePreview: {
marginTop: Module712.space.PX_12,
position: "relative",
height: 280
},
profilePreviewContainer: {
position: "relative",
flex: 1,
alignItems: "center",
overflow: "hidden"
},
profilePreview: {
width: "66%"
},
profilePreviewGradient: {
...StyleSheet.absoluteFillObject,
bottom: -1,
pointerEvents: "none",
color: Module712.colors.MOBILE_ACTIONSHEET_BACKGROUND
}
});
export { ProfileEffectPreview };
export { AvatarDecorationPreview };
export { NameplatePreview };
export function IndividualProductPreview(props) {
const { product, width, handlePreviewPress: handlePreviewPress3, onTrackPress: onTrackPress3 } = props;
const type = product.type;
if (CollectiblesItemType.NAMEPLATE === type) {
return <NameplatePreview product={product} />;
}
if (CollectiblesItemType.PROFILE_EFFECT === type) {
return <ProfileEffectPreview profileEffect={product.items[0]} width={width} handlePreviewPress={handlePreviewPress3} onTrackPress={onTrackPress3} />;
}
if (CollectiblesItemType.PROFILE_FRAME === type) {
return <ProfileFramePreview profileFrame={product.items[0]} width={width} handlePreviewPress={handlePreviewPress3} onTrackPress={onTrackPress3} />;
}
if (CollectiblesItemType.AVATAR_DECORATION === type) {
return <AvatarDecorationPreview product={product} handlePreviewPress={handlePreviewPress3} onTrackPress={onTrackPress3} />;
}
if (CollectiblesItemType.EXTERNAL_SKU === type) {
return FractionalPremiumSKUsSets.ALL.has(product.skuId) ? <FractionalNitroPreview /> : product.skuId === EXTERNAL_PRODUCT_SKU_IDS.ORB_PROFILE_BADGE ? <OrbBadgePreview /> : null;
}
return null;
}
@@ -0,0 +1,197 @@
// Metro module 8759 (f8760).
import { Pressable, View } from "react-native";
import IAPStore_android from "../../../stores/native/IAPStore.android";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { AnalyticsSections, CurrencyCodes } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { Text } from "../../../design/components/Text/native/Text";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { isOrbsExclusiveProduct } from "../utils/CollectiblesProductUtils";
import { getProductDiscount, DISCOUNT_DISPLAY_MINIMUM_THRESHOLD, getShopDiscountSource, ShopDiscountSource } from "../CollectiblesUtils";
import { OrbsIcon } from "../../../design/components/Icon/native/redesign/generated/OrbsIcon";
import { intl, t } from "../../../intl/index.native";
import { useCurrentUser } from "../hooks/useCurrentUser";
import PremiumUtils from "../../../utils/PremiumUtils";
import useOpenNitroSubscribeActionSheet from "./useOpenNitroSubscribeActionSheet";
import { useProductDisableState } from "../hooks/useProductDisableState";
import { getFormattedPriceForCollectiblesProduct } from "./CollectiblesUtils";
import { useVirtualCurrencyData } from "./hooks/useVirtualCurrencyData";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useIsProfileFramesEarlyAccessPhase } from "../hooks/useCanPurchaseFrames";
import { CollectiblesShopPricePlaceholder } from "./CollectiblesShopPricePlaceholder";
import { isAndroid } from "../../../utils/PlatformUtils";
import { TagIcon } from "../../../design/components/Icon/native/redesign/generated/TagIcon";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
let useStyles, OrbsPriceTag, useStyles2, BundleDiscountV2;
const PriceTag = function PriceTag(props) {
const { priceFormatted, style, color = "interactive-text-active", icon, variant = "text-md/medium", accessibilityLabel } = props;
return <>
{icon}
<Text variant={variant} style={[useStyles().priceTag, style]} color={color} accessibilityLabel={accessibilityLabel}>{priceFormatted}</Text>
</>;
};
OrbsPriceTag = function OrbsPriceTag(props) {
const { vcData, isProductDisabled, product, eligibleForShopDiscount } = props;
const styles2 = useStyles();
if (vcData.price == null) {
return null;
}
let r9 = product.type === CollectiblesItemType.BUNDLE && isOrbsExclusiveProduct(product);
const productDiscount = getProductDiscount(product, eligibleForShopDiscount, CurrencyCodes.DISCORD_ORB);
const { original, discountPercentage } = productDiscount;
if (r9) {
r9 = discountPercentage >= DISCOUNT_DISPLAY_MINIMUM_THRESHOLD;
}
const style = [styles2.priceTagRow, ,];
const canAfford = vcData.canAfford;
style[1] = (canAfford ? isProductDisabled : !canAfford) && styles2.disabled;
return <View style={style}>
{r9 && <PriceTag priceFormatted={original.toString()} variant="text-md/medium" style={styles2.strikedOrbPrice} icon={<OrbsIcon color="interactive-text-active" size="sm" style={styles2.orbsIcon} />} accessibilityLabel={intl.formatToPlainString(t.QfcKZ5, {
orbAmount: original.toString()
})} />}
<PriceTag priceFormatted={vcData.price.amount.toString()} variant="text-md/semibold" icon={r9 ? void 0 : <OrbsIcon color="interactive-text-active" size="sm" style={styles2.orbsIcon} />} accessibilityLabel={r9 ? intl.formatToPlainString(t.ckguyq, {
orbAmount: vcData.price.amount.toString(),
discountPercentage
}) : intl.formatToPlainString(t["a/Y8PK"], {
orbAmount: vcData.price.amount.toString()
})} />
{r9 ? <BundleDiscountV2 discountPercentage={discountPercentage} /> : null}
</View>;
};
BundleDiscountV2 = function BundleDiscountV2(props) {
const discountPercentage = props.discountPercentage;
const styles2 = useStyles2();
return discountPercentage < DISCOUNT_DISPLAY_MINIMUM_THRESHOLD ? null : <View style={styles2.discount}>
<Text variant="text-md/normal" color="text-feedback-positive">
-
{discountPercentage}
%
</Text>
</View>;
};
useStyles = createStyles({
priceTag: {
flexDirection: "row",
alignItems: "center"
},
strikedPrice: {
textDecorationLine: "line-through",
textDecorationStyle: "solid",
opacity: 0.7
},
strikedOrbPrice: {
textDecorationLine: "line-through",
textDecorationStyle: "solid",
opacity: 0.7,
marginRight: 4
},
regularPrice: {},
nitroIcon: {
width: 20,
height: 20,
marginLeft: 8,
marginRight: 4
},
nitroIconSubscribeNow: {
marginLeft: 0
},
container: {
flexDirection: "row",
alignItems: "flex-start",
justifyContent: "space-between"
},
priceTagRow: {
flexDirection: "row",
alignItems: "center"
},
priceTagColumn: {
flexDirection: "column",
alignItems: "flex-start",
flexShrink: 1
},
underline: {
textDecorationLine: "underline"
},
subscribeNowPressable: {
marginBottom: -2,
marginTop: Module712.space.PX_8,
flexDirection: "row",
alignItems: "center"
},
androidTextPadding: {
paddingBottom: 2
},
orbsIcon: {
marginRight: 4
},
disabled: {
opacity: 0.5
}
});
useStyles2 = createStyles(() => ({
discount: {
backgroundColor: "rgba(46, 204, 113, 0.25)",
flexDirection: "row",
flexShrink: 1,
borderRadius: Module712.radii.xs - 1,
paddingHorizontal: 6,
marginLeft: 6,
paddingTop: isAndroid() ? 0 : void 0,
paddingBottom: isAndroid() ? 2 : void 0
}
}));
export default function InlinePriceTag(props) {
const { product, onTrackPress } = props;
const styles = useStyles();
const currentUser = useCurrentUser();
const shopDiscountSource = getShopDiscountSource(currentUser);
const canUseShopDiscounts = PremiumUtils.canUseShopDiscounts(currentUser);
let c16773_2 = useOpenNitroSubscribeActionSheet(AnalyticsSections.SHOP_PRODUCT_DETAILS);
const isDisabled = useProductDisableState(product.skuId).isDisabled;
const formattedPriceForCollectiblesProduct = getFormattedPriceForCollectiblesProduct(product, false, true);
const virtualCurrencyData = useVirtualCurrencyData(product, canUseShopDiscounts);
const stateFromStores = useStateFromStores([IAPStore_android], () => IAPStore_android.isFetchingGoogleSkus());
const isProfileFramesEarlyAccessPhase = useIsProfileFramesEarlyAccessPhase("InlinePriceTag");
const r73 = product.type === CollectiblesItemType.PROFILE_FRAME && isProfileFramesEarlyAccessPhase;
if (stateFromStores && formattedPriceForCollectiblesProduct == null) {
return <CollectiblesShopPricePlaceholder />;
}
if (formattedPriceForCollectiblesProduct == null) {
return virtualCurrencyData.price != null ? <OrbsPriceTag vcData={virtualCurrencyData} isProductDisabled={isDisabled} product={product} eligibleForShopDiscount={canUseShopDiscounts} /> : null;
}
const r17 = canUseShopDiscounts || r73;
const formattedPriceForCollectiblesProduct2 = getFormattedPriceForCollectiblesProduct(product, true, true);
const discountPercentage = getProductDiscount(product, canUseShopDiscounts).discountPercentage;
const r140 = [<View style={styles.priceTagRow}>
<PriceTag priceFormatted={formattedPriceForCollectiblesProduct} variant={r17 ? void 0 : "heading-md/semibold"} style={r17 ? styles.strikedPrice : styles.regularPrice} color="interactive-text-active" accessibilityLabel={intl.formatToPlainString(t.sPvyr8, {
price: formattedPriceForCollectiblesProduct
})} />
{product.type === CollectiblesItemType.BUNDLE ? canUseShopDiscounts ? null : <BundleDiscountV2 discountPercentage={discountPercentage} /> : null}
{formattedPriceForCollectiblesProduct2 != null && r17 && <PriceTag priceFormatted={formattedPriceForCollectiblesProduct2} variant="text-md/medium" color="interactive-text-active" accessibilityLabel={intl.formatToPlainString(t.kWkpdG, {
price: formattedPriceForCollectiblesProduct2
})} style={isAndroid() ? styles.androidTextPadding : void 0} icon={shopDiscountSource === ShopDiscountSource.THIRDPARTY ? <TagIcon color="interactive-text-active" style={styles.nitroIcon} /> : <NitroWheelIcon color="interactive-text-active" style={styles.nitroIcon} />} />}
</View>, ,];
r140[1] = formattedPriceForCollectiblesProduct2 != null && !r17 && <View style={styles.priceTagRow}>
<Pressable onPress={() => {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.SUBSCRIBE_NOW);
}
c16773_2();
}} style={styles.subscribeNowPressable} accessibilityRole="button">
<NitroWheelIcon color="interactive-text-default" style={[styles.nitroIcon, styles.nitroIconSubscribeNow]} />
<Text variant="text-md/normal" color="interactive-text-default" style={isAndroid() ? styles.androidTextPadding : void 0}>
{intl.format(t.Kxw2LT, {
price: formattedPriceForCollectiblesProduct2,
subscribeNowHook: (a0, a1) => <Text key={a1} variant="text-md/normal" style={styles.underline}>
{a0}
</Text>
})}
</Text>
</Pressable>
</View>;
return <View style={styles.container}>
<View style={styles.priceTagColumn}>{r140}</View>
{virtualCurrencyData.price != null && <OrbsPriceTag vcData={virtualCurrencyData} isProductDisabled={isDisabled} product={product} eligibleForShopDiscount={canUseShopDiscounts} />}
</View>;
};
@@ -0,0 +1,67 @@
// Metro module 8704 (f8705).
import { View } from "react-native";
import LocaleStore from "../../user_settings/LocaleStore";
import ThemeStore from "../../user_settings/ThemeStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { intl, t } from "../../../intl/index.native";
import { useStateFromStores } from "../../../_bundle/Module589";
import { isThemeDark } from "../../../design/shared";
import useCountdown from "../../../hooks/useCountdown";
import { Text } from "../../../design/components/Text/native/Text";
const useStyles = createStyles({
root: {
borderRadius: Module712.radii.md,
paddingHorizontal: 8,
paddingVertical: 2
},
backgroundDarkMode: {
backgroundColor: Module712.colors.WHITE
},
backgroundLightMode: {
backgroundColor: Module712.colors.BACKGROUND_MOD_STRONG
}
});
export default function LimitedTimeBadge(props) {
let r50, r82;
const { unpublishedAt, style } = props;
const styles = useStyles();
const stateFromStores = useStateFromStores([ThemeStore], () => isThemeDark(ThemeStore.theme));
const r35 = ["en-US", "en-GB"].includes(useStateFromStores([LocaleStore], () => LocaleStore.locale));
const countdown = useCountdown(unpublishedAt, 1000, void 0, true);
const { days, hours } = countdown;
if (r35) {
L14: {
if (days > 1) {
r82 = intl.formatToPlainString(t.DkxLY0, {
days
});
} else {
if (days <= 1 && hours > 0) {
r82 = intl.formatToPlainString(t.WJieZ2, {
hours
});
break L14;
}
r82 = intl.formatToPlainString(t.WJieZ2, {
hours: 0
});
}
}
r50 = r82;
} else {
r50 = days + intl.string(t.QJyuxY);
let r60 = hours + intl.string(t["1LyF1h"]);
if (!(days > 1)) {
if (!(days <= 1 && hours > 0)) {
r60 = "0" + intl.string(t["1LyF1h"]);
}
r50 = r60;
}
}
return <View style={[styles.root, stateFromStores ? styles.backgroundDarkMode : styles.backgroundLightMode, style]}>
<Text color={stateFromStores ? "text-overlay-dark" : "text-overlay-light"} variant="text-xs/bold" accessibilityLabel={intl.formatToPlainString(t.TlZULM, {
daysLeft: days
})} allowFontScaling={false}>{r50}</Text>
</View>;
};
@@ -0,0 +1,67 @@
// Metro module 15627 (f15628).
import { useRef, useCallback, useEffect, useMemo } from "react";
import { Image as Image2 } from "react-native";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { isYouNavFloating } from "../../main_tabs_v2/native/tabs/you/YouNavFloatingExperiment";
import { intl, t } from "../../../intl/index.native";
import { useCoachmark } from "../../../design/components/Coachmark/native/useCoachmark.native";
const useStyles = createStyles({
image: {
height: 80,
width: 80,
marginTop: Module712.space.PX_8,
marginBottom: -Module712.space.PX_16
}
});
export default function MobileShopButtonCoachmark({ marketing, shopButtonRef, navigateToShop, visible, onDismiss }) {
let callback2, ref2;
callback2 = void 0;
ref2 = void 0;
const styles = useStyles();
const assetLight = marketing.assetLight;
const ref = useRef(false);
const callback = useCallback(() => {
ref.current = true;
onDismiss(ContentDismissActionType.TAKE_ACTION);
navigateToShop();
}, [onDismiss, navigateToShop]);
callback2 = useCallback(() => {
ref.current = true;
onDismiss(ContentDismissActionType.USER_DISMISS);
}, [onDismiss]);
ref2 = useRef(onDismiss);
useEffect(() => {
ref2.current = onDismiss;
});
useEffect(() => () => {
if (!ref.current) {
ref2.current(ContentDismissActionType.AUTO_DISMISS);
}
}, []);
useCoachmark(shopButtonRef, useMemo(() => {
const r2 = {
title: marketing.title,
description: marketing.body,
visible,
position: isYouNavFloating() ? "top" : "bottom",
renderImgComponent: () => <Image2 style={styles.image} source={{
uri: assetLight
}} />,
buttonLabel: null,
buttonVariant: "secondary",
onButtonPress: null,
onDismiss: null
};
let buttonLabel = marketing.buttonLabel;
if (buttonLabel == null) {
buttonLabel = intl.string(t.fYfGgK);
}
r2.buttonLabel = buttonLabel;
r2.onButtonPress = callback;
r2.onDismiss = callback2;
return r2;
}, [marketing.title, marketing.body, marketing.buttonLabel, visible, assetLight, styles.image, callback, callback2]));
return null;
};
@@ -0,0 +1,8 @@
// Metro module 8751 (f8752).
import Module8531, { Path } from "../../../_bundle/Module8531";
export default function NitroIcon(props) {
const { width = 106, height = 26, color = "#ffffff" } = props;
return <Module8531 width={width} height={height} viewBox="0 0 106 26">
<Path fill={color} d="M98.83,8.65L97.58,17.08C97.29,19.08,95.05,20,92.98,20C91.06,20,89.17,19.08,89.42,17.26L90.67,8.65C90.95,6.76,93.2,5.8,95.26,5.8C97.33,5.8,99.11,6.76,98.83,8.65M96.25,0L82.82,0C82.48,0,82.19,0.25,82.14,0.59L81.48,5.05C81.42,5.46,81.75,5.84,82.17,5.84L84.62,5.84C84.87,5.84,85.04,6.09,84.94,6.31C84.63,7.03,84.41,7.81,84.29,8.65L83.04,17.26C82.22,23.03,87.03,25.91,92.27,25.91C97.76,25.91,103.14,23.03,103.96,17.26L105.21,8.65C106.01,3,101.37,0.12,96.25,0M15.58,11.79L15.65,15.97C15.65,16.06,15.59,16.14,15.51,16.16L14.08,11.11C14.08,11.11,14.08,11.1,14.08,11.09L9.66,0.78C9.55,0.52,9.3,0.36,9.03,0.36L4.03,0.36C3.68,0.36,3.39,0.61,3.34,0.95L0.01,24.77C-0.05,25.18,0.27,25.55,0.69,25.55L5.67,25.55C6.02,25.55,6.31,25.3,6.36,24.96L7.66,15.49C7.67,15.49,7.67,15.48,7.67,15.47L7.59,10.61L7.74,10.57L9.23,15.61C9.23,15.62,9.24,15.63,9.24,15.63L13.37,25.14C13.48,25.39,13.73,25.55,14,25.55L19.4,25.55C19.74,25.55,20.03,25.3,20.08,24.96L23.42,1.14C23.47,0.73,23.15,0.36,22.73,0.36L17.78,0.36C17.44,0.36,17.15,0.61,17.1,0.95L15.58,11.77C15.58,11.77,15.58,11.78,15.58,11.79M25.22,25.55L30.2,25.55C30.55,25.55,30.84,25.3,30.89,24.96L34.22,1.14C34.28,0.73,33.96,0.36,33.54,0.36L28.55,0.36C28.21,0.36,27.92,0.61,27.87,0.95L24.54,24.77C24.48,25.18,24.8,25.55,25.22,25.55M37.59,0.91L36.94,5.37C36.87,5.78,37.2,6.16,37.62,6.16L42.83,6.16C43.25,6.16,43.58,6.53,43.52,6.94L41.06,24.77C41.01,25.18,41.33,25.55,41.75,25.55L46.8,25.55C47.15,25.55,47.44,25.3,47.49,24.96L50,6.75C50.04,6.41,50.34,6.16,50.68,6.16L56.29,6.16C56.63,6.16,56.92,5.91,56.97,5.57L57.62,1.11C57.69,0.69,57.36,0.32,56.94,0.32L38.27,0.32C37.93,0.32,37.64,0.57,37.59,0.91M72.92,9.15C72.74,10.61,71.6,12.06,69.64,12.06L66.69,12.06C66.27,12.06,65.95,11.69,66.01,11.28L66.63,6.89C66.68,6.55,66.97,6.3,67.31,6.3L70.46,6.3C72.35,6.3,73.09,7.62,72.92,9.15M71.17,0.36L61.68,0.36C61.34,0.36,61.05,0.61,61,0.95L57.67,24.77C57.61,25.18,57.93,25.55,58.35,25.55L63.4,25.55C63.75,25.55,64.04,25.3,64.09,24.96L65.07,17.84C65.09,17.67,65.24,17.55,65.41,17.55L66.06,17.55C66.18,17.55,66.29,17.61,66.35,17.7L71.18,25.23C71.31,25.43,71.53,25.55,71.76,25.55L78,25.55C78.56,25.55,78.89,24.92,78.57,24.47L73.51,17.24C73.38,17.06,73.45,16.82,73.64,16.73C76.87,15.15,78.75,13.54,79.37,9.04C80.08,3.13,76.37,0.36,71.17,0.36Z" />
</Module8531>;
};
@@ -0,0 +1,132 @@
// Metro module 11906 (f11907).
import { useCallback, useEffect } from "react";
import { View, StyleSheet } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import { jsx } from "react/jsx-runtime";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { getHeaderCloseButton } from "../../../design/components/Navigator/native/NavigatorHeader.native";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { useFetchVirtualCurrencyBalance } from "../../virtual_currency/hooks/index";
import { BalanceWidgetPill } from "../../virtual_currency/native/index";
import { useStateFromStores } from "../../../_bundle/Module589";
import FastImage from "../../../components_native/common/FastImage";
import Module10972 from "../../../_bundle/Module10972";
import { VideoComponent } from "../../../components_native/common/Video";
import Module10973 from "../../../_bundle/Module10973";
import { SafeAreaPaddingView } from "../../../components_native/common/SafeAreaView";
import Module8713 from "../../../_bundle/Module8713";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { Button } from "../../../design/components/Button/native/Button.native";
import { pinUserProfileBadgesOnClient } from "../../user_profile/UserProfileActionCreators";
import { createOrbProfileBadge } from "./CollectiblesUtils";
import { Navigator } from "../../../design/components/Navigator/native/Navigator.native";
let useStyles, c8161_9;
const OrbBadgeCollectedRootScreen = function OrbBadgeCollectedRootScreen(props) {
const { modalKey, onPressViewBadge } = props;
const styles = useStyles();
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const callback = useCallback(() => {
onPressViewBadge();
}, [onPressViewBadge]);
const callback2 = useCallback(() => {
ModalActionCreators.popWithKey(modalKey);
}, [modalKey]);
return <View style={styles.root}>
{stateFromStores ? <FastImage source={{
uri: Module10972
}} style={styles.background} /> : <VideoComponent source={{
uri: Module10973
}} poster={Module10972} style={styles.background} resizeMode="contain" muted pauseWhileAppInactive paused={false} />}
<SafeAreaPaddingView style={styles.main} top bottom left right>
<View style={styles.body}>
<FastImage source={{
uri: Module8713
}} style={styles.orbBadge} />
<View style={styles.bottomContainer}>
<View style={styles.textContainer}>
<Text variant="heading-xl/bold" color="text-overlay-light" style={styles.text}>
{intl.string(t.Bal8Cv)}
</Text>
<Text variant="text-sm/medium" color="text-overlay-light" style={styles.text}>
{intl.string(t.B25MUf)}
</Text>
</View>
<View style={styles.buttonsContainer}>
<Button onPress={callback} variant="primary" size="lg" text={intl.string(t.uYLGci)} />
<Button onPress={callback2} variant="secondary" size="lg" text={intl.string(t["6gF4aS"])} />
</View>
</View>
</View>
</SafeAreaPaddingView>
</View>;
};
useStyles = createStyles({
root: {
flex: 1
},
background: {
...StyleSheet.absoluteFillObject
},
orbBadge: {
width: 172,
height: 172,
alignSelf: "center"
},
main: {
flex: 1
},
body: {
paddingTop: "50%",
padding: Module712.space.PX_16,
flex: 1,
justifyContent: "space-between",
gap: Module712.space.PX_32
},
bottomContainer: {
alignSelf: "flex-end",
alignItems: "stretch",
gap: Module712.space.PX_32,
width: "100%"
},
textContainer: {
alignItems: "center",
gap: Module712.space.PX_8
},
text: {
textAlign: "center"
},
buttonsContainer: {
alignItems: "stretch",
gap: Module712.space.PX_16
}
});
c8161_9 = {
ROOT: "ROOT"
};
export default function OrbBadgeCollectedModal(props) {
let modalKey2, onPressViewBadge2, orbBalancePriorToPurchase;
const { modalKey: modalKey4, onPressViewBadge: onPressViewBadge3, orbBalancePriorToPurchase: orbBalancePriorToPurchase2 } = props;
useEffect(() => {
pinUserProfileBadgesOnClient([createOrbProfileBadge()], 600);
}, []);
modalKey2 = modalKey4;
onPressViewBadge2 = onPressViewBadge3;
orbBalancePriorToPurchase = orbBalancePriorToPurchase2;
const screens = {};
screens[c8161_9.ROOT] = {
render: () => <OrbBadgeCollectedRootScreen modalKey={modalKey2} onPressViewBadge={onPressViewBadge2} />,
ignoreKeyboard: true,
fullscreen: true,
headerLeft: () => {
const modalKey3 = modalKey2;
return jsx(getHeaderCloseButton(() => ModalActionCreators.popWithKey(modalKey3)), {
tintColor: "white"
});
},
headerRight: () => <BalanceWidgetPill initialRenderedBalance={orbBalancePriorToPurchase} balance={useFetchVirtualCurrencyBalance().balance} />,
title: ""
};
return <Navigator screens={screens} initialRouteName={c8161_9.ROOT} />;
};
@@ -0,0 +1,19 @@
// Metro module 8752 (f8753).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { useCurrentUser } from "../hooks/useCurrentUser";
import UserProfilePreview from "../../user_profile/native/UserProfilePreview";
import { createOrbProfileBadge } from "./CollectiblesUtils";
import { intl, t } from "../../../intl/index.native";
const useStyles = createStyles({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
export function OrbBadgePreview() {
return <View style={useStyles().container}>
<UserProfilePreview compact user={useCurrentUser()} additionalBadges={[createOrbProfileBadge()]} accessibilityLabel={intl.string(t.bxcI6Y)} />
</View>;
}
@@ -0,0 +1,58 @@
// Metro module 8428 (f8429).
import { useMemo } from "react";
import { Image as Image2, View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module8429 from "../../../_bundle/Module8429";
import { intl, t } from "../../../intl/index.native";
import { getRootNavigationRef } from "../../main_tabs_v2/RootNavigationRef.native";
import { useCoachmark } from "../../../design/components/Coachmark/native/useCoachmark.native";
let useStyles;
const OrbsBadgeCoachmarkImg = function OrbsBadgeCoachmarkImg() {
const styles2 = useStyles();
return <View style={styles2.coachmarkImageContainer}>
<Image2 source={{
uri: Module8429
}} style={styles2.coachmarkImage} />
</View>;
};
useStyles = createStyles({
coachmarkImageContainer: {
alignItems: "center",
justifyContent: "center"
},
coachmarkImage: {
width: 80,
height: 80
},
coachmarkDescription: {
marginBottom: -10
}
});
export default function OrbsBadgeCoachmark(a0) {
const { badgeRef, ...rest } = a0;
useCoachmark(a0.badgeRef, rest);
return null;
};
export function useOrbsBadgeCoachmark({ disabled }) {
const styles = useStyles();
const memo = useMemo(() => ({
title: intl.string(t["4ivm+P"]),
description: <View style={styles.coachmarkDescription} />,
position: "bottom",
visible: !disabled,
onDismiss: () => {
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null && rootNavigationRef.isReady()) {
rootNavigationRef.setParams({
showOrbsBadgeCoachmark: void 0
});
return void 0;
}
return false;
},
renderImgComponent: () => <OrbsBadgeCoachmarkImg />
}), [disabled, styles.coachmarkDescription]);
return disabled ? null : {
props: memo
};
}
@@ -0,0 +1,39 @@
// Metro module 14627 (f14628).
import { useCallback } from "react";
import { HelpdeskArticles } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import Linking from "../../../lib/native/Linking";
import HelpdeskUtils from "../../../utils/HelpdeskUtils";
import { BottomSheet } from "../../../design/components/Sheet/native/BottomSheet.native";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { ButtonGroup } from "../../../design/components/ButtonGroup/native/ButtonGroup.native";
import { Button } from "../../../design/components/Button/native/Button.native";
import { LinkExternalSmallIcon } from "../../../design/components/Icon/native/redesign/generated/LinkExternalSmallIcon";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
const useStyles = createStyles({
container: {
paddingHorizontal: Module712.space.PX_16
},
header: {
paddingVertical: Module712.space.PX_8,
alignSelf: "center",
textAlign: "center"
}
});
export default function PersonalizationDisclaimerActionSheet() {
const styles = useStyles();
const callback = useCallback(() => {
Linking.openURL(HelpdeskUtils.getArticleURL(HelpdeskArticles.DATA_USED_FOR_RECOMMENDED));
}, []);
return <BottomSheet contentStyles={styles.container}>
<Text variant="heading-md/medium" color="mobile-text-heading-primary" accessibilityRole="header" style={styles.header}>
{intl.string(t.euks4U)}
</Text>
<ButtonGroup>
<Button size="lg" text={intl.string(t.hvVgAZ)} onPress={callback} icon={<LinkExternalSmallIcon color={Module712.colors.WHITE} />} iconPosition="end" />
<Button variant="tertiary" size="lg" text={intl.string(t.WAI6xu)} onPress={() => ActionSheetActionCreators.hideActionSheet()} />
</ButtonGroup>
</BottomSheet>;
};
@@ -0,0 +1,289 @@
// Metro module 8732 (f8733).
import * as Module19 from "react";
import { useCallback, useMemo, useRef, useState, useEffect } from "react";
import { Pressable, View } from "react-native";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { AnalyticEvents } from "../../../Constants";
import { PaymentGateways, ThemeTypes } from "../../../_bundle/Module505";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { MEDIUM_BUTTON_HEIGHT } from "../../../design/components/Button/native/ButtonConstants.native";
import { useThemeContext, setColorOpacity } from "../../../_bundle/Module3901";
import * as _shared from "../../../design/shared";
import { intl, t } from "../../../intl/index.native";
import { EyeIcon } from "../../../design/components/Icon/native/redesign/generated/EyeIcon";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { useCurrentUser } from "../hooks/useCurrentUser";
import showUserProfileActionSheet from "../../user_profile/native/showUserProfileActionSheet";
import { openProductDetailsActionSheet, PRODUCT_DETAILS_ACTION_SHEET_KEY } from "./openProductDetailsActionSheet";
import { OTPACOMOrderExperiment } from "../../billing/native/ACOMExperiments";
import { useAndroidShopOrdersEnabled } from "../../billing/experiments/AndroidShopOrdersExperiment";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { getProductSkuIds, getSelectedProduct, isDynamicProduct, isOrbsExclusiveProduct } from "../utils/CollectiblesProductUtils";
import { useTrackPdpClick } from "../hooks/useTrackPdpClick";
import { usePreviewCollectibleProduct } from "../hooks/usePreviewCollectiblesProduct";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import useTrackImpression from "../../app_analytics/useTrackImpression";
import { ImpressionTypes, ImpressionNames } from "../../../_bundle/Module503";
import { useShopProductItems } from "../hooks/useShopProductItems";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { useIsProfileFramesEarlyAccessPhase } from "../hooks/useCanPurchaseFrames";
import FramesEarlyAccessBadge from "./FramesEarlyAccessBadge";
import { DynamicBadgeTooltip } from "./DynamicBadgeTooltip";
import { IconTextBadge } from "./CollectiblesBadges";
import { DiceIcon } from "../../../design/components/Icon/native/redesign/generated/DiceIcon";
import { OrbsIcon } from "../../../design/components/Icon/native/redesign/generated/OrbsIcon";
import { isGooglePlayBillingSupported } from "../../device/BillingPlatformUtils";
import useCollectiblesExternalGatewayFacet_android from "./hooks/useCollectiblesExternalGatewayFacet.android";
import { BottomSheet } from "../../../design/components/Sheet/native/BottomSheet.native";
import { BottomSheetScrollView } from "../../../_bundle/Module5245";
import WishlistButton from "./WishlistButton";
import ProductDetailsActionSheetPreview from "./ProductDetailsActionSheetPreview";
import ProductDetailsActionSheetInfo from "./ProductDetailsActionSheetInfo";
import ProductDetailsActionSheetVariants from "./ProductDetailsActionSheetVariants";
import { Spacer } from "../../../design/void/native";
import { NativePaymentContextProvider } from "../../payments/native/NativePaymentContext";
import NativeCheckoutStoreProvider from "../../checkout/native/stores/NativeCheckoutStoreProvider";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import ProductDetailsActionSheetPurchaseSection from "./ProductDetailsActionSheetPurchaseSection";
import { isIOS } from "../../../utils/PlatformUtils";
let newValue, useStyles, ProductDetailsActionSheetInner, ProductDetailsActionSheetWithOrderCTX;
const PreviewProfileTrigger = function PreviewProfileTrigger(props) {
const { handlePreviewPress, onTrackPress } = props;
const styles = useStyles();
const theme = useThemeContext().theme;
const isThemeLight = _shared.isThemeLight(theme);
let c16749_3 = theme === ThemeTypes.MIDNIGHT;
const previewProfileButtonLight = isThemeLight ? styles.previewProfileButtonLight : styles.previewProfileButtonDark;
const previewProfileButtonLightPressed = isThemeLight ? styles.previewProfileButtonLightPressed : styles.previewProfileButtonDarkPressed;
return <Pressable style={({ pressed }) => {
const r5 = [styles.previewProfileButton, previewProfileButtonLight, c16749_3 && styles.previewProfileButtonMidnight, ,];
if (pressed) {
pressed = previewProfileButtonLightPressed;
}
r5[3] = pressed;
return r5;
}} onPress={Module19.useCallback(() => {
onTrackPress(ShopCtaEnum.FULL_PROFILE_PREVIEW_BUTTON);
handlePreviewPress();
}, [handlePreviewPress, onTrackPress])} accessibilityRole="button" accessibilityLabel={intl.string(t["3Qcx6K"])}>
<EyeIcon size="md" color={Module712.colors.INTERACTIVE_ICON_DEFAULT} />
</Pressable>;
};
ProductDetailsActionSheetInner = function ProductDetailsActionSheetInner(props) {
let r35;
let trackPdpClick, setState2, shopProductItems, c16750_7, setState3;
const { product, initialVariantIndex = 0, analyticsLocations: analyticsLocations2 = [] } = props;
const location_stack = analyticsLocations2;
const paymentGateway = props.paymentGateway;
trackPdpClick = void 0;
setState2 = void 0;
shopProductItems = void 0;
c16750_7 = void 0;
setState3 = void 0;
const enabled = OTPACOMOrderExperiment.useConfig({
location: "ProductDetailsActionSheetInner"
}).enabled;
const androidShopOrdersEnabled = useAndroidShopOrdersEnabled({
location: "ProductDetailsActionSheetInner"
});
const styles2 = useStyles();
const ref2 = useRef(null);
const ref = useRef(null);
const analyticsLocations3 = useAnalyticsLocations([...location_stack, AnalyticsLocation.COLLECTIBLES_SHOP_PROFILE_PREVIEW]).analyticsLocations;
const [state2, setState] = useState(true);
const memo = useMemo(() => getProductSkuIds(product), [product]);
const [state3, onVariantSelect] = useState(initialVariantIndex);
const selectedProduct = getSelectedProduct(product, state3);
trackPdpClick = useTrackPdpClick({
skuId: selectedProduct.skuId,
productSkuIds: memo,
analyticsLocations: analyticsLocations3
});
let state4;
[state4, setState2] = useState(void 0);
const [state5, setState5] = useState(selectedProduct.skuId);
if (selectedProduct.skuId !== state5) {
setState5(selectedProduct.skuId);
setState2(void 0);
state4 = void 0;
}
usePreviewCollectibleProduct(selectedProduct, state2, state4);
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
useTrackImpression({
type: ImpressionTypes.HALFSHEET,
name: ImpressionNames.SHOP_PRODUCT_DETAIL,
properties: {
sku_id: selectedProduct.skuId,
location_stack: analyticsLocations3,
card_id: collectiblesAnalyticsContext?.cardId,
position_in_section: collectiblesAnalyticsContext?.tilePosition,
shop_session_id: collectiblesAnalyticsContext?.sessionId,
product_sku_ids: memo
}
});
let r120 = collectiblesAnalyticsContext;
if (r120 == null) {
r120 = void 0;
}
const product2 = product;
const state = state3;
const analyticsLocations = analyticsLocations3;
const shopAnalyticsContext = r120;
const setState4 = setState;
const currentUser = useCurrentUser();
const callback = Module19.useCallback(() => {
setState4(false);
showUserProfileActionSheet({
userId: currentUser.id,
isPreviewingChanges: true,
sourceAnalyticsLocations: analyticsLocations,
onClose: () => openProductDetailsActionSheet({
product: product2,
initialVariantIndex: state,
analyticsLocations,
shopAnalyticsContext
})
});
}, [product, state, setState, currentUser.id, analyticsLocations, shopAnalyticsContext]);
shopProductItems = useShopProductItems(product);
const r139 = product.type === CollectiblesItemType.BUNDLE;
c16750_7 = r139;
let state6;
[state6, setState3] = useState(() => {
if (c16750_7) {
return shopProductItems.firstProfileEffect != null ? CollectiblesItemType.PROFILE_EFFECT : shopProductItems.firstAvatarDecoration != null ? CollectiblesItemType.AVATAR_DECORATION : shopProductItems.firstNameplate != null ? CollectiblesItemType.NAMEPLATE : void 0;
}
});
const callback2 = useCallback((a0) => {
setState2(a0);
setState3(a0.type);
}, []);
if (!r139) {
state6 = selectedProduct.type;
}
let r150 = state6 != null && (state6 === CollectiblesItemType.PROFILE_EFFECT || state6 === CollectiblesItemType.PROFILE_FRAME || state6 === CollectiblesItemType.AVATAR_DECORATION);
const callback3 = useCallback(() => {
if (product.type === CollectiblesItemType.BUNDLE) {
setState(false);
}
}, [product, setState]);
useEffect(() => {
AnalyticsUtils.track(AnalyticEvents.OPEN_MODAL, {
type: "Collectibles Shop Details Modal",
location_stack,
sku_id: product.skuId
});
}, [location_stack, product.skuId]);
const hideBadge = product.hideBadge;
const isProfileFramesEarlyAccessPhase = useIsProfileFramesEarlyAccessPhase("ProductDetailsActionSheet");
const r182 = selectedProduct.type === CollectiblesItemType.PROFILE_FRAME && isProfileFramesEarlyAccessPhase && !hideBadge;
const isThemeDark = _shared.isThemeDark(useThemeContext().theme);
const r192 = r139 ? state4 != null ? {
skuId: state4.skuId,
type: state4.type,
items: [state4]
} : selectedProduct : selectedProduct;
L39: {
if (r182) {
r35 = <FramesEarlyAccessBadge location="ProductDetailsActionSheet" disablePressable />;
} else {
const r198 = product.badgeOverride != null;
r35 = null;
if (!r198) {
if (isDynamicProduct(r192) && !hideBadge) {
r35 = <DynamicBadgeTooltip accessibilityLabel={intl.string(t["+drfVi"])}>
<IconTextBadge icon={DiceIcon} label={intl.string(t["+drfVi"])} isDark={isThemeDark} />
</DynamicBadgeTooltip>;
break L39;
}
r35 = isOrbsExclusiveProduct(selectedProduct) && !hideBadge ? <IconTextBadge icon={OrbsIcon} label={intl.string(t["0TmQRG"])} isDark={isThemeDark} /> : null;
}
}
}
const orderRequired = paymentGateway === PaymentGateways.APPLE_ADVANCED_COMMERCE && enabled || paymentGateway === PaymentGateways.GOOGLE && isGooglePlayBillingSupported() && androidShopOrdersEnabled;
const collectiblesExternalGatewayFacet_android = useCollectiblesExternalGatewayFacet_android(selectedProduct);
if (r150) {
r150 = <PreviewProfileTrigger handlePreviewPress={callback} onTrackPress={trackPdpClick} />;
}
return <AnalyticsLocationProvider value={analyticsLocations}>
<BottomSheet scrollable startExpanded onExpand={() => {
const current = ref.current;
return current == null ? void 0 : current.scrollToEnd({
animated: true
});
}} onDismiss={() => trackPdpClick(ShopCtaEnum.CLOSE_DETAIL)} ref={ref2}>
<BottomSheetScrollView scrollsToTop={false} style={styles2.container} ref={ref}>
<View style={styles2.actionButtons}>
{r150}
<WishlistButton selectedProduct={selectedProduct} size="md" onTrackPress={trackPdpClick} />
</View>
{r35 != null && <View style={styles2.badgeWrapper}>{r35}</View>}
<ProductDetailsActionSheetPreview product={selectedProduct} handlePreviewPress={callback} onTrackPress={trackPdpClick} onBundleActiveItemTypeChange={setState3} onBundleActiveItemChange={callback2} />
<ProductDetailsActionSheetInfo product={selectedProduct} onTrackPress={trackPdpClick} />
<ProductDetailsActionSheetVariants product={product} selectedVariantIndex={state} onVariantSelect={onVariantSelect} />
<Spacer size={Module712.space.PX_16} />
</BottomSheetScrollView>
<NativePaymentContextProvider skuIDs={[]} activeSubscription={null}>
<NativeCheckoutStoreProvider key={selectedProduct.skuId} paymentGateway={paymentGateway} orderRequired={orderRequired} skuIds={[selectedProduct.skuId]} isGift={false} activeSubscription={null} initialExternalGatewayFacet={collectiblesExternalGatewayFacet_android} onOrderRetryCancellation={() => ActionSheetActionCreators.hideActionSheet(PRODUCT_DETAILS_ACTION_SHEET_KEY)}>
<ProductDetailsActionSheetPurchaseSection onBuy={callback3} product={selectedProduct} analyticsLocations={analyticsLocations} onTrackPress={trackPdpClick} />
</NativeCheckoutStoreProvider>
</NativePaymentContextProvider>
</BottomSheet>
</AnalyticsLocationProvider>;
};
ProductDetailsActionSheetWithOrderCTX = function ProductDetailsActionSheetWithOrderCTX(props) {
return <ProductDetailsActionSheetInner {...props} paymentGateway={isIOS() ? PaymentGateways.APPLE_ADVANCED_COMMERCE : PaymentGateways.GOOGLE} />;
};
newValue = {};
useStyles = createStyles({
container: {
position: "relative",
flex: 1
},
actionButtons: {
position: "absolute",
top: 0,
right: Module712.space.PX_16,
zIndex: 2,
flexDirection: "row",
gap: Module712.space.PX_8
},
previewProfileButton: {
width: MEDIUM_BUTTON_HEIGHT,
height: MEDIUM_BUTTON_HEIGHT,
alignItems: "center",
justifyContent: "center",
borderRadius: Module712.radii.round,
borderWidth: 1,
borderColor: Module712.colors.CONTROL_SECONDARY_BORDER_DEFAULT
},
previewProfileButtonLight: {
backgroundColor: setColorOpacity("white", 0.72)
},
previewProfileButtonLightPressed: {
backgroundColor: setColorOpacity("white", 0.62)
},
previewProfileButtonDark: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT
},
previewProfileButtonDarkPressed: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_ACTIVE
},
previewProfileButtonMidnight: {
borderColor: Module712.colors.BORDER_STRONG
},
badgeWrapper: {
position: "absolute",
top: 0,
left: Module712.space.PX_16,
zIndex: 2
}
});
export default function ProductDetailsActionSheet(props) {
const { shopAnalyticsContext: shopAnalyticsContext2 = newValue, ...rest } = props;
return <CollectiblesAnalyticsProvider newValue={shopAnalyticsContext2}>
<ProductDetailsActionSheetWithOrderCTX {...rest} />
</CollectiblesAnalyticsProvider>;
};
@@ -0,0 +1,71 @@
// Metro module 8757 (f8758).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useProductDescription } from "../hooks/useProductDescription";
import { Text } from "../../../design/components/Text/native/Text";
import * as _CollectiblesUtils from "../CollectiblesUtils";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import { intl, t } from "../../../intl/index.native";
import InlinePriceTag from "./InlinePriceTag";
import { useCollectiblesMobileFlexibleBundlesExperiment } from "../experiments/CollectiblesMobileFlexibleBundlesExperiment";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
let useStyles, ProductPurchaseStatus, BundleProductDetailsActionSheetInfo;
const ProductNameAndDescription = function ProductNameAndDescription(props) {
const product = props.product;
const styles = useStyles();
return <View style={styles.description}>
<Text variant="heading-xl/bold" color="mobile-text-heading-primary" style={styles.title} accessibilityRole="header">{product.name}</Text>
<Text variant="text-md/medium" color="text-default">
{useProductDescription(product)}
</Text>
</View>;
};
ProductPurchaseStatus = function ProductPurchaseStatus(props) {
const { product, onTrackPress } = props;
const isPremiumCollectiblesProduct = _CollectiblesUtils.isPremiumCollectiblesProduct(product);
const productPurchaseState = useProductPurchaseState(product);
const { isPurchased, isPartiallyOwnedBundle } = productPurchaseState;
return <View>
{isPurchased ? <Text variant="text-md/semibold" color="interactive-text-active">
{intl.string(t["6cfuDj"])}
</Text> : isPartiallyOwnedBundle ? <Text variant="text-md/semibold" color="interactive-text-active">
{intl.string(t.BEjTij)}
</Text> : isPremiumCollectiblesProduct ? !isPremiumCollectiblesProduct : <InlinePriceTag product={product} onTrackPress={onTrackPress} />}
</View>;
};
BundleProductDetailsActionSheetInfo = function BundleProductDetailsActionSheetInfo(props) {
const { product, onTrackPress } = props;
const styles = useStyles();
const enabled = useCollectiblesMobileFlexibleBundlesExperiment("BundleProductDetailsActionSheetInfo").enabled;
return <View style={[styles.body, enabled && styles.bundleBody]}>
{enabled ? !enabled : <ProductNameAndDescription product={product} />}
<ProductPurchaseStatus product={product} onTrackPress={onTrackPress} />
</View>;
};
useStyles = createStyles({
title: {
marginBottom: 2
},
body: {
marginTop: Module712.space.PX_24,
marginHorizontal: Module712.space.PX_16,
flexDirection: "column",
gap: 20
},
bundleBody: {
marginTop: 0
},
description: {
flexDirection: "column",
gap: 6
}
});
export default function ProductDetailsActionSheetInfo(props) {
const { product, onTrackPress } = props;
const styles = useStyles();
return product.type === CollectiblesItemType.BUNDLE ? <BundleProductDetailsActionSheetInfo product={product} onTrackPress={onTrackPress} /> : <View style={styles.body}>
<ProductNameAndDescription product={product} />
<ProductPurchaseStatus product={product} onTrackPress={onTrackPress} />
</View>;
};
@@ -0,0 +1,132 @@
// Metro module 8741 (f8742).
import { useCallback, useEffect, useMemo, useState } from "react";
import { View } from "react-native";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import { useCollectiblesMobileFlexibleBundlesExperiment } from "../experiments/CollectiblesMobileFlexibleBundlesExperiment";
import BundleProductDetailsActionSheetPreview from "./BundleProductDetailsActionSheetPreview";
import { useShopProductItems } from "../hooks/useShopProductItems";
import { intl, t } from "../../../intl/index.native";
import { ProfileEffectPreview, AvatarDecorationPreview, NameplatePreview, IndividualProductPreview } from "./IndividualProductPreview";
import { useSegmentedControlState } from "../../../design/components/SegmentedControl/native/SegmentedControlState.native";
import { SegmentedControlPages } from "../../../design/components/SegmentedControl/native/SegmentedControlPages.native";
import { SegmentedControl } from "../../../design/components/SegmentedControl/native/SegmentedControl.native";
let useStyles, c5702_13, BundlePreview;
const BundleProductPreview = function BundleProductPreview(props) {
const { product: product2, width: width2, handlePreviewPress: handlePreviewPress2, onTrackPress: onTrackPress2, onActiveItemChange: onActiveItemChange2, onActiveItemTypeChange: onActiveItemTypeChange2 } = props;
const styles = useStyles();
return useCollectiblesMobileFlexibleBundlesExperiment("ProductDetailsActionSheetPreview").enabled ? <BundleProductDetailsActionSheetPreview product={product2} width={width2} handlePreviewPress={handlePreviewPress2} onTrackPress={onTrackPress2} onActiveItemChange={onActiveItemChange2} /> : <View style={styles.previewDivider}>
<BundlePreview product={product2} width={width2} handlePreviewPress={handlePreviewPress2} onTrackPress={onTrackPress2} onActiveItemChange={onActiveItemChange2} onActiveItemTypeChange={onActiveItemTypeChange2} />
</View>;
};
BundlePreview = function BundlePreview(props) {
let memo2;
const { product, width, handlePreviewPress, onTrackPress, onActiveItemChange, onActiveItemTypeChange } = props;
memo2 = void 0;
const shopProductItems = useShopProductItems(product);
const [state, setState] = useState(0);
const memo = useMemo(() => [shopProductItems.firstProfileEffect != null ? {
label: intl.string(t["s+YSgo"]),
id: "profile",
page: <ProfileEffectPreview profileEffect={shopProductItems.firstProfileEffect} profileEffectRestartKey={state} width={width} handlePreviewPress={handlePreviewPress} onTrackPress={onTrackPress} />
} : null, shopProductItems.firstAvatarDecoration != null ? {
label: intl.string(t.aVCcr8),
id: "decoration",
page: <AvatarDecorationPreview product={product} handlePreviewPress={handlePreviewPress} onTrackPress={onTrackPress} />
} : null, shopProductItems.firstNameplate != null ? {
label: intl.string(t.HNnSVZ),
id: "nameplate",
page: <NameplatePreview product={product} />
} : null].filter((item) => item != null), [product, width, handlePreviewPress, shopProductItems, onTrackPress, state]);
memo2 = useMemo(() => ({
profile: shopProductItems.firstProfileEffect,
decoration: shopProductItems.firstAvatarDecoration,
nameplate: shopProductItems.firstNameplate
}), [shopProductItems]);
useEffect(() => {
let firstProfileEffect = shopProductItems.firstProfileEffect;
if (firstProfileEffect == null) {
firstProfileEffect = shopProductItems.firstAvatarDecoration;
}
if (firstProfileEffect == null) {
firstProfileEffect = shopProductItems.firstNameplate;
}
if (firstProfileEffect != null && onActiveItemChange != null) {
onActiveItemChange(firstProfileEffect);
}
}, [shopProductItems, onActiveItemChange]);
const segmentedControlState = useSegmentedControlState({
items: memo,
pageWidth: width,
defaultIndex: 0,
onPageChange: (a0) => {
const id = memo[a0]?.id;
if (id != null) {
const r6 = c5702_13[id];
if (r6 != null && onActiveItemTypeChange != null) {
onActiveItemTypeChange(r6);
}
const r14 = memo2[id];
if (r14 != null && onActiveItemChange != null) {
onActiveItemChange(r14);
}
}
if (id === "profile") {
setState((prevState) => prevState + 1);
}
},
onSetActiveIndex: (a0) => {
const id = memo[a0]?.id;
if (id === "profile") {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.BUNDLE_VIEW_PROFILE_EFFECT);
}
} else if (id === "decoration") {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.BUNDLE_VIEW_AVATAR_DECORATION);
}
} else if (id === "nameplate" && onTrackPress != null) {
onTrackPress(ShopCtaEnum.BUNDLE_VIEW_NAMEPLATE);
}
}
});
return <View>
<SegmentedControlPages state={segmentedControlState} />
<View style={{
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_12
}}>
<SegmentedControl state={segmentedControlState} variant="default" />
</View>
</View>;
};
useStyles = createStyles({
previewContainer: {
flex: 1
},
previewDivider: {
borderBottomColor: Module712.colors.BACKGROUND_MOD_SUBTLE,
borderBottomWidth: 1,
paddingBottom: Module712.space.PX_16,
flex: 1
}
});
c5702_13 = {
profile: CollectiblesItemType.PROFILE_EFFECT,
decoration: CollectiblesItemType.AVATAR_DECORATION,
nameplate: CollectiblesItemType.NAMEPLATE
};
export default function ProductDetailsActionSheetPreview(props) {
const { product: product2, handlePreviewPress: handlePreviewPress2, onTrackPress: onTrackPress2, onBundleActiveItemTypeChange, onBundleActiveItemChange } = props;
const styles = useStyles();
const [width2, setState2] = useState(0);
return <View style={styles.previewContainer} onLayout={useCallback((a0) => {
setState2(a0.nativeEvent.layout.width);
}, [])}>
{product2.type === CollectiblesItemType.BUNDLE ? <BundleProductPreview product={product2} width={width2} handlePreviewPress={handlePreviewPress2} onTrackPress={onTrackPress2} onActiveItemChange={onBundleActiveItemChange} onActiveItemTypeChange={onBundleActiveItemTypeChange} /> : <View style={styles.previewDivider}>
<IndividualProductPreview product={product2} width={width2} handlePreviewPress={handlePreviewPress2} onTrackPress={onTrackPress2} />
</View>}
</View>;
};
@@ -0,0 +1,396 @@
// Metro module 8766 (f8767).
import { useCallback } from "react";
import { View } from "react-native";
import { useNativeCheckoutStore } from "../../checkout/native/NativeCheckoutStore";
import CollectiblesPurchaseStore from "../CollectiblesPurchaseStore";
import { EXTERNAL_PRODUCT_SKU_IDS, ShopCtaEnum } from "../CollectiblesShopConstants";
import { HelpdeskArticles, MarketingURLs, UserSettingsSections } from "../../../Constants";
import { RootNavigatorScreen } from "../../main_tabs_v2/native/MainTabsConstants";
import { PremiumTypes, SubscriptionIntervalTypes } from "../../premium/PremiumConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import { GiftIcon } from "../../../design/components/Icon/native/redesign/generated/GiftIcon";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { PRODUCT_DETAILS_ACTION_SHEET_KEY } from "./openProductDetailsActionSheet";
import { openShopGiftModal } from "./openGiftModal";
import { intl, t } from "../../../intl/index.native";
import { useVirtualCurrencyData } from "./hooks/useVirtualCurrencyData";
import { useProductDisableState } from "../hooks/useProductDisableState";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { fetchCollectiblesPurchases } from "../CollectiblesActionCreators";
import { FractionalPremiumSKUsSets } from "../../../_bundle/Module679";
import ProductPurchaseSuccessActionCreators from "./ProductPurchaseSuccessActionCreators";
import { OrbsIcon } from "../../../design/components/Icon/native/redesign/generated/OrbsIcon";
import { Text } from "../../../design/components/Text/native/Text";
import { BaseTextButton } from "../../../design/components/Button/native/BaseTextButton.native";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import useTheme from "../../../hooks/useTheme";
import * as _shared from "../../../design/shared";
import { useToken } from "../../../design/tokens/native/useToken";
import { useCurrentUser } from "../hooks/useCurrentUser";
import { useStateFromStoresArray } from "../../../_bundle/Module589";
import { useIsPremiumSubscriber } from "../../premium/useIsPremiumSubscriber";
import PremiumUtils from "../../../utils/PremiumUtils";
import * as _CollectiblesUtils from "../CollectiblesUtils";
import * as _CollectiblesProductUtils from "../utils/CollectiblesProductUtils";
import { useFetchVirtualCurrencyBalance } from "../../virtual_currency/hooks/index";
import { useHandleUseNow } from "./useHandleUseNow";
import useHandleBuyNow from "./useHandleBuyNow";
import { useHandleClaim } from "./useHandleClaim";
import useShouldShowPremiumProfileFrameCTA from "../hooks/useShouldShowPremiumProfileFrameCTA";
import { useIsEligibleForBogoOffer } from "../../premium/native/hooks/useIsEligibleForBogoOffer.android";
import { useCanGiftProduct } from "../hooks/useCanGiftProduct";
import useSafeAreaInsets_native from "../../safe_area/useSafeAreaInsets.native";
import { isAndroid } from "../../../_bundle/Module501";
import Module4611 from "../../../_bundle/Module4611";
import Module8531, { Defs, RadialGradient, Stop, Rect } from "../../../_bundle/Module8531";
import { Button } from "../../../design/components/Button/native/Button.native";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import HelpdeskUtils from "../../../utils/HelpdeskUtils";
import { UnlockWithNitroButton } from "./UnlockWithNitroButton";
let modalKey, c5725_20, useStyles, VCButton, PurchaseDisclaimer;
const GiftButton = function GiftButton(props) {
const { product, analyticsLocations, variant = "primary", onTrackPress } = props;
return <IconButton size="lg" variant={variant} icon={<GiftIcon size="md" color={variant === "primary" ? Module712.colors.WHITE : Module712.colors.TEXT_STRONG} />} onPress={() => {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.SEND_AS_GIFT);
}
ActionSheetActionCreators.hideActionSheet(PRODUCT_DETAILS_ACTION_SHEET_KEY);
openShopGiftModal({
skuId: product.skuId,
analyticsLocations
});
}} accessibilityLabel={intl.string(t.PEjaCx)} />;
};
VCButton = function VCButton(props) {
let INTERACTIVE_TEXT_ACTIVE, color;
const { balance, product: product2, hasShopDiscount = false, onTrackPress: onTrackPress2 } = props;
INTERACTIVE_TEXT_ACTIVE = void 0;
color = void 0;
const styles = useStyles();
const virtualCurrencyData = useVirtualCurrencyData(product2, hasShopDiscount);
const { price, canAfford } = virtualCurrencyData;
let isDisabled = useProductDisableState(product2.skuId).isDisabled;
const isPartiallyOwnedBundle = useProductPurchaseState(product2).isPartiallyOwnedBundle;
if (!isDisabled) {
isDisabled = !canAfford;
}
if (!isDisabled) {
isDisabled = isPartiallyOwnedBundle;
}
const navigation = useNavigation();
const analyticsLocations2 = useAnalyticsLocations().analyticsLocations;
const callback = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
ModalActionCreators.pushLazy(import("../../virtual_currency/checkout/native/OrbCheckoutModal"), {
skuId: product2.skuId,
analyticsLocations: analyticsLocations2,
onCheckoutSuccess: ({ entitlements }) => {
fetchCollectiblesPurchases();
ModalActionCreators.popWithKey(c5725_20);
if (product2.skuId === EXTERNAL_PRODUCT_SKU_IDS.ORB_PROFILE_BADGE) {
ModalActionCreators.pushLazy(import("./OrbBadgeCollectedModal"), {
modalKey,
onPressViewBadge: () => navigation.navigate(RootNavigatorScreen.YOU, {
showOrbsBadgeCoachmark: true
}),
orbBalancePriorToPurchase: balance
}, modalKey);
} else if (FractionalPremiumSKUsSets.ALL.has(product2.skuId)) {
const r43 = import("./FractionalNitroCollectedActionSheet");
let consumed = entitlements[0]?.consumed;
if (consumed == null) {
consumed = false;
}
ActionSheetActionCreators.openLazy(r43, "FractionalNitroCollectedActionSheet", {
skuId: product2.skuId,
consumed,
onPressExplorePerks: () => {
navigation.navigate(UserSettingsSections.PREMIUM);
ActionSheetActionCreators.hideActionSheet();
},
onPressViewCredits: () => {
navigation.navigate(UserSettingsSections.PREMIUM_MANAGE_PLAN);
ActionSheetActionCreators.hideActionSheet();
}
});
} else {
ProductPurchaseSuccessActionCreators.open({
product: product2,
useCategoryImage: true,
showOrbBalancePill: true,
orbBalancePriorToPurchase: balance
});
}
}
}, c5725_20);
}, [navigation, product2, balance, analyticsLocations2]);
if (price == null) {
return null;
}
INTERACTIVE_TEXT_ACTIVE = isDisabled ? Module712.colors.INTERACTIVE_TEXT_ACTIVE : Module712.colors.WHITE;
color = isDisabled ? "interactive-text-active" : "text-overlay-light";
const r60 = intl.format(t.JC15qj, {
orbPrice: price.amount,
orbIconHook: () => <OrbsIcon key="orbs-icon" size="sm" color={INTERACTIVE_TEXT_ACTIVE} />
});
const r65 = Array.isArray(r60) ? r60 : [r60];
return <View style={styles.buttonContainer}>
<BaseTextButton loading={false} textElement={<View style={styles.orbsButtonLabel} accessibilityLabel={intl.formatToPlainString(t.yi41qQ, {
orbPrice: price.amount
})}>
{r65.map((item, index) => typeof item !== "string" ? typeof item === "number" ? <Text key={index} style={styles.orbsButtonText} variant="text-md/semibold" color={color}>
{item}
</Text> : item : <Text key={index} style={styles.orbsButtonText} variant="text-md/semibold" color={color}>
{item}
</Text>)}
</View>} onPress={() => {
if (onTrackPress2 != null) {
onTrackPress2(ShopCtaEnum.BUY_WITH_ORBS);
}
callback();
}} disabled={isDisabled} size="lg" variant={isDisabled ? "secondary" : "primary"} grow />
</View>;
};
PurchaseDisclaimer = function PurchaseDisclaimer(props) {
const { product: product4, buyButtonLabel } = props;
return <Text style={useStyles().disclaimer} variant="text-xxs/normal" color="interactive-text-active">
{product4.type !== CollectiblesItemType.EXTERNAL_SKU && intl.format(t.iIglwJ, {
buyButtonLabel,
paidServiceTermURL: MarketingURLs.PAID_TERMS
})}
</Text>;
};
modalKey = "ORB_BADGE_COLLECTED_MODAL";
c5725_20 = "ORB_CHECKOUT_MODAL";
useStyles = createStyles({
container: {
backgroundColor: Module712.colors.MOBILE_ACTIONSHEET_BACKGROUND,
paddingHorizontal: Module712.space.PX_16,
paddingTop: Module712.space.PX_8
},
containerFramesEA: {
borderWidth: 1,
borderStyle: "solid",
borderColor: Module712.colors.BORDER_MUTED
},
gradientOverlay: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0
},
purchaseSection: {
gap: Module712.space.PX_12
},
disclaimer: {
opacity: 0.75
},
buttonContainer: {
flexDirection: "row",
gap: Module712.space.PX_12
},
framesEAContainer: {
flexDirection: "column",
gap: Module712.space.PX_8
},
orbsButtonLabel: {
flexDirection: "row",
alignItems: "center"
},
orbsButtonText: {
flexShrink: 1
}
});
export default function ProductDetailsActionSheetPurchaseSection(props) {
let r198, children;
let handleUseNow, handleEditProfile, handleBuyNow, handleClaim;
const { product: product3, analyticsLocations: analyticsLocations3, onBuy, onTrackPress: onTrackPress3 } = props;
handleUseNow = void 0;
handleEditProfile = void 0;
handleBuyNow = void 0;
handleClaim = void 0;
const styles2 = useStyles();
const isThemeDark = _shared.isThemeDark(useTheme());
const token = useToken(Module712.colors.MOBILE_ACTIONSHEET_BACKGROUND);
const currentUser = useCurrentUser();
const productPurchaseState = useProductPurchaseState(product3);
const { isPurchased, isPartiallyOwnedBundle } = productPurchaseState;
const [loading] = useStateFromStoresArray([CollectiblesPurchaseStore], () => [CollectiblesPurchaseStore.isClaiming === product3.skuId], [product3]);
const isPremiumSubscriber = useIsPremiumSubscriber(PremiumTypes.TIER_2);
const canUseShopDiscounts = PremiumUtils.canUseShopDiscounts(currentUser);
const isPremiumCollectiblesProduct = _CollectiblesUtils.isPremiumCollectiblesProduct(product3);
const isFreeCollectiblesProduct = _CollectiblesUtils.isFreeCollectiblesProduct(product3);
const isOrbsExclusiveProduct = _CollectiblesProductUtils.isOrbsExclusiveProduct(product3);
const balance2 = useFetchVirtualCurrencyBalance().balance;
const canAfford = useVirtualCurrencyData(product3, canUseShopDiscounts).canAfford;
const handleUseNow2 = useHandleUseNow({
product: product3,
analyticsLocations: analyticsLocations3
});
handleUseNow = handleUseNow2.handleUseNow;
const { isApplying, canUseNow } = handleUseNow2;
handleEditProfile = handleUseNow2.handleEditProfile;
const handleBuyNow2 = useHandleBuyNow({
product: product3,
analyticsLocations: analyticsLocations3,
onBuy,
orderId: useNativeCheckoutStore((a0) => a0.orderRecord)?.id
});
handleBuyNow = handleBuyNow2.handleBuyNow;
const isBuying = handleBuyNow2.isBuying;
handleClaim = useHandleClaim({
product: product3
}).handleClaim;
const shouldShowPremiumProfileFrameCTA = useShouldShowPremiumProfileFrameCTA({
location: "ProductDetailsActionSheetPurchaseSection",
product: product3
});
let r27 = shouldShowPremiumProfileFrameCTA && !isPurchased;
const r33 = useIsEligibleForBogoOffer() ? SubscriptionIntervalTypes.MONTH : SubscriptionIntervalTypes.YEAR;
let r12 = useCanGiftProduct(product3);
let bottom = useSafeAreaInsets_native().bottom;
const style = [styles2.container, r27 ? styles2.containerFramesEA : r27, ,];
if (bottom == null) {
bottom = Module712.space.PX_16;
}
style[2] = {
paddingBottom: bottom
};
const props2 = {
style,
children: null
};
if (r27) {
r27 = !isAndroid();
}
if (r27) {
r27 = <>
<Module4611 colors={["rgba(160, 86, 242, 0.45)", "rgba(22, 26, 138, 0.45)"]} locations={[0.0854, 0.7847]} start={{
x: 0,
y: 0
}} end={{
x: 1,
y: 1
}} style={[styles2.gradientOverlay, isThemeDark ? !isThemeDark : {
opacity: 0.4
}]} pointerEvents="none" />
<Module8531 style={styles2.gradientOverlay} preserveAspectRatio="none" viewBox="0 0 100 100" pointerEvents="none">
<Defs>
<RadialGradient id="frameEAVignette" cx="50%" cy="100%" rx="100%" ry="100%" fx="50%" fy="100%">
<Stop offset="60%" stopColor={token} stopOpacity={1} />
<Stop offset="100%" stopColor={token} stopOpacity={0} />
</RadialGradient>
</Defs>
<Rect x="0" y="0" width="100" height="100" fill="url(#frameEAVignette)" />
</Module8531>
</>;
}
L69: {
children = [r27, ,];
if (isPurchased) {
let r407 = product3.type !== CollectiblesItemType.EXTERNAL_SKU;
if (r407) {
const r437 = [<Button {...canUseNow ? {
loading: isApplying,
text: intl.string(t.MAS7uK),
onPress: () => {
if (onTrackPress3 != null) {
onTrackPress3(ShopCtaEnum.USE_NOW);
}
handleUseNow();
},
size: "lg",
grow: true
} : {
text: intl.string(t["2p2aYz"]),
onPress: () => {
if (onTrackPress3 != null) {
onTrackPress3(ShopCtaEnum.EDIT_PROFILE);
}
handleEditProfile();
},
size: "lg",
grow: true
}} />, ,];
if (r12) {
r12 = <GiftButton product={product3} analyticsLocations={analyticsLocations3} onTrackPress={onTrackPress3} />;
}
r437[1] = r12;
r407 = <View style={styles2.buttonContainer}>{r437}</View>;
}
r198 = r407;
} else if (shouldShowPremiumProfileFrameCTA) {
const r326 = isAndroid() ? t.COObWR : t["7wpqfj"];
r198 = <AnalyticsLocationProvider value={[...analyticsLocations3, AnalyticsLocation.PROFILE_FRAMES_EA_MARKETING]}>
<View style={styles2.framesEAContainer}>
<Text variant="text-xs/semibold" color="text-strong">
{intl.format(t["3cglst"], {
articleURL: HelpdeskUtils.getArticleURL(HelpdeskArticles.SHOP_FRAMES_EARLY_ACCESS)
})}
</Text>
<UnlockWithNitroButton onTrackPress={onTrackPress3} text={intl.string(t["9wfL34"])} />
<Text variant="text-xxs/normal">
{intl.format(r326, {
paidURL: MarketingURLs.PAID_TERMS,
interval: PremiumUtils.getIntervalStringAsNoun(r33),
ctaText: intl.string(t["9wfL34"])
})}
</Text>
</View>
</AnalyticsLocationProvider>;
} else {
if (isPremiumCollectiblesProduct && !isPremiumSubscriber && !isFreeCollectiblesProduct) {
r198 = <UnlockWithNitroButton onTrackPress={onTrackPress3} />;
break L69;
}
L56: {
if (!isFreeCollectiblesProduct) {
if (isPremiumCollectiblesProduct && isPremiumSubscriber) {
break L56;
}
const text = product3.type === CollectiblesItemType.BUNDLE ? intl.string(t.V1AWw0) : product3.type === CollectiblesItemType.PROFILE_EFFECT ? intl.string(t.kAeDcK) : product3.type === CollectiblesItemType.NAMEPLATE ? intl.string(t.H3vhqU) : product3.type === CollectiblesItemType.AVATAR_DECORATION ? intl.string(t.AQ0Veg) : product3.type === CollectiblesItemType.PROFILE_FRAME ? intl.string(t.BlSW1e) : intl.string(t.AQ0Veg);
const r279 = [canAfford && <VCButton product={product3} hasShopDiscount={canUseShopDiscounts} balance={balance2} onTrackPress={onTrackPress3} />, , , ,];
let r280 = !isOrbsExclusiveProduct;
if (!isOrbsExclusiveProduct) {
let variant = "primary";
const r292 = [<Button loading={isBuying} text={text} onPress={() => {
if (onTrackPress3 != null) {
onTrackPress3(ShopCtaEnum.BUY_WITH_FIAT);
}
handleBuyNow();
}} disabled={isPartiallyOwnedBundle} variant={canAfford ? "secondary" : "primary"} size="lg" grow />, ,];
let r293 = r12;
if (r12) {
if (canAfford) {
variant = "secondary";
}
r293 = <GiftButton product={product3} analyticsLocations={analyticsLocations3} variant={variant} onTrackPress={onTrackPress3} />;
}
r292[1] = r293;
r280 = <View style={styles2.buttonContainer}>{r292}</View>;
}
r279[1] = r280;
r279[2] = canAfford ? !canAfford : <VCButton product={product3} hasShopDiscount={canUseShopDiscounts} balance={balance2} onTrackPress={onTrackPress3} />;
r279[3] = isOrbsExclusiveProduct ? !isOrbsExclusiveProduct : <PurchaseDisclaimer product={product3} buyButtonLabel={text} />;
r198 = <View style={styles2.purchaseSection}>{r279}</View>;
break L69;
}
}
r198 = <Button text={intl.string(t.zp6caO)} loading={loading} onPress={() => {
if (onTrackPress3 != null) {
onTrackPress3(ShopCtaEnum.ADD_TO_COLLECTION);
}
handleClaim();
}} size="lg" grow />;
}
}
children[1] = r198;
props2.children = children;
return <View {...props2} />;
};
@@ -0,0 +1,97 @@
// Metro module 8763 (f8764).
import { View } from "react-native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../intl/index.native";
import useIsVariantColorLight from "../hooks/useIsVariantColorLight";
import { CheckmarkSmallIcon } from "../../../design/components/Icon/native/redesign/generated/CheckmarkSmallIcon";
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
import { Text } from "../../../design/components/Text/native/Text";
let useStyles, useStyles2, VariantCheckmark;
const VariantOption = function VariantOption(props) {
const { variant, isSelected, onSelect: onSelect2 } = props;
const styles2 = useStyles2(isSelected);
let isPurchased = useProductPurchaseState(variant).isPurchased;
const accessibilityLabel = isPurchased ? intl.formatToPlainString(t["SfQB4+"], {
variantLabel: variant.name
}) : variant.name;
if (isPurchased) {
isPurchased = <VariantCheckmark variant={variant} />;
}
return <PressableOpacity accessibilityRole="button" accessibilityLabel={accessibilityLabel} accessibilityState={{
selected: isSelected
}} onPress={onSelect2} style={styles2.variantOption}>
<View style={[styles2.variantOptionInner, {
backgroundColor: variant.variantValue
}]}>{isPurchased}</View>
</PressableOpacity>;
};
VariantCheckmark = function VariantCheckmark(props) {
return <CheckmarkSmallIcon color={useIsVariantColorLight(props.variant) ? Module712.colors.BLACK : Module712.colors.WHITE} size="md" />;
};
useStyles = createStyles({
container: {
flex: 1,
display: "flex",
flexDirection: "column",
marginTop: Module712.space.PX_16,
marginHorizontal: Module712.space.PX_16,
gap: Module712.space.PX_8
},
headerRow: {
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_12
},
variantsContainer: {
display: "flex",
flexWrap: "wrap",
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_12
},
text: {
flexGrow: 1,
flexShrink: 1,
minWidth: 28
}
});
useStyles2 = createStyles((a0) => ({
variantOption: {
width: 28,
height: 28,
borderRadius: Module712.radii.round,
justifyContent: "center",
alignItems: "center",
borderWidth: 1,
borderColor: a0 ? Module712.colors.BUTTON_OUTLINE_PRIMARY_TEXT : Module712.colors.BORDER_STRONG
},
variantOptionInner: {
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center",
borderRadius: Module712.radii.round,
borderWidth: 1,
borderColor: Module712.colors.BACKGROUND_BASE_LOW
}
}));
export default function ProductDetailsActionSheetVariants(props) {
const { product, selectedVariantIndex, onVariantSelect } = props;
const styles = useStyles();
return getIsVariantProduct(product) ? <View style={styles.container}>
<View style={styles.headerRow}>
<Text variant="text-md/bold" color="mobile-text-heading-primary">
{intl.string(t.wbgaj6)}
</Text>
{product.variants.length > selectedVariantIndex && <Text variant="text-md/medium" color="text-default" lineClamp={1} style={styles.text}>{product.variants[selectedVariantIndex].variantLabel}</Text>}
</View>
<View style={styles.variantsContainer}>
{product.variants.map((a0, index) => {
return <VariantOption key={a0.variantValue} variant={a0} isSelected={selectedVariantIndex === index} onSelect={() => onVariantSelect(index)} />;
})}
</View>
</View> : null;
};
@@ -0,0 +1,13 @@
// Metro module 9790 (f9791).
import ModalActionCreators from "../../../actions/ModalActionCreators";
let c6494_4 = "ShopProductPurchaseSuccessModal";
const r17 = {
open: (a0) => {
ModalActionCreators.pushLazy(async () => (await import("./ProductPurchaseSuccessModal")).default, a0, c6494_4);
},
close: () => {
ModalActionCreators.popWithKey(c6494_4);
}
};
export default r17;
export const MODAL_KEY = "ShopProductPurchaseSuccessModal";
@@ -0,0 +1,365 @@
// Metro module 9791 (f9792).
import _toArray from "../../../_bundle/_toArray";
import { useCallback, useMemo, useRef, useEffect, useState } from "react";
import { Image as Image2, ScrollView, View } from "react-native";
import AccessibilityStore from "../../a11y/AccessibilityStore";
import { Orientation, VerticalGradient } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import ProductPurchaseSuccessActionCreators from "./ProductPurchaseSuccessActionCreators";
import { HeaderBackButton } from "../../../_bundle/Module5150";
import { XSmallIcon } from "../../../design/components/Icon/native/redesign/generated/XSmallIcon";
import { intl, t } from "../../../intl/index.native";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, withDelay, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withSpring } from "../../../design/animation/reanimated/spring/spring";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
import { triggerHapticFeedback, HapticFeedbackTypes } from "../../haptics/HapticUtils.native";
import tinycolor from "../../../_bundle/tinycolor";
import useCollectiblesShopStyles_native from "../useCollectiblesShopStyles.native";
import { useToken } from "../../../design/tokens/native/useToken";
import Module4611 from "../../../_bundle/Module4611";
import { useCurrentUser } from "../hooks/useCurrentUser";
import { useAvatarDecorationPreviewSizes } from "./useAvatarDecorationPreviewSizes";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useFetchCollectiblesProductCategory } from "../hooks/useFetchCollectiblesProductCategory";
import { useHandleUseNow } from "./useHandleUseNow";
import { useFetchVirtualCurrencyBalance } from "../../virtual_currency/hooks/useFetchVirtualCurrencyBalance";
import { lockOrientation, restoreDefaultOrientation } from "../../device/native/DeviceOrientation";
import { usePreviewCollectibleProduct } from "../hooks/usePreviewCollectiblesProduct";
import { useShopProductItems } from "../hooks/useShopProductItems";
import { SafeAreaPaddingView } from "../../../components_native/common/SafeAreaView";
import { BalanceWidgetPill } from "../../virtual_currency/native/index";
import BundleSampleV2 from "./BundleSampleV2";
import AvatarDecorationSampleV2 from "./AvatarDecorationSampleV2";
import ProfileEffectUserPreview from "../profile_effects/native/previews/ProfileEffectUserPreview";
import ProfileFrameUserPreview from "../profile_frames/native/previews/ProfileFrameUserPreview";
import { NameplatePreview } from "../nameplates/native/NameplatePreview";
import { Text } from "../../../design/components/Text/native/Text";
import { isPremiumCollectiblesProduct } from "../CollectiblesUtils";
import { Button } from "../../../design/components/Button/native/Button.native";
let useStyles, useStyles2, __initData, __initData2, __initData3, c6495_21, c6495_22, ProductPurchaseGradientBackground;
const CancelButton = function CancelButton(props) {
const { tintColor, onCancel } = props;
const styles = useStyles();
return <HeaderBackButton onPress={useCallback(() => {
if (onCancel != null) {
onCancel();
}
ProductPurchaseSuccessActionCreators.close();
}, [onCancel])} backImage={() => <XSmallIcon size="lg" style={[styles.closeButtonIcon, {
tintColor
}]} />} accessibilityLabel={intl.string(t.cpT0Cq)} labelVisible={false} />;
};
ProductPurchaseGradientBackground = function ProductPurchaseGradientBackground(props) {
const product = props.product;
const styles2 = useStyles2(product.type);
const backgroundColors = useCollectiblesShopStyles_native(product.styles).backgroundColors;
const r21 = backgroundColors?.tertiary != null;
let c17494_1 = r21;
const token = useToken(Module712.colors.BACKGROUND_BASE_LOW);
const token2 = useToken(Module712.colors.BACKGROUND_SURFACE_HIGH);
return <Module4611 style={styles2.backdrop} start={VerticalGradient.START} end={VerticalGradient.END} locations={r21 ? [0, 0.6, 0.85] : [0, 0.05, 0.6, 0.95, 1]} colors={useMemo(() => {
let r10;
if (backgroundColors == null) {
r10 = [token, token, token2, c6495_22, c6495_22];
} else {
const r5 = backgroundColors.primary.toHexString();
r10 = c17494_1 ? [r5, backgroundColors.secondary.toHexString(), backgroundColors.tertiary.toHexString()] : [r5, backgroundColors.primary.toHexString(), backgroundColors.secondary.toHexString(), c6495_22, c6495_22];
}
return r10;
}, [backgroundColors, token, token2, r21])} />;
};
useStyles = createStyles({
closeButtonIcon: {
tintColor: Module712.colors.MOBILE_TEXT_HEADING_PRIMARY
}
});
useStyles2 = createStyles(function(a0, r8 = false) {
return {
root: {
flex: 1,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
header: {
flexDirection: "row",
alignItems: "center",
paddingHorizontal: Module712.space.PX_16
},
headerLeading: {
flex: 1,
flexDirection: "row",
alignItems: "center"
},
imageBackground: {
resizeMode: "cover",
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0
},
backdrop: {
position: "absolute",
top: 0,
bottom: 0,
left: 0,
right: 0
},
main: {
flex: 1
},
curtain: {
position: "absolute",
backgroundColor: Module712.colors.BLACK,
top: 0,
bottom: 0,
left: 0,
right: 0
},
body: {
flexGrow: 1,
flexDirection: "column",
justifyContent: "center"
},
preview: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
flex: a0 === CollectiblesItemType.AVATAR_DECORATION ? 1 : 0,
marginTop: a0 === CollectiblesItemType.AVATAR_DECORATION ? "20%" : 0,
marginHorizontal: a0 === CollectiblesItemType.NAMEPLATE ? Module712.space.PX_32 : void 0,
...r8 && a0 === CollectiblesItemType.AVATAR_DECORATION ? {
shadowColor: Module712.unsafe_rawColors.PRIMARY_630,
shadowOffset: {
width: 0,
height: 0
},
shadowOpacity: 1,
shadowRadius: 60,
elevation: 24
} : {}
},
previewBundle: {
flex: 1,
justifyContent: "flex-start",
alignItems: "center",
minHeight: 250
},
messages: {
paddingTop: Module712.space.PX_24,
minHeight: a0 === CollectiblesItemType.AVATAR_DECORATION ? "32%" : void 0,
flexDirection: "column",
alignItems: "center",
justifyContent: "flex-start",
gap: Module712.space.PX_16
},
title: {
textAlign: "center",
marginHorizontal: Module712.space.PX_32
},
footer: {
marginBottom: Module712.space.PX_16
},
cta: {
flexDirection: "row",
gap: Module712.space.PX_12,
paddingVertical: Module712.space.PX_16,
marginHorizontal: Module712.space.PX_24,
borderRadius: Module712.radii.round
}
};
});
__initData = {
code: "function ProductPurchaseSuccessModalTsx1(){const{interpolate,springInput,isProfilePreview}=this.__closure;return{opacity:interpolate(springInput.get(),[0,1],[0.1,1]),transform:[{scale:interpolate(springInput.get(),[0,1],[isProfilePreview?0.6:0,1])}]};}"
};
__initData2 = {
code: "function ProductPurchaseSuccessModalTsx2(){const{interpolate,springInput}=this.__closure;return{opacity:interpolate(springInput.get(),[0,1],[0,1]),transform:[{scale:interpolate(springInput.get(),[0,1],[0.75,1])}]};}"
};
__initData3 = {
code: "function ProductPurchaseSuccessModalTsx3(){const{interpolate,linearInput}=this.__closure;return{opacity:interpolate(linearInput.get(),[0,1],[0.5,0])};}"
};
c6495_21 = [80, 79, 78, 75, 72, 50, 45, 35, 70];
c6495_22 = tinycolor("black").toHexString();
export default function ProductPurchaseSuccessModal(props) {
const { product, useCategoryImage = false, renderMessages, onSuccess, onCancel: onCancel2 } = props;
let showOrbBalancePill = props.showOrbBalancePill;
if (showOrbBalancePill === void 0) {
showOrbBalancePill = false;
}
let orbBalancePriorToPurchase = props.orbBalancePriorToPurchase;
if (orbBalancePriorToPurchase === void 0) {
orbBalancePriorToPurchase = null;
}
let setState;
setState = void 0;
const currentUser = useCurrentUser();
const backgroundColors2 = useCollectiblesShopStyles_native(product.styles).backgroundColors;
const styles2 = useStyles2(product.type, backgroundColors2?.tertiary != null);
const token3 = useToken(Module712.colors.INTERACTIVE_TEXT_ACTIVE);
const ref = useRef(c6495_21);
const callback = useCallback(() => {
const r8 = _toArray(ref.current);
const r12 = r8[0];
const current = r8.slice(1);
if (r12 != null && current.length === 0) {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_HEAVY);
} else if (current.length >= c6495_21.length / 2) {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_LIGHT);
} else {
triggerHapticFeedback(HapticFeedbackTypes.IMPACT_MEDIUM);
}
if (r12 != null) {
setTimeout(callback, r12);
}
ref.current = current;
}, []);
useEffect(() => {
callback();
return () => {
ref.current = [];
};
}, [callback]);
const avatarDecorationPreviewSizes = useAvatarDecorationPreviewSizes();
const { avatarSize, avatarDecorationSize } = avatarDecorationPreviewSizes;
const stateFromStores2 = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const isProfilePreview = product.type === CollectiblesItemType.PROFILE_EFFECT || product.type === CollectiblesItemType.PROFILE_FRAME;
const stateFromStores = stateFromStores2;
let c17496_1 = isProfilePreview;
const sharedValue = useSharedValue(0);
const sharedValue2 = useSharedValue(0);
useEffect(() => {
sharedValue.set(stateFromStores ? 1 : withDelay(200, withSpring(1, {
duration: 500,
dampingRatio: 0.7
})));
sharedValue2.set(stateFromStores ? 1 : withDelay(200, withTiming(1, {
duration: 200
})));
}, [sharedValue, stateFromStores, sharedValue2]);
const l = () => ({
opacity: _ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [0.1, 1]),
transform: [{
scale: _ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [c17496_1 ? 0.6 : 0, 1])
}]
});
l.__closure = {
interpolate: _ReanimatedRexport.interpolate,
springInput: sharedValue,
isProfilePreview
};
l.__workletHash = 15385317790278;
l.__initData = __initData;
const animatedStyle = useAnimatedStyle(l);
const n = () => ({
opacity: _ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [0, 1]),
transform: [{
scale: _ReanimatedRexport.interpolate(sharedValue.get(), [0, 1], [0.75, 1])
}]
});
n.__closure = {
interpolate: _ReanimatedRexport.interpolate,
springInput: sharedValue
};
n.__workletHash = 4517716462039;
n.__initData = __initData2;
const animatedStyle2 = useAnimatedStyle(n);
const r124 = () => ({
opacity: _ReanimatedRexport.interpolate(sharedValue2.get(), [0, 1], [0.5, 0])
});
r124.__closure = {
interpolate: _ReanimatedRexport.interpolate,
linearInput: sharedValue2
};
r124.__workletHash = 6018737312;
r124.__initData = __initData3;
const animatedStyle3 = useAnimatedStyle(r124);
const mobileBgUrl = useFetchCollectiblesProductCategory(product.skuId).category?.mobileBgUrl;
const [item] = product.items;
const handleUseNow = useHandleUseNow({
product,
onSuccess
});
const { handleUseNow: handleUseNow2, canUseNow, isApplying, handleEditProfile } = handleUseNow;
const avatarSource = currentUser.getAvatarSource(void 0, false, avatarSize);
const balance = useFetchVirtualCurrencyBalance().balance;
useEffect(() => {
lockOrientation(Orientation.PORTRAIT);
return () => {
restoreDefaultOrientation();
};
}, []);
usePreviewCollectibleProduct(product, true);
const shopProductItems = useShopProductItems(product);
let targetSize;
[targetSize, setState] = useState();
const callback2 = useCallback((a0) => {
const layout = a0.nativeEvent.layout;
const { width, height } = layout;
setState((prevState) => prevState != null && (prevState.width === width && prevState.height === height) ? prevState : {
width,
height
});
}, []);
const r193 = [useCategoryImage && mobileBgUrl != null ? <Image2 source={{
uri: mobileBgUrl
}} style={styles2.imageBackground} /> : <ProductPurchaseGradientBackground product={product} />, , ,];
const style = [styles2.main, {
backgroundColor: useCategoryImage ? "rgba(0, 0, 0, 0.3)" : void 0
}];
if (showOrbBalancePill) {
showOrbBalancePill = <BalanceWidgetPill initialRenderedBalance={orbBalancePriorToPurchase} balance={balance} />;
}
const r211 = [<View style={styles2.headerLeading}>{showOrbBalancePill}</View>, ,];
let tintColor2 = backgroundColors2 == null ? void 0 : backgroundColors2.label.toHexString();
if (tintColor2 == null) {
tintColor2 = token3;
}
r211[1] = <CancelButton tintColor={tintColor2} onCancel={onCancel2} />;
const r220 = [<View style={styles2.header}>{r211}</View>, , ,];
const type = product.type;
const r284 = [<ReanimatedRexport.View style={[styles2.preview, animatedStyle]}>
{CollectiblesItemType.BUNDLE === type ? <View style={styles2.previewBundle} onLayout={callback2}>
{targetSize != null && <BundleSampleV2 deco={shopProductItems.firstAvatarDecoration} pfx={shopProductItems.firstProfileEffect} nameplate={shopProductItems.firstNameplate} previewAssets={product.previewAssets} disableStaticBackground size="large" targetSize={targetSize} exposureLocation="ProductPurchaseSuccessModal" />}
</View> : CollectiblesItemType.AVATAR_DECORATION === type ? <AvatarDecorationSampleV2 item={item} size={avatarDecorationSize} avatarSource={avatarSource} animate={!stateFromStores} /> : CollectiblesItemType.PROFILE_EFFECT === type ? <ProfileEffectUserPreview user={currentUser} profileEffect={product.items[0]} /> : CollectiblesItemType.PROFILE_FRAME === type ? <ProfileFrameUserPreview user={currentUser} profileFrame={product.items[0]} /> : CollectiblesItemType.NAMEPLATE === type ? <NameplatePreview user={currentUser} nameplate={product.items[0]} animate /> : null}
</ReanimatedRexport.View>, ,];
r284[1] = <ReanimatedRexport.View style={[styles2.messages, animatedStyle2]}>
{renderMessages != null ? renderMessages() : <>
{[<Text variant="heading-xl/bold" color="text-overlay-light" style={styles2.title}>
{intl.format(t.YNaxMp, {
itemName: product.name
})}
</Text>, <Text variant="text-md/medium" color="text-overlay-light" style={styles2.title}>
{isPremiumCollectiblesProduct(product) ? intl.format(t.nW6E3m, {
itemName: product.name
}) : intl.format(t["4kp0AB"], {
itemName: product.name
})}
</Text>]}
</>}
</ReanimatedRexport.View>;
r220[1] = <ScrollView style={{
flex: 1
}} contentContainerStyle={styles2.body} alwaysBounceVertical={false}>{r284}</ScrollView>;
r220[2] = <View style={styles2.footer}>
<View style={styles2.cta}>
<Button {...canUseNow ? {
loading: isApplying,
disabled: isApplying,
onPress: handleUseNow2,
text: intl.string(t.MAS7uK),
size: "lg",
grow: true
} : {
onPress: handleEditProfile,
text: intl.string(t["2p2aYz"]),
size: "lg",
grow: true
}} />
</View>
</View>;
r193[1] = <SafeAreaPaddingView style={style} top bottom left right>{r220}</SafeAreaPaddingView>;
r193[2] = <ReanimatedRexport.View style={[styles2.curtain, animatedStyle3]} pointerEvents="none" />;
return <View style={styles2.root} id={product.skuId}>{r193}</View>;
};
@@ -0,0 +1,40 @@
// Metro module 8057 (f8058).
import { View } from "react-native";
import { SAMPLE_PROFILE_ASPECT_RATIO } from "./CollectiblesPreviewConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import FastImage from "../../../components_native/common/FastImage";
import Module8058 from "../../../_bundle/Module8058";
import ProfileEffect from "../profile_effects/native/ProfileEffect";
const useStyles = createStyles({
profileContainer: {
position: "absolute",
display: "flex",
height: "100%",
width: "100%"
},
profileBackground: {
backgroundColor: Module712.colors.BACKGROUND_MOD_SUBTLE
},
sampleProfileImage: {
aspectRatio: SAMPLE_PROFILE_ASPECT_RATIO
},
profileBorder: {
position: "absolute",
height: "100%",
width: "100%",
borderWidth: 1,
borderColor: Module712.colors.BORDER_MUTED
}
});
export default function ProfileEffectSample(props) {
const { item, hideBackground = false } = props;
const styles = useStyles();
return <View style={[styles.profileContainer, hideBackground ? !hideBackground : styles.profileBackground]}>
<FastImage style={[styles.sampleProfileImage]} source={{
uri: Module8058
}} accessible={false} resizeMode="cover" />
{hideBackground ? !hideBackground : <View style={styles.profileBorder} />}
<ProfileEffect skuId={item.skuId} bannerAdjustment={0} useThumbnail />
</View>;
};
+138
View File
@@ -0,0 +1,138 @@
// Metro module 14633 (f14634).
import { useMemo, useCallback } from "react";
import { Image as Image2, View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { UserSettingsSections } from "../../../Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import { useCollectiblesCoachmarkScrollDismissContext } from "./CollectiblesCoachmarkScrollDismissContext";
import useAnalyticsLocations, { AnalyticsLocationProvider } from "../../app_analytics/useAnalyticsLocations";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { useStateFromStores } from "../../../_bundle/Module589";
import useGetProductsFromSkus from "../hooks/useGetProductsFromSkus";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_WIDTH } from "./CollectiblesShopCardV2";
import { Heading } from "../../../design/components/Text/native/Text";
import { Button } from "../../../design/components/Button/native/Button.native";
import { intl, t } from "../../../intl/index.native";
import { LayerScope } from "../../../design/components/Layers/native/LayerScope.native";
import { FlashList } from "../../../_bundle/noop_6676";
let useStyles, ListItemSeparator;
const ListEdgeSpacer = function ListEdgeSpacer() {
return <View style={useStyles().listEdgeSpacer} />;
};
ListItemSeparator = function ListItemSeparator() {
return <View style={useStyles().listItemSeparator} />;
};
useStyles = createStyles({
container: {
width: "100%",
paddingTop: Module712.space.PX_16,
paddingBottom: Module712.space.PX_16
},
containerWithBackground: {
marginTop: Module712.space.PX_24,
paddingTop: Module712.space.PX_24,
paddingBottom: Module712.space.PX_24,
overflow: "hidden"
},
backgroundImage: {
position: "absolute",
top: 0,
left: 0,
bottom: 0,
minWidth: "100%",
aspectRatio: 2.5,
resizeMode: "cover"
},
header: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16,
marginBottom: Module712.space.PX_16,
zIndex: 1
},
headingWrapper: {
flexShrink: 1
},
listEdgeSpacer: {
width: Module712.space.PX_16
},
listItemSeparator: {
width: Module712.space.PX_12
}
});
export default ({ block, preferVCPrice }) => {
let c21266_5;
c21266_5 = void 0;
const styles = useStyles();
const navigation = useNavigation();
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
const handleDismissCoachmarkOnScroll = useCollectiblesCoachmarkScrollDismissContext().handleDismissCoachmarkOnScroll;
const analyticsLocations = useAnalyticsLocations(AnalyticsLocation.COLLECTIBLES_SHOP_SHELF).analyticsLocations;
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => block.categorySkuId != null ? CollectiblesCategoryStore.getCategory(block.categorySkuId) : void 0);
const getProductsFromSkus = useGetProductsFromSkus();
c21266_5 = getProductsFromSkus;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products: useMemo(() => c21266_5(block.rankedSkuIds), [block.rankedSkuIds, getProductsFromSkus])
});
const callback2 = useCallback(() => {
if (stateFromStores != null) {
if (stateFromStores.isOrbsExclusive) {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP,
screen: CollectiblesMobileShopScreen.ORBS
});
} else {
navigation.navigate(UserSettingsSections.COLLECTIBLES_SHOP_VIEW_ALL_CATEGORY_ITEMS, {
category: stateFromStores,
analyticsContext: collectiblesAnalyticsContext
});
}
}
}, [stateFromStores, navigation, collectiblesAnalyticsContext]);
const callback3 = useCallback((a0) => <CollectiblesAnalyticsProvider newValue={{
tilePosition: a0.index,
pageSection: block.name
}}>
<CollectiblesShopCardV2 product={a0.item} preferVCPrice={preferVCPrice} />
</CollectiblesAnalyticsProvider>, [block.name, preferVCPrice]);
const callback = useCallback((a0) => a0.skuId, []);
if (filteredAndSortedProducts.length === 0) {
return null;
}
const r3 = block.mobileBackgroundImage != null;
const style = [styles.container, r3 ? styles.containerWithBackground : r3];
const r91 = [r3 && block.mobileBackgroundImage != null && <Image2 style={styles.backgroundImage} source={{
uri: block.mobileBackgroundImage
}} />, , ,];
let style2 = void 0;
if (r3) {
let titleColor = block.titleColor;
if (titleColor == null) {
titleColor = "#ffffff";
}
style2 = {
color: titleColor
};
}
r91[1] = <View style={styles.header}>
<View style={styles.headingWrapper}>
<Heading variant="text-md/semibold" style={style2}>{block.name}</Heading>
</View>
{block.showButton && stateFromStores != null && <Button variant={r3 ? "primary-overlay" : "secondary"} size="sm" shrink grow={false} text={intl.string(t.xFcotU)} onPress={callback2} />}
</View>;
r91[2] = <LayerScope>
<FlashList horizontal accessibilityRole="list" accessibilityLabel={block.name} data={filteredAndSortedProducts} keyExtractor={callback} onScroll={handleDismissCoachmarkOnScroll} renderItem={callback3} decelerationRate="fast" snapToInterval={COLLECTIBLES_SHOP_CARD_WIDTH + Module712.space.PX_12} showsHorizontalScrollIndicator={false} ListHeaderComponent={ListEdgeSpacer} ListFooterComponent={ListEdgeSpacer} ItemSeparatorComponent={ListItemSeparator} />
</LayerScope>;
return <AnalyticsLocationProvider value={analyticsLocations}>
<View style={style}>{r91}</View>
</AnalyticsLocationProvider>;
};
@@ -0,0 +1,74 @@
// Metro module 14612 (f14613).
import { useMemo } from "react";
import { View } from "react-native";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useStateFromStores } from "../../../_bundle/Module589";
import { ShopBlockType } from "../../../_bundle/Module5829";
import { CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import FramesHeroBlock from "./FramesHeroBlock";
import HeroBlock from "./HeroBlock";
import FeaturedBlock from "./FeaturedBlock";
import FeedBlock from "./FeedBlock";
import FramesProductShelfBlock from "./FramesProductShelfBlock";
import ShelfBlock from "./ShelfBlock";
const useStyles = createStyles({
shopBlockSpacing: {
marginTop: Module712.space.PX_16
}
});
export default ({ block, screen, preferVCPrice, framesBannerBlock }) => {
let stateFromStores2;
stateFromStores2 = void 0;
const styles = useStyles();
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.categories);
stateFromStores2 = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.products);
const memo = useMemo(() => block.type === ShopBlockType.HERO ? `hero-${block.categoryStoreListingId}` : block.type === ShopBlockType.REWARD_HERO ? `reward-hero-${block.categoryStoreListingId}` : `${stateFromStores.size}-${stateFromStores2.size}`, [block, stateFromStores.size, stateFromStores2.size]);
const type = block.type;
if (ShopBlockType.HERO === type) {
return <CollectiblesAnalyticsProvider newValue={{
pageSection: "top 4"
}}>
{framesBannerBlock != null ? <FramesHeroBlock key={memo} heroBlock={block} bannerBlock={framesBannerBlock} preferVCPrice={preferVCPrice} screen={screen} /> : <HeroBlock key={memo} heroBlock={block} preferVCPrice={preferVCPrice} screen={screen} />}
</CollectiblesAnalyticsProvider>;
}
if (ShopBlockType.FEATURED === type) {
return <CollectiblesAnalyticsProvider newValue={{
pageSection: "featured_block"
}}>
<View key={memo} style={styles.shopBlockSpacing}>
<FeaturedBlock featuredBlock={block} />
</View>
</CollectiblesAnalyticsProvider>;
}
if (ShopBlockType.FEED === type) {
return <CollectiblesAnalyticsProvider newValue={{
pageSection: "popular picks"
}}>
<View style={styles.shopBlockSpacing}>
<FeedBlock key={memo} feedBlock={block} screen={screen} preferVCPrice={preferVCPrice} disableBundleStaticBackground />
</View>
</CollectiblesAnalyticsProvider>;
}
if (ShopBlockType.FRAMES_PRODUCT_SHELF === type) {
return <CollectiblesAnalyticsProvider newValue={{
pageSection: "frames_product_shelf"
}}>
<FramesProductShelfBlock key={memo} block={block} preferVCPrice={preferVCPrice} />
</CollectiblesAnalyticsProvider>;
}
if (ShopBlockType.SHELF === type) {
return <CollectiblesAnalyticsProvider newValue={{
pageSection: block.name
}}>
<View style={styles.shopBlockSpacing}>
<ShelfBlock key={memo} block={block} preferVCPrice={preferVCPrice} />
</View>
</CollectiblesAnalyticsProvider>;
}
if (ShopBlockType.WIDE_BANNER !== type) {
ShopBlockType.FRAMES_BANNER;
}
return null;
};
@@ -0,0 +1,166 @@
// Metro module 14609 (f14610).
import { useRef, useEffect, useCallback } from "react";
import { View } from "react-native";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { UserSettingsSections } from "../../../Constants";
import CollectiblesShopCardV2, { COLLECTIBLES_SHOP_CARD_HEIGHT, COLLECTIBLES_SHOP_CARD_WIDTH } from "./CollectiblesShopCardV2";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
import { useFilteredAndSortedProducts } from "./hooks/useFilteredAndSortedProducts";
import { useCollectiblesShopDeepLinkProps } from "./useCollectiblesShopDeepLinkProps";
import { useRecyclingState, FlashList } from "../../../_bundle/noop_6676";
import { useScrollToInitialIndexOnce, INITIAL_SCROLL_DELAY_MS } from "./hooks/useScrollToInitialIndexOnce";
import { useCollectiblesAnalyticsContext, CollectiblesAnalyticsProvider } from "../CollectiblesAnalyticsContext";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import { openProductDetailsActionSheet } from "./openProductDetailsActionSheet";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { PressableOpacity } from "../../../design/void/Pressables/native/Pressables";
import { intl, t } from "../../../intl/index.native";
import FastImage from "../../../components_native/common/FastImage";
import { ChevronSmallRightIcon } from "../../../design/components/Icon/native/redesign/generated/ChevronSmallRightIcon";
let useStyles, HeaderAndFooterSpacing;
const Spacing = function Spacing() {
return <View style={{
width: 12
}} />;
};
HeaderAndFooterSpacing = function HeaderAndFooterSpacing() {
return <View style={{
width: 16
}} />;
};
const height = 100 + COLLECTIBLES_SHOP_CARD_HEIGHT;
useStyles = createStyles({
categoryContainer: {
marginTop: Module712.space.PX_16,
marginBottom: 24,
height
},
categoryHeader: {
display: "flex",
flexDirection: "row",
justifyContent: "flex-end",
alignItems: "center",
marginBottom: 16,
marginHorizontal: 16,
borderRadius: Module712.radii.sm,
overflow: "hidden",
borderWidth: 1,
height: 84,
padding: 20
},
categoryHeaderBorderDark: {
borderColor: Module712.unsafe_rawColors.PRIMARY_660
},
categoryHeaderBorderLight: {
borderColor: Module712.colors.BACKGROUND_BASE_LOWEST
},
imageBackground: {
top: 0,
bottom: 0,
left: 0,
right: 0,
position: "absolute"
},
viewAllIcon: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
padding: 6,
borderRadius: Module712.radii.round
}
});
export { height as CATEGORY_CONTAINER_HEIGHT };
export const CATEGORY_CONTAINER_BOTTOM_MARGIN = 24;
export function ShopCategory(props) {
let collectiblesAnalyticsContext;
const { index, category, isDarkTheme } = props;
collectiblesAnalyticsContext = void 0;
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
const styles = useStyles();
const navigation = useNavigation();
const { products, unpublishedAt } = category;
const filteredAndSortedProducts = useFilteredAndSortedProducts({
products,
bypassAndroidUnsyncedFilter: category.isOrbsExclusive
});
const mobileBannerUrl = category.mobileBannerUrl;
const collectiblesShopDeepLinkProps = useCollectiblesShopDeepLinkProps({
products: filteredAndSortedProducts
});
const { productIndex, initialProductSkuId, initialVariantIndex } = collectiblesShopDeepLinkProps;
const ref = useRef(null);
useRecyclingState(null, [category.storeListingId], () => {
const current = ref.current;
if (current != null) {
current.scrollToOffset({
offset: 0,
animated: false
});
}
});
useScrollToInitialIndexOnce({
shouldScroll: productIndex != null && productIndex > 0,
initialScrollIndex: productIndex,
flashListRef: ref,
afterMs: INITIAL_SCROLL_DELAY_MS,
resetKey: category.storeListingId
});
collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
useEffect(() => {
const product = initialProductSkuId != null ? filteredAndSortedProducts.find((filteredAndSortedProduct) => filteredAndSortedProduct.skuId === initialProductSkuId) : null;
if (product != null) {
ActionSheetActionCreators.hideActionSheet();
let shopAnalyticsContext = collectiblesAnalyticsContext;
if (collectiblesAnalyticsContext == null) {
shopAnalyticsContext = void 0;
}
openProductDetailsActionSheet({
product,
initialVariantIndex,
analyticsLocations,
shopAnalyticsContext
});
}
}, [initialProductSkuId, initialVariantIndex, filteredAndSortedProducts, analyticsLocations, collectiblesAnalyticsContext]);
const callback = useCallback((a0) => <CollectiblesAnalyticsProvider newValue={{
tilePosition: a0.index
}}>
<CollectiblesShopCardV2 product={a0.item} unpublishedAt={unpublishedAt} />
</CollectiblesAnalyticsProvider>, [unpublishedAt]);
return <CollectiblesAnalyticsProvider newValue={{
categoryPosition: index
}}>
<View style={styles.categoryContainer}>
<PressableOpacity key={category.storeListingId} style={[styles.categoryHeader, isDarkTheme ? styles.categoryHeaderBorderDark : styles.categoryHeaderBorderLight]} accessibilityRole="button" accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: category.name
})} accessibilityHint={intl.string(t.F8ma9x)} activeOpacity={0.8} androidRippleConfig={{
radius: Module712.radii.lg
}} hitSlop={8} onPress={() => {
if (category.isOrbsExclusive) {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP,
screen: CollectiblesMobileShopScreen.ORBS
});
} else {
navigation.navigate(UserSettingsSections.COLLECTIBLES_SHOP_VIEW_ALL_CATEGORY_ITEMS, {
category,
analyticsContext: collectiblesAnalyticsContext
});
}
}}>
{mobileBannerUrl != null && <FastImage source={{
uri: mobileBannerUrl
}} resizeMode="cover" style={styles.imageBackground} />}
<View style={styles.viewAllIcon}>
<ChevronSmallRightIcon size="sm" color="white" />
</View>
</PressableOpacity>
<FlashList ref={ref} horizontal accessibilityLabel={intl.formatToPlainString(t.FNtLb3, {
category: category.name
})} accessibilityRole="list" data={filteredAndSortedProducts} renderItem={callback} drawDistance={150} decelerationRate="fast" snapToInterval={COLLECTIBLES_SHOP_CARD_WIDTH + 12} showsHorizontalScrollIndicator={false} ListHeaderComponent={HeaderAndFooterSpacing} ListFooterComponent={HeaderAndFooterSpacing} ItemSeparatorComponent={Spacing} initialScrollIndex={productIndex} />
</View>
</CollectiblesAnalyticsProvider>;
}
@@ -0,0 +1,46 @@
// Metro module 15620 (f15621).
import { useMemo } from "react";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import { Avatar, AvatarSizes } from "../../../design/void/native";
import { isYouNavFloating } from "../../main_tabs_v2/native/tabs/you/YouNavFloatingExperiment";
import Module712 from "../../../_bundle/Module712";
import { intl, t } from "../../../intl/index.native";
import { useCoachmark } from "../../../design/components/Coachmark/native/useCoachmark.native";
let useStyles;
const CoachmarkImg = function CoachmarkImg(props) {
const { source, decorationAsset: decorationAsset2 } = props;
return <Avatar style={useStyles().image} source={source} avatarDecoration={{
asset: decorationAsset2
}} size={AvatarSizes.XXLARGE} />;
};
useStyles = createStyles({
image: {
marginTop: 12
}
});
export default function ShopCoachmark({ buttonRef, markAsDismissed, visible, title, description, avatarSrc, decorationAsset, navigateToShop, renderImgComponent }) {
useCoachmark(buttonRef, useMemo(() => {
const position = isYouNavFloating() ? "top" : "bottom";
const offsetY = isYouNavFloating() ? Module712.space.PX_12 : void 0;
let renderImgComponent2 = renderImgComponent;
if (renderImgComponent == null) {
renderImgComponent2 = () => <CoachmarkImg source={avatarSrc} decorationAsset={decorationAsset} />;
}
return {
title,
description,
onDismiss: () => {
markAsDismissed(ContentDismissActionType.USER_DISMISS);
},
visible,
position,
offsetY,
renderImgComponent: renderImgComponent2,
buttonLabel: intl.string(t.fYfGgK),
buttonVariant: "primary",
onButtonPress: navigateToShop
};
}, [avatarSrc, decorationAsset, description, renderImgComponent, markAsDismissed, title, visible, navigateToShop]));
return null;
};
@@ -0,0 +1,32 @@
// Metro module 14637 (f14638).
import { useRef } from "react";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useScrollToInitialIndexOnce, INITIAL_SCROLL_DELAY_MS } from "./hooks/useScrollToInitialIndexOnce";
import { FlashList } from "../../../_bundle/noop_6676";
import { EmptyState } from "../../../design/void/native";
import { NoResults } from "../../../design/components/Illustration/native/redesign/generated/NoResults";
import { intl, t } from "../../../intl/index.native";
let useStyles;
const ShopEmptyState = function ShopEmptyState() {
return <EmptyState style={{
marginTop: 42
}} Illustration={NoResults} body={intl.string(t.eAn6z2)} />;
};
useStyles = createStyles({
contentContainer: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOWEST
}
});
export default function ShopFlashList(props) {
const { data, renderItem, initialScrollIndex, getItemType } = props;
const ref = useRef(null);
const styles = useStyles();
useScrollToInitialIndexOnce({
shouldScroll: initialScrollIndex != null && initialScrollIndex > 0,
initialScrollIndex,
flashListRef: ref,
afterMs: INITIAL_SCROLL_DELAY_MS
});
return <FlashList ref={ref} data={data} renderItem={renderItem} showsVerticalScrollIndicator={false} ListEmptyComponent={ShopEmptyState} initialScrollIndex={initialScrollIndex} getItemType={getItemType} contentContainerStyle={styles.contentContainer} />;
};
@@ -0,0 +1,46 @@
// Metro module 14109 (f14110).
import { useEffect } from "react";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { COLLECTIBLES_SHOP_CARD_WIDTH, COLLECTIBLES_SHOP_CARD_HEIGHT } from "./CollectiblesShopCardV2";
import ReanimatedRexport, { useSharedValue, withRepeat, useAnimatedStyle } from "../../reanimated/ReanimatedRexport";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
let __initData;
const useStyles = createStyles((a0, a1) => ({
skeletonCard: {
width: a0,
height: a1,
backgroundColor: Module712.colors.BORDER_SUBTLE,
borderRadius: Module712.radii.sm
}
}));
__initData = {
code: "function SkeletonCardTsx1(){const{opacity}=this.__closure;return{opacity:opacity.get()};}"
};
export default (a0) => {
let width = a0.width;
if (width === void 0) {
width = COLLECTIBLES_SHOP_CARD_WIDTH;
}
let height = a0.height;
const style = a0.style;
if (height == null) {
height = COLLECTIBLES_SHOP_CARD_HEIGHT;
}
const styles = useStyles(width, height);
const sharedValue = useSharedValue(0.3);
useEffect(() => {
sharedValue.set(withRepeat(withTiming(1, {
duration: 650
}), -1, true));
}, [sharedValue]);
const C = () => ({
opacity: sharedValue.get()
});
C.__closure = {
opacity: sharedValue
};
C.__workletHash = 5620456625640;
C.__initData = __initData;
return <ReanimatedRexport.View style={[styles.skeletonCard, style, useAnimatedStyle(C)]} />;
};
@@ -0,0 +1,32 @@
// Metro module 11914 (f11915).
import IAPStore_android from "../../../stores/native/IAPStore.android";
import CollectiblesPurchaseStore from "../CollectiblesPurchaseStore";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { useStateFromStores } from "../../../_bundle/Module589";
import { ProductIds } from "../../premium/native/ProductIds.android";
import useOpenNitroSubscribeActionSheet from "./useOpenNitroSubscribeActionSheet";
import { intl, t } from "../../../intl/index.native";
import { BaseTextButton } from "../../../design/components/Button/native/BaseTextButton.native";
import { Text } from "../../../design/components/Text/native/Text";
import { NitroWheelIcon } from "../../../design/components/Icon/native/redesign/generated/NitroWheelIcon";
export function UnlockWithNitroButton(props) {
let shouldShrink = props.shouldShrink;
if (shouldShrink === void 0) {
shouldShrink = false;
}
let c19267_1;
const onTrackPress = props.onTrackPress;
let text = props.text;
c19267_1 = void 0;
const stateFromStores = useStateFromStores([CollectiblesPurchaseStore, IAPStore_android], () => CollectiblesPurchaseStore.isClaiming != null || IAPStore_android.isPurchasingProduct(ProductIds.GENERIC_CONSUMABLE));
c19267_1 = useOpenNitroSubscribeActionSheet();
if (text == null) {
text = intl.string(t.sEAnVH);
}
return <BaseTextButton textElement={shouldShrink ? <Text variant="text-xs/semibold" color="text-overlay-light" allowFontScaling={false}>{text}</Text> : void 0} text={shouldShrink ? void 0 : text} accessibilityLabel={text} variant="primary" size={shouldShrink ? "sm" : "md"} grow icon={<NitroWheelIcon size="sm" color="white" />} onPress={() => {
if (onTrackPress != null) {
onTrackPress(ShopCtaEnum.UNLOCK_WITH_NITRO);
}
c19267_1();
}} disabled={stateFromStores} />;
}
@@ -0,0 +1,51 @@
// Metro module 11919 (f11920).
import Module19, { useEffect, useRef } from "react";
import { View } from "react-native";
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
export default ({ children, onChange, resetKey }) => {
let ref, ref2, width, height, ref3, callback;
ref = void 0;
ref2 = void 0;
width = void 0;
height = void 0;
ref3 = void 0;
callback = void 0;
const stopWatching2 = function stopWatching() {
if (ref3.current !== null) {
clearInterval(ref3.current);
ref3.current = null;
}
};
ref = useRef(null);
ref2 = useRef(false);
const windowDimensions_native = useWindowDimensions_native();
width = windowDimensions_native.width;
height = windowDimensions_native.height;
ref3 = useRef(null);
useEffect(() => {
ref2.current = false;
}, [resetKey]);
callback = Module19.useCallback((c27209_0, c27209_1) => {
if (ref3.current === null) {
ref3.current = setInterval(() => {
if (ref.current !== null) {
ref.current.measure((a0, a1, a2, a3, a4, a5) => {
const current = a5 + a3 > 0 && a5 < c27209_1 && a4 < c27209_0 && a4 + a2 > 0;
if (current !== ref2.current) {
ref2.current = current;
onChange(current);
}
});
}
}, 1000);
}
}, [onChange]);
useEffect(() => {
callback(width, height);
return stopWatching2;
}, [callback, height, width]);
return <View collapsable={false} ref={ref}>
{children}
<View />
</View>;
};
@@ -0,0 +1,340 @@
// Metro module 8707 (f8708).
import { useContext, useState, useCallback, useEffect } from "react";
import { Pressable, View } from "react-native";
import AuthenticationStore from "../../../stores/AuthenticationStore";
import UserStore from "../../../stores/UserStore";
import { ShopCtaEnum } from "../CollectiblesShopConstants";
import { ThemeTypes } from "../../../_bundle/Module505";
import * as _ReanimatedRexport from "../../reanimated/ReanimatedRexport";
import ReanimatedRexport, { useSharedValue, useAnimatedStyle, Easing } from "../../reanimated/ReanimatedRexport";
import { SMALL_BUTTON_HEIGHT, MEDIUM_BUTTON_HEIGHT } from "../../../design/components/Button/native/ButtonConstants.native";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useThemeContext, setColorOpacity } from "../../../_bundle/Module3901";
import { ICON_SIZE } from "../../../design/components/Icon/IconSize";
import * as _shared from "../../../design/shared";
import { AccessibilityPreferencesContext } from "../../../_bundle/Module3908";
import ToastActionCreators from "../../toast/native/ToastActionCreators";
import * as _index_native from "../../../intl/index.native";
import { intl } from "../../../intl/index.native";
import { withTiming } from "../../../design/animation/reanimated/timing/timing";
import * as _spring from "../../../design/animation/reanimated/spring/spring";
import * as _springPresets from "../../../design/animation/reanimated/spring/springPresets";
import { HeartOutlineIcon } from "../../../design/components/Icon/native/redesign/generated/HeartOutlineIcon";
import { HeartIcon } from "../../../design/components/Icon/native/redesign/generated/HeartIcon";
import { useStateFromStores } from "../../../_bundle/Module589";
import useWishlistNUXActionSheet from "./useWishlistNUXActionSheet";
import { useWishlistButtonState } from "../hooks/useWishlistButtonState";
import { useProductPurchaseState } from "../hooks/useProductPurchaseState";
import * as _CollectiblesWishlistUtils from "../../wishlists/CollectiblesWishlistUtils";
import { HermesBuiltin } from "../../../_hermes/prelude";
let c5676_14, c5676_15, c5676_16, useStyles, __initData, __initData2, __initData3, __initData4, WishlistButton;
const WishlistButtonBase = function WishlistButtonBase(props) {
const { isWishlisted, onPress, busy, disabled, accessibilityLabel, accessibilityHidden = false, style: style2, size = "sm", onTrackPress } = props;
const styles = useStyles(size);
const width = ICON_SIZE[c5676_16[size]];
const theme = useThemeContext().theme;
const isThemeLight = _shared.isThemeLight(theme);
let c16736_7 = theme === ThemeTypes.MIDNIGHT;
const light = isThemeLight ? styles.light : styles.dark;
const lightPressed = isThemeLight ? styles.lightPressed : styles.darkPressed;
const enabled = useContext(AccessibilityPreferencesContext).reducedMotion.enabled;
const [state, setState] = useState(false);
const state2 = isWishlisted ? isWishlisted : state;
const sharedValue = useSharedValue(isWishlisted ? 1 : 0);
const callback = useCallback(() => {
if (disabled) {
ToastActionCreators.open({
key: "WISHLIST_DISABLED",
content: intl.string(_index_native.t["50TX9k"])
});
} else if (!busy) {
if (onTrackPress != null) {
onTrackPress(isWishlisted ? ShopCtaEnum.REMOVE_FROM_WISHLIST : ShopCtaEnum.ADD_TO_WISHLIST);
}
let r15 = isWishlisted;
if (!isWishlisted && !enabled) {
setState(true);
} else {
if (isWishlisted) {
r15 = state;
}
if (r15) {
setState(false);
}
}
if (onPress != null) {
onPress();
}
}
}, [disabled, busy, onPress, isWishlisted, enabled, state, onTrackPress]);
useEffect(() => {
if (!state) {
sharedValue.set(isWishlisted ? 1 : 0);
}
}, [isWishlisted, state, sharedValue]);
useEffect(() => {
if (state) {
sharedValue.set(0);
let c26273_0 = requestAnimationFrame(() => {
const t = function t(a0) {
if (a0) {
_ReanimatedRexport.runOnJS(setState)(false);
}
};
t.__closure = {
runOnJS: _ReanimatedRexport.runOnJS,
setIsClickAnimating: setState
};
t.__workletHash = 13061953734403;
t.__initData = __initData;
sharedValue.set(withTiming(1, c5676_14, "animate-always", t));
});
return () => cancelAnimationFrame(c26273_0);
}
}, [state, sharedValue]);
const J = () => {
let r0 = 1;
const r4 = {
...styles.animationFill,
opacity: _spring.withSpring(state2 ? 0 : 1, _springPresets.SUBTLE_SPRING, "animate-always")
};
if (state2) {
r0 = 0.9;
}
r4.transform = [{
scale: _spring.withSpring(r0, _springPresets.SUBTLE_SPRING, "animate-always")
}];
return r4;
};
J.__closure = {
styles,
withSpring: _spring.withSpring,
showFilled: state2,
SUBTLE_SPRING: _springPresets.SUBTLE_SPRING
};
J.__workletHash = 1357254413161;
J.__initData = __initData2;
const animatedStyle = useAnimatedStyle(J);
const Y = function Y() {
const r10 = sharedValue.get();
return {
...styles.animationFill,
opacity: _spring.withSpring(state2 ? 1 : 0, _springPresets.SUBTLE_SPRING, "animate-always"),
transform: [{
scale: _ReanimatedRexport.interpolate(r10, [0, 0.625, 1], [0, 1.35, 1], _ReanimatedRexport.Extrapolation.CLAMP)
}]
};
};
Y.__closure = {
animationFillProgress: sharedValue,
styles,
withSpring: _spring.withSpring,
showFilled: state2,
SUBTLE_SPRING: _springPresets.SUBTLE_SPRING,
interpolate: _ReanimatedRexport.interpolate,
Extrapolation: _ReanimatedRexport.Extrapolation
};
Y.__workletHash = 15039903885060;
Y.__initData = __initData3;
const animatedStyle2 = useAnimatedStyle(Y);
const K = function K() {
const r8 = sharedValue.get();
return {
...styles.animationFill,
opacity: state2 ? _ReanimatedRexport.interpolate(r8, [0, 0.7], [1, 0], _ReanimatedRexport.Extrapolation.CLAMP) : 0,
transform: [{
scale: _ReanimatedRexport.interpolate(r8, [0, 0.625, 1], [0, 1.35, 1], _ReanimatedRexport.Extrapolation.CLAMP)
}]
};
};
K.__closure = {
animationFillProgress: sharedValue,
styles,
showFilled: state2,
interpolate: _ReanimatedRexport.interpolate,
Extrapolation: _ReanimatedRexport.Extrapolation
};
K.__workletHash = 12429379889426;
K.__initData = __initData4;
return <Pressable style={({ pressed }) => {
const r6 = [styles.button, light, c16736_7 && styles.midnight, , , ,];
if (pressed) {
pressed = !disabled;
}
if (pressed) {
pressed = lightPressed;
}
r6[3] = pressed;
let r10 = disabled;
if (disabled) {
r10 = styles.disabled;
}
r6[4] = r10;
r6[5] = style2;
return r6;
}} onPress={callback} accessibilityRole={accessibilityHidden ? "none" : "togglebutton"} accessibilityLabel={accessibilityHidden ? void 0 : accessibilityLabel} accessibilityState={accessibilityHidden ? void 0 : {
checked: isWishlisted,
busy,
disabled
}} accessibilityElementsHidden={accessibilityHidden} importantForAccessibility={accessibilityHidden ? "no-hide-descendants" : "auto"}>
<View style={[styles.iconContainer, {
width,
height: width
}]}>
<ReanimatedRexport.View style={animatedStyle} pointerEvents="none">
<HeartOutlineIcon size={c5676_16[size]} color={Module712.colors.INTERACTIVE_ICON_DEFAULT} />
</ReanimatedRexport.View>
<ReanimatedRexport.View style={animatedStyle2} pointerEvents="none">
<HeartIcon size={c5676_16[size]} color={Module712.unsafe_rawColors.RED_NEW_50} />
</ReanimatedRexport.View>
<ReanimatedRexport.View style={useAnimatedStyle(K)} pointerEvents="none">
<HeartIcon size={c5676_16[size]} color="white" />
</ReanimatedRexport.View>
</View>
</Pressable>;
};
WishlistButton = function WishlistButton(props) {
let shouldShowWishlistNUXActionSheet, showWishlistNUXActionSheet, content, isWishlisted2, handleToggle;
const { skuId, product, onPress: onPress2, onTrackPress: onTrackPress2 } = props;
const r23 = {};
let r2 = null;
const props2 = HermesBuiltin.copyDataProperties(r23, props, {
__proto__: null,
skuId: 0,
product: 0,
onPress: 0,
onTrackPress: 0
});
shouldShowWishlistNUXActionSheet = void 0;
showWishlistNUXActionSheet = void 0;
content = void 0;
isWishlisted2 = void 0;
handleToggle = void 0;
const stateFromStores = useStateFromStores([AuthenticationStore], () => AuthenticationStore.getId());
const stateFromStores2 = useStateFromStores([UserStore], () => UserStore.getCurrentUser());
const wishlistNUXActionSheet = useWishlistNUXActionSheet();
shouldShowWishlistNUXActionSheet = wishlistNUXActionSheet.shouldShowWishlistNUXActionSheet;
showWishlistNUXActionSheet = wishlistNUXActionSheet.showWishlistNUXActionSheet;
const accessibilityLabel = intl.formatToPlainString(_index_native.t["7kFjeK"], {
productName: product.name
});
const callback = useCallback(() => {
if (shouldShowWishlistNUXActionSheet) {
showWishlistNUXActionSheet(product);
}
}, [shouldShowWishlistNUXActionSheet, showWishlistNUXActionSheet, product]);
content = intl.string(_index_native.t.F8FvUy);
const wishlistButtonState = useWishlistButtonState({
userId: stateFromStores,
skuId,
onAddSuccess: callback,
onError: useCallback(() => {
ToastActionCreators.open({
key: "WISHLIST_ERROR",
content
});
}, [content]),
skipAddAnnouncement: shouldShowWishlistNUXActionSheet
});
isWishlisted2 = wishlistButtonState.isWishlisted;
const isBusy = wishlistButtonState.isBusy;
handleToggle = wishlistButtonState.handleToggle;
const callback2 = useCallback(async () => {
if (onTrackPress2 != null) {
onTrackPress2(isWishlisted2 ? ShopCtaEnum.REMOVE_FROM_WISHLIST : ShopCtaEnum.ADD_TO_WISHLIST);
}
if (onPress2 != null) {
onPress2();
}
await handleToggle();
}, [onPress2, onTrackPress2, isWishlisted2, handleToggle]);
if (stateFromStores2 != null) {
r2 = <WishlistButtonBase isWishlisted={isWishlisted2} onPress={callback2} busy={isBusy} accessibilityLabel={accessibilityLabel} {...props2} />;
}
return r2;
};
c5676_14 = {
duration: 400,
easing: Easing.bezier(0.67, 0, 0.26, 1)
};
c5676_15 = {
sm: SMALL_BUTTON_HEIGHT,
md: MEDIUM_BUTTON_HEIGHT
};
c5676_16 = {
sm: "sm",
md: "md"
};
useStyles = createStyles((a0) => ({
button: {
width: c5676_15[a0],
height: c5676_15[a0],
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: Module712.radii.round,
borderWidth: 1,
borderColor: Module712.colors.CONTROL_SECONDARY_BORDER_DEFAULT
},
light: {
backgroundColor: setColorOpacity("white", 0.72)
},
lightPressed: {
backgroundColor: setColorOpacity("white", 0.62)
},
dark: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT
},
darkPressed: {
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_ACTIVE
},
midnight: {
borderColor: Module712.colors.BORDER_STRONG
},
disabled: {
opacity: 0.5
},
iconContainer: {
position: "relative",
alignItems: "center",
justifyContent: "center"
},
animationFill: {
position: "absolute",
inset: 0,
alignItems: "center",
justifyContent: "center"
}
}));
__initData = {
code: "function WishlistButtonTsx1(done){const{runOnJS,setIsClickAnimating}=this.__closure;if(done){runOnJS(setIsClickAnimating)(false);}}"
};
__initData2 = {
code: "function WishlistButtonTsx2(){const{styles,withSpring,showFilled,SUBTLE_SPRING}=this.__closure;return{...styles.animationFill,opacity:withSpring(showFilled?0:1,SUBTLE_SPRING,'animate-always'),transform:[{scale:withSpring(showFilled?0.9:1,SUBTLE_SPRING,'animate-always')}]};}"
};
__initData3 = {
code: "function WishlistButtonTsx3(){const{animationFillProgress,styles,withSpring,showFilled,SUBTLE_SPRING,interpolate,Extrapolation}=this.__closure;const progress=animationFillProgress.get();return{...styles.animationFill,opacity:withSpring(showFilled?1:0,SUBTLE_SPRING,'animate-always'),transform:[{scale:interpolate(progress,[0,0.625,1],[0,1.35,1],Extrapolation.CLAMP)}]};}"
};
__initData4 = {
code: "function WishlistButtonTsx4(){const{animationFillProgress,styles,showFilled,interpolate,Extrapolation}=this.__closure;const progress=animationFillProgress.get();return{...styles.animationFill,opacity:showFilled?interpolate(progress,[0,0.7],[1,0],Extrapolation.CLAMP):0,transform:[{scale:interpolate(progress,[0,0.625,1],[0,1.35,1],Extrapolation.CLAMP)}]};}"
};
export default function CollectiblesWishlistButton(props) {
const { selectedProduct, onTrackPress: onTrackPress3 } = props;
const r14 = {};
let r2 = null;
const props2 = HermesBuiltin.copyDataProperties(r14, props, {
__proto__: null,
selectedProduct: 0,
onTrackPress: 0
});
const skuId = selectedProduct.skuId;
const isPurchased = useProductPurchaseState(selectedProduct).isPurchased;
const isWishlistableCollectiblesProduct = _CollectiblesWishlistUtils.isWishlistableCollectiblesProduct(selectedProduct);
if (!isPurchased) {
r2 = <WishlistButton skuId={skuId} product={selectedProduct} disabled={!isWishlistableCollectiblesProduct} onTrackPress={onTrackPress3} {...props2} />;
}
return r2;
};
export { WishlistButtonBase };
export { WishlistButton };
@@ -0,0 +1,33 @@
// Metro module 14616 (f14617).
import { useMemo, useEffect } from "react";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { useHasNeverWishlisted } from "./useWishlistNUXActionSheet";
import { DismissibleContent } from "../../../_bundle/Module1358";
import { useSelectedDismissibleContent } from "../../dismissible_content/hooks/useSelectedDismissibleContent";
import { useCollectiblesCoachmarkScrollDismissContext } from "./CollectiblesCoachmarkScrollDismissContext";
import { intl, t } from "../../../intl/index.native";
import { useCoachmark } from "../../../design/components/Coachmark/native/useCoachmark.native";
export default function WishlistButtonCoachmark({ anchorRef }) {
let c21256_1, visible, registerDismiss;
c21256_1 = void 0;
visible = void 0;
registerDismiss = void 0;
const hasNeverWishlisted = useHasNeverWishlisted();
const [r24, r25] = useSelectedDismissibleContent(useMemo(() => hasNeverWishlisted ? [DismissibleContent.WISHLIST_MOBILE_NUX_PRODUCT_CARD_COACHMARK] : [], [hasNeverWishlisted]));
c21256_1 = r25;
visible = r24 === DismissibleContent.WISHLIST_MOBILE_NUX_PRODUCT_CARD_COACHMARK;
registerDismiss = useCollectiblesCoachmarkScrollDismissContext().registerDismiss;
useEffect(() => {
if (visible) {
return registerDismiss(() => c21256_1(ContentDismissActionType.INDIRECT_ACTION));
}
}, [visible, registerDismiss, r25]);
useCoachmark(anchorRef, useMemo(() => ({
title: intl.string(t["47Rhc3"]),
description: intl.string(t.PXjA0b),
position: "top",
visible,
onDismiss: () => c21256_1(ContentDismissActionType.USER_DISMISS)
}), [visible, r25]));
return null;
};
@@ -0,0 +1,85 @@
// Metro module 8668 (f8669).
import { useMemo, useCallback } from "react";
import { View } from "react-native";
import UserStore from "../../../stores/UserStore";
import { UserProfileSections } from "../../user_profile/Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { useStateFromStores } from "../../../_bundle/Module589";
import { CollectiblesItemType } from "../../../_bundle/Module1901";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import showUserProfileActionSheet from "../../user_profile/native/showUserProfileActionSheet";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { CollectiblesPreview } from "../../skus/native/SKUPreview";
import { BottomSheet } from "../../../design/components/Sheet/native/BottomSheet.native";
import WishlistItemCardBase from "../../wishlists/native/WishlistItemCardBase";
import { Text } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { ButtonGroup } from "../../../design/components/ButtonGroup/native/ButtonGroup.native";
import { Button } from "../../../design/components/Button/native/Button.native";
const useStyles = createStyles({
container: {
alignItems: "center",
padding: Module712.space.PX_16,
gap: Module712.space.PX_24
},
textContainer: {
alignItems: "center",
paddingHorizontal: Module712.space.PX_8,
gap: Module712.space.PX_8
},
subtitle: {
textAlign: "center"
}
});
export default function WishlistNUXAddedItemActionSheet(props) {
let memo;
const product = props.product;
memo = void 0;
const styles = useStyles();
const stateFromStores = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), []);
memo = useMemo(() => {
if (product.type === CollectiblesItemType.BUNDLE) {
return {
type: "bundle",
items: product.items,
previewAssets: product.previewAssets
};
}
const [item] = product.items;
return item == null ? void 0 : {
type: "single",
item
};
}, [product]);
const callback = useCallback(() => {
ActionSheetActionCreators.hideActionSheet();
}, []);
const callback2 = useCallback(() => {
ActionSheetActionCreators.hideAllActionSheets();
if (stateFromStores != null) {
showUserProfileActionSheet({
userId: stateFromStores.id,
sourceAnalyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP],
initialSection: UserProfileSections.WISHLIST
});
}
}, [stateFromStores]);
return <BottomSheet>
<View style={styles.container}>
<WishlistItemCardBase renderPreview={useCallback(() => memo != null ? <CollectiblesPreview collectiblesItemData={memo} /> : null, [memo])} />
<View style={styles.textContainer}>
<Text variant="heading-lg/extrabold" color="text-strong" accessibilityRole="header">
{intl.string(t["3T2jbf"])}
</Text>
<Text variant="text-md/normal" color="text-default" style={styles.subtitle}>
{intl.string(t.SXb73A)}
</Text>
</View>
<ButtonGroup direction="horizontal">
<Button text={intl.string(t.tM4PUv)} onPress={callback} size="lg" variant="primary" grow />
<Button text={intl.string(t.TxBQzD)} onPress={callback2} variant="secondary" size="lg" grow />
</ButtonGroup>
</View>
</BottomSheet>;
};
@@ -0,0 +1,54 @@
// Metro module 7969 (f7970).
import { useMemo } from "react";
import { View } from "react-native";
import AccessibilityStore from "../../../a11y/AccessibilityStore";
import { useStateFromStores } from "../../../../_bundle/defaultAreStatesEqual";
import { getAvatarDecorationURL } from "../../../../utils/AvatarUtils";
import { isAndroid } from "../../../../utils/PlatformUtils";
import ClipView from "../../../../design/components/Icon/native/ClipView";
import Module6208 from "../../../../_bundle/Module6208";
import FastImage from "../../../../components_native/common/FastImage";
export default function CutoutableAvatarDecoration(props) {
const { size, avatarDecoration, decorationStyle, animate, cutout } = props;
const stateFromStores = useStateFromStores([AccessibilityStore], () => AccessibilityStore.useReducedMotion);
const memo = useMemo(() => {
let canAnimate = animate;
if (animate) {
canAnimate = !stateFromStores;
}
if (canAnimate) {
canAnimate = avatarDecoration != null;
}
let uri = getAvatarDecorationURL({
avatarDecoration,
canAnimate,
size
});
if (uri == null) {
uri = "";
}
return {
avatarDecorationUrl: uri,
sizeStyle: {
width: size,
height: size
},
style: [{
width: size,
height: size
}, decorationStyle],
shouldAnimate: canAnimate,
source: {
uri
}
};
}, [animate, size, avatarDecoration, decorationStyle, stateFromStores]);
const { shouldAnimate, avatarDecorationUrl, style, sizeStyle, source } = memo;
return avatarDecoration == null ? null : avatarDecorationUrl == null ? null : isAndroid() && shouldAnimate ? cutout != null ? <ClipView style={style} cutouts={cutout.nativeCutouts}>
<Module6208 url={avatarDecorationUrl} style={sizeStyle} />
</ClipView> : <View style={style} pointerEvents="none">
<Module6208 url={avatarDecorationUrl} style={sizeStyle} />
</View> : cutout != null ? <ClipView style={style} cutouts={cutout.nativeCutouts}>
<FastImage source={source} style={sizeStyle} />
</ClipView> : <FastImage source={source} style={style} />;
};
@@ -0,0 +1,51 @@
// Metro module 14620 (f14621).
import { COLLECTIBLES_SHOP_CARD_WIDTH, COLLECTIBLES_SHOP_CARD_GAP, COLLECTIBLES_SHOP_CARD_MAX_WIDTH } from "../CollectiblesShopCardV2";
import useWindowDimensions_native from "../../../screen/useWindowDimensions.native";
export function useCardLayout() {
const width = useWindowDimensions_native().width;
const columns = width >= 320 ? 2 : 1;
if (columns < 2) {
return {
columns,
cardWidth: void 0,
rowWidth: void 0
};
}
const r7 = width >= 768 ? 4 : 2;
const r2 = COLLECTIBLES_SHOP_CARD_WIDTH * columns;
const r31 = columns - 1;
const r33 = width - (r2 + COLLECTIBLES_SHOP_CARD_GAP * r31);
const r41 = r33 < 2 * COLLECTIBLES_SHOP_CARD_GAP ? Math.max(4, r33) : 2 * COLLECTIBLES_SHOP_CARD_GAP;
const r51 = (width - (r41 + COLLECTIBLES_SHOP_CARD_GAP * r31)) / columns;
let r55 = r51;
let columns2 = columns;
if (r51 > COLLECTIBLES_SHOP_CARD_MAX_WIDTH) {
let r58 = columns;
r55 = r51;
columns2 = r58;
while (columns2 < r7) {
const r63 = r58 + 1;
const r72 = (width - (r41 + COLLECTIBLES_SHOP_CARD_GAP * (r63 - 1))) / r63;
r55 = r72;
columns2 = r63;
if (!(r72 > COLLECTIBLES_SHOP_CARD_MAX_WIDTH)) {
break;
}
r58 = r63;
r55 = r72;
columns2 = r58;
}
}
const cardWidth = Math.min(Math.max(r55, COLLECTIBLES_SHOP_CARD_WIDTH), COLLECTIBLES_SHOP_CARD_MAX_WIDTH);
const r96 = cardWidth * columns2;
const r100 = columns2 - 1;
return r96 + (r41 + COLLECTIBLES_SHOP_CARD_GAP * r100) > width && 1 < columns2 ? {
columns: 1,
cardWidth: void 0,
rowWidth: void 0
} : {
columns: columns2,
cardWidth,
rowWidth: cardWidth * columns2 + COLLECTIBLES_SHOP_CARD_GAP * r100 + r41
};
}
@@ -0,0 +1,18 @@
// Metro module 8740 (f8741).
import { useMemo } from "react";
import UserStore from "../../../../stores/UserStore";
import { useStateFromStores } from "../../../../_bundle/Module589";
import { getCollectibleGoogleSkuId } from "../CollectiblesUtils";
export default function useCollectiblesExternalGatewayFacet(a0) {
const stateFromStores = useStateFromStores([UserStore], () => UserStore.getCurrentUser());
return useMemo(() => {
const collectibleGoogleSkuId = getCollectibleGoogleSkuId(a0, stateFromStores);
if (collectibleGoogleSkuId != null) {
return {
line_items: [{
external_product_id: collectibleGoogleSkuId
}]
};
}
}, [stateFromStores, a0]);
};
@@ -0,0 +1,26 @@
// Metro module 14103 (f14104).
import { useCallback, useMemo } from "react";
import UserStore from "../../../../stores/UserStore";
import { CollectiblesMobileShopScreen } from "../../CollectiblesShopConstants";
import { useBadBundleFilter } from "../../hooks/useBadBundleFilter";
import { useAndroidUnsyncedFilter } from "../useAndroidUnsyncedFilter";
import { usePurchasedProductsSort } from "../../hooks/usePurchasedProductsSort";
import { useStateFromStores } from "../../../../_bundle/Module589";
import PremiumUtils from "../../../../utils/PremiumUtils";
import { getProductOrbPrice } from "../../utils/CollectiblesProductUtils";
export function useFilteredAndSortedProducts({ products, maxProducts, bypassAndroidUnsyncedFilter, screen }) {
let callback, purchasedProductsSort;
callback = void 0;
purchasedProductsSort = void 0;
const badBundleFilter = useBadBundleFilter();
const androidUnsyncedFilter = useAndroidUnsyncedFilter();
const r1 = screen === CollectiblesMobileShopScreen.ORBS;
let c20908_0 = r1;
const canUseShopDiscounts = PremiumUtils.canUseShopDiscounts(useStateFromStores([UserStore], () => UserStore.getCurrentUser()));
callback = useCallback((a0) => c20908_0 ? a0.filter((item) => getProductOrbPrice({
product: item,
hasShopDiscount: canUseShopDiscounts
}) != null) : a0, [r1, canUseShopDiscounts]);
purchasedProductsSort = usePurchasedProductsSort(useMemo(() => [bypassAndroidUnsyncedFilter ? (a0) => a0 : androidUnsyncedFilter, badBundleFilter, callback].reduce((acc, item) => item(acc), products), [badBundleFilter, androidUnsyncedFilter, products, bypassAndroidUnsyncedFilter, callback]));
return useMemo(() => maxProducts != null ? purchasedProductsSort.slice(0, maxProducts) : purchasedProductsSort, [purchasedProductsSort, maxProducts]);
}
@@ -0,0 +1,13 @@
// Metro module 11888 (f11889).
import UserStore from "../../../../stores/UserStore";
import { useStateFromStores } from "../../../../_bundle/Module589";
import { getCollectibleGoogleSkuId } from "../CollectiblesUtils";
import useMobilePurchaseSKU_android from "../../../billing/native/hooks/useMobilePurchaseSKU.android";
export default function useMobileCollectiblesPurchaseSKU({ product, ...rest }) {
return useMobilePurchaseSKU_android({
...rest,
skuId: product.skuId,
platformSkuId: getCollectibleGoogleSkuId(product, useStateFromStores([UserStore], () => UserStore.getCurrentUser())),
isFreeForStaffSelfPurchase: true
});
};
@@ -0,0 +1,278 @@
// Metro module 14095 (f14096).
import { useState, useEffect, useMemo } from "react";
import StorefrontProductStore from "../../../storefront/StorefrontProductStore";
import UserStore from "../../../../stores/UserStore";
import CollectiblesCategoryStore from "../../CollectiblesCategoryStore";
import CollectiblesProductRecord from "../../records/CollectiblesProductRecord";
import { CollectiblesMobileShopScreen } from "../../CollectiblesShopConstants";
import Durations from "../../../../utils/Durations";
import { getProductOrbPrice } from "../../utils/CollectiblesProductUtils";
import { useStateFromStores, useStateFromStoresArray } from "../../../../_bundle/Module589";
import PremiumUtils from "../../../../utils/PremiumUtils";
import { BountiesShopCarouselExperimentVariation } from "../../../quests/experiments/BountiesShopCarouselExperiment";
import { CollectibleSearchSortType } from "../../../../_bundle/Module681";
import { search } from "../../api/Shopfront";
import { CollectibleSearchCurrencyFilter } from "../../../../_bundle/Module14099";
import { CollectibleSearchSortDirection } from "../../../../_bundle/Module682";
import { useFetchCollectiblesProducts } from "../../hooks/useFetchCollectiblesProducts";
import { maybeFetchProductsBySkuIds } from "../../../storefront/StorefrontProductActionCreators";
import { useGetOrFetchStorefrontPricesForSkuIds } from "../../../storefront/hooks/useGetOrFetchStorefrontPrices";
import useGetProductsFromSkus from "../../hooks/useGetProductsFromSkus";
import { useFilteredAndSortedProducts } from "./useFilteredAndSortedProducts";
const timeout = 10 * Durations.Millis.SECOND;
let c9861_12 = 10 * Durations.Millis.SECOND;
export const MIN_PRODUCTS_FOR_ORB_SHOP_CAROUSEL = 3;
export function usePopularOrbShopProducts(a0) {
let POPULARITY2;
let POPULARITY, stateFromStoresArray, stateFromStoresArray2, c20899_10, memo, filteredAndSortedProducts;
let enabled2 = a0.enabled;
const enabled = enabled2;
const variation = a0.variation;
POPULARITY = void 0;
stateFromStoresArray = void 0;
stateFromStoresArray2 = void 0;
c20899_10 = void 0;
memo = void 0;
filteredAndSortedProducts = void 0;
const [state, setState] = useState([]);
const [state2, setState2] = useState(false);
const [state3, setState3] = useState(false);
const canUseShopDiscounts = PremiumUtils.canUseShopDiscounts(useStateFromStores([UserStore], () => UserStore.getCurrentUser()));
if (BountiesShopCarouselExperimentVariation.POPULARITY === variation) {
POPULARITY2 = CollectibleSearchSortType.POPULARITY;
} else if (BountiesShopCarouselExperimentVariation.RECENCY === variation) {
POPULARITY2 = CollectibleSearchSortType.RECENCY;
} else {
BountiesShopCarouselExperimentVariation.BASE;
POPULARITY2 = CollectibleSearchSortType.POPULARITY;
}
POPULARITY = POPULARITY2;
useEffect(() => {
let c27631_0;
let _fetchSearchResults2 = function _fetchSearchResults() {
const r9 = async () => {
let skus, c31706_3;
let c31706_4 = 0;
let c32055_0;
L16: {
try {
c32055_0 = void 0;
c31706_4 = 2;
c32055_0 = await search({
item_types: [],
colors: [],
themes: [],
orbs_eligible: true,
currency: CollectibleSearchCurrencyFilter.ORBS,
offset: 0,
limit: 10,
sort_type: POPULARITY,
sort_direction: CollectibleSearchSortDirection.DESC
}, {
timeout
});
if (!c27631_0) {
const skus2 = c32055_0.skus;
skus = skus2;
if (skus2 == null) {
skus = [];
}
setState(skus);
}
c31706_4 = 1;
c31706_4 = 0;
if (!c27631_0) {
(0, setState2)(true);
}
} catch ($e) {
const r29 = $e;
let r7 = r29;
c31706_3 = r29;
let r30 = c31706_4;
if (r30 !== 0) {
while (true) {
if (r30 === 1) {
try {
const r103 = c31706_3;
c31706_4 = 0;
if (!c27631_0) {
(0, setState2)(true);
}
throw r103;
} catch (r101) {
r7 = r101;
c31706_3 = r101;
r30 = c31706_4;
if (r30 === 0) {
break;
}
}
} else {
try {
c31706_4 = 1;
if (!c27631_0) {
(0, setState)([]);
}
c31706_4 = 0;
if (c27631_0) {
break L16;
}
(0, setState2)(true);
break L16;
} catch (r86) {
r7 = r86;
c31706_3 = r86;
r30 = c31706_4;
if (r30 === 0) {
break;
}
}
}
}
}
throw r7;
}
}
};
_fetchSearchResults2 = r9;
return r9.apply(this, arguments);
};
if (enabled) {
c27631_0 = false;
setState2(false);
(function fetchSearchResults() {
return _fetchSearchResults2.apply(this, arguments);
})();
return () => {
c27631_0 = true;
};
}
setState([]);
setState2(false);
}, [enabled, POPULARITY]);
useEffect(() => {
if (enabled && state2) {
setState3(false);
let c27632_0 = setTimeout(() => setState3(true), c9861_12);
return () => clearTimeout(c27632_0);
}
setState3(false);
}, [enabled, state2, state]);
let isLoadingProducts = useFetchCollectiblesProducts(state);
useEffect(() => {
if (state.length !== 0) {
maybeFetchProductsBySkuIds({
skuIds: state
});
}
}, [state]);
useGetOrFetchStorefrontPricesForSkuIds({
skuIds: state
});
stateFromStoresArray = useStateFromStoresArray([StorefrontProductStore], () => state.map((item) => StorefrontProductStore.getProductsForSku(item)));
stateFromStoresArray2 = useStateFromStoresArray([StorefrontProductStore], () => state.map((item) => StorefrontProductStore.getFetchStateForSku(item)));
const getProductsFromSkus = useGetProductsFromSkus();
c20899_10 = getProductsFromSkus;
memo = useMemo(() => c20899_10(state).map((a0, index) => {
const r12 = stateFromStoresArray[index];
const productOrbPrice = getProductOrbPrice({
product: a0,
hasShopDiscount: canUseShopDiscounts
});
let r23 = a0;
if (productOrbPrice == null) {
const r26 = (function getStorefrontPricesForSkuId(c27630_0, a1) {
if (a1 == null) {
return null;
}
for (const item of a1) {
const r28 = item.skus.find((sku) => sku.id === c27630_0);
if (r28 == null) {
continue;
}
if (!(Object.keys(r28.prices).length > 0)) {
continue;
}
return r28.prices;
}
return null;
})(a0.skuId, r12);
r23 = a0;
if (r26 != null) {
const r27 = r12 == null ? void 0 : r12.flatMap((item) => item.skus).find((item) => item.id === a0.skuId);
const prices = {
...a0.prices,
...r26
};
let googleSkuIds = r27?.googleSkuIds;
if (googleSkuIds == null) {
googleSkuIds = a0.googleSkuIds;
}
r23 = new CollectiblesProductRecord({
storeListingId: a0.storeListingId,
skuId: a0.skuId,
name: a0.name,
summary: a0.summary,
styles: a0.styles,
type: a0.type,
premiumType: a0.premiumType,
items: a0.items,
categorySkuId: a0.categorySkuId,
isCategoryReward: a0.isCategoryReward,
prices,
bundledProducts: a0.bundledProducts,
previewAssets: a0.previewAssets,
googleSkuIds,
variants: a0.variants,
eligibleOffers: a0.eligibleOffers,
badgeOverride: a0.badgeOverride,
hideBadge: a0.hideBadge
});
}
}
return r23;
}), [getProductsFromSkus, state, stateFromStoresArray, canUseShopDiscounts]);
const memo2 = useMemo(() => state.length !== 0 && state.some((item, index) => {
const product = CollectiblesCategoryStore.getProduct(item);
if (product != null && getProductOrbPrice({
product,
hasShopDiscount: canUseShopDiscounts
}) != null) {
return false;
}
const r18 = stateFromStoresArray2[index];
return r18 === "loading" || r18 == null;
}), [state, stateFromStoresArray2, canUseShopDiscounts]);
filteredAndSortedProducts = useFilteredAndSortedProducts({
products: useMemo(() => memo.filter((item) => getProductOrbPrice({
product: item,
hasShopDiscount: canUseShopDiscounts
}) != null), [memo, canUseShopDiscounts]),
screen: CollectiblesMobileShopScreen.ORBS
});
const memo3 = useMemo(() => filteredAndSortedProducts.slice(0, 10), [filteredAndSortedProducts]);
if (!isLoadingProducts) {
isLoadingProducts = memo2;
}
const r122 = state2 ? state.length >= 3 : state2;
const r127 = memo3.length >= 3;
const isSearchingSkuIds = enabled ? !state2 : enabled;
if (enabled) {
enabled2 = r122;
}
if (enabled2) {
enabled2 = !r127;
}
if (enabled2) {
enabled2 = isLoadingProducts;
}
if (enabled2) {
enabled2 = !state3;
}
return {
products: memo3,
isSearchingSkuIds,
isLoadingProducts,
showPlaceholderCarousel: enabled2
};
}
@@ -0,0 +1,28 @@
// Metro module 14610 (f14611).
import { useRef, useEffect } from "react";
export const INITIAL_SCROLL_DELAY_MS = 100;
export function useScrollToInitialIndexOnce(a0) {
const { initialScrollIndex, shouldScroll, flashListRef, afterMs = 100 } = a0;
let c21252_3 = afterMs;
const resetKey = a0.resetKey;
const ref = useRef(false);
const ref2 = useRef(resetKey);
useEffect(() => {
if (ref2.current !== resetKey) {
ref2.current = resetKey;
ref.current = false;
}
if (initialScrollIndex != null && shouldScroll && !ref.current) {
ref.current = true;
setTimeout(() => {
const current = flashListRef.current;
if (current != null) {
current.scrollToIndex({
animated: true,
index: initialScrollIndex
});
}
}, c21252_3);
}
}, [shouldScroll, initialScrollIndex, afterMs, flashListRef, resetKey]);
}
@@ -0,0 +1,122 @@
// Metro module 8662 (f8663).
import { useRef, useEffect, useCallback } from "react";
import { AnalyticEvents } from "../../../../Constants";
import { useCollectiblesAnalyticsContext } from "../../CollectiblesAnalyticsContext";
import useAnalyticsLocations from "../../../app_analytics/useAnalyticsLocations";
import useWindowDimensions_native from "../../../screen/useWindowDimensions.native";
import { useCurrentUser } from "../../hooks/useCurrentUser";
import PremiumUtils from "../../../../utils/PremiumUtils";
import { getShopDiscountSource, getPriceForCollectiblesProduct, getStrikeThroughPriceAmountForCollectiblesProduct, getAnalyticsShopDiscountSource } from "../../CollectiblesUtils";
import AnalyticsUtils from "../../../../utils/AnalyticsUtils";
import { trackImpression } from "../../../app_analytics/useTrackImpression";
import { ImpressionNames, ImpressionTypes } from "../../../../_bundle/Module503";
import { getProductSkuIds } from "../../utils/CollectiblesProductUtils";
export function useTrackShopCardImpression(a0, a1, a2) {
let callback, callback2;
let c16700_0 = a0;
let c16700_1 = a1;
let c16700_2 = a2;
const collectiblesAnalyticsContext = useCollectiblesAnalyticsContext();
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
const windowDimensions_native = useWindowDimensions_native();
const { width, height } = windowDimensions_native;
const currentUser = useCurrentUser();
const canUseCollectibles = PremiumUtils.canUseCollectibles(currentUser);
const shopDiscountSource = getShopDiscountSource(currentUser);
const ref = useRef(null);
const ref2 = useRef(null);
const ref3 = useRef({
windowWidth: width,
windowHeight: height
});
const ref4 = useRef(false);
const ref5 = useRef(false);
const ref6 = useRef(false);
const ref7 = useRef(false);
useEffect(() => {
ref3.current = {
windowWidth: width,
windowHeight: height
};
}, [width, height]);
const sessionId = collectiblesAnalyticsContext?.sessionId;
callback = useCallback(() => {
const r10 = c16700_0 != null ? getPriceForCollectiblesProduct(c16700_0, canUseCollectibles, true) : null;
const display_price_strikethrough = c16700_0 != null ? getStrikeThroughPriceAmountForCollectiblesProduct(c16700_0, canUseCollectibles, true) : void 0;
const COLLECTIBLES_TILE_IMPRESSION = AnalyticEvents.COLLECTIBLES_TILE_IMPRESSION;
AnalyticsUtils.track(COLLECTIBLES_TILE_IMPRESSION, {
collectibles_shop_session_id: collectiblesAnalyticsContext?.sessionId,
sku_id: c16700_0.skuId,
display_price: r10?.amount,
display_price_currency: r10 == null ? void 0 : r10.currency.toString(),
display_price_strikethrough,
position: collectiblesAnalyticsContext?.tilePosition,
page_category: collectiblesAnalyticsContext?.pageCategory,
page_section: collectiblesAnalyticsContext?.pageSection,
category_position: collectiblesAnalyticsContext?.categoryPosition,
type: "product"
});
}, [canUseCollectibles, sessionId, collectiblesAnalyticsContext?.tilePosition, collectiblesAnalyticsContext?.pageCategory, collectiblesAnalyticsContext?.pageSection, collectiblesAnalyticsContext?.categoryPosition, a0]);
callback2 = useCallback(() => {
trackImpression({
name: ImpressionNames.SHOP_CARD,
type: ImpressionTypes.VIEW,
properties: {
sku_id: c16700_1.skuId,
card_id: collectiblesAnalyticsContext?.cardId,
shop_session_id: collectiblesAnalyticsContext?.sessionId,
position_in_section: collectiblesAnalyticsContext?.tilePosition,
product_sku_ids: getProductSkuIds(c16700_0),
location_stack: analyticsLocations,
discount_source: getAnalyticsShopDiscountSource(shopDiscountSource)
}
}, false, true);
}, [a0, a1, collectiblesAnalyticsContext?.cardId, collectiblesAnalyticsContext?.sessionId, collectiblesAnalyticsContext?.tilePosition, analyticsLocations, shopDiscountSource]);
useEffect(() => {
if (c16700_2) {
ref2.current = setInterval(() => {
if (ref.current != null) {
ref.current.measure((a0, a1, a2, a3, a4, a5) => {
const current = ref3.current;
const { windowWidth, windowHeight } = current;
const r36 = Math.max(0, Math.min(a5 + a3, windowHeight) - Math.max(a5, 0)) * Math.max(0, Math.min(a4 + a2, windowWidth) - Math.max(a4, 0));
const r37 = a2 * a3;
const current2 = r37 > 0 && r36 > 0 && r36 / r37 >= 0;
const r61 = Math.max(0, Math.min(a5 + a3, windowHeight) - Math.max(a5, 0)) * Math.max(0, Math.min(a4 + a2, windowWidth) - Math.max(a4, 0));
const r62 = a2 * a3;
const current3 = r62 > 0 && r61 > 0 && r61 / r62 >= 0.5;
if (current2) {
if (ref4.current && !ref5.current) {
callback();
ref5.current = true;
}
} else {
ref5.current = false;
}
ref4.current = current2;
if (current3) {
if (ref6.current && !ref7.current) {
callback2();
ref7.current = true;
}
} else {
ref7.current = false;
}
ref6.current = current3;
});
}
}, 1000);
return () => {
if (ref2.current !== null) {
clearInterval(ref2.current);
ref2.current = null;
}
ref4.current = false;
ref5.current = false;
ref6.current = false;
ref7.current = false;
};
}
}, [a2, callback, callback2]);
return ref;
}
@@ -0,0 +1,16 @@
// Metro module 8762 (f8763).
import { useMemo } from "react";
import { getProductOrbPrice } from "../../utils/CollectiblesProductUtils";
import { useFetchVirtualCurrencyBalance } from "../../../virtual_currency/hooks/index";
export function useVirtualCurrencyData(a0, a1) {
const productOrbPrice = getProductOrbPrice({
product: a0,
hasShopDiscount: a1
});
const balance = useFetchVirtualCurrencyBalance().balance;
return {
price: productOrbPrice,
balance,
canAfford: useMemo(() => productOrbPrice == null ? null : balance == null ? null : productOrbPrice.amount <= balance, [productOrbPrice, balance])
};
}
@@ -0,0 +1,16 @@
// Metro module 8769 (f8770).
import ModalActionCreators from "../../../actions/ModalActionCreators";
let c5727_3 = "Shop Gift Modal";
export const ShopGiftModalKey = "Shop Gift Modal";
export function openShopGiftModal({ navigationParams, skuId, analyticsLocations, lockedRecipientUser, onGiftModalDismiss, giftingOrigin }) {
ModalActionCreators.pushLazy(import("./CollectiblesShopGiftModal"), {
skuId,
analyticsLocations,
lockedRecipientUser,
onGiftModalDismiss,
giftingOrigin
}, c5727_3, navigationParams);
}
export function closeShopGiftModal() {
ModalActionCreators.popWithKey(c5727_3);
}
@@ -0,0 +1,17 @@
// Metro module 8731 (f8732).
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
import { productDetailsOpened } from "../CollectiblesActionCreators";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
let c5693_3 = "Shop Product Preview";
export const PRODUCT_DETAILS_ACTION_SHEET_KEY = "Shop Product Preview";
export function openProductDetailsActionSheet({ product, initialVariantIndex = 0, analyticsLocations, shopAnalyticsContext }, a1) {
const isVariantProduct = getIsVariantProduct(product);
const initialVariantIndex2 = isVariantProduct ? initialVariantIndex < product.variants.length ? initialVariantIndex : 0 : 0;
productDetailsOpened(isVariantProduct ? product.variants[initialVariantIndex2].skuId : product.skuId);
ActionSheetActionCreators.openLazy(import("./ProductDetailsActionSheet"), c5693_3, {
product,
initialVariantIndex: initialVariantIndex2,
analyticsLocations,
shopAnalyticsContext
}, a1);
}
@@ -0,0 +1,262 @@
// Metro module 14819 (f14820).
import { useState, useLayoutEffect, useEffect } from "react";
import { ScrollView, View } from "react-native";
import CollectiblesCategoryStore from "../../CollectiblesCategoryStore";
import CollectiblesPurchaseStore from "../../CollectiblesPurchaseStore";
import { useFramePreviewOverrideStore } from "../../profile_frames/native/tooling/FramePreviewOverrideStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import CollectiblesShopCardV2 from "../CollectiblesShopCardV2";
import { Text } from "../../../../design/components/Text/native/Text";
import { BaseTextButton } from "../../../../design/components/Button/native/BaseTextButton.native";
import { useStateFromStores } from "../../../../_bundle/defaultAreStatesEqual";
import useFetchCollectiblesCategoriesAndPurchases from "../../hooks/useFetchCollectiblesCategoriesAndPurchases";
import { ShopSkipCategoriesFilter } from "./ShopSkipCategoriesFilter";
import { TextInput } from "../../../../design/void/native";
import ProductPurchaseSuccessActionCreators from "../ProductPurchaseSuccessActionCreators";
let useStyles, UnpurchasedCollectiblesShopCardV2;
const FramePreviewOverrideSection = function FramePreviewOverrideSection() {
let r37;
let framePreviewOverrideStore;
const styles = useStyles();
const framePreviewOverrideStore3 = useFramePreviewOverrideStore((a0) => a0.override);
const framePreviewOverrideStore2 = useFramePreviewOverrideStore((a0) => a0.status);
let r5 = useFramePreviewOverrideStore((a0) => a0.error);
framePreviewOverrideStore = useFramePreviewOverrideStore((a0) => a0.loadFromDevice);
const framePreviewOverrideStore4 = useFramePreviewOverrideStore((a0) => a0.clear);
const r3 = framePreviewOverrideStore2 === "error";
const r19 = r3 ? styles.statusError : framePreviewOverrideStore2 === "loading" ? styles.statusLoading : styles.statusSuccess;
let r17 = "Loading…";
if (framePreviewOverrideStore2 !== "loading") {
if (r3) {
if (r5 == null) {
r5 = "Failed to load";
}
r37 = r5;
} else {
r37 = framePreviewOverrideStore3 != null ? `Showing "${framePreviewOverrideStore3.frameKey}" · ${framePreviewOverrideStore3.layers.length} layer${framePreviewOverrideStore3.layers.length === 1 ? "" : "s"}` : "No frame loaded";
}
r17 = r37;
}
return <View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Frame Preview Override</Text>
</View>
<Text variant="text-sm/normal" style={styles.description}>Overrides every profile-frame preview with a frame pushed to this device. Tap Load after Cap (or pushFrameOverride.mjs) pushes one.</Text>
<Text variant="text-xs/normal" style={[styles.statusText, r19]}>{r17}</Text>
<BaseTextButton pillStyle={styles.secondaryButton} text="Load from device" onPress={() => {
framePreviewOverrideStore();
}} />
{framePreviewOverrideStore3 != null && <BaseTextButton pillStyle={styles.secondaryButton} text="Clear override" onPress={framePreviewOverrideStore4} />}
</View>;
};
useStyles = createStyles({
container: {
flex: 1,
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW
},
scrollContainer: {
padding: Module712.space.PX_16,
paddingBottom: Module712.space.PX_32
},
section: {
backgroundColor: Module712.colors.BACKGROUND_SURFACE_HIGH,
borderRadius: Module712.radii.lg,
padding: Module712.space.PX_16,
marginBottom: Module712.space.PX_16,
borderWidth: 1,
borderColor: Module712.colors.BORDER_MUTED
},
sectionHeader: {
flexDirection: "row",
alignItems: "center",
marginBottom: Module712.space.PX_16
},
sectionTitle: {
flex: 1,
color: Module712.colors.TEXT_DEFAULT
},
inputContainer: {
marginBottom: Module712.space.PX_16
},
inputWrapper: {
backgroundColor: Module712.colors.BACKGROUND_BASE_LOW,
borderRadius: Module712.radii.md,
borderWidth: 1,
borderColor: Module712.colors.BORDER_MUTED,
padding: Module712.space.PX_4
},
inputLabel: {
marginBottom: Module712.space.PX_8,
color: Module712.colors.TEXT_DEFAULT,
fontWeight: "600"
},
statusText: {
marginTop: Module712.space.PX_8,
fontSize: 12,
fontWeight: "500"
},
statusSuccess: {
color: Module712.colors.TEXT_FEEDBACK_POSITIVE
},
statusError: {
color: Module712.colors.TEXT_FEEDBACK_CRITICAL
},
statusLoading: {
color: Module712.colors.TEXT_MUTED
},
previewContainer: {
marginBottom: Module712.space.PX_16
},
previewButton: {
backgroundColor: "#23a55a",
borderRadius: Module712.radii.md,
paddingVertical: Module712.space.PX_12,
alignItems: "center"
},
secondaryButton: {
backgroundColor: Module712.colors.BACKGROUND_MOD_NORMAL,
borderRadius: Module712.radii.md,
paddingVertical: Module712.space.PX_12,
alignItems: "center",
marginTop: Module712.space.PX_8
},
description: {
color: Module712.colors.TEXT_MUTED,
marginBottom: Module712.space.PX_12
},
placeholder: {
backgroundColor: Module712.colors.BACKGROUND_MOD_NORMAL,
borderRadius: Module712.radii.md,
borderWidth: 2,
borderStyle: "dashed",
borderColor: Module712.colors.BORDER_MUTED,
padding: Module712.space.PX_32,
alignItems: "center",
justifyContent: "center",
minHeight: 120
},
placeholderText: {
color: Module712.colors.TEXT_MUTED,
textAlign: "center",
fontSize: 14
}
});
UnpurchasedCollectiblesShopCardV2 = (props) => {
const [key, setState] = useState(0);
useLayoutEffect(() => {
const getPurchase = CollectiblesPurchaseStore.getPurchase;
CollectiblesPurchaseStore.getPurchase = () => {};
CollectiblesPurchaseStore.emitChange();
setState(1);
return () => {
CollectiblesPurchaseStore.getPurchase = getPurchase;
CollectiblesPurchaseStore.emitChange();
};
}, []);
return <CollectiblesShopCardV2 key={key} {...props} />;
};
export default () => {
const styles = useStyles();
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.categories);
const stateFromStores2 = useStateFromStores([CollectiblesPurchaseStore], () => CollectiblesPurchaseStore.purchases);
const stateFromStores3 = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.lastSuccessfulFetch);
const noOp = stateFromStores.size > 0 && stateFromStores2.size > 0 && stateFromStores3 != null;
const fetchCollectiblesCategoriesAndPurchases = useFetchCollectiblesCategoriesAndPurchases({
logPerf: false,
stalePurchasesOK: true,
noOp
});
const isFetching = fetchCollectiblesCategoriesAndPurchases.isFetching;
let categories = fetchCollectiblesCategoriesAndPurchases.categories;
let r21 = noOp;
if (!r21) {
let r54 = !isFetching;
if (!isFetching) {
if (noOp) {
categories = stateFromStores;
}
r54 = categories.size > 0;
}
r21 = r54;
}
let c21374_0 = r21;
const [state, onChangeText] = useState("");
const [state2, setState2] = useState(null);
const [state3, setState3] = useState(null);
useEffect(() => {
if (state.trim() !== "" && c21374_0) {
const product = CollectiblesCategoryStore.getProduct(state);
const categoryForProduct = CollectiblesCategoryStore.getCategoryForProduct(state);
if (product != null && categoryForProduct != null) {
setState2(product);
setState3(categoryForProduct);
} else {
setState2(null);
setState3(null);
}
return void 0;
}
setState2(null);
setState3(null);
}, [state, r21]);
const r96 = [<View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Shop Settings</Text>
</View>
<ShopSkipCategoriesFilter />
</View>, , , ,];
const r107 = [<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Product Configuration</Text>
</View>, ,];
const r115 = [<Text variant="text-md/semibold" style={styles.inputLabel}>Primary Product SKU ID</Text>, <View style={styles.inputWrapper}>
<TextInput value={state} onChangeText={onChangeText} placeholder="Enter product SKU ID (e.g., 1366494385482502184)" returnKeyType="done" style={{
fontSize: 14,
padding: Module712.space.PX_12
}} />
</View>, (r21 ? !r21 : state.trim() !== "") && <Text variant="text-xs/normal" style={[styles.statusText, styles.statusLoading]}>Loading products...</Text>, , ,];
if (r21) {
r21 = state.trim() !== "";
}
if (r21) {
r21 = state2 == null;
}
if (r21) {
r21 = <Text variant="text-xs/normal" style={[styles.statusText, styles.statusError]}>Product not found</Text>;
}
r115[3] = r21;
r115[4] = state2 != null && <Text variant="text-xs/normal" style={[styles.statusText, styles.statusSuccess]}>
{"Found: "}
{state2.name}
</Text>;
r107[1] = <View style={styles.inputContainer}>{r115}</View>;
r96[1] = <View style={styles.section}>{r107}</View>;
r96[2] = <View style={styles.section}>
<View style={styles.sectionHeader}>
<Text variant="heading-md/semibold" style={styles.sectionTitle}>Product Preview</Text>
</View>
{state2 != null && state3 != null ? <View>
<View style={styles.previewContainer}>
<UnpurchasedCollectiblesShopCardV2 product={state2} />
</View>
<BaseTextButton pillStyle={styles.previewButton} text="Show Collectibles Modal" onPress={function onPress() {
if (state2 != null) {
ProductPurchaseSuccessActionCreators.open({
product: state2,
useCategoryImage: true
});
}
}} />
</View> : <View style={styles.placeholder}>
<Text variant="text-sm/normal" style={styles.placeholderText}>
Enter a valid product SKU ID above
{"\n"}
to see the product preview
</Text>
</View>}
</View>;
r96[3] = <FramePreviewOverrideSection />;
return <View style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollContainer} showsVerticalScrollIndicator={false}>{r96}</ScrollView>
</View>;
};
@@ -0,0 +1,66 @@
// Metro module 14820 (f14821).
import { Pressable, View } from "react-native";
import CollectiblesCategoryStore from "../../CollectiblesCategoryStore";
import { createStyles } from "../../../../design/components/Styles/native/createStyles";
import Module712 from "../../../../_bundle/Module712";
import { useStateFromStores } from "../../../../_bundle/Module589";
import { Stack } from "../../../../design/components/Stack/native/Stack.native";
import { Text } from "../../../../design/components/Text/native/Text";
import { setSkipNumCategories } from "../../CollectiblesActionCreators";
const useStyles = createStyles({
container: {
paddingVertical: Module712.space.PX_12,
paddingHorizontal: Module712.space.PX_16
},
label: {
marginBottom: Module712.space.PX_8
},
stepperContainer: {
flexDirection: "row",
alignItems: "center",
gap: Module712.space.PX_12
},
stepperButton: {
width: 32,
height: 32,
borderRadius: Module712.radii.xs,
backgroundColor: Module712.colors.CONTROL_OVERLAY_SECONDARY_BACKGROUND_DEFAULT,
justifyContent: "center",
alignItems: "center"
},
stepperButtonDisabled: {
opacity: 0.5
},
valueText: {
minWidth: 40,
textAlign: "center"
}
});
export function ShopSkipCategoriesFilter() {
const styles = useStyles();
const stateFromStores = useStateFromStores([CollectiblesCategoryStore], () => CollectiblesCategoryStore.skipNumCategories);
const disabled = stateFromStores <= 0;
const disabled2 = stateFromStores >= 100;
return <View style={styles.container}>
<Stack spacing={8}>
<Text variant="text-md/normal" style={styles.label}>Hide first # of categories</Text>
<View style={styles.stepperContainer}>
<Pressable style={[styles.stepperButton, disabled && styles.stepperButtonDisabled]} onPress={function onPress() {
if (stateFromStores > 0) {
setSkipNumCategories(stateFromStores - 1);
}
}} disabled={disabled}>
<Text variant="text-lg/semibold">−</Text>
</Pressable>
<Text variant="text-md/semibold" style={styles.valueText}>{stateFromStores}</Text>
<Pressable style={[styles.stepperButton, disabled2 && styles.stepperButtonDisabled]} onPress={function onPress() {
if (stateFromStores < 100) {
setSkipNumCategories(stateFromStores + 1);
}
}} disabled={disabled2}>
<Text variant="text-lg/semibold">+</Text>
</Pressable>
</View>
</Stack>
</View>;
}
@@ -0,0 +1,13 @@
// Metro module 14105 (f14106).
import { useCallback } from "react";
import DevSettingsStore from "../../devtools/dev_settings/DevSettingsStore";
import IAPStore_android from "../../../stores/native/IAPStore.android";
import { useStateFromStores } from "../../../_bundle/Module589";
import { isGooglePlayBillingSupported } from "../../device/BillingPlatformUtils";
import { isGPlaySynced } from "./CollectiblesUtils";
export function useAndroidUnsyncedFilter() {
let stateFromStores2;
const stateFromStores = useStateFromStores([IAPStore_android], () => IAPStore_android.isFetchingGoogleSkus());
stateFromStores2 = useStateFromStores([DevSettingsStore], () => DevSettingsStore.get("bypass_google_sku_sync"));
return useCallback((a0) => isGooglePlayBillingSupported() ? stateFromStores2 ? a0 : stateFromStores ? a0 : a0.filter((item) => isGPlaySynced(item)) : a0, [stateFromStores, stateFromStores2]);
}
@@ -0,0 +1,11 @@
// Metro module 9794 (f9795).
import useWindowDimensions_native from "../../screen/useWindowDimensions.native";
import { avatarPlaceholderSizeRatio } from "./AvatarDecorationSampleV2";
export function useAvatarDecorationPreviewSizes() {
const windowDimensions_native = useWindowDimensions_native();
const avatarDecorationSize = 2 * Math.min(windowDimensions_native.width, windowDimensions_native.height) / 3;
return {
avatarDecorationSize,
avatarSize: avatarDecorationSize * avatarPlaceholderSizeRatio
};
}
@@ -0,0 +1,14 @@
// Metro module 7963 (f7964).
import { useCallback, useState } from "react";
export default function useCollectibleListLayout() {
const [size, setState] = useState(0);
return {
size,
onLayout: useCallback((a0) => {
setState((a0.nativeEvent.layout.width - 64) / 3);
}, [])
};
};
export const GUTTER_SIZE = 16;
export const ROW_SIZE = 3;
export const COLLECTIBLE_ROW_HEIGHT = 114;
@@ -0,0 +1,50 @@
// Metro module 14608 (f14609).
import { useMemo } from "react";
import CollectiblesCategoryStore from "../CollectiblesCategoryStore";
import CollectiblesShopStore from "../CollectiblesShopStore";
import { useStateFromStoresObject } from "../../../_bundle/Module589";
import { getIsVariantProduct } from "../utils/CollectiblesProductUtils";
let c10299_5 = {};
export function useCollectiblesShopDeepLinkProps({ categories, products }) {
let initialCategorySkuId, initialBaseProductSkuId, initialVariantIndex;
initialCategorySkuId = void 0;
initialBaseProductSkuId = void 0;
initialVariantIndex = void 0;
const stateFromStoresObject = useStateFromStoresObject([CollectiblesCategoryStore, CollectiblesShopStore], () => {
const initialProductSkuId = CollectiblesShopStore.initialProductSkuId;
const product = CollectiblesCategoryStore.getProduct(initialProductSkuId);
const r2 = product != null;
let initialVariantIndex2 = 0;
let initialBaseProductSkuId2 = initialProductSkuId;
if (r2) {
const r15 = product.variantGroupStoreListingId != null;
initialVariantIndex2 = 0;
initialBaseProductSkuId2 = initialProductSkuId;
if (r15) {
const productByStoreListingId = CollectiblesCategoryStore.getProductByStoreListingId(product.variantGroupStoreListingId);
const r18 = productByStoreListingId != null && getIsVariantProduct(productByStoreListingId);
initialVariantIndex2 = 0;
initialBaseProductSkuId2 = initialProductSkuId;
if (r18) {
initialBaseProductSkuId2 = productByStoreListingId.skuId;
initialVariantIndex2 = Math.max(0, productByStoreListingId.variants.findIndex((variant) => variant.skuId === initialProductSkuId));
}
}
}
return {
initialCategorySkuId: CollectiblesCategoryStore.getCategoryForProduct(initialProductSkuId)?.skuId,
initialBaseProductSkuId: initialBaseProductSkuId2,
initialVariantIndex: initialVariantIndex2
};
});
initialCategorySkuId = stateFromStoresObject.initialCategorySkuId;
initialBaseProductSkuId = stateFromStoresObject.initialBaseProductSkuId;
initialVariantIndex = stateFromStoresObject.initialVariantIndex;
return useMemo(() => initialBaseProductSkuId != null && initialCategorySkuId != null ? {
initialProductSkuId: initialBaseProductSkuId,
initialVariantIndex,
initialCategorySkuId,
productIndex: products != null ? Math.max(0, products.findIndex((product) => product.skuId === initialBaseProductSkuId)) : void 0,
categoryIndex: categories != null ? Math.max(0, categories.findIndex((category) => category.skuId === initialCategorySkuId)) : void 0
} : c10299_5, [initialBaseProductSkuId, initialVariantIndex, initialCategorySkuId, products, categories]);
}
@@ -0,0 +1,167 @@
// Metro module 14634 (f14635).
import { useMemo, useCallback, useLayoutEffect } from "react";
import { View } from "react-native";
import UserStore from "../../../stores/UserStore";
import { CollectiblesMobileShopScreen } from "../CollectiblesShopConstants";
import { AnalyticEvents } from "../../../Constants";
import { RewardFilterTypes } from "../../quests/QuestConstants";
import { UserProfileSections } from "../../user_profile/Constants";
import { createStyles } from "../../../design/components/Styles/native/createStyles";
import Module712 from "../../../_bundle/Module712";
import { ShopIcon } from "../../../design/components/Icon/native/redesign/generated/ShopIcon";
import { Heading } from "../../../design/components/Text/native/Text";
import { intl, t } from "../../../intl/index.native";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useFetchVirtualCurrencyBalance } from "../../virtual_currency/hooks/useFetchVirtualCurrencyBalance";
import { openCollectiblesShopMobile } from "../CollectiblesActionCreators";
import AnalyticsLocation from "../../app_analytics/AnalyticsLocation";
import { CheckmarkSmallIcon } from "../../../design/components/Icon/native/redesign/generated/CheckmarkSmallIcon";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import AnalyticsUtils from "../../../utils/AnalyticsUtils";
import { openQuestHome } from "../../quests/native/QuestUtils.native";
import { QuestContent } from "../../quests/QuestTypes";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import showUserProfileActionSheet from "../../user_profile/native/showUserProfileActionSheet";
import { BalanceWidgetPillButton } from "../../virtual_currency/native/index";
import { IconButton } from "../../../design/components/Button/native/IconButton.native";
import { HeartIcon } from "../../../design/components/Icon/native/redesign/generated/HeartIcon";
import { ContextMenu } from "../../../design/components/ContextMenu/native/ContextMenu.native";
import { MenuIcon } from "../../../design/components/Icon/native/redesign/generated/MenuIcon";
import { useNavigation } from "../../../design/components/Navigator/native/useNavigation.native";
let useStyles, CollectiblesShopHeaderRight;
const CollectiblesShopHeaderTitle = function CollectiblesShopHeaderTitle(props) {
const currentScreen3 = props.currentScreen;
const styles = useStyles();
return <View style={styles.headerTitleContainer}>
<ShopIcon size="md" color="icon-strong" />
<Heading variant="redesign/heading-18/bold" color="mobile-text-heading-primary" maxFontSizeMultiplier={2} lineClamp={1} style={styles.headerTitle}>
{currentScreen3 === CollectiblesMobileShopScreen.ORBS ? intl.string(t.ElYQFS) : intl.string(t.pWG4ze)}
</Heading>
</View>;
};
CollectiblesShopHeaderRight = function CollectiblesShopHeaderRight(props) {
let balance;
const currentScreen = props.currentScreen;
balance = void 0;
const styles = useStyles();
const stateFromStores = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), []);
balance = useFetchVirtualCurrencyBalance().balance;
const memo = useMemo(() => [{
label: intl.string(t["xNiB/O"]),
action: () => {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_FEATURED_PAGE_MENU_ITEM],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_FEATURED_PAGE_MENU_ITEM,
screen: CollectiblesMobileShopScreen.FEATURED_PAGE
});
},
trailingIndicator: currentScreen === CollectiblesMobileShopScreen.FEATURED_PAGE ? CheckmarkSmallIcon : void 0
}, {
label: intl.string(t.RSyoZu),
action: () => {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_SHOP_ALL_MENU_ITEM],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_SHOP_ALL_MENU_ITEM,
screen: CollectiblesMobileShopScreen.SHOP_ALL
});
},
trailingIndicator: currentScreen === CollectiblesMobileShopScreen.SHOP_ALL ? CheckmarkSmallIcon : void 0
}, {
label: intl.string(t.EBYkzk),
action: () => {
openCollectiblesShopMobile({
analyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_ORBS_MENU_ITEM],
analyticsSource: AnalyticsLocation.COLLECTIBLES_SHOP_MOBILE_ORBS_MENU_ITEM,
screen: CollectiblesMobileShopScreen.ORBS
});
},
trailingIndicator: currentScreen === CollectiblesMobileShopScreen.ORBS ? CheckmarkSmallIcon : void 0
}], [currentScreen]);
const callback = useCallback(() => {
ActionSheetActionCreators.openLazy(() => import("../../virtual_currency/native/BalanceWidgetActionSheet").then((result) => result.default), "BalanceWidgetActionSheet", {
balance,
primaryButtonConfig: {
buttonText: intl.string(t.SymzJC),
onButtonPress: () => {
AnalyticsUtils.track(AnalyticEvents.ORB_BALANCE_ACTION_SHEET_ACTION, {
type: "GO_TO_QUEST_HOME",
source: AnalyticsLocation.COLLECTIBLES_SHOP,
balance
});
ActionSheetActionCreators.hideActionSheet();
openQuestHome({
mergeExistingRoutes: true,
filter: RewardFilterTypes.VIRTUAL_CURRENCY,
fromContent: QuestContent.ORBS_BALANCE_MENU
});
}
},
secondaryButtonConfig: {
buttonText: intl.string(t["/g10LC"]),
onButtonPress: () => {
AnalyticsUtils.track(AnalyticEvents.ORB_BALANCE_ACTION_SHEET_ACTION, {
type: "GO_BACK",
source: AnalyticsLocation.COLLECTIBLES_SHOP,
balance
});
ActionSheetActionCreators.hideActionSheet();
}
},
source: AnalyticsLocation.COLLECTIBLES_SHOP
});
}, [balance]);
const callback2 = useCallback(() => {
if (stateFromStores?.id != null) {
AnalyticsUtils.track(AnalyticEvents.COLLECTIBLES_SHOP_ELEMENT_CLICKED, {
cta_name: "wishlist header button",
page_type: currentScreen
});
ModalActionCreators.popAll();
showUserProfileActionSheet({
userId: stateFromStores.id,
sourceAnalyticsLocations: [AnalyticsLocation.COLLECTIBLES_SHOP],
initialSection: UserProfileSections.WISHLIST
});
}
}, [currentScreen, stateFromStores?.id]);
return <View style={styles.headerRightContainer}>
<BalanceWidgetPillButton balance={balance} onPress={callback} />
{stateFromStores != null && <IconButton accessibilityLabel={intl.string(t["7lZ31J"])} variant="tertiary" size="sm" icon={<HeartIcon size="sm" color="redesign-button-tertiary-text" />} onPress={callback2} />}
<ContextMenu key={currentScreen} items={memo} align="below" title={intl.string(t.nSFuC0)} keyboardShouldPersistTaps="handled">
{(a0) => {
const { ref, ...rest } = a0;
return <IconButton ref={a0.ref} {...rest} variant="tertiary" accessibilityLabel={intl.string(t.nSFuC0)} size="sm" icon={<MenuIcon size="sm" color="redesign-button-tertiary-text" />} />;
}}
</ContextMenu>
</View>;
};
useStyles = createStyles({
headerTitleContainer: {
width: "100%",
flexDirection: "row",
alignItems: "center",
marginTop: Module712.space.PX_8,
paddingLeft: Module712.space.PX_8,
gap: Module712.space.PX_8
},
headerTitle: {
flexShrink: 1
},
headerRightContainer: {
flexDirection: "row",
justifyContent: "flex-end",
alignItems: "center",
gap: Module712.space.PX_8,
marginTop: Module712.space.PX_8
}
});
export default function useCollectiblesShopHeader(r3 = {}) {
const currentScreen2 = r3.currentScreen;
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.setOptions({
headerTitle: () => <CollectiblesShopHeaderTitle currentScreen={currentScreen2} />,
headerRight: () => <CollectiblesShopHeaderRight currentScreen={currentScreen2} />
});
}, [navigation, currentScreen2]);
};
@@ -0,0 +1,145 @@
// Metro module 11909 (f11910).
import { useState, useCallback } from "react";
import { Routes } from "../../../Constants";
import Logger from "../../debug/Logger";
import useMobileCollectiblesPurchaseSKU_android from "./hooks/useMobileCollectiblesPurchaseSKU.android";
import { fetchCollectiblesPurchases } from "../CollectiblesActionCreators";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import ProductPurchaseSuccessActionCreators from "./ProductPurchaseSuccessActionCreators";
import { isMetaQuest } from "../../device/MetaQuestUtils.android";
import MobileWebHandoffLinking from "../../mobile_web_handoff/native/MobileWebHandoffLinking";
import { captureBillingException } from "../../../utils/BillingUtils";
import ToastActionCreators from "../../toast/native/ToastActionCreators";
import { intl, t } from "../../../intl/index.native";
let c8163_7;
export function useHandleBuyNow({ product, analyticsLocations, onBuy, orderId }) {
let state, setState, c19265_4;
state = void 0;
setState = void 0;
c19265_4 = void 0;
let _onPurchaseComplete2 = function _onPurchaseComplete() {
const r9 = async () => {
let c30473_0;
c30473_0 = void 0;
await fetchCollectiblesPurchases();
(0, setState)(false);
ActionSheetActionCreators.hideActionSheet();
ProductPurchaseSuccessActionCreators.open({
product,
useCategoryImage: true
});
};
_onPurchaseComplete2 = r9;
return r9.apply(this, arguments);
};
[state, setState] = useState(false);
const mobileCollectiblesPurchaseSKU_android = useMobileCollectiblesPurchaseSKU_android({
product,
analyticsLocations,
onPurchaseComplete: function onPurchaseComplete() {
return _onPurchaseComplete2.apply(this, arguments);
},
onPurchaseError: function onPurchaseError() {
setState(false);
},
onPurchasePending: function onPurchasePending() {},
orderId
});
c19265_4 = mobileCollectiblesPurchaseSKU_android;
return {
handleBuyNow: useCallback(async () => {
let c27207_2;
let c27207_3 = 0;
let c30474_0, c30474_1;
L16: {
L18: {
try {
if (isMetaQuest()) {
c27207_3 = 1;
await MobileWebHandoffLinking.redirectWithHandoffToken(`${Routes.COLLECTIBLES_SHOP}#itemSkuId=${product.skuId}`, {
forceExternalBrowser: true
});
ActionSheetActionCreators.hideActionSheet();
c27207_3 = 0;
break L16;
}
c27207_3 = 2;
if (state) {
c27207_3 = 0;
break L18;
}
setState(true);
await c19265_4();
if (onBuy != null) {
(0, onBuy)();
}
c27207_3 = 0;
break L16;
} catch ($e) {
const r40 = $e;
let r7 = r40;
c27207_2 = r40;
let r41 = c27207_3;
if (r41 !== 0) {
while (true) {
if (r41 === 1) {
try {
const r164 = c27207_2;
c27207_3 = 0;
c30474_0 = r164;
c8163_7.error(`Error performing web handoff: ${JSON.stringify(c30474_0)}`);
captureBillingException(c30474_0, {
tags: {
source: "useHandleBuyNow",
skuId: product.skuId
}
});
ToastActionCreators.open({
key: "SHOP_ITEM_HANDOFF_ERROR",
content: intl.string(t["rTU7/z"])
});
break L16;
} catch (r161) {
r7 = r161;
c27207_2 = r161;
r41 = c27207_3;
if (r41 === 0) {
break;
}
}
} else {
try {
const r135 = c27207_2;
c27207_3 = 0;
c30474_1 = r135;
(0, setState)(false);
c8163_7.error(`Error running purchase: ${JSON.stringify(c30474_1)}`);
captureBillingException(c30474_1, {
tags: {
source: "useHandleBuyNow",
skuId: product.skuId
}
});
break L16;
} catch (r133) {
r7 = r133;
c27207_2 = r133;
r41 = c27207_3;
if (r41 === 0) {
break;
}
}
}
}
}
throw r7;
}
}
return void 0;
}
}, [mobileCollectiblesPurchaseSKU_android, state, onBuy, product.skuId]),
isBuying: state
};
}
c8163_7 = new Logger("useHandleBuyNow");
export default useHandleBuyNow;
@@ -0,0 +1,47 @@
// Metro module 11910 (f11911).
import { useCallback } from "react";
import { claimPremiumCollectiblesProduct, fetchCollectiblesPurchases } from "../CollectiblesActionCreators";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import ProductPurchaseSuccessActionCreators from "./ProductPurchaseSuccessActionCreators";
import ToastActionCreators from "../../toast/native/ToastActionCreators";
import { intl, t } from "../../../intl/index.native";
export function useHandleClaim({ product }) {
return {
handleClaim: useCallback(async () => {
let c27208_3 = 0;
L10: {
try {
c27208_3 = 1;
await claimPremiumCollectiblesProduct(product.skuId);
ActionSheetActionCreators.hideActionSheet();
ProductPurchaseSuccessActionCreators.open({
product,
useCategoryImage: true
});
fetchCollectiblesPurchases();
c27208_3 = 0;
} catch ($e) {
let r7 = $e;
if (c27208_3 !== 0) {
while (true) {
try {
c27208_3 = 0;
ToastActionCreators.open({
key: "collectible shop claim error",
content: intl.string(t.CKsXk3)
});
break L10;
} catch ($e) {
r7 = $e;
if (c27208_3 === 0) {
break;
}
}
}
}
throw r7;
}
}
}, [product])
};
}
@@ -0,0 +1,54 @@
// Metro module 9796 (f9797).
import { useCallback } from "react";
import { RootNavigatorScreen } from "../../main_tabs_v2/native/MainTabsConstants";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
import ModalActionCreators from "../../../actions/ModalActionCreators";
import { getRootNavigationRef } from "../../main_tabs_v2/RootNavigationRef.native";
import ToastActionCreators from "../../toast/native/ToastActionCreators";
import { intl, t } from "../../../intl/index.native";
import * as _useHandleUseNow from "../hooks/useHandleUseNow";
import useOpenProfileSettings from "../../profile_customization/useOpenProfileSettings";
export function useHandleUseNow({ product, onSuccess, analyticsLocations }) {
let c17499_1;
c17499_1 = void 0;
const handleUseNow = _useHandleUseNow.useHandleUseNow({
product,
onSuccess: useCallback(() => {
if (onSuccess == null) {
ActionSheetActionCreators.hideActionSheet();
ModalActionCreators.popAll();
const rootNavigationRef = getRootNavigationRef();
if (rootNavigationRef != null && rootNavigationRef.isReady()) {
rootNavigationRef.navigate(RootNavigatorScreen.YOU);
}
} else {
onSuccess();
}
}, [onSuccess]),
onError: useCallback(() => {
ToastActionCreators.open({
key: "collectible shop apply error",
content: intl.string(t.CKsXk3)
});
}, [])
});
const { handleUseNow: handleUseNow2, isApplying, canUseNow } = handleUseNow;
const openProfileSettings = useOpenProfileSettings({
analyticsLocations
});
c17499_1 = openProfileSettings;
return {
handleUseNow: handleUseNow2,
isApplying,
canUseNow,
handleEditProfile: useCallback(() => {
c17499_1();
if (onSuccess == null) {
ActionSheetActionCreators.hideActionSheet();
ModalActionCreators.popAll();
} else {
onSuccess();
}
}, [openProfileSettings, onSuccess])
};
}
@@ -0,0 +1,20 @@
// Metro module 8760 (f8761).
import { useCallback } from "react";
import { AnalyticsPages, AnalyticsSections } from "../../../Constants";
import { PremiumTypes } from "../../premium/PremiumConstants";
import useAnalyticsLocations from "../../app_analytics/useAnalyticsLocations";
import openPremiumPlanSelectionActionSheet from "../../premium/native/openPremiumPlanSelectionActionSheet";
export default function useOpenNitroSubscribeActionSheet(r5 = AnalyticsSections.COLLECTIBLES_SHOP) {
const COLLECTIBLES_SHOP = r5;
const analyticsLocations = useAnalyticsLocations().analyticsLocations;
return useCallback(() => {
openPremiumPlanSelectionActionSheet({
analyticsLocation: {
page: AnalyticsPages.COLLECTIBLES_SHOP,
section: COLLECTIBLES_SHOP
},
analyticsLocations,
premiumType: PremiumTypes.TIER_2
});
}, [analyticsLocations, COLLECTIBLES_SHOP]);
};
@@ -0,0 +1,30 @@
// Metro module 14603 (f14604).
import { useRef, useEffect } from "react";
import { isMetaQuest } from "../../device/MetaQuestUtils.android";
import { lockOrientation, unlockOrientation } from "../../device/native/DeviceOrientation";
let c10295_3 = 0;
export function useShopOrientationLock() {
const ref = useRef(false);
useEffect(() => {
if (isMetaQuest()) {
return void 0;
}
if (c10295_3 === 0) {
lockOrientation("PORTRAIT", true);
}
ref.current = true;
c10295_3 = c10295_3 + 1;
return () => {
if (ref.current) {
const r0 = c10295_3 - 1;
c10295_3 = r0;
if (r0 === 0) {
unlockOrientation({
unlockAfterRotatingToPreviousLock: false
});
}
ref.current = false;
}
};
}, []);
}
@@ -0,0 +1,58 @@
// Metro module 8667 (f8668).
import { useCallback } from "react";
import UserProfileStore from "../../user_profile/UserProfileStore";
import AuthenticationStore from "../../../stores/AuthenticationStore";
import { ContentDismissActionType } from "../../dismissible_content/DismissibleContentConstants";
import { useStateFromStores } from "../../../_bundle/Module589";
import { useIsDismissibleContentDismissed_UNSAFE, UNSAFE_markDismissibleContentAsDismissed } from "../../dismissible_content/DismissibleContentUnsafeUtils";
import { DismissibleContent } from "../../../_bundle/Module1358";
import { trackDismissibleContentShown } from "../../dismissible_content/DismissibleContentUtils";
import ActionSheetActionCreators from "../../action_sheet/native/ActionSheetActionCreators";
function $mk81102($env) {
return () => $env.$parent[4].getFirstWishlistId($env[0]);
}
function $mk81103($env) {
return () => {
const userProfile = $env.$parent[4].getUserProfile($env[0]);
return userProfile != null && userProfile.fetchEndedAt > 0;
};
}
let $mk81101 = function() {
return () => AuthenticationStore.getId();
};
let env5643 = {};
export default function useWishlistNUXActionSheet() {
let env16703;
const r4 = env16703 = {
$parent: env5643
};
env16703[0] = useStateFromStores([AuthenticationStore], $mk81101());
const stateFromStores = useStateFromStores([UserProfileStore], $mk81102(r4));
let shouldShowWishlistNUXActionSheet = useStateFromStores([UserProfileStore], $mk81103(r4)) && stateFromStores == null;
const isDismissibleContentDismissed_UNSAFE = useIsDismissibleContentDismissed_UNSAFE(DismissibleContent.WISHLIST_MOBILE_NUX_ACTION_SHEET);
if (shouldShowWishlistNUXActionSheet) {
shouldShowWishlistNUXActionSheet = !isDismissibleContentDismissed_UNSAFE;
}
return {
shouldShowWishlistNUXActionSheet,
showWishlistNUXActionSheet: useCallback((a0) => {
trackDismissibleContentShown(DismissibleContent.WISHLIST_MOBILE_NUX_ACTION_SHEET);
ActionSheetActionCreators.openLazy(import("./WishlistNUXAddedItemActionSheet"), "WishlistNUXAddedItemActionSheet", {
product: a0
}, "stack");
UNSAFE_markDismissibleContentAsDismissed(DismissibleContent.WISHLIST_MOBILE_NUX_ACTION_SHEET, {
dismissAction: ContentDismissActionType.USER_DISMISS,
forceTrack: true
});
}, [])
};
};
export function useHasNeverWishlisted() {
let env16702;
const r1 = env16702 = {
$parent: env5643
};
env16702[0] = useStateFromStores([AuthenticationStore], $mk81101());
const stateFromStores = useStateFromStores([UserProfileStore], $mk81102(r1));
return useStateFromStores([UserProfileStore], $mk81103(r1)) && stateFromStores == null;
}