Skip to content

Commit

Permalink
Hide collectibles based on feature flag (#6073)
Browse files Browse the repository at this point in the history
* hide collectibles section based on feature flag

* change default remote config

* re-enable for e2e

* what happened to the linter
  • Loading branch information
walmat authored and ibrahimtaveras00 committed Sep 4, 2024
1 parent 103510e commit 4ca3624
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 17 deletions.
10 changes: 7 additions & 3 deletions src/components/asset-list/RecyclerAssetList2/NFTEmptyState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Animated from 'react-native-reanimated';
import { Box, Stack, Text, useColorMode } from '@/design-system';
import * as i18n from '@/languages';
import { TokenFamilyHeaderHeight } from './NFTLoadingSkeleton';
import { MINTS, useExperimentalFlag } from '@/config';
import { MINTS, NFTS_ENABLED, useExperimentalFlag } from '@/config';
import { useRemoteConfig } from '@/model/remoteConfig';
import { IS_TEST } from '@/env';
import { useMints } from '@/resources/mints';
Expand Down Expand Up @@ -44,7 +44,8 @@ const LaunchFeaturedMintButton = ({ featuredMint }: LaunchFeaturedMintButtonProp
as={Animated.View}
borderRadius={15}
justifyContent="center"
paddingHorizontal="10px"
paddingVertical="12px"
paddingHorizontal="20px"
style={[{ backgroundColor: isDarkMode ? SEPARATOR_COLOR : LIGHT_SEPARATOR_COLOR }]}
>
<Text size="13pt" color={'label'} style={{ opacity: isDarkMode ? 0.6 : 0.75 }} weight="heavy">
Expand All @@ -58,15 +59,18 @@ const LaunchFeaturedMintButton = ({ featuredMint }: LaunchFeaturedMintButtonProp
};

export function NFTEmptyState() {
const { mints_enabled } = useRemoteConfig();
const { mints_enabled, nfts_enabled } = useRemoteConfig();
const { accountAddress } = useAccountSettings();

const {
data: { featuredMint },
} = useMints({ walletAddress: accountAddress });

const nftsEnabled = (useExperimentalFlag(NFTS_ENABLED) || nfts_enabled) && !IS_TEST;
const mintsEnabled = (useExperimentalFlag(MINTS) || mints_enabled) && !IS_TEST;

if (!nftsEnabled) return null;

return (
<Box
alignItems="center"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { useForegroundColor } from '@/design-system';
import { useTheme } from '@/theme';
import { opacity } from '@/__swaps__/utils/swaps';
import { deviceUtils } from '@/utils';
import { NFTS_ENABLED, useExperimentalFlag } from '@/config';
import { useRemoteConfig } from '@/model/remoteConfig';
import { IS_TEST } from '@/env';

export const TokenFamilyHeaderHeight = 50;

Expand Down Expand Up @@ -45,6 +48,11 @@ const NFTItem = () => {
};

const NFTLoadingSkeleton = ({ items = 5 }) => {
const { nfts_enabled } = useRemoteConfig();
const nftsEnabled = (useExperimentalFlag(NFTS_ENABLED) || nfts_enabled) && !IS_TEST;

if (!nftsEnabled) return null;

return (
<View style={sx.container}>
{[...Array(items)].map((_, index) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import * as i18n from '@/languages';
import { ListHeaderMenu } from '@/components/list/ListHeaderMenu';
import { NftCollectionSortCriterion } from '@/graphql/__generated__/arc';
import useNftSort from '@/hooks/useNFTsSortBy';
import { useRemoteConfig } from '@/model/remoteConfig';
import { NFTS_ENABLED, useExperimentalFlag } from '@/config';
import { IS_TEST } from '@/env';

const TokenFamilyHeaderHeight = 48;

Expand All @@ -30,7 +33,12 @@ const getMenuItemIcon = (value: NftCollectionSortCriterion) => {
};

const CollectiblesHeader = () => {
const { nfts_enabled } = useRemoteConfig();
const nftsEnabled = (useExperimentalFlag(NFTS_ENABLED) || nfts_enabled) && !IS_TEST;
const { nftSort, updateNFTSort } = useNftSort();

if (!nftsEnabled) return null;

return (
<Box
height={{ custom: TokenFamilyHeaderHeight }}
Expand Down
9 changes: 9 additions & 0 deletions src/components/asset-list/RecyclerAssetList2/WrappedNFT.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { UniqueAsset } from '@/entities';
import { useCollectible } from '@/hooks';
import { useNavigation } from '@/navigation';
import Routes from '@/navigation/routesNames';
import { useRemoteConfig } from '@/model/remoteConfig';
import { NFTS_ENABLED, useExperimentalFlag } from '@/config';
import { IS_TEST } from '@/env';

export default React.memo(function WrappedNFT({
onPress,
Expand All @@ -21,6 +24,9 @@ export default React.memo(function WrappedNFT({
placement: 'left' | 'right';
externalAddress?: string;
}) {
const { nfts_enabled } = useRemoteConfig();
const nftsEnabled = (useExperimentalFlag(NFTS_ENABLED) || nfts_enabled) && !IS_TEST;

const assetCollectible = useCollectible(uniqueId, externalAddress);

const asset = useMemo(
Expand Down Expand Up @@ -58,6 +64,9 @@ export default React.memo(function WrappedNFT({
alignItems: 'flex-end',
paddingRight: '19px (Deprecated)',
};

if (!nftsEnabled) return null;

return (
<Box flexGrow={1} justifyContent="center" testID={`wrapped-nft-${asset.name}`} {...placementProps}>
<UniqueTokenCard item={asset} onPress={onPress || handleItemPress} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React from 'react';
import { TokenFamilyHeader } from '../../token-family';
import { useLatestCallback, useOpenFamilies } from '@/hooks';
import { ThemeContextProps } from '@/theme';
import { useRemoteConfig } from '@/model/remoteConfig';
import { NFTS_ENABLED, useExperimentalFlag } from '@/config';
import { IS_TEST } from '@/env';

type Props = {
name: string;
Expand All @@ -12,6 +15,9 @@ type Props = {
};

export default React.memo(function WrappedTokenFamilyHeader({ name, total, image, theme, testID }: Props) {
const { nfts_enabled } = useRemoteConfig();
const nftsEnabled = (useExperimentalFlag(NFTS_ENABLED) || nfts_enabled) && !IS_TEST;

const { openFamilies, updateOpenFamilies } = useOpenFamilies();
const isFamilyOpen = openFamilies[name];

Expand All @@ -21,6 +27,8 @@ export default React.memo(function WrappedTokenFamilyHeader({ name, total, image
})
);

if (!nftsEnabled) return null;

return (
<TokenFamilyHeader
childrenAmount={total}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { LegacyRef, useCallback, useEffect, useMemo, useRef } from 'react';
import React, { LegacyRef, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
import { LayoutChangeEvent } from 'react-native';
import { SetterOrUpdater } from 'recoil';
import { DataProvider, RecyclerListView } from 'recyclerlistview';
Expand All @@ -21,6 +21,9 @@ import { useTheme } from '@/theme';
import { remoteCardsStore } from '@/state/remoteCards/remoteCards';
import { useRoute } from '@react-navigation/native';
import Routes from '@/navigation/routesNames';
import { useRemoteConfig } from '@/model/remoteConfig';
import { useExperimentalFlag } from '@/config';
import { RainbowContext } from '@/helpers/RainbowContext';

const dataProvider = new DataProvider((r1, r2) => {
return r1.uid !== r2.uid;
Expand Down Expand Up @@ -54,6 +57,8 @@ const RawMemoRecyclerAssetList = React.memo(function RawRecyclerAssetList({
scrollIndicatorInsets?: object;
type?: AssetListType;
}) {
const remoteConfig = useRemoteConfig();
const experimentalConfig = useContext(RainbowContext).config;
const currentDataProvider = useMemoOne(() => dataProvider.cloneWithRows(briefSectionsData), [briefSectionsData]);
const { isCoinListEdited, setIsCoinListEdited } = useCoinListEdited();
const y = useRecyclerAssetListPosition()!;
Expand All @@ -65,8 +70,16 @@ const RawMemoRecyclerAssetList = React.memo(function RawRecyclerAssetList({
const cardIds = useMemo(() => getCardIdsForScreen(name as keyof typeof Routes), [getCardIdsForScreen, name]);

const layoutProvider = useMemo(
() => getLayoutProvider(briefSectionsData, isCoinListEdited, cardIds, isReadOnlyWallet),
[briefSectionsData, isCoinListEdited, cardIds, isReadOnlyWallet]
() =>
getLayoutProvider({
briefSectionsData,
isCoinListEdited,
cardIds,
isReadOnlyWallet,
remoteConfig,
experimentalConfig,
}),
[briefSectionsData, isCoinListEdited, cardIds, isReadOnlyWallet, experimentalConfig]
);

const { accountAddress } = useAccountSettings();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { Dimension, Layout, LayoutManager, LayoutProvider } from 'recyclerlistvi
import ViewDimensions from './ViewDimensions';
import { BaseCellType, CellType } from './ViewTypes';
import { deviceUtils } from '@/utils';
import { getRemoteConfig, RainbowConfig } from '@/model/remoteConfig';
import { NFTS_ENABLED, REMOTE_CARDS, useExperimentalFlag } from '@/config';
import { useContext } from 'react';
import { RainbowContextType } from '@/helpers/RainbowContext';
import { IS_TEST } from '@/env';

const getStyleOverridesForIndex = (indices: number[]) => (index: number) => {
if (indices.includes(index)) {
Expand Down Expand Up @@ -30,7 +35,24 @@ class BetterLayoutProvider extends LayoutProvider {
}
}

const getLayoutProvider = (briefSectionsData: BaseCellType[], isCoinListEdited: boolean, cardIds: string[], isReadOnlyWallet: boolean) => {
const getLayoutProvider = ({
briefSectionsData,
isCoinListEdited,
cardIds,
isReadOnlyWallet,
experimentalConfig,
remoteConfig,
}: {
briefSectionsData: BaseCellType[];
isCoinListEdited: boolean;
cardIds: string[];
isReadOnlyWallet: boolean;
experimentalConfig: ReturnType<typeof useContext<RainbowContextType>>['config'];
remoteConfig: RainbowConfig;
}) => {
const remoteCardsEnabled = (remoteConfig.remote_cards_enabled || experimentalConfig[REMOTE_CARDS]) && !IS_TEST;
const nftsEnabled = (remoteConfig.nfts_enabled || experimentalConfig[NFTS_ENABLED]) && !IS_TEST;

const indicesToOverride = [];
for (let i = 0; i < briefSectionsData.length; i++) {
const val = briefSectionsData[i];
Expand All @@ -55,7 +77,24 @@ const getLayoutProvider = (briefSectionsData: BaseCellType[], isCoinListEdited:
dim.height = ViewDimensions[type].height;
dim.width = ViewDimensions[type].width || dim.width;

if ((type === CellType.REMOTE_CARD_CAROUSEL && !cardIds.length) || (type === CellType.REMOTE_CARD_CAROUSEL && isReadOnlyWallet)) {
// NOTE: If NFTs are disabled, we don't want to render the NFTs section, so adjust the height to 0
if (
[
CellType.NFTS_EMPTY,
CellType.NFTS_HEADER_SPACE_AFTER,
CellType.NFTS_HEADER_SPACE_BEFORE,
CellType.NFTS_HEADER,
CellType.NFTS_LOADING,
CellType.NFT,
CellType.FAMILY_HEADER,
].includes(type) &&
!nftsEnabled
) {
dim.height = 0;
}

// NOTE: If remote cards are disabled, we don't want to render the remote cards section, so adjust the height to 0
if (type === CellType.REMOTE_CARD_CAROUSEL && (!remoteCardsEnabled || !cardIds.length || isReadOnlyWallet)) {
dim.height = 0;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function ProfileAvatarRow({ size = ProfileAvatarSize }: { size?: number }
const ContextMenuButton = onAvatarPressProfile ? React.Fragment : ContextMenu;

const handlePressMenuItem = useLatestCallback((e: any) => {
const index = avatarContextMenuConfig.menuItems?.findIndex(item => item.actionKey === e.nativeEvent.actionKey);
const index = avatarContextMenuConfig?.menuItems?.findIndex(item => item && item.actionKey === e.nativeEvent.actionKey);
onSelectionCallback(index);
});

Expand Down
2 changes: 2 additions & 0 deletions src/config/experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const DAPP_BROWSER = 'Dapp Browser';
export const ETH_REWARDS = 'ETH Rewards';
export const DEGEN_MODE = 'Degen Mode';
export const FEATURED_RESULTS = 'Featured Results';
export const NFTS_ENABLED = 'Nfts Enabled';

/**
* A developer setting that pushes log lines to an array in-memory so that
Expand Down Expand Up @@ -66,6 +67,7 @@ export const defaultConfig: Record<string, ExperimentalValue> = {
[ETH_REWARDS]: { settings: true, value: false },
[DEGEN_MODE]: { settings: true, value: false },
[FEATURED_RESULTS]: { settings: true, value: false },
[NFTS_ENABLED]: { settings: true, value: false },
};

const storageKey = 'config';
Expand Down
1 change: 0 additions & 1 deletion src/config/experimentalHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import isTestFlight from '@/helpers/isTestFlight';

const useExperimentalFlag = (name: any) => {
if (IS_DEV || isTestFlight) {
// @ts-expect-error ts-migrate(2339) FIXME: Property 'config' does not exist on type '{}'.
// eslint-disable-next-line react-hooks/rules-of-hooks
return useContext(RainbowContext).config[name];
} else {
Expand Down
15 changes: 13 additions & 2 deletions src/helpers/RainbowContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSharedValue } from 'react-native-reanimated';
import DevButton from '../components/dev-buttons/DevButton';
import Emoji from '../components/text/Emoji';
import { showReloadButton, showSwitchModeButton, showConnectToHardhatButton } from '../config/debug';
import { defaultConfig } from '../config/experimental';
import { defaultConfig } from '@/config/experimental';
import { useDispatch } from 'react-redux';

import { useTheme } from '../theme/ThemeContext';
Expand All @@ -16,7 +16,18 @@ import { Navigation } from '@/navigation';
import Routes from '@rainbow-me/routes';
import { useConnectedToHardhatStore } from '@/state/connectedToHardhat';

export const RainbowContext = createContext({});
export type RainbowContextType = {
config: Record<keyof typeof defaultConfig, boolean>;
setConfig: (newConfig: Record<string, boolean>) => void;
setGlobalState: (newState: any) => void;
};

export const RainbowContext = createContext<RainbowContextType>({
config: {},
setConfig: () => {},
setGlobalState: () => {},
});

const storageKey = 'config';

const storage = new MMKV({
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useImportingWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default function useImportingWallet({ showImportModal = true } = {}) {
}
setResolvedAddress(address);
name = forceEmoji ? `${forceEmoji} ${input}` : input;
avatarUrl = avatarUrl || avatar?.imageUrl;
avatarUrl = avatarUrl || (avatar && avatar?.imageUrl);
setBusy(false);
startImportProfile(name, guardedForceColor, address, avatarUrl);
analytics.track('Show wallet profile modal for ENS address', {
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/useOnAvatarPress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export default ({ screenType = 'transaction' }: UseOnAvatarPressProps = {}) => {
].filter(x => x),
};

const avatarActionSheetOptions = avatarContextMenuConfig.menuItems.map(item => item.actionTitle).concat(ios ? ['Cancel'] : []);
const avatarActionSheetOptions = avatarContextMenuConfig.menuItems.map(item => item && item.actionTitle).concat(ios ? ['Cancel'] : []);

const onAvatarPressProfile = useCallback(() => {
navigate(Routes.PROFILE_SHEET, {
Expand Down
5 changes: 4 additions & 1 deletion src/model/remoteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export interface RainbowConfig extends Record<string, string | boolean | number>

degen_mode: boolean;
featured_results: boolean;
nfts_enabled: boolean;
}

export const DEFAULT_CONFIG: RainbowConfig = {
Expand Down Expand Up @@ -175,6 +176,7 @@ export const DEFAULT_CONFIG: RainbowConfig = {

degen_mode: false,
featured_results: false,
nfts_enabled: true,
};

export async function fetchRemoteConfig(): Promise<RainbowConfig> {
Expand Down Expand Up @@ -230,7 +232,8 @@ export async function fetchRemoteConfig(): Promise<RainbowConfig> {
key === 'idfa_check_enabled' ||
key === 'rewards_enabled' ||
key === 'degen_mode' ||
key === 'featured_results'
key === 'featured_results' ||
key === 'nfts_enabled'
) {
config[key] = entry.asBoolean();
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/screens/points/PointsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ export function PointsScreen() {
<Navbar
hasStatusBarInset
leftComponent={
pointsEnabled && (
pointsEnabled ? (
<ButtonPressAnimation onPress={() => navigate(Routes.CHANGE_WALLET_SHEET)} scaleTo={0.8} overflowMargin={50}>
{accountImage ? (
<ImageAvatar image={accountImage} marginRight={10} size="header" />
) : (
<ContactAvatar color={accountColor} marginRight={10} size="small" value={accountSymbol} />
)}
</ButtonPressAnimation>
)
) : null
}
rightComponent={pointsNotificationsToggleEnabled ? <NotificationToggleContextMenu /> : undefined}
title={rewardsEnabled ? i18n.t(i18n.l.account.tab_rewards) : i18n.t(i18n.l.account.tab_points)}
Expand Down

0 comments on commit 4ca3624

Please sign in to comment.