Files
discord-decomp/modules/collectibles/native/CollectiblesShopCardV2.tsx
T
2026-11-01 12:12:55 +02:00

291 lines
14 KiB
TypeScript

// 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;